我正在处理一个用 VB6 编写的遗留应用程序,它读取 Excel 电子表格并将它们插入数据库。
它在大多数情况下都有效,但如果电子表格中的数据不是从第一行开始,则第一个数据行会重复。
例如,电子表格中的前 3 行是空白的,前 4 行数据如下所示:
_| 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)。如果我使用语句选择整个工作表,则可以确认这一点 - 它只返回数据块。
因此,当我选择该范围之外的任何单元格时,提供者不会执行返回 null 之类的明智操作,而是从该特定列的最上面的非空单元格返回数据。
我可以假设更改系统,使其简单地获取所有数据并假设最左上角的单元格是单元格 A1,但这会破坏与已经存在的数据的兼容性。
我现在需要的是一种方法来获取返回数据的单元格引用,以便我可以适当地对待它,或者一种强制这种情况不再发生的方法。