title: Delphi 2007 and Dynamic Variant Array as Var Parameter
body: <p>I have a form which allows a use to select a record and this form then returns the ID of the record and an arbitrary number of fields values that the calling form may need.  To do this, I have a function which handles creating the select form and passes all the values to and from the calling form:</p>
  
  <pre><code>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;
  </code></pre>
  
  <p>The selector form has the following public properties:</p>
  
  <pre><code>public
    Connection: TADOConnection;
    Editor: String;
    Buttons: TViewButtons;
    ID: Integer;
    RtnVals: Array of Variant;
  end;
  </code></pre>
  
  <p>And in the OK click, I have the following code:</p>
  
  <pre><code>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;
  </code></pre>
  
  <p>So, once the user clicks OK to select a record, the RtnVals array is populated with the field values of the fields to be returned.  I now need to copy these values to ARtnVals in the Execute function so that they are returned to the calling form.</p>
  
  <p>My question is how do I set the size of the ARtnVals array so that I can copy the fields?  SetLength doesn't work like it does in the OK click function above.  VarArrayRedim doesn't work either.</p>