Collectives™ on Stack Overflow
Find centralized, trusted content and collaborate around the technologies you use most.
Learn more about Collectives
Teams
Q&A for work
Connect and share knowledge within a single location that is structured and easy to search.
Learn more about Teams
Delphi Tokyo - I am using Delphi to do some Excel spreadsheet pre-processing prior to a load operation. I am trying to read an Excel Range into a VarArray, loop through the array to do cleanup (in this case, it is a zip code column. If it is a 4 digit zipcode, prefix a '0'), and then write the VarArray back to the Excel range. Everything compiles, but I get an error message on the first access of the VarArray. The specific error is 'Variant or safe array index out of bounds'. My VarArray starts at row 2 of the excel range. Any idea why I am getting this error?
I have tried to simplify the code as much as possible here....
function PROCESS_ZIP_CODE_5DIGIT_MIN(P1,P2 : String): integer;
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;
// Now write the VarArray back to the spreadsheet
thisSheet.range[RangeStartAddr, RangeEndAddr].Value2 := myRange;
–
–
–
–
I'm not going to try to sort out your code, because it has a bunch of errors in it.
Here's a working sample of code to retrieve a range of cells (in this case, H1
through the last populated cell in J
) into a variant array and then put that array into a Delphi TStringGrid
. While the code uses late binding instead of early binding, it pretty clearly demonstrates the proper use of VarArrayCreate
when reading a range from Excel.
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');
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;
–
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.