在Excel中运行ACE SQL查询的UDF函数,JOIN两个表不起作用

时间:2015-06-26 08:41:19

标签: sql excel vba join adodb

我试图找出Excel中试图连接两个表的函数可能出现的错误。我假设错误是在SQL字符串中的某个地方。

该函数在没有连接的情况下运行良好,将表正确地返回到数组 - 单元格范围。即当strSQL只是" SELECT * FROM [" &安培; currAddress& "]"

当字符串包含连接时,它不起作用,即strSQL =" SELECT * FROM [" &安培; currAddress& "]" &安培; _              " LEFT JOIN [" &安培; currAddress2& "] ON [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

2 个答案:

答案 0 :(得分:1)

It looks like you are not specifying the fields/columns in the join. Both currAddress and curAddress2 look like tables. The SQL should be something like:

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

Are Indeks and Indeks2 your field names? If so, you need to place the field name after the table name:

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

答案 1 :(得分:1)

我相信'Indeks'是你在两个表中的共同领域,那么strSQL应该是这样的:

strSQL =“SELECT * FROM [”&amp; currAddress&amp; “]”&amp; _           “LEFT JOIN [”&amp; currAddress2&amp; “] ON [”&amp; currAddress&amp; “]。[Indeks] = [”&amp; currAddress2&amp; “]。[Indeks]”