Невозможно получить значение из пользовательской функции в Access 2007 - PullRequest
1 голос
/ 12 мая 2011

Я создал эту функцию GetSubName, которая должна возвращать имя, сохраненное из выпадающего списка.Он делает это очень хорошо, так как диалоговые окна, которые я использовал, показывают, что он устанавливает переменную правильно.Проблема в том, что когда SQL-запрос выполняется в запросе, я получаю сообщение об ошибке: «Неопределенная функция« GetSubName »в выражении».Я новичок в VBA, поэтому любая помощь будет высоко ценится.

Вот код:

Option Compare Database
Option Explicit
Private stSubName As String

Private Sub Command2_Click()
On Error GoTo Err_Command2_Click
Dim stDocName As String
Dim stSubName As String

SubcontractorCombo.SetFocus
stSubName = SubcontractorCombo.SelText
'Confirm that stSubName variable is holding correct value'
MsgBox "Name of Subcontractor Selected is " & stSubName

SetSubName stSubName
GetSubName

DoCmd.Close

stDocName = "Summary Asphalt Production for Subcontractor"
DoCmd.OpenQuery stDocName

Exit_Command2_Click:
Exit Sub

Err_Command2_Click:
MsgBox Err.Description
Resume Exit_Command2_Click

End Sub

Public Sub SetSubName(Value As String)
'Set the module variable to be the value passed in from externally'
stSubName = Value
End Sub

Public Function GetSubName() As String
'Returns the value of the module variable'
GetSubName = stSubName
'MsgBox "GetSubName Variable is " & stSubName'

End Function

А вот мой SQL изнутри Access 2007:

SELECT DISTINCTROW Subs.Subcontractor, Counties.County, Projects.ContractID,
Sum(Project_Items.USTons) AS SumOfUSTons, Projects.PlanQuantity,
Max(Project_Items.EstDate) AS MaxOfEstDate, Project_Items.Sub
FROM Counties INNER JOIN (Subs INNER JOIN (Projects INNER JOIN Project_Items ON  
Projects.ContractID = Project_Items.ProjectID) ON Subs.VendID = Project_Items.Sub) ON 
Counties.ID = Project_Items.County
WHERE (((Projects.Completed)<>True) AND ((Subs.Subcontractor)=GetSubName()))
GROUP BY Subs.Subcontractor, Counties.County, Projects.ContractID,   
Projects.PlanQuantity, Project_Items.Sub;

Ответы [ 3 ]

2 голосов
/ 14 мая 2011

Причина, по которой функции не распознаются, заключается в том, что вы не указали полностью имя.Публичная функция в модуле формы должна быть указана с именем формы:

  Forms!MyForm.GetSubName()

Но это неправильный подход, и ваш код слишком запутан.Вы можете получить доступ к значению поля со списком в своем запросе напрямую:

  Forms!MyForm!SubcontractorCombo

Теперь тот факт, что вы используете .SelText, подсказывает мне, что вы делаете что-то очень очень сложное, или выневерно настроено поле со списком.У полей со списком могут быть найденное поле и отображаемое значение, так что список сотрудников может отображать LastName / FirstName сотрудника, в то время как поле со списком фактически имеет в качестве связанного поля идентификатор EmployeeID.

Если в вашем поле со списком естьскрытое связанное поле, но вы хотите отображаемое значение, вам не нужно использовать .SelText - просто используйте соответствующий .Column () поля со списком:

  Forms!MyForm!SubcontractorCombo.Column(1)

(количество столбцов равно нулюна основе этого, поэтому скрытый столбец будет столбцом 0, при условии, что это первый скрытый столбец)

Кроме того, существует проблема, заключающаяся в том, что если пользователь выберет ЧАСТЬ текста в поле со списком, вы получитенеполное совпадение, так что вы действительно не хотите использовать .SelText вообще.

