我有一个允许用户选择记录的表单,然后这个表单返回记录的ID和调用表单可能需要的任意数量的字段值。为此,我有一个函数来处理创建选择表单并将所有值传递给调用表单和从调用表单传递:
Function Execute(AOwner: TComponent; AConnection: TADOConnection;
AEditor: String; AButtons: TViewButtons; Var AID: Integer;
Var ARtnVals: Array of Variant): TModalResult;
Var
I: Integer;
Begin
frmSelectGrid := TfrmSelectGrid.Create(AOwner);
Try
With frmSelectGrid Do
Begin
Connection := AConnection;
Editor := AEditor;
Buttons := AButtons;
ID := AID;
Result := ShowModal;
If Result = mrOK Then
Begin
AID := ID;
//VarArrayRedim(ARtnVals, Length(RtnVals)); !! Won't compile
//SetLength(ARtnVals, Length(RtnVals)); !! Won't compile either
For I := 0 To High(RtnVals) Do
ARtnVals[I] := RtnVals[I]; // Causes runtime exception
End;
End;
Finally
FreeAndNil(frmSelectGrid);
End;
End;
选择器表单具有以下公共属性:
public
Connection: TADOConnection;
Editor: String;
Buttons: TViewButtons;
ID: Integer;
RtnVals: Array of Variant;
end;
在OK点击中,我有以下代码:
Var
I, Idx, C: Integer;
// Count how many fields are being returned
C := 0;
For I := 0 To Config.Fields.Count - 1 Do
If Config.Fields[I].Returned Then
Inc(C);
// If no fields to be returned, then just exit.
If C = 0 Then
Exit;
// Set the size of the RtnVals and assign the field values to the array.
SetLength(RtnVals, C);
Idx := 0;
For I := 0 To Config.Fields.Count - 1 Do
If Config.Fields[I].Returned Then
Begin
RtnVals[Idx] := aqItems.FieldByName(Config.Fields[I].FieldName).Value;
Inc(Idx);
End;
因此,一旦用户单击“确定”选择记录,就会使用要返回的字段的字段值填充RtnVals数组。我现在需要将这些值复制到Execute函数中的ARtnVals,以便它们返回到调用表单。
我的问题是如何设置ARtnVals数组的大小以便我可以复制字段? SetLength不像上面的OK点击功能那样工作。 VarArrayRedim也不起作用。
答案 0 :(得分:6)
当在过程参数列表中写入时,此代码
Var ARtnVals: Array of Variant
是开放数组,而不是动态数组。无法调整打开的数组大小。打开数组对你没用。
而是定义数组的类型:
type
TDynamicArrayOfVariant = array of Variant;
将该类型用于您的参数,这实际上最适合作为输出参数:
function Execute(..., out RtnVals: TDynamicArrayOfVariant): TModalResult;
然后传递函数a TDynamicArrayOfVariant
进行填充。
现在,Execute
中有一个动态数组而不是一个开放数组,您可以使用SetLength
来调整它的大小。