Функция VBA, возвращающая значение набора записей из SQL-запроса - PullRequest
0 голосов
/ 05 сентября 2018

Я пытаюсь вернуть значение валюты из таблицы, и мне нужно передать переменные в определенную функцию 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

Ответы [ 2 ]

0 голосов
/ 05 сентября 2018

Прежде всего, я тоже рекомендую использовать 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 намного проще в работе и чтении, если вы не используете пробелы и символы в именах.

0 голосов
/ 05 сентября 2018

Рассмотрим функцию DLookUp вместо извлечения набора записей DAO, которая не доступна напрямую для формирования элементов управления, таких как текстовые поля. Затем непосредственно присвойте значение текстовому полю в VBA и обязательно удалите все ControlSource, так как текстовое поле должно быть пустым для назначения VBA.

Доступный в Access SQL и VBA, аргумент критерия DLookUp может принимать любое совместимое условие 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)
...