Delphi, передайте массив выходных параметров - PullRequest
0 голосов
/ 05 июля 2018

У меня есть десятки функций, которые запрашивают одну таблицу, проверяют, есть ли в ней записи в гигантском массиве, обновляют или вставляют по мере необходимости.

Это выглядит примерно так:

function UpdateTableA;
var
    AFieldA,
    AFieldB,
    (...),
    AFieldZ: TField;
begin
    FSqlQuery.SQL.Text :=
        'select fielda, fieldb, (...), fieldz '+
        'from tablea '+
        'where id in (0, 1, 5, 7, 8, (...))'
    ;
    FClientDataset.Open; // this client is connected to FSqlQuery

    AFieldA := FClientDataset.FieldByName('fielda');
    AFieldB := FClientDataset.FieldByName('fieldb');
    (...)
    AFieldZ := FClientDataset.FieldByName('fieldz');

    for Obj in GLongArray do
    begin
        if FClientDataset.locate('id', Obj.id, []) then
            FClientDataset.Edit
        else
            FClientDataset.Insert;

        AFieldA.AsInteger := Obj.ValueA;
        AFieldB.AsInteger := Obj.ValueB;
        (...)
    end;
end;

Могу ли я создать функцию, в которой я передаю все переменные TField внутри массива и инициализирую их там?

Примерно так: (псевдокод)

function SetTFields(AFields: array of out TField);
begin
    for I := 0 to FClientDataset.Fields.Count-1 do
        AFields[I] := FClientDataset.Fields[I];
end;

и после открытия FClientDataset используйте его так:

SetTFields([AFieldA, AFieldB, AFieldC, AFieldD, etc])
or this:
SetTFields([@AFieldA, @AFieldB, @AFieldC, @AFieldD, etc])

Если нет, то есть ли подобный способ сделать это, не включающий в себя копирование большого количества переменных?

1 Ответ

0 голосов
/ 05 июля 2018

Вы можете использовать что-то вроде этого:

type
  PField: ^TField;

function SetTFields(AFields: array of PField);
begin
  for I := 0 to FClientDataset.Fields.Count-1 do
    AFields[I]^ := FClientDataset.Fields[I];
end;

function UpdateTableA;
var
  AFieldA,
  AFieldB,
  (...),
  AFieldZ: TField;
begin
  FSqlQuery.SQL.Text := 'select fielda, fieldb, (...), fieldz '+
    'from tablea '+
    'where id in (0, 1, 5, 7, 8, (...))';
  FClientDataset.Open; // this client is connected to FSqlQuery

  SetTFields([@AFieldA, @AFieldB, (...), @AFieldZ]);

  for Obj in GLongArray do
  begin
    if FClientDataset.Locate('id', Obj.id, []) then
      FClientDataset.Edit
    else
      FClientDataset.Insert;

    AFieldA.AsInteger := Obj.ValueA;
    AFieldB.AsInteger := Obj.ValueB;
    (...)
  end;
end;

Или вы можете использовать динамический массив вместо отдельных переменных, например:

type
  TFieldArray: array of TField;

function SetTFields(out AFields: TFieldArray);
begin
  SetLength(AFields, FClientDataset.Fields.Count);
  for I := 0 to FClientDataset.Fields.Count-1 do
    AFields[I] := FClientDataset.Fields[I];
end;

function UpdateTableA;
var
  AFields: TFieldArray;
begin
  FSqlQuery.SQL.Text := 'select fielda, fieldb, (...), fieldz '+
    'from tablea '+
    'where id in (0, 1, 5, 7, 8, (...))';
  FClientDataset.Open; // this client is connected to FSqlQuery

  SetTFields(AFields);

  for Obj in GLongArray do
  begin
    if FClientDataset.Locate('id', Obj.id, []) then
      FClientDataset.Edit
    else
      FClientDataset.Insert;

    AFields[0].AsInteger := Obj.ValueA;
    AFields[1].AsInteger := Obj.ValueB;
    (...)
  end;
end;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...