我正在使用Delphi Rio来控制Excel,我正在读写整列数据,所以我使用VarArrayCreate来创建数组变体来读取一列数据。 我正在读取和写入整列数据,因此我使用VarArrayCreate来创建一个Variant数组来读取一列的数据。 我更新数据的特定部分,然后将更新内容写回Variant数组。完成后,我将整个Variant数组写回我的列。
当我在数组中循环时,我读取数组中的一个元素......并有可能写回数组中的那个元素......。
... read from the array
CellText := arrData[i, 1];
... possibly update data
... write the updated data back to the array
arrData[i,1] := CellPadded;
这样做没有问题。 我的问题是如何将更新写回数组。 我遇到了函数VarArrayPut。 为什么我要使用这个函数,而不是像上面的代码那样直接把数据放回数组?
简单的答案是 VarArrayPut
和数组访问器一样(方括号语法),最后它们都调用内部过程 _VarArrayPut
单位 System.Variants
. 同样地,使用方括号或 VarArrayGet
将导致调用内部函数 _VarArrayGet
. 你可以很容易地自己检查,通过步入(F7)的转让 arrData[i, 1] := CellPadded;
在调试过程中。
也就是说,变数组访问器只是Delphi编译器提供的一种语法糖,目的是让代码更短,更易读,但这是个人口味的问题。可以考虑下面的情况。
arrData[i, 1] := CellPadded;
{ vs }
VarArrayPut(arrData, CellPadded, [i, 1]);
如果你做了大量的数据处理 而且你在处理过程中没有调整数组的大小,你可以用 VarArrayLock
.. VarArrayUnlock
块来获得一些额外的性能,通过直接访问数组数据,绕过所有理智检查和API调用,以获得额外的性能 _VarArrayGet
和 _VarArrayPut
在内部做。
{ untested, use at your own risk }
{$POINTERMATH ON}
var
Data: PVariant; { in case of variant array of varVariant }
LBound1, LBound2, HBound2: Integer;
Data := VarArrayLock(arrData);
try
LBound1 := VarArrayLowBound(V, 1);
LBound2 := VarArrayLowBound(V, 2);
HBound2 := VarArrayHighBound(V, 2);
{ access element value at [i, j] }
(Data + i - LBound1 + (j - LBound2) * (HBound2 - LBound2 + 1))^ := CellPadded;
{ ... }
finally
VarArrayUnlock(arrData);
end;
当然,这对锯齿状的数组是行不通的。