У меня экспортирован веб-отчет в формате .xlsx с 3 таблицами из 3 вкладок, которые необходимо экспортировать в базу данных Access.
Человек, который собирается запустить веб-отчет, а затем скопировать данные из Excel для доступа, находится за рубежом и не может открывать и работать с самой базой данных Access. (Имеет доступ, но проблема с задержкой усложняет задачу)
Экспортированный веб-отчет не может содержать макрос, поэтому я создал книгу Excel с одним макросом, который будет считывать данные из экспортированного веб-отчета и затем добавлять их в существующие таблицы в базе данных Access.
Код ниже работает, если в таблицах базы данных нет «совпадающих первичных ключей». Но мне нужно улучшить его, чтобы он перезаписывал любые данные соответствующими первичными ключами и создавал новые записи для новых первичных ключей.
Что усложняет ситуацию, так это то, что 2 из 3 таблиц имеют 2 поля в качестве первичного ключа, а другая таблица имеет 3 поля в качестве первичного ключа.
Может кто-нибудь помочь мне с этим вопросом, пожалуйста?
(Если бы я мог сделать это прямо из WebI, это было бы замечательно, но я не смог бы найти рабочее решение.)
Table1:
- mDate: первичный ключ
- Страна: первичный ключ
Table2:
- mDate: первичный ключ
- Страна: первичный ключ
Таблица3:
- mDate: первичный ключ
- mTime: первичный ключ
- Страна: первичный ключ
Код VBA:
Sub ADOFromExcelToAccess()
' exports data from the active worksheet to a table in an Access database
' this procedure must be edited before use
Dim cn As ADODB.Connection, rs As ADODB.Recordset, r As Long
Dim wb As Workbook
Set wb = Workbooks("Exported_webi_Report")
Set wb1 = wb.Worksheets("tbl1")
Set wb2 = wb.Worksheets("tbl2")
Set wb3 = wb.Worksheets("tbl3")
' connect to the Access database
Set cn = New ADODB.Connection
cn.Open "Provider=Microsoft.ACE.OLEDB.12.0; " & _
"Data Source=\\networkdrive\database.accdb;"
' open a recordset
Set rs = New ADODB.Recordset
rs.Open "tbl1", cn, adOpenKeyset, adLockOptimistic, adCmdTable
' all records in a table
r = 8 ' the start row in the worksheet
Do While Len(wb1.Range("B" & r).Formula) > 0
' repeat until first empty cell in column A
With rs
.AddNew ' create a new record
' add values to each field in the record
.Fields("mDate") = wb1.Range("B" & r).Value
.Fields("Country") = wb1.Range("C" & r).Value
.Fields("1") = wb1.Range("D" & r).Value
.Fields("2") = wb1.Range("E" & r).Value
.Fields("3") = wb1.Range("F" & r).Value
.Fields("4") = wb1.Range("G" & r).Value
.Fields("5") = wb1.Range("H" & r).Value
.Fields("6") = wb1.Range("I" & r).Value
.Fields("7") = wb1.Range("J" & r).Value
.Fields("8") = wb1.Range("K" & r).Value
.Fields("9") = wb1.Range("L" & r).Value
' add more fields if necessary...
.Update ' stores the new record
End With
r = r + 1 ' next row
Loop
rs.Close
Set rs = Nothing
' open a recordset
Set rs = New ADODB.Recordset
rs.Open "tbl2", cn, adOpenKeyset, adLockOptimistic, adCmdTable
' all records in a table
r = 8 ' the start row in the worksheet
Do While Len(wb2.Range("B" & r).Formula) > 0
' repeat until first empty cell in column A
With rs
.AddNew ' create a new record
' add values to each field in the record
.Fields("mDate") = wb2.Range("B" & r).Value
.Fields("Country") = wb2.Range("C" & r).Value
.Fields("1") = wb2.Range("D" & r).Value
' add more fields if necessary...
.Update ' stores the new record
End With
r = r + 1 ' next row
Loop
rs.Close
Set rs = Nothing
' open a recordset
Set rs = New ADODB.Recordset
rs.Open "tbl3", cn, adOpenKeyset, adLockOptimistic, adCmdTable
' all records in a table
r = 8 ' the start row in the worksheet
Do While Len(wb3.Range("B" & r).Formula) > 0
' repeat until first empty cell in column A
With rs
.AddNew ' create a new record
' add values to each field in the record
.Fields("mDate") = wb3.Range("B" & r).Value
.Fields("mTime") = wb3.Range("C" & r).Value
.Fields("Country") = wb3.Range("D" & r).Value
.Fields("1") = wb3.Range("E" & r).Value
.Fields("2") = wb3.Range("F" & r).Value
.Fields("3") = wb3.Range("G" & r).Value
' add more fields if necessary...
.Update ' stores the new record
End With
r = r + 1 ' next row
Loop
rs.Close
Set rs = Nothing
cn.Close
Set cn = Nothing
End Sub
EDIT ::
' open a recordset
Set rs = New ADODB.Recordset
rs.Open "tbl1", cn, adOpenKeyset, adLockOptimistic, adCmdTable
' all records in a table
r = 8 ' the start row in the worksheet
Do While Len(wb1.Range("B" & r).Formula) > 0
' repeat until first empty cell in column A
With rs
.AddNew ' create a new record
' add values to each field in the record
.Fields("mDate") = wb1.Range("B" & r).Value
.Fields("Country") = wb1.Range("C" & r).Value
.Fields("1") = wb1.Range("D" & r).Value
.Fields("2") = wb1.Range("E" & r).Value
.Fields("3") = wb1.Range("F" & r).Value
.Fields("4") = wb1.Range("G" & r).Value
.Fields("5") = wb1.Range("H" & r).Value
.Fields("6") = wb1.Range("I" & r).Value
.Fields("7") = wb1.Range("J" & r).Value
.Fields("8") = wb1.Range("K" & r).Value
.Fields("9") = wb1.Range("L" & r).Value
' add more fields if necessary...
.Update ' stores the new record
End With
r = r + 1 ' next row
Loop
rs.Close
Set rs = Nothing
Следуя совету Тима, я изменил вышеуказанную часть кода, как показано ниже.
Dim sql As String, pk1 As Variant, pk2 As Variant, pk3 As Variant, pk As Variant
' open a recordset
Set rs = New ADODB.Recordset
' all records in a table
r = 8 ' the start row in the worksheet
Do While Len(wb1.Range("B" & r).Formula) > 0
' repeat until first empty cell in column A
With rs
pk1 = wb1.Range("B" & r).Value
pk2 = wb1.Range("C" & r).Value
strSQL = "SELECT * " & _
"FROM tbl1 " & _
"WHERE [tbl1].[mDate] = # " & pk1 & " # " & _
"AND [tbl1].[Country] = ' " & pk2 & " ';"
.Open Source:=strSQL, _
ActiveConnection:=cn, _
CursorType:=adOpenDynamic, _
LockType:=adLockOptimistic, _
Options:=adCmdText
'if EOF add new record otherwise overwrite old record
If .EOF = True Then
.AddNew 'Create a new record
End If
' add values to each field in the record
.Fields("mDate") = pk1
.Fields("Country") = pk2
.Fields("1") = wb1.Range("D" & r).Value
.Fields("2") = wb1.Range("E" & r).Value
.Fields("3") = wb1.Range("F" & r).Value
.Fields("4") = wb1.Range("G" & r).Value
.Fields("5") = wb1.Range("H" & r).Value
.Fields("6") = wb1.Range("I" & r).Value
.Fields("7") = wb1.Range("J" & r).Value
.Fields("8") = wb1.Range("K" & r).Value
.Fields("9") = wb1.Range("L" & r).Value
' add more fields if necessary...
.Update ' stores the new record
End With
r = r + 1 ' next row
Loop
rs.Close
Set rs = Nothing
При запуске он пытается добавить новые данные для существующих дат и возвращается с сообщением об ошибке, в котором говорится, что я пытаюсь создать дубликат первичного ключа.
РЕДАКТИРОВАТЬ # 2
Продолжая инструкции Тима, я закрыл набор записей внутри каждого цикла (и без пробелов между датами и #), как показано ниже.
Dim sql As String, pk1 As Variant, pk2 As Variant, pk3 As Variant, pk As Variant
' open a recordset
Set rs = New ADODB.Recordset
' all records in a table
r = 8 ' the start row in the worksheet
Do While Len(wb1.Range("B" & r).Formula) > 0
' repeat until first empty cell in column A
With rs
pk1 = wb1.Range("B" & r).Value
pk2 = wb1.Range("C" & r).Value
strSQL = "SELECT * " & _
"FROM tbl1 " & _
"WHERE [tbl1].[mDate] = #" & pk1 & "# " & _
"AND [tbl1].[Country] = ' " & pk2 & " ';"
.Open Source:=strSQL, _
ActiveConnection:=cn, _
CursorType:=adOpenDynamic, _
LockType:=adLockOptimistic, _
Options:=adCmdText
'if EOF add new record otherwise overwrite old record
If .EOF = True Then
.AddNew 'Create a new record
End If
' add values to each field in the record
.Fields("mDate") = pk1
.Fields("Country") = pk2
.Fields("1") = wb1.Range("D" & r).Value
.Fields("2") = wb1.Range("E" & r).Value
.Fields("3") = wb1.Range("F" & r).Value
.Fields("4") = wb1.Range("G" & r).Value
.Fields("5") = wb1.Range("H" & r).Value
.Fields("6") = wb1.Range("I" & r).Value
.Fields("7") = wb1.Range("J" & r).Value
.Fields("8") = wb1.Range("K" & r).Value
.Fields("9") = wb1.Range("L" & r).Value
' add more fields if necessary...
.Update ' stores the new record
End With
r = r + 1 ' next row
rs.Close
Set rs = Nothing
Loop
Теперь, это работало хорошо в последние пару дней в августе (30 и 31).
Но как только он сталкивается с 1 сентября, он пытается создать новую запись и возвращается с повторяющейся ошибкой pk.
Что я мог делать не так? Я подумал, что это может быть формат даты, поэтому я попытался вручную сопоставить все форматы даты, что привело к той же ошибке.
Буду признателен за любую помощь.
Спасибо.