2017-08-28 60 views
0

Delphi XE10。我需要从Excel工作表中逐行读取(制表符分隔)字符串。当您使用'选择一行 - 复制 - 粘贴到记事本'时会得到什么。工作表包含各种格式的字符串,数字和日期。 什么工作是这样的:获取excel行作为TXT字符串

function TexcelSource.nextRow: string; 
var k : integer; 
begin 
    result:=sheet.cells.items[currentRow,1].text; 
    for k:=2 to maxCol do 
     result:=result+tab+sheet.cells.items[currentRow,k].text; 
    inc(currentRow) 
end; 

,其中板材是引用到Excel工作表(VAR变):

XLApp:=createOLEobject('excel.application'); 
XLApp.Workbooks.open(filename) ; 
Sheet:=XLApp.WorkSheets[1] ; 
MaxRow:=Sheet.Usedrange.EntireRow.count ; 
MaxCol:=sheet.Usedrange.EntireColumn.count; 

然而,这是不可接受的慢。我试图导入整个工作表中的一阶段的阵列和阵列读取:

sheetData:=Sheet.UsedRange.Value; 

这是速度不够快,但我不能让所有sheetData [行,列]作为一个字符串值。它返回带有字符串值的单元格,但在具有整数值的单元格处停止,错误为'无法将类型变体(UnicodeString)转换为类型(Double)'。 (该元素的VarType似乎是vtPointer - 我不明白;我也不明白这个错误。)

我也试过通过Delphi剪贴板复制和粘贴。有一段时间,然后剪贴板变得不可用。无论如何,这不是我喜欢的一个操作系统的方法。

我很乐意提供有关如何以可接受的性能读取工作表行的建议。

+0

哪个Excel版本? – MartynA

+0

有没有这样的事情,XE10,FWIW –

回答

0

阅读一气呵成的范围是做到这一点的方式(因为你已经尝试了):

sheetData := Sheet.UsedRange.Value; 

,如果我直接在环路串联的sheetData元素我可以重现你的错误。我没有调查错误的原因。

但是,如果每个元素首先分配给一个string变量,然后将该变量连接起来,则不会出现错误。因此,与一个临时字符串变量,tmpstr以下解决方法,适用于各种数值:

for row := ... 
begin 
    rowstr := sheetData[row, 1]; 
    for col := 2 to ... 
    begin 
    tmpstr := sheetData[row, col]; 
    rowstr := rowstr + tab + tmpstr; 
    end; 
    // use rowstr as needed 
end; 

“更清洁”的方式任意单元格的值转换为字符串,是使用VarToStr()功能,其中有至少存在于Delphi 7中。

for row := ... 
begin 
    rowstr := sheetData[row, 1]; 
    for col := 2 to ... 
    rowstr := rowstr + tab + VarToStr(sheetData[row, col]); 
    // use rowstr as needed 
end; 
+0

令人惊叹。这按预期工作,速度足够快。 – user3212191