Я имею дело с унаследованным приложением, написанным на VB6, которое читает электронные таблицы Excel и вставляет их в базу данных.Это работает по большей части, но если данные в электронной таблице не начинаются с первой строки, первая строка данных дублируется.Скажем, например, что первые 3 строки в электронной таблице пустые, верхние четыре строки данных выглядят следующим образом:
_| 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 |
IЯ пытался подключиться к электронной таблице и получать данные множеством способов, но, похоже, ничего не работает - либо соединение не будет установлено, либо данные будут просто пустыми.Я нашел некоторые обходные пути - например, если я введу пробел в ячейку A1, проблема больше не возникает.Тем не менее, я хотел бы получить программное решение, вместо того, чтобы заставлять пользователей делать дополнительные шаги, чтобы избежать этого.Он только копирует первый ряд данных.Если данные в ячейке являются числом, то они копируют данные в каждую ячейку над ним в этом столбце, если это текст, то они повышаются только на один уровень.Интересно отметить, что, если я изменю электронную таблицу, чтобы сказать, что все данные являются текстовыми, он затем копирует каждую ячейку, как если бы они были числами (т.е. в каждую ячейку выше, а не в одну строку)
В целом это довольно раздражает - так как мне не везет при поиске этой проблемы, я могу только сделать вывод, что мы делаем что-то не так, или очень мало людей обеспокоены этим типом тестаданные.
[править] После некоторых исследований я добился определенных успехов в решении этой проблемы: «Поставщик предполагает, что ваша таблица данных начинается с самой верхней, самой левой, непустой ячейки на указанном рабочем листе»(http://support.microsoft.com/default.aspx?scid=kb;en-us;257819).Это подтверждается, если я использую инструкцию для выбора всего листа - он возвращает только блок данных.Поэтому, когда я выбираю любую ячейку, находящуюся за пределами этого диапазона, провайдер вместо того, чтобы делать что-то разумное, например, возвращать ноль, возвращает данные из самой верхней непустой ячейки из этого конкретного столбца.Я мог бы гипотетически изменить систему так, чтобы она просто собирала все данные и предполагала, что самая верхняя левая ячейка - это ячейка A1, но это нарушит совместимость с данными, которые уже существуют.Теперь мне нужен способ получения ссылок на ячейки для возвращаемых данных, чтобы я мог относиться к ним соответствующим образом, или способ заставить это больше не происходить.