Excel中有一列數據是數字和文本方式混合排列的,在用ADO導入數據時就會出現部分數據不能導入的問題
解決這個問題 首先想到的是常用的數字轉換為文本格式的方法 WorkSheet.Columns[1].NumberFormatLocal:='@';
幾行代碼一敲,測試發現沒效果,就馬上開始 baidu,google 鋪天蓋地的搜索。。。
沒怎麼搜索就找到了Excel 中有用分列方法將整列數據文本格式化的方法:數據->分列->列數據格式->文本
錄制下的宏代碼如下:
Sub Macro2()
Columns("D:D").Select
Selection.TextToColumns Destination:=Range("D1"), DataType:=xlDelimited, _
TextQualifIEr:=xlDoubleQuote, ConsecutiveDelimiter:=False, Tab:=True, _
Semicolon:=False, Comma:=False, Space:=False, Other:=False, FIEldInfo _
:=Array(1, 2), TrailingMinusNumbers:=True
End Sub
接下來將VBA宏代碼翻譯成Delphi代碼:
WorkSheet.Columns[4].Select;
WorkSheet.Selection.TextToColumns(WorkSheet.Cells[1,4],xlDelimited,xlDoubleQuote,False,True,False,False,False,False,Array(1, 2),True);
一編譯才發現 Array(1,2) 語法錯誤,於是將其改成Delphi 中的數組格式 Array[0..1] of Integer=(1,2) ,
編譯還是報錯,發現是因為是Delphi調用OLE自動化控制器操縱Excel,該方法只能出現OleVariant類型的參數,馬上找資料看有沒有OleVariant類型的數組,一下就找到了馬上改了代碼換上去:
var a:OleVariant;
a:=VarArrayCreate([0,1],varInteger);
a[0]:=1;
a[1]:=2;
WorkSheet.Columns[4].Select;
WorkSheet.Selection.TextToColumns(WorkSheet.Cells[1,4],xlDelimited,xlDoubleQuote,False,True,False,False,False,False,a,True);
滿以為這下問題應該解決了吧,編譯通過,測試發現點都麼反應,郁悶了。。。
到底是哪點的原因呢?開始排查問題中。。。
第一個可能的原因,Excel 宏寫錯了?反復測試,都能正常運行,效果明顯。
第二個可能的原因,Delphi OLE操縱Excel 失效?測試了其他Ole代碼,都能正常運行,沒有問題。
現在就剩下一個比較確定的問題了,WorkSheet.Selection.TextToColumns 這個方法的問題。
搜索引擎中輸入"Delphi TextToColumns" 搜出來的結果寥寥可數,遇到這個問題的很少,提的問題大多都沒人回答,
許多人甚至不知所雲,千辛萬苦找到MSDN中的幫助中有 C# 調用 Excel 這個方法的示例,但是關鍵地方就是數組參數
他用空值代替了:
public Object TextToColumns(
Object Destination,
XlTextParsingType DataType,
XlTextQualifier TextQualifIEr,
Object ConsecutiveDelimiter,
Object Tab,
Object Semicolon,
Object Comma,
Object Space,
Object Other,
Object OtherChar,
Object FIEldInfo,
Object DecimalSeparator,
Object ThousandsSeparator,
Object TrailingMinusNumbers
)
private void ConvertTextToColumns()
{
Microsoft.Office.Tools.Excel.NamedRange namedRange1 =
this.Controls.AddNamedRange(this.Range["A1", missing],
"namedRange1");
namedRange1.Value2 = "01 01 2001";
Excel.Range destinationRange = this.Range["A5", missing];
namedRange1.TextToColumns(destinationRange,
Excel.XlTextParsingType.xlDelimited,
Excel.XlTextQualifier.xlTextQualifIErDoubleQuote, missing,
missing, missing, missing, true, missing, missing, missing,
missing, missing, missing);
}
反復的看幫助中對 FIEldInfo 的描述:
FIEldInfo
類型:System..::.Object
一個數組,包含各個數據列的分析信息。解釋取決於 DataType 的值。當對數據進行分隔時,此參數是一個由兩元素數組組成的數組,每個兩元素數組都指定特定列的轉換選項。第一個元素是列號(從 1 開始),第二個元素是指定如何分析列的 XlColumnDataType 常數之一。
可以是下列 XlColumnDataType 值之一:
xlGeneralFormat
xlTextFormat
xlMDYFormat
xlDMYFormat
xlYMDFormat
xlMYDFormat
xlDYMFormat
xlYDMFormat
xlEMDFormat
xlSkipColumn
只有當安裝並選擇了台語支持時,才能使用 xlEMDFormat。xlEMDFormat 指定所使用的台語紀元日期。
列說明符可以采用任何順序。如果對於輸入數據中的特定列,給定的列說明符不存在,則用 xlGeneralFormat 設置對列進行分析。
如果源數據具有固定寬度的列,則每個兩元素數組中的第一個元素都指定該列中的起始字符位置(以整數形式指定;0(零)是第一個字符)。兩元素數組的第二個元素將該列的分析選項指定為從 1 至 9 的數字,如上面列出的那樣。
還是不明所以。。。接下來就是漫長的碰運氣時間。。。。
改不同的參數運行測試,反復N次,每次都是失望的結果。就這樣被這個問題折磨了3天多的時間,我絕望了,很想放棄,因為我至少找到了數據導入出現空行的原因和解決方法,只是不能用程序實現,每次導入數據前人工操作Excel將數據格式化也不是太麻煩。但在花了這麼多時間和精力後我能放得下嗎?就這樣心甘情願的認輸?對自己說,我做不到?不!一定能行,我還沒有失敗,相反已經成功了一半了,剩下的那一半只是時間和靈感問題,這時候放棄了才是真的失敗了。稍微放松下,暫時什麼都不想,等會一定把你搞定 。打幾盤魔獸先
這一刻終於來臨,一段代碼突然給我帶來了靈感,我是不是應該把參數類型帶進去?雖然資料和幫助都沒提到,但是語法上應該是沒問題的,說做就做:
var a:OleVariant;
a:=VarArrayCreate([0,1],varInteger);
a[0]:=1;
a[1]:=2;
WorkSheet.Columns[4].Select;
WorkSheet.Columns[4].TextToColumns(WorkSheet.Cells[1,4],DataType:=xlDelimited,TextQualifier:=xlDoubleQuote,FIEldInfo:=a);
運行,測試,通過 !!!喔耶,完美解決,perfect ! 怎一個爽字了得。。。哈哈哈哈哈哈
編程也需要不拋棄,不放棄,還有一點點靈感。我能!無所不能!