#excel #vba
#excel #vba
Вопрос:
Я пытаюсь выполнить следующий процесс, у меня есть две разные базы данных access, и я программирую некоторые sql-запросы в Excel Vba для обработки данных этих баз данных. Я установил связь с этой базой данных, используя ADOX Connection, вы можете увидеть сценарий ниже. Мой вопрос связан с самим запросом, из одной таблицы у меня много данных, и я ищу эти данные из другой таблицы, которые находятся в другой БД, но если запрос не находит отношения, он должен сообщить все данные из первой таблицы и использовать другуютаблицы в качестве дополнительной информации, если совпадения нет, то результат будет нулевым.
Чтобы сделать такую вещь, я использую LEFT OUTER JOIN
on all таблицы, но они не подходят. Поскольку он возвращает сообщение
«Синтаксическая ошибка при операции соединения»
Как я могу исправить эту ошибку?
Public Function getUMEByIdent()
Dim i As Long
Dim j As Integer
Dim nData() As Variant
Dim adox_table1 As ADOX.Table
Dim adox_table2 As ADOX.Table
Dim adox_table3 As ADOX.Table
Dim fatorConv As Double
With connection
.ConectDB ("compDraw.mdb")
Set adox_catalog = New ADOX.Catalog
Set adox_catalog.ActiveConnection = connection.conn
Set adox_table1 = New ADOX.Table
With adox_table1
Set .ParentCatalog = adox_catalog
.Name = "lkdTbl1"
.Properties("Jet OLEDB:Link Datasource") = ThisWorkbook.Path amp; "assetsconfigs.mdb"
.Properties("Jet OLEDB:Link Provider String") = "MS Access"
.Properties("Jet OLEDB:Remote Table Name") = "mditems"
.Properties("Jet OLEDB:Create Link") = True
End With
Set adox_table2 = New ADOX.Table
With adox_table2
Set .ParentCatalog = adox_catalog
.Name = "lkdTbl2"
.Properties("Jet OLEDB:Link Datasource") = ThisWorkbook.Path amp; "assetsconfigs.mdb"
.Properties("Jet OLEDB:Link Provider String") = "MS Access"
.Properties("Jet OLEDB:Remote Table Name") = "umestatistics"
.Properties("Jet OLEDB:Create Link") = True
End With
Set adox_table3 = New ADOX.Table
With adox_table3
Set .ParentCatalog = adox_catalog
.Name = "lkdTbl3"
.Properties("Jet OLEDB:Link Datasource") = ThisWorkbook.Path amp; "assetsconfigs.mdb"
.Properties("Jet OLEDB:Link Provider String") = "MS Access"
.Properties("Jet OLEDB:Remote Table Name") = "convume"
.Properties("Jet OLEDB:Create Link") = True
End With
Set .rs = .conn.Execute( _
"SELECT bom.ident_mp, lkdTbl1.ncm, lkdTbl1.umc, lkdTbl2.ume, lkdTbl3.fator_conv FROM" amp; _
" ((bom LEFT OUTER JOIN lkdTbl1 ON lkdTbl1.ident = bom.ident_mp) " amp; _
" LEFT OUTER JOIN tkdTbl2 ON lkdTb1.ncm = lkdTbl2.ncm)" amp; _
" LEFT OUTER JOIN lkdTbl3 ON lkdTbl1.umc = lkdTbl3.umc AND lkdTbl2.ume = lkdTbl3.ume" amp; _
" GROUP BY bom.ident_mp, lkdTbl1.ncm, lkdTbl1.umc, lkdTbl2.ume, lkdTbl3.fator_conv", , adCmdText)
Do While Not .rs.EOF
If IsNull(.rs.Fields("ident_mp").Value) = False Then
ReDim Preserve nData(i)
nData(i) = Array(.rs.Fields("ident_mp").Value, .rs.Fields("ncm").Value, .rs.Fields("umc").Value, .rs.Fields("ume").Value, .rs.Fields("fator_conv").Value)
i = i 1
End If
.rs.MoveNext
Loop
.rs.Close
adox_catalog.Tables.Delete "lkdTbl1"
adox_catalog.Tables.Delete "lkdTbl2"
adox_catalog.Tables.Delete "lkdTbl3"
.FechaDb
End With
End Function
Комментарии:
1.
LEFT OUTER JOIN tkdTbl2 ON
Это может быть просто простая опечатка. Должно ли это бытьlkdTbl2
?2.
lkdTb1.ncm = lkdTbl2.ncm
Кроме того, я думаю, что это должно бытьlkdTbl1
(отсутствует L)3. Привет, Дик Куслейка, После исправления этой ошибки sintax, теперь я получил ошибку, связанную с выражением соединения, она показывает, что выражение соединения не поддерживается. Похоже, что при использовании кратного выражения LEFT OUTER JOIN в VBA невозможно отправить два параметра, например, в третьем ЛЕВОМ ВНЕШНЕМ СОЕДИНЕНИИ » ЛЕВОЕ СОЕДИНЕНИЕ lkdTbl3 НА lkdTbl1.umc = lkdTbl3.umc И lkdTbl2.ume = lkdTbl3.ume» amp;
Ответ №1:
Анализатор запросов Access не может обрабатывать определенные соединения. Обычно вы можете обойти это, создав подзапрос.
SELECT temp.ident_mp
, temp.ncm
, temp.umc
, temp.ume
, lkdTbl3.fator_conv
FROM
(SELECT *
FROM bom
LEFT OUTER JOIN lkdTbl1 ON
lkdTbl1.ident = bom.ident_mp
LEFT OUTER JOIN tkdTbl2 ON
lkdTb1.ncm = lkdTbl2.ncm) temp
LEFT OUTER JOIN lkdTbl3 ON
temp.umc = lkdTbl3.umc
AND temp.ume = lkdTbl3.ume
GROUP BY temp.ident_mp
, temp.ncm
, temp.umc
, temp.ume
, lkdTbl3.fator_conv
Это помещает первые два левых соединения в подзапрос с таким именем temp
, чтобы последнее левое соединение соединяло только две таблицы. Я не смог это протестировать, потому что у меня нет вашей настройки, но я сделал что-то подобное в Northwind.mdb, и это сработало.
Комментарии:
1. Привет, Дик Куслейка, я внес некоторые изменения в ваш код, и теперь он идеально подходит… Большое вам спасибо.. Окончательный код выглядит следующим образом:
SELECT temp.ident_mp, temp.ncm_item, temp.umc_item, temp.ume, lkdTbl3.fator_conv FROM (SELECT * FROM (bom LEFT OUTER JOIN lkdTbl1 ON lkdTbl1.ident = bom.ident_mp) LEFT OUTER JOIN lkdTbl2 ON lkdTbl1.ncm_item = lkdTbl2.ncm) temp LEFT OUTER JOIN lkdTbl3 ON temp.umc_item = lkdTbl3.umc AND temp.ume = lkdTbl3.ume GROUP BY temp.ident_mp, temp.ncm_item, temp.umc_item, temp.ume, lkdTbl3.fator_conv