我正在處理用VB6編寫的遺留應用程序,它讀取Excel電子表格並將它們插入到數據庫中。
它可以工作,但如果電子表格中的數據沒有從第一行開始,則第一個數據行將被複制。
說,例如在電子表格中的第一3行是空白的,數據的前四列如下所示:如何防止VB6中的Microsoft ACE和JET複製Excel電子表格中第一行的數據?
_| A | B | C | D | E | F | G |
1| | | | | | | |
2| | | | | | | |
3| | | | | | | |
4| 99 |Text1|Text2|Text3|Text4|Text5| 77 |
應用程序連接到Excel電子表格和在使用以下代碼讀取它:
Public Function obtainConnectionExcel(sql_conn, uid) As Variant
Dim cn As Object
Set cn = CreateObject("ADODB.Connection")
On Error Resume Next
cn.Provider = "Microsoft.ACE.OLEDB.12.0"
cn.Properties("Extended Properties").Value = "Excel 12.0;ReadOnly=True;HDR=No;IMEX=1"
If (Err <> 0) Then
cn.Provider = "Microsoft.Jet.OLEDB.4.0"
cn.Properties("Extended Properties").Value = "Excel 8.0;ReadOnly=True;HDR=No;IMEX=1"
End If
On Error Resume Next
cn.open getSpreadsheetPath(sql_conn, uid)
Set obtainConnectionExcel = cn
Exit Function
End Function
.....
Public Function extractAllData(parameters) As String
..... 'Variable declarations etc
On Error Resume Next
Set dbo_conn = obtainConnectionExcel(sql_conn, uid)
If Err <> 0 Then
....'logs error, goes to error handler
End If
On Error GoTo ErrorHandler
If (dbo_conn.State = 1) Then
rownumber = 1
Do While rownumber <= numberOfRowsToGet
For x = lettercount To lettercount + lettercount_offset
letter = Chr(x)
sSql = "SELECT * FROM [" & worksheet & "$" & letter & rownumber & ":" & letter & rownumber & "]"
On Error Resume Next
Set rs = dbo_conn.execute(sSql)
If (Not rs.EOF) Then
'inserts the data into the db
End If
Next x
rownumber = rownumber + 1
Loop
.... 'Post processing
Exit Function
....'Error handlers
End Function
這應該是相關的代碼。發生在線路的問題:
sSql = "SELECT * FROM [" & worksheet & "$" & letter & rownumber & ":" & letter & rownumber & "]"
On Error Resume Next
Set rs = dbo_conn.execute(sSql)
當數據被讀取,無論我們使用JET或ACE,數據返回是這樣的:
_| A | B | C | D | E | F | G |
1| 99 | | | | | | 77 |
2| 99 | | | | | | 77 |
3| 99 |Text1|Text2|Text3|Text4|Text5| 77 |
4| 99 |Text1|Text2|Text3|Text4|Text5| 77 |
我曾嘗試連接到電子表格並以多種方式獲取數據,但似乎沒有任何工作 - 連接將失敗,或者數據只會是空值。
我找到了一些解決方法 - 例如,如果我在單元格A1中輸入空格字符,問題不再發生。但是,我想要一個基於程序的解決方案,而不是告訴用戶採取額外的步驟來避免這種情況。
它只複製第一行數據。如果單元格中的數據是一個數字,那麼它會將數據複製到該列上方的每個單元格中,如果它是文本,那麼它只會上升一個級別。
有趣的是,如果我改變電子表格來表示所有的數據都是文本,那麼它就會複製每個單元格,就好像它們是數字一樣(即在上面的每個單元格中,而不是單個單元格中)
總而言之,這是相當令人生氣的 - 因爲我在搜索這個問題時沒有任何運氣,所以我只能斷定我們做錯了什麼,或者很少有人對這種類型的測試數據感到困擾。
[編輯]經過一番調查我解決了這個已經取得了一些進展 - 「提供者假定你的數據表最上面,最左邊的非空指定工作表上的細胞開始」 (http://support.microsoft.com/default.aspx?scid=kb;en-us;257819)。如果我使用語句來選擇整個工作表,這是確認 - 它只返回數據塊。
因此,當我選擇任何超出該範圍的單元格時,提供程序(而不是像返回空值這樣明智的操作)將從該特定列的最上面的非空單元格返回數據。
我可以假設地改變系統,以便它抓住所有的數據,並假定最上面最左邊的單元格是單元格A1,但這會破壞已經存在的數據的兼容性。
我現在需要的是一種獲取返回數據的單元格引用的方式,所以我可以適當地對待它,或者強制它不再發生。
你可以添加調試語句記錄字符串'sSql'到一個文件(或打印或其他)每個迭代?查看您在問題中提供的每個測試行的SQL是多少有用的。 – jmtd
好吧,我不打算列出所有的(大約1250個語句),但是在我使用的測試示例中,它們是這樣的:'SELECT * FROM [Sheet1 $ A1:A1]'直到' SELECT * FROM [Sheet1 $ Z1:Z1]',然後它轉到'SELECT * FROM [Sheet1 $ A2:A2]'並重復。 – Aradiel
好的,所以您對電子表格的每個* Cell *有一個SQL查詢?查詢後「rs」的值是多少?你可以檢查它,看看它是否是空字符串,如果是,跳過該行的其餘部分? – jmtd