VBA函数从SQL查询返回记录集值

VBA函数从SQL查询返回记录集值,vba,ms-access,dao,recordset,Vba,Ms Access,Dao,Recordset,我试图从一个表中返回一个货币值,我需要将变量传递到一个VBA定义的函数中,该函数包含一个查询,以便获得正确的值。我在表单的文本框中使用了函数,但它返回: #Name? 感谢您的帮助。代码如下: Option Compare Database Public Function payrollVar(dateVar As Date, roleidVar As String, typeVar As String) As DAO.Recordset Dim dbs As DAO.Database D

我试图从一个表中返回一个货币值,我需要将变量传递到一个VBA定义的函数中,该函数包含一个查询,以便获得正确的值。我在表单的文本框中使用了函数,但它返回:

#Name?
感谢您的帮助。代码如下:

Option Compare Database

Public Function payrollVar(dateVar As Date, roleidVar As String, typeVar As String) As DAO.Recordset

Dim dbs As DAO.Database
Dim rsSQL As DAO.Recordset
Dim strSQL As String

Set dbs = CurrentDb

'typeVar must either be ODE, Actual, or Forecast

If typeVar = "Actual" Or "Forecast" Then
    strSQL = "SELECT [Master Data].[*Quantity]" & _
             "FROM [Master Data]" & _
             "WHERE ((([Master Data].[*Category])='Payroll') AND (([Master Data].[*Date])= " & dateVar & ") AND (([Master Data].[*Role ID])= '" & roleidVar & "' ) AND (([Master Data].[*Type])= '" & typeVar & "' ));"
ElseIf typeVar = "ODE" Then
    strSQL = "SELECT [Master Data].[*Quantity]" & _
             "FROM [Master Data]" & _
             "WHERE ((([Master Data].[*Data Version])='Resource_Detail_Cost_Increase_Projections_Table') AND (([Master Data].[*Category])='Payroll') AND (([Master Data].[*Date])= " & dateVar & ") AND (([Master Data].[*Role ID])= '" & roleidVar & "' ));"
End If

Set rsSQL = dbs.OpenRecordset(strSQL)

payrollVar = rsSQL.GetRows(0)

End Function
考虑使用该函数,而不是DAO记录集检索,它不能直接用于文本框等表单控件。然后,直接在VBA中将该值分配给文本框,并确保删除任何控制源,因为对于VBA分配,文本框应为空

DLookUp的criteria参数可以在Access SQL和VBA中使用,它可以接受任何符合SQL WHERE条件的参数。因此,可以重用SELECT语句的部分内容。此外,如果应该返回多个值,该函数将返回查找的第一个实例

Public Function payrollVar(dateVar As Date, roleidVar As String, typeVar As String)
    Dim val As Variant

    If typeVar = "Actual" Or typeVar = "Forecast" Then

        val = DLookUp("[*Quantity]", "[Master Data]", _
                      "[*Category] = 'Payroll' AND " _
                       & "[*Date] = #" & dateVar & "#) AND " _
                       & "[*Role ID] = '" & roleidVar & "' AND " _
                       & "[*Type] = '" & typeVar & "'")

    ElseIf typeVar = "ODE" Then

        val = DLookUp("[*Quantity]", "[Master Data]", _
                      "[*Category] = 'Resource_Detail_Cost_Increase_Projections_Table' AND " _
                       & "[*Date] = #" & dateVar & "#) AND  " _
                       & "[*Role ID] = '" & roleidVar & "' AND " _
                       & "[*Type] = '" & typeVar & "'")

    End If

    ' ASSIGN TO UNBOUND TEXTBOX 
    Me.[myTextbox] = val

End Function
然后,在事件触发器上,可以是OnClick、OnOpen、AfterUpdate等。调用未返回的方法:

Call payrollVar(param1, param2, param3)

首先,我也建议像冻糕建议的那样使用DLookup。我会更进一步,把它和IIF结合起来,这样一个函数甚至不是必需的,但这也取决于其他因素。但是,如果您确实想使用记录集,并且假设您的SQL是正确的,那么这就是您所缺少的:

而不是

payrollVar = rsSQL.GetRows(0)
你需要:

rsSQL.MoveFirst
payrollVar=rsSQL![*Quantity]
rsSQL.Close
这通常是不够的!只有当您确信您的查询将返回一个值时,这才足够好。如果有可能找不到要返回的记录,则需要将其包含在If语句中,如下所示:

if rsSQL.EOF=False OR rsSQL.BOF=False Then
  rsSQL.MoveFirst
  payrollVar=rsSQL![*Quantity]
Else
  payrollVar=0 (or whatever value indicates no result found)
End If
rsSQL.Close

最后,你到底为什么要在列名上使用*??如果在名称中不使用空格和符号,SQL的工作和阅读就会容易得多。

如果没有记录,则工资单没有默认值。另外,您如何访问这些值?正如行上的注释所示,您正在将记录集返回到文本框。您分配了strSQL,但从未使用它。OpenRecordSet行丢失了吗?功能的最终目标是什么?它是如何从文本框中调用的?对不起,是的-它在提交之前编辑得太快了。我试图从查询中获得一个单一货币值作为整个函数的结果。您在哪里看到Name??我猜您在表单字段中看到了错误值?您共享的函数返回一个记录集对象,因此从技术上讲,它不会返回您所说的返回的内容。。。它应该是一个有效的对象,或者什么都不是。任何其他操作都会导致错误,因此您看到的可能是Access自动处理错误并向您显示错误值的结果。Name?是文本框在控制源中的结果:=payrollVar7/1/2017,CE_013,ODE