VBA函数从SQL Query返回记录集值

问题描述 投票:0回答:2

我正在尝试从表中返回货币值,我需要将变量传递给包含查询的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
vba ms-access dao recordset
2个回答
0
投票

考虑DLookUp函数而不是DAO记录集检索,它不能直接用于形成文本框之类的控件。然后,直接将值分配给VBA中的文本框,并确保删除任何ControlSource,因为文本框应为空白以进行VBA分配。

在Access SQL和VBA中可用,DLookUp的criteria参数可以采用任何兼容的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

然后在事件触发器上,它是OnClickOnOpenAfterUpdate等调用非返回方法:

Call payrollVar(param1, param2, param3)

0
投票

首先,我也建议使用像Parfait建议的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更易于工作和读取。

© www.soinside.com 2019 - 2024. All rights reserved.