Синтаксическая ошибка в SQL-запросе с использованием ВНЕШНЕГО СОЕДИНЕНИЯ СЛЕВА

#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