procedure TDataEditDrFrm.btn8Click(Sender: TObject);
var
ExcelApp: Variant;
WorkBook: OleVariant;
ExcelRowCount, ExcelColCount: LongInt;
i, j, Row, Row1: Integer;
ExcelX, ExcelY: string;
begin
Row1 := 1;
pb1.Min := 0;
dlgOpen1.Filter := 'Excel檔案|*.xls|*.xlsx';
if dlgOpen1.Execute then begin
try
// 建立 Excel 應用程式物件
ExcelApp := CreateOleObject('Excel.Application');
WorkBook := ExcelApp.WorkBooks.Open(dlgOpen1.FileName);
ExcelApp.Visible := False; // 背景執行,不顯示 Excel 視窗
// 取得已使用區域列數
ExcelRowCount := ExcelApp.ActiveSheet.UsedRange.Rows.Count;
Row := 1;
pb1.Max := ExcelRowCount;
// 逐列讀取前兩欄資料
for i := 1 to ExcelRowCount do begin
ExcelX := ExcelApp.Cells[i, 1].Value;
ExcelY := ExcelApp.Cells[i, 2].Value;
if (ExcelX <> '') and (ExcelY <> '') then begin
// 動態擴充 StringGrid 列數
if StringGrid1.RowCount < i then
StringGrid1.RowCount := StringGrid1.RowCount + 1;
StringGrid1.Cells[0, Row] := IntToStr(Row); // 流水號
StringGrid1.Cells[1, Row] := ExcelX; // 第 1 欄
StringGrid1.Cells[2, Row] := ExcelY; // 第 2 欄
Row := Row + 1;
end;
pb1.StepBy(1); // 進度條更新
end;
finally
// 必須正確釋放 COM 物件,否則 Excel 進程殘留
WorkBook.Close;
ExcelApp.Quit;
ExcelApp := Unassigned;
WorkBook := Unassigned;
end;
end;
end;
| 技術點 | 說明 |
|---|---|
| CreateOleObject | 建立 Excel COM 物件,需機器安裝 Excel |
| WorkBooks.Open | 開啟指定檔案,支援 .xls/.xlsx |
| Visible := False | 背景模式,提升速度、不干擾使用者 |
| UsedRange.Rows.Count | 取得實際有資料的列數 (含標題列) |
| Cells[i, j].Value | 讀取指定儲存格值,回傳 Variant |
| Unassigned | 釋放 Variant 介面參考計數,關鍵步驟 |
| 進度條同步 | 大量資料時提供視覺回饋 |
finally 區塊呼叫 Quit 並設為 UnassignedValue 可能回傳 Double,用 VarToStr 或 VarToStrDef 安全轉字串VarToDateTime 轉換UsedRange.Value 一次讀取整個陣列 (Variant 陣列),再批次寫入 StringGridTExcelWorkbook、FlexCel)var
DataArray: OleVariant;
Rows, Cols: Integer;
begin
// ... 開啟 WorkBook ...
DataArray := ExcelApp.ActiveSheet.UsedRange.Value; // 一次取得二維陣列
Rows := VarArrayHighBound(DataArray, 1);
Cols := VarArrayHighBound(DataArray, 2);
StringGrid1.RowCount := Rows + 1;
for i := 1 to Rows do begin
for j := 1 to Cols do begin
StringGrid1.Cells[j-1, i] := VarToStrDef(DataArray[i, j], '');
end;
end;
// ... 釋放資源 ...
end;
此法大幅減少 COM 呼叫次數,百萬列級資料亦可在秒級完成。