Итак, предложение WHERE вашего SQL в итоге окажется таким (при условии, что я все правильно диагностировал):

  WHERE Projects.Completed<>True 
     AND Subs.Subcontractor=Forms!MyForm!SubcontractorCombo.Column(1)

... и вы можете потерять весь отмеченный код:

Option Compare Database
Option Explicit
<strike>Private stSubName As String</strike>

Private Sub Command2_Click()
On Error GoTo Err_Command2_Click
  Dim stDocName As String
  Dim stSubName As String

  SubcontractorCombo.SetFocus
  <strike>stSubName = SubcontractorCombo.SelText</strike>
  'Confirm that stSubName variable is holding correct value'
  <strike>MsgBox "Name of Subcontractor Selected is " & stSubName</strike>

  <strike>SetSubName stSubName</strike>
  <strike>GetSubName</strike>

  DoCmd.Close

  stDocName = "Summary Asphalt Production for Subcontractor"
  DoCmd.OpenQuery stDocName

Exit_Command2_Click:
  Exit Sub

Err_Command2_Click:
  MsgBox Err.Description
  Resume Exit_Command2_Click

End Sub

<strike>Public Sub SetSubName(Value As String)
  'Set the module variable to be the value passed in from externally'
  stSubName = Value
End Sub</strike>

<strike>Public Function GetSubName() As String
  'Returns the value of the module variable'
  GetSubName = stSubName
  'MsgBox "GetSubName Variable is " & stSubName'    
End Function</strike>
0 голосов
/ 13 мая 2011

Не то чтобы это лучшее решение, но оно должно решить некоторые будущие проблемы, связанные с попыткой ссылки на функцию в форме. Вы можете использовать параметр в своем запросе и установить его значение в поле со списком.

Вы должны поместить публичные функции в Модуль. Я назвал это Module2

Option Compare Database
Option Explicit


Private stSubName As String

Public Sub SetSubName(Value As String)
'Set the module variable to be the value passed in from externally'
stSubName = Value
End Sub

Public Function GetSubName() As String
'Returns the value of the module variable'
GetSubName = stSubName
'MsgBox "GetSubName Variable is " & stSubName'

End Function

Ваша форма будет ссылаться на функции в модуле:

Option Compare Database
Option Explicit
Private stSubName As String

Private Sub Command2_Click()
On Error GoTo Err_Command2_Click
Dim stDocName As String
Dim stSubName As String

SubcontractorCombo.SetFocus
stSubName = SubcontractorCombo.SelText
'Confirm that stSubName variable is holding correct value'
MsgBox "Name of Subcontractor Selected is " & stSubName

Module2.SetSubName stSubName
Module2.GetSubName

DoCmd.Close

stDocName = "Summary Asphalt Production for Subcontractor"
DoCmd.OpenQuery stDocName

Exit_Command2_Click:
Exit Sub
Err_Command2_Click:
MsgBox Err.Description
Resume Exit_Command2_Click
End Sub

Запрос сможет найти общедоступную функцию в модуле.

0 голосов
/ 12 мая 2011

Будет ли работать альтернативный подход?

Создать таблицу ( SubNameTable ) с одним полем: SubName .

Добавить одну запись к нему.

Затем измените свой Sub на это:

Public Sub SetSubName(Value As String)
  CurrentDb.Execute ("Update SubNameTable Set SubName = '" & Value & "'")
End Sub

Теперь вы можете удалить функцию и модульную переменную.

Затем измените ваш SQL следующим образом:

SELECT 
  *BlahBlahBlahFields*
FROM 
     *BlahBlahBlahTables* 
              INNER JOIN Subs 
                 INNER JOIN SubNameTable ON Subs.SubContractor = SubNameTable.SubName
WHERE (((Projects.Completed)<>True) 
GROUP BY 
          Subs.Subcontractor, 
          Counties.County, 
          Projects.ContractID,   
          Projects.PlanQuantity, 
          Project_Items.Sub
...