Delphi-使用VarArrayCreate在Excel数据范围内循环
Delphi Tokyo-我正在使用Delphi在加载操作之前进行一些Excel电子表格预处理。我正在尝试将Excel区域读取到VarArray中,在数组中循环以进行清理(在本例中,它是一个邮政编码列。如果它是4位zipcode,则前缀为“0”),然后将VarArray写回Excel区域。一切都编译好了,但我在第一次访问VarArray时收到一条错误消息。具体错误为“变量或安全数组索引超出范围”。我的VarArray从excel范围的第2行开始。知道我为什么会犯这个错误吗? 我已经尝试在这里尽可能地简化代码Delphi-使用VarArrayCreate在Excel数据范围内循环,excel,delphi,Excel,Delphi,Delphi Tokyo-我正在使用Delphi在加载操作之前进行一些Excel电子表格预处理。我正在尝试将Excel区域读取到VarArray中,在数组中循环以进行清理(在本例中,它是一个邮政编码列。如果它是4位zipcode,则前缀为“0”),然后将VarArray写回Excel区域。一切都编译好了,但我在第一次访问VarArray时收到一条错误消息。具体错误为“变量或安全数组索引超出范围”。我的VarArray从excel范围的第2行开始。知道我为什么会犯这个错误吗? 我已经尝试在这里尽可
function PROCESS_ZIP_CODE_5DIGIT_MIN(P1,P2 : String): integer;
var
MyColumnLetter : String;
thisSheet : _Worksheet;
i : Integer;
CellText : String;
arrData: Variant;
myRange : ExcelRange;
RangeStartAddr, RangeEndAddr : String;
begin
MyColumnLetter := 'H';
thisSheet := oExcel.ActiveSheet as _Worksheet;
{create variant array where we'll copy our data}
arrData := VarArrayCreate([2, 500 ], varVariant);
// Get the Range Address
RangeStartAddr := MyColumnLetter + '2';
RangeEndAddr := MyColumnLetter + IntToStr(500);
// Now read the data into the VarArray
myRange := thisSheet.range[RangeStartAddr, RangeEndAddr];
arrData := myRange.Value2;
// Now process the data itself
for i := 2 to 500 do
begin
CellText := arrData[i]; // ERROR ON THIS LINE
if Length(CellText) = 4 then
begin
CellText:= '0' + CellText;
arrData[i] := CellText;
end;
end;
// Now write the VarArray back to the spreadsheet
thisSheet.range[RangeStartAddr, RangeEndAddr].Value2 := myRange;
end;
我不会尝试整理你的代码,因为它有一堆错误 下面是一个工作代码示例,用于将一系列单元格(在本例中,
H1
通过J
中最后填充的单元格)检索到变量数组中,然后将该数组放入DelphiTStringGrid
。虽然代码使用后期绑定而不是早期绑定,但它清楚地演示了在从Excel读取范围时如何正确使用VarArrayCreate
var
Excel, Book, Sheet, Range1: OleVariant;
i, j: Integer;
Data: Variant;
const
// Obtained at https://msdn.microsoft.com/en-us/library/office/ff820880.aspx
xlDown = -4121;
begin
Excel := CreateOleObject('Excel.Application');
try
Book := Excel.WorkBooks.Open('E:\TempFiles\Test.xlsx');
Sheet := Book.Worksheets.Item['Sheet1'];
// Get tne range we want to extract, in this case all rows of columns H-J.
// .End(xlDown) finds the last used cell in the indicated column
Range1 := Sheet.Range['H1', Sheet.Range['J1'].End[xlDown]];
Data := Range1.Value;
// Get the number of columns and rows from the array itself. The addition
// of 1 is for the fixed row and column, and to synch up with the Data
// array being 1 based instead of 0
StringGrid1.ColCount := VarArrayHighBound(Data, 2) + 1;
StringGrid1.RowCount := VarArrayHighBound(Data, 1) + 1;
// StringGrid.Cells are accessed in Col, Row order, but the
// array is returned in Row, Col layout. Note the swap in
// i and j below in the subscripts to accomodate that fact.
for i := 1 to StringGrid1.ColCount - 1 do
for j := 1 to StringGrid1.RowCount - 1 do
StringGrid1.Cells[i, j] := Data[j, i];
finally
// Clean up all references so Excel will close cleanly
Range1 := null;
Sheet := null;
Book := null;
Excel.Quit;
Excel := null;
end;
我不会尝试整理你的代码,因为它有一堆错误 下面是一个工作代码示例,用于将一系列单元格(在本例中,
H1
通过J
中最后填充的单元格)检索到变量数组中,然后将该数组放入DelphiTStringGrid
。虽然代码使用后期绑定而不是早期绑定,但它清楚地演示了在从Excel读取范围时如何正确使用VarArrayCreate
var
Excel, Book, Sheet, Range1: OleVariant;
i, j: Integer;
Data: Variant;
const
// Obtained at https://msdn.microsoft.com/en-us/library/office/ff820880.aspx
xlDown = -4121;
begin
Excel := CreateOleObject('Excel.Application');
try
Book := Excel.WorkBooks.Open('E:\TempFiles\Test.xlsx');
Sheet := Book.Worksheets.Item['Sheet1'];
// Get tne range we want to extract, in this case all rows of columns H-J.
// .End(xlDown) finds the last used cell in the indicated column
Range1 := Sheet.Range['H1', Sheet.Range['J1'].End[xlDown]];
Data := Range1.Value;
// Get the number of columns and rows from the array itself. The addition
// of 1 is for the fixed row and column, and to synch up with the Data
// array being 1 based instead of 0
StringGrid1.ColCount := VarArrayHighBound(Data, 2) + 1;
StringGrid1.RowCount := VarArrayHighBound(Data, 1) + 1;
// StringGrid.Cells are accessed in Col, Row order, but the
// array is returned in Row, Col layout. Note the swap in
// i and j below in the subscripts to accomodate that fact.
for i := 1 to StringGrid1.ColCount - 1 do
for j := 1 to StringGrid1.RowCount - 1 do
StringGrid1.Cells[i, j] := Data[j, i];
finally
// Clean up all references so Excel will close cleanly
Range1 := null;
Sheet := null;
Book := null;
Excel.Quit;
Excel := null;
end;
您尝试过VarArrayPut吗?在
arrData:=VarArrayCreate([2500],varvarvariant)之后代码>使用arrData:=myRange.Value2为arrData赋值代码>,该赋值将覆盖var数组。这是否也返回一个var数组?@nil:即使它也返回一个var数组,它仍然会覆盖使用VarArrayCreate
创建的数组。我认为没有必要调用VarArrayCreate
。新数组可以有不同的边界。在进入循环之前必须检查这些。我的代码示例基于这里的工作。。。它将stringGrid复制到Excel。显然我做错了什么…:(您的代码示例不同。您使用字符串访问单元格(MyColumnLetter+'2'
),而它们使用数字:[wb.workSheets[1]。单元格[1,1]等。)
。你确定收到了什么吗?而且你可能也需要一个二维数组,即使二维数组的大小只有1。只需逐字尝试他们的exampe,然后根据需要修改它,不断检查它是否仍然有效。如果出现问题,你知道你最后做了什么,这一定是问题所在。你试过VararyPU吗t?在arrData:=VarArrayCreate([2500],varVariant)之后;
您使用arrData:=myRange.Value2;
为arrData赋值,该赋值将覆盖您的var数组。这是否也返回一个var数组?@nil:即使它也返回一个var数组,它仍然会覆盖使用VarArrayCreate
创建的数组。我认为调用VarArrayCreate
是不必要的Y.和新数组可能有不同的边界。在进入循环之前必须检查这些边界。我的代码示例基于此处的工作…将stringGrid复制到Excel。显然我做错了…:(您的代码示例不同。您使用字符串访问单元格(MyColumnLetter+'2'
),而它们使用数字:[wb.workSheets[1]。单元格[1,1]等
。你确定收到了什么吗?而且你可能也需要一个二维数组,即使二维数组的大小只有1。只需逐字尝试他们的exampe,然后根据你的需要修改它,不断检查它是否仍然有效。如果出了问题,你知道你最后做了什么,这一定是问题所在。这给了我eeded。我真的很感谢这些深入的评论。仅供参考-我无法获得要编译的范围1:=行(Excel 2016),因此我不得不更改它。如果我更改范围,使其从H1到H50,我会预期“数据”变量是一个一维数组,但它仍然是二维的(根据VarArrayDimCount(数据))。你能解释一下原因吗?这给了我所需的信息。我非常感谢你的深入评论。仅供参考-我无法获得要编译的Range1:=行(Excel 2016)所以我必须改变它。如果我改变范围,使它从H1到H50,我会期望“数据”变量是一个一维数组,但它仍然是二维的(根据VarArrayDimCount(Data)。你能解释为什么吗?