Reputation: 9096
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?
Upvotes: 1
Views: 1317
Reputation: 613013
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.
Upvotes: 2