Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I'm a bit of newbie when it comes to these things, so apologies if this is a stupid question.

I need to run an SQL query from a piece of VBA. The query is a little odd, because it contains a VBA variable in its function. Otherwise everything is pretty straight forward. The VBA should call the query and then insert it into a client excel document.

Every time I run the query within Access everything is fine, the function returns the correct value and filters down the columns. Every time I run it from VBA in Excel it says "Run-Time Error "3085": Undefined Function 'CutOff' in expression.

I've look for info and have found old sites saying that Access 2003 sometimes has an issue doing this sort of thing, but I'm running 2010 (I think). Just hoping the problem is solve-able and greatly appreciate any advice.

The query is as follows :

 SELECT [<TableName>].ID...*
    FROM [<TableName>]
    WHERE ((([<TableName>].ID)>CutOff()))
    ORDER BY [<TableName>]].ID;

Public Function Cutoff()
    Dim WB1 As Excel.Workbook, WS1 As Excel.Worksheet
    Dim y As Long
    Set WB1 = Workbooks.Open("C:\filepath.z.xlsm")
    Set WS1 = WB1.Sheets("Sheet2")
    y = WS1.Range("A1").End(xlDown).Offset(0, 0).Value
    'Debug.Print y
    Cutoff = y
    'Debug.Print Cutoff
End Function 

The VBA that runs it is operated from Excel. I have tried the following:

Sub Export2()

    Dim db2 As Database
    Dim rs2 As DAO.Recordset, i As Long, sFormat As String
    Dim WB2 As Excel.Workbook, WS2 As Excel.Worksheet
    Set WB2 = Workbooks.Open("C:\FilePath.z.xlsm")
    Set WS2 = WB.Sheets("Sheet2")
    Set db2 = OpenDatabase("C:\FilePath.x.mdb")
    Set qd2 = db2.QueryDefs("ExportCount")
    Set rs2 = qd2.OpenRecordset()

        If rs2.EOF Then
            GoTo EndLoop
        End If

    WS2.Range("a1").End(xlsDown).Offset(1, 0).CopyFromRecordset rs2
    WS2.Cells.EntireColumn.AutoFit: WS2.Cells.EntireRow.AutoFit
EndLoop:


    Set WB = Nothing
    Set WS2 = Nothing
    Set db2 = Nothing
    Set qd2 = Nothing
    Set rs2 = Nothing

End Sub

EDIT:

Have also tried:

Sub SQLquery1()

    Dim WB1 As Excel.Workbook, WS1 As Excel.Worksheet
    Dim wt As DAO.Database
    Dim we As DAO.Recordset
    Dim wd As DAO.QueryDef

    Set WB1 = Workbooks.Open("C:\x.xlsm")
    Set WS1 = WB1.Sheets("Sheet2")
    mySQLVariable = WS1.Range("A1").End(xlDown).Offset(0, 0).Value
    'Debug.Print mySQLVariable
    Set wt = OpenDatabase("C:\z.mdb")
    Set wd = wt.QueryDefs("ExportCount")
    Set we = wd.OpenRecordset("h")

    WS2.Range("a1").End(xlsDown).Offset(1, 0).CopyFromRecordset wd
    WS2.Cells.EntireColumn.AutoFit: WS2.Cells.EntireRow.AutoFit

    Set WB1 = Nothing
    Set WS1 = Nothing
    Set wt = Nothing
    Set we = Nothing
    Set wd = Nothing

End Sub

EDIT2

Sub CreateQueryDef()
    Dim WB1 As Excel.Workbook, WS1 As Excel.Worksheet
    Dim dbPP As Database
    Dim qdfTemp As QueryDef
    Dim Counter As DAO.Recordset
    Dim mySQLVariable As String
    Dim rs5 As DAO.Recordset


    Set dbPP = OpenDatabase("C:\filepath\z.mdb")
    Set Counter = dbPP.OpenRecordset("j")
    Set WB1 = Workbooks.Open("C:\filepath\x.xlsm")
    Set WS1 = WB1.Sheets("Sheet2")
    mySQLVariable = WS1.Range("A1").End(xlDown).Offset(0, 0).Value
    'Debug.Print mySQLVariable

    With dbPP
        Set qdfTemp = dbPP.CreateQueryDef("NewQueryDef", "SELECT * FROM [j]")
        'WHERE ((j.[ID])=>(mySQLVariable)))") I can't get the syntax of these lines right - they are supposed to all be on the same line
        Set rs5 = qdfTemp.OpenRecordset() ' maybe Set rs5 = qdfTemp.OpenRecordset("NewQueryDef")?
    End With

        WS1.Range("a1").End(xlsDown).Offset(1, 0).CopyFromRecordset rs5
        WS1.Cells.EntireColumn.AutoFit: WS2.Cells.EntireRow.AutoFit
        dbPP.QueryDefs.Delete "NewQueryDef"

