Question

I have inherited this code:

var
  FSavedRecords : Variant;  { actually, a private property in an ancestor }
  lFieldsArray  : Variant;
  lClientDataSet: TClientDataSet;

  FSavedRecords := VarArrayCreate([0, lCount], varVariant);

  for lRow := 0 to lCount do
  begin
    FSavedRecords[lRow] := VarArrayCreate([0, lClientDataSet.FieldCount-1], varVariant);
    with lClientDataSet do
      begin
        lFieldsArray := FSavedRecords[lRow];
        if <SomeCondition> then
           put lClientDataSet field values into lFieldsArray

Since the condition is not always true, I end up with fewer than lCount(+1) elements in FSavedRecords.
I can count those of course (say: lNrOutput), but cannot do a SetLength(FSavedRecords,lNrOutput) ('Constant object cannot be passed as a var parameter').

If SetLength() cannot be used, I assume I can convert the variant array to a dynamic 'array of Variant' with DynArrayFromVariant and use SetLength on that, but this has the disadvantage of the extra copy operation. I would like to re-use the private FSavedRecords from an ancestor form, which is used in other places in the program for the same purpose.

Is there maybe a better way out?

Was it helpful?

Solution

SetLength is used to resize dynamic arrays and long strings. To resize a variant array you use VarArrayRedim.

Another option is to build your list of elements in a temporary container of type TList<T>. When you are finished, you can use the Count property of that container to size the variant array once and for all. And then you'd copy across the actual values.

I think it makes little difference which approach you use.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top