2

I have a fairly simple problem which I cannot find an answer to.

I have the following SQL:-

Select a from filea where a in (select b from fileb)

I am attempting to run this in Excel using VBA.

The problem I have is that filea is a table on an AS/400 and fileb is a table in an Excel spreadsheet. That is, two different datasources. I can't find a way to combine the two datasources in one SQL statement.

Anybody got any bright ideas.

2
  • What provider do you use to connect to the AS/400? Commented Jun 4, 2015 at 15:37
  • I use the client access provider. I should have said I know I can do this by traversing recordsets but I don't like that solution. Commented Jun 4, 2015 at 16:15

1 Answer 1

3

The below example shows how to get data from two excel workbooks within single SQL query (since I haven't got any AS/400 data source), and put result recordset to the worksheet. The code is placed in Query.xlsm:

Option Explicit

Sub SqlWhereInTest()

    Dim strConnection As String
    Dim strQuery As String
    Dim objConnection As Object
    Dim objRecordSet As Object

    strConnection = _
        "Provider=Microsoft.ACE.OLEDB.12.0;" & _
        "User ID=Admin;" & _
        "Data Source='" & ThisWorkbook.FullName & "';" & _
        "Mode=Read;" & _
        "Extended Properties=""Excel 12.0 Macro;"";"

    strQuery = _
        "SELECT * FROM [Sheet1$] " & _
        "IN '" & ThisWorkbook.Path & "\Src1.xlsx' " & _
        "[Excel 12.0;Provider=Microsoft.ACE.OLEDB.12.0;Mode=Read;Extended Properties='HDR=YES;'] " & _
        "WHERE Country IN " & _
        "(SELECT CountryFilter FROM [Sheet1$] " & _
        "IN '" & ThisWorkbook.Path & "\Src2.xlsx' " & _
        "[Excel 12.0;Provider=Microsoft.ACE.OLEDB.12.0;Mode=Read;Extended Properties='HDR=YES;'])"

    Set objConnection = CreateObject("ADODB.Connection")
    objConnection.Open strConnection
    Set objRecordSet = objConnection.Execute(strQuery)
    RecordSetToWorksheet Sheets(1), objRecordSet
    objConnection.Close

End Sub

Sub RecordSetToWorksheet(objSheet As Worksheet, objRecordSet As Object)

    Dim i As Long

    With objSheet
        .Cells.Delete
        For i = 1 To objRecordSet.Fields.Count
            .Cells(1, i).Value = objRecordSet.Fields(i - 1).Name
        Next
        .Cells(2, 1).CopyFromRecordset objRecordSet
        .Cells.Columns.AutoFit
    End With

End Sub

Also there are two workbooks as data sources in the same folder as Query.xlsm.

Src1.xlsx containing Customers:

src1

Src2.xlsx:

src2

The resulting worksheet is as follows:

result

It works on 64-bit version Excel 2013 for me. To make it compatible with .xls and Excel 2003 (where the provider ACE.OLEDB.12.0 isn't installed) you have to replace Provider=Microsoft.ACE.OLEDB.12.0; with Provider=Microsoft.Jet.OLEDB.4.0;, and also in extended properties Excel 12.0 Macro; / Excel 12.0; with Excel 8.0;. Actually data source for connection object isn't limited the only Query.xlsm file (see ThisWorkbook.FullName part within strConnection), which the code placed in. It could be another data source, compatible with one of the available providers, either file-based or server-based. Find more connection strings for your data source on http://www.connectionstrings.com/

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.