End Sub

Or

    Sub CreateQueryDef()
            Dim dbPP As Database
            Dim qdfTemp As QueryDef
            Dim Counter As DAO.Recordset
            Dim mySQLVariable As String
            Dim rs5 As DAO.Recordset


            Set dbPP = OpenDatabase("C:\filepath\z.mdb")
            Set Counter = dbPP.OpenRecordset("j")
            mySQLVariable = CutOff
            'Debug.Print mySQLVariable

            With dbPP
                Set qdfTemp = dbPP.CreateQueryDef("NewQueryDef", "SELECT * FROM [j] WHERE ((j.[ID])=>(mySQLVariable)))")
                Set rs5 = qdfTemp.OpenRecordset("NewQueryDef")
            End With

            WS1.Range("A1").End(xlsDown).Offset(1, 0).CopyFromRecordset rs5
            WS1.Cells.EntireColumn.AutoFit: WS2.Cells.EntireRow.AutoFit
            dbPP.QueryDefs.Delete "NewQueryDef"

            dbPP.Close

            Set dbPP = Nothing
            Set qdfTemp = Nothing
            Set Counter = Nothing
            Set mySQLVariable = Nothing
            Set rs5 = Nothing
End Sub

Public Function Cutoff()
        Dim WB1 As Excel.Workbook, WS1 As Excel.Worksheet
        Dim y As Long
        Set WB1 = Workbooks.Open("C:\filepath.z.xlsm")
        Set WS1 = WB1.Sheets("Sheet2")
        y = WS1.Range("A1").End(xlDown).Offset(0, 0).Value
        'Debug.Print y
        Cutoff = y
        'Debug.Print Cutoff
End Function 
share|improve this question
    
does the cutoff function exist in both the database and the excel spreadsheet, just the spreadsheet (if so how does the MDB find it?), or just the database? if in excel, you'll need to modify the query in access to accept the parameter for exportcount which contains the value of the cutoff. –  xQbert Dec 13 '13 at 20:26
    
Thanks for this. However, I put the function in both excel and access just in case that was the problem. Originally I set it up in access and, as I say, it derives the correct value when run in access and the query results display correctly. The problem comes when the query is called from excel vba. –  Orphid Dec 13 '13 at 22:52
    
Maybe I need to change mySQLVariable in the SQL query (in EDIT 2) to a call to the CutOff function in excel? Or define mySQLVariable by CutOff before initiating the query? –  Orphid Dec 13 '13 at 23:21

1 Answer 1

up vote 0 down vote accepted

Worked out what I was doing wrong.

The current value of the variable needs to be inserted into an SQL string written in VBA and passed to Access as a temporary query. The value of the variable is fixed by the time it is handed to Access, so Access doesn't need to run a macro to retrieve it, which would require the database to be open with macros enabled e.g.:

    Public y As String

    Sub definey()
      y = (VariableInput)
    Call Query
    End Sub

    Sub Query
    Dim q As DAO.Database
    Dim s As DAO.Recordset
    Dim mySQLVariable As String
    Dim strSQL As String

    mySQLVariable = y

        strSQL = "SELECT * FROM [Table1] WHERE (((Table1.ID)>" & "Chr$36 MySQLVariable Chr$36")) 
    'I'm free writing, not copying from code, so apologies if this isn't quite right

        Set q = OpenDatabase("Filepath\h.mdb")
        Set s = q.OpenRecordset(strSQL)

    '... then copy to workbook.
End Sub
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.