2015-06-26 1 views
0

Я пытаюсь выяснить, что может быть неправильно с функцией в Excel, которая пытается объединить две таблицы. Я предполагаю, что ошибка находится где-то в строке SQL.Функция UDF в Excel с использованием ACE SQL-запроса, JOIN две таблицы не работают

Функция работает без объединения, правильно вернув таблицу в массив - диапазон ячеек. т.е. когда strSQL только "SELECT * FROM [" & currAddress & "]"

Это не работает, если строка содержит соединение, т.е. strSQL = "SELECT * FROM [" & currAddress & "]" & _ "LEFT JOIN [" & currAddress2 & "] ВКЛ [Indeks]. [" & currAddress & "] = [Indeks2]. [" & currAddress2 & "];"

Вот мой код, спасибо за помощь:

Function SQL(dataRange As Range, dataRange2 As Range) As Variant 
    Application.Volatile 

    Dim cn As ADODB.Connection 
    Dim rs As ADODB.Recordset 
    Dim currAddress, currAddress2 As String 
    Dim varHdr, varDat, contentOut As Variant 
    Dim nc, nr, i, j As Long 

    SQL = Null 

    currAddress = ActiveSheet.Name & "$" & dataRange.Address(False, False) 
    Debug.Print currAddress 

    currAddress2 = ActiveSheet.Name & "$" & dataRange2.Address(False, False) 
    Debug.Print currAddress2 


    strFile = ThisWorkbook.FullName 
    strCon = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & strFile _ 
    & ";Extended Properties=""Excel 12.0;HDR=Yes;IMEX=0"";" 

    Set cn = CreateObject("ADODB.Connection") 
    Set rs = CreateObject("ADODB.Recordset") 

    rs.CursorLocation = adUseClient ' required to return the number of rows correctly 
    cn.Open strCon 



     strSQL = "SELECT * FROM [" & currAddress & "] " & _ 
      "LEFT JOIN [" & currAddress2 & "] ON [Indeks].[" & currAddress & "] = [Indeks2].[" & currAddress2 & "];" 


    Debug.Print strSQL 

    rs.Open strSQL, cn 

    'Check if recordset is empty 
    If rs.EOF Then 
     MsgBox "Function does not return any values" 
     SQL = "" 
     Exit Function 
    End If 


    ' Process Column Headings 
    nc = rs.Fields.Count 
    ReDim varHdr(nc - 1, 0) 
    For i = 0 To rs.Fields.Count - 1 
     varHdr(i, 0) = rs.Fields(i).Name 
    Next 

    ' Get Rows from the Recordset 
    nr = rs.RecordCount 
    varDat = rs.GetRows 

    ' Combing Header and Data and Transpose 

    ReDim contentOut(0 To nr, 0 To nc - 1) 
    For i = 0 To nc - 1 
     contentOut(0, i) = varHdr(i, 0) 
    Next 




    For i = 1 To nr 
     For j = 0 To nc - 1 
      contentOut(i, j) = varDat(j, i - 1) 



     Next 
    Next 

    ' Optional solution: Write Output Array to Sheet2 
    ' With Sheet2 
    '  .Cells.Clear 
    '  .Range("A1").Resize(nr, nc) = contentOut 
    ' End With 


    'Figure out size of calling range which will receive the output array 
    Dim nRow As Long: nRow = Application.Caller.Rows.Count 
    Dim nCol As Long: nCol = Application.Caller.Columns.Count 

    'Error if calling range too small 
    If nRow < UBound(contentOut, 1) Or nCol < UBound(contentOut, 2) Then 
     'Popup message 
     'MsgBox "your range is too small." 
     ' or return #VALUE! error 
     SQL = "Too small range" 'CVErr(xlValue) 
     ' or both or whatever else you want there to happen 
     Exit Function 
    End If 

    'Initialise output array to match size of calling range 
    Dim varOut As Variant 
    ReDim varOut(1 To nRow, 1 To nCol) 
    'And fill it with some background value 
    Dim iRow As Long 
    Dim iCol As Long 
    For iRow = 1 To nRow 

     For iCol = 1 To nCol 
      varOut(iRow, iCol) = "" ' or "funny bear", or whatever 
     Next 
    Next 

    'Put content in output array and return 
    For iRow = 0 To UBound(contentOut, 1) 
     For iCol = 0 To UBound(contentOut, 2) 
      varOut(iRow + 1, iCol + 1) = contentOut(iRow, iCol) 
     Next 
    Next 



     SQL = varOut 

    'Cleanup 
    Erase contentOut 
    Erase varHdr 
    Erase varDat 

    rs.Close 
    Set rs = Nothing 
    Set cn = Nothing 


End Function 

ответ

1

Похоже, вы не указанием полей/столбцов в объединении. Оба currAddress и curAddress2 выглядят как таблицы. SQL должно быть что-то вроде:

strSQL = "SELECT * FROM [Table1] " & _ 
     "LEFT JOIN [Table2] ON [Table1].[Field] = [Table2].[Field];" 

ли Indeks и Indeks2 ваши имена полей? Если да, то вам нужно разместить название поля после имени таблицы:

strSQL = "SELECT * FROM [" & currAddress & "] " & _ 
     "LEFT JOIN [" & currAddress2 & "] ON [" & currAddress & "].[Indeks] = [" & currAddress2 & "].[Indeks2];" 
1

Я считаю, что «Indeks» Ваше общее поле в двух таблицах, то strSQL должен быть таким:

strSQL = «SELECT * ОТ [»& currAddress & "]" & _ "LEFT JOIN [" & currAddress2 & "] на [" & currAddress & "]. [Indeks] = [" & currAddress2 & "]. [Indeks]"

Смежные вопросы