将参数设置为 VBA 和 SQL 使用 DAO 查询
Setting Parameters to VBA and SQL Query using DAO
所以我使用按钮 运行 查询,然后将所选电子邮件提取到电子邮件中。
这个有一个单一的功能,然后每个按钮发送相应的查询作为记录集
Sub EmailQuery(strQueryName As String)
'On Error GoTo Err_EmailRequery_Click
Dim cn As ADODB.Connection
Dim rs As ADODB.Recordset
Dim strEmail As String
Set cn = CurrentProject.Connection
Set rs = New ADODB.Recordset
rs.Open strQueryName, cn
With rs
.MoveLast
.MoveFirst
Do While Not .EOF
strEmail = strEmail & .Fields("Email") & ";"
.MoveNext
Loop
.Close
End With
strEmail = Left(strEmail, Len(strEmail) - 1)
DoCmd.SendObject , , , , , strEmail, , , True, False
'Exit_EmailRequery_Click:
'
' Exit Sub
'
'Err_EmailRequery_Click:
'
' MsgBox Err.Description
'
' Resume Exit_EmailRequery_Click
End Sub
Private Sub cmdActive_Click()
EmailQuery ("qryActiveSuppliers")
End Sub
Private Sub cmdAllSuppliers_Click()
EmailQuery ("qryAllSuppliers")
End Sub
Private Sub cmdArrangements_Click()
EmailQuery ("qryAgreementEmail")
End Sub
Private Sub cmdInactive_Click()
EmailQuery ("qryInactiveSuppliers")
End Sub
Form where the buttons are located
只需在访问中单击它,所有查询 运行 都正确,所有栏安排查询 运行 正确。我从它的 SQL 语句中取出标准,看看它是否会 运行 并且确实如此。
该条件与表单上的组合框选择相匹配。
以下是“安排”按钮的 SQL 语句。
SELECT DISTINCT tblSuppliers.SupplierName, Nz([BusinessEmail],[PersonalEmail]) AS Email
FROM ((tblSuppliers
INNER JOIN tblSuppliersAgreements ON tblSuppliers.ID = tblSuppliersAgreements.SupplierID)
INNER JOIN tblContacts ON tblSuppliers.ID = tblContacts.SupplierID)
WHERE ((tblSuppliersAgreements.AgreementID)=[Forms]![frmMainMenu]![cboAgreement]);
This is the error I am getting when I try to click the button to run it
我认为这可能与我在 rs.open 行中打开查询的方式有关,我需要调用条件而不仅仅是在 SQL 语句中?非常感谢对此问题或解决方案的任何帮助。
编辑
所以我用 DAO 将我的代码更改为这个,看看是否可以解决问题。我现在在行 Set rs = db.OpenRecordset(strQueryname)
上收到错误
The error
我已经留下了以前的评论方式,所以如果提供了解决方案,我可以随时改回来。
Sub EmailQuery(strQueryName As String)
'On Error GoTo Err_EmailRequery_Click
' Dim cn As ADODB.Connection
' Dim rs As ADODB.Recordset
Dim strEmail As String
Dim db As DAO.Database
Dim rs As DAO.Recordset
Set db = CurrentDb
Set rs = db.OpenRecordset(strQueryName)
' Set cn = CurrentProject.Connection
' Set rs = New ADODB.Recordset
MsgBox strQueryName
' rs.Open strQueryName, cn
With rs
' .MoveLast
' .MoveFirst
Do While Not .EOF
strEmail = strEmail & .Fields("Email") & ";"
.MoveNext
Loop
.Close
End With
strEmail = Left(strEmail, Len(strEmail) - 1)
DoCmd.SendObject , , , , , strEmail, , , True, False
'Exit_EmailRequery_Click:
'
' Exit Sub
'
'Err_EmailRequery_Click:
'
' MsgBox Err.Description
'
' Resume Exit_EmailRequery_Click
End Sub
编辑 2
主函数中的当前代码
Sub EmailQuery(strQueryName As String)
'On Error GoTo Err_EmailQuery_Click
Dim strEmail As String
Dim db As DAO.Database
Dim rs As DAO.Recordset
Set db = CurrentDb
Set rs = db.OpenRecordset(strQueryName)
MsgBox strQueryName
With rs
' .MoveLast
' .MoveFirst
Do While Not .EOF
strEmail = strEmail & .Fields("Email") & ";"
.MoveNext
Loop
.Close
End With
strEmail = Left(strEmail, Len(strEmail) - 1)
DoCmd.SendObject , , , , , strEmail, , , True, False
'Exit_EmailQuery_Click:
'
' Exit Sub
'
'Err_EmailQuery_Click:
'
' MsgBox Err.Description
'
' Resume Exit_EmailQuery_Click
End Sub
当前SQL
PARAMETERS [PrmID] Long;
SELECT DISTINCT tblSuppliers.SupplierName, IIf( IsNull(BusinessEmail) , PersonalEmail, BusinessEmail) AS Email
FROM (tblSuppliers
INNER JOIN tblSuppliersAgreements ON tblSuppliers.ID = tblSuppliersAgreements.SupplierID)
INNER JOIN tblContacts ON tblSuppliers.ID = tblContacts.SupplierID
WHERE ((tblSuppliersAgreements.AgreementID)=[PrmID]);
我知道 SQL 的完成方式可能存在问题,参数化一半或只是做错了。
你的尝试有几个问题:
命名对象:使用 ADO Recordset.Open
调用已保存的查询,主要需要 SQL 语句或命令对象而不是命名对象.因此,您的第一个错误的原因。相反,使用 Conn.Execute
将标准 SQL 语法添加到命名对象。或者显式传递 SELECT * FROM
与查询对象。这不是 DAO 记录集的问题(专门针对 MS Access 对象模型的库,而 ADO 是针对 any 后端进行概括的)。
参数:在看不到表单值的后端查询中使用表单控件值。任何非 运行 且 DoCmd
的查询,例如 OpenQuery
(对于 select 查询)或 RunSQL
(对于操作查询),都无法识别表单控件。因此,第二个错误的原因。使用 ADO Command parameters or DAO QueryDefs parameters 而不是 Forms!MyForm!MyControl
。
搜索 my [vba]
tag answers 无数的 ADO 或 DAO 参数解决方案。请参阅下面的用例:
Sub EmailQuery(strQueryName As String)
On Error GoTo Err_EmailQuery_Click
Dim strEmail As String
Dim db As DAO.Database
Dim qdef As DAO.QueryDef
Dim rs As DAO.Recordset
Set db = CurrentDb
Set qdef = db.QueryDefs(strQueryName)
With qdef
' BIND PARAMETER
.Parameters("PrmID") = [Forms]![frmMainMenu]![cboAgreement]
' OPEN RECORDSET
Set rs = .OpenRecordset()
End With
'...loop and email...
Exit_EmailQuery_Click:
rs.Close
Set rs = Nothing: Set qdef = Nothing: Set db = Nothing
Exit Sub
Err_EmailQuery_Click:
MsgBox Err.Number & " - " & Err.Description, vbCritical, "RUNTIME ERROR"
Resume Exit_EmailQuery_Click
End Sub
特殊功能: 运行 只有 MS Access GUI 方法像 NZ
在不识别此类功能的后端查询中。如果您解决以上两个问题,您将 运行 进入此错误。使用 IIF
+ ISNULL
/IS NULL
。同样,VBA user-defined 函数将无法识别。
所以我使用按钮 运行 查询,然后将所选电子邮件提取到电子邮件中。 这个有一个单一的功能,然后每个按钮发送相应的查询作为记录集
Sub EmailQuery(strQueryName As String)
'On Error GoTo Err_EmailRequery_Click
Dim cn As ADODB.Connection
Dim rs As ADODB.Recordset
Dim strEmail As String
Set cn = CurrentProject.Connection
Set rs = New ADODB.Recordset
rs.Open strQueryName, cn
With rs
.MoveLast
.MoveFirst
Do While Not .EOF
strEmail = strEmail & .Fields("Email") & ";"
.MoveNext
Loop
.Close
End With
strEmail = Left(strEmail, Len(strEmail) - 1)
DoCmd.SendObject , , , , , strEmail, , , True, False
'Exit_EmailRequery_Click:
'
' Exit Sub
'
'Err_EmailRequery_Click:
'
' MsgBox Err.Description
'
' Resume Exit_EmailRequery_Click
End Sub
Private Sub cmdActive_Click()
EmailQuery ("qryActiveSuppliers")
End Sub
Private Sub cmdAllSuppliers_Click()
EmailQuery ("qryAllSuppliers")
End Sub
Private Sub cmdArrangements_Click()
EmailQuery ("qryAgreementEmail")
End Sub
Private Sub cmdInactive_Click()
EmailQuery ("qryInactiveSuppliers")
End Sub
Form where the buttons are located 只需在访问中单击它,所有查询 运行 都正确,所有栏安排查询 运行 正确。我从它的 SQL 语句中取出标准,看看它是否会 运行 并且确实如此。 该条件与表单上的组合框选择相匹配。 以下是“安排”按钮的 SQL 语句。
SELECT DISTINCT tblSuppliers.SupplierName, Nz([BusinessEmail],[PersonalEmail]) AS Email
FROM ((tblSuppliers
INNER JOIN tblSuppliersAgreements ON tblSuppliers.ID = tblSuppliersAgreements.SupplierID)
INNER JOIN tblContacts ON tblSuppliers.ID = tblContacts.SupplierID)
WHERE ((tblSuppliersAgreements.AgreementID)=[Forms]![frmMainMenu]![cboAgreement]);
This is the error I am getting when I try to click the button to run it
我认为这可能与我在 rs.open 行中打开查询的方式有关,我需要调用条件而不仅仅是在 SQL 语句中?非常感谢对此问题或解决方案的任何帮助。
编辑
所以我用 DAO 将我的代码更改为这个,看看是否可以解决问题。我现在在行 Set rs = db.OpenRecordset(strQueryname)
上收到错误
The error
我已经留下了以前的评论方式,所以如果提供了解决方案,我可以随时改回来。
Sub EmailQuery(strQueryName As String)
'On Error GoTo Err_EmailRequery_Click
' Dim cn As ADODB.Connection
' Dim rs As ADODB.Recordset
Dim strEmail As String
Dim db As DAO.Database
Dim rs As DAO.Recordset
Set db = CurrentDb
Set rs = db.OpenRecordset(strQueryName)
' Set cn = CurrentProject.Connection
' Set rs = New ADODB.Recordset
MsgBox strQueryName
' rs.Open strQueryName, cn
With rs
' .MoveLast
' .MoveFirst
Do While Not .EOF
strEmail = strEmail & .Fields("Email") & ";"
.MoveNext
Loop
.Close
End With
strEmail = Left(strEmail, Len(strEmail) - 1)
DoCmd.SendObject , , , , , strEmail, , , True, False
'Exit_EmailRequery_Click:
'
' Exit Sub
'
'Err_EmailRequery_Click:
'
' MsgBox Err.Description
'
' Resume Exit_EmailRequery_Click
End Sub
编辑 2
主函数中的当前代码
Sub EmailQuery(strQueryName As String)
'On Error GoTo Err_EmailQuery_Click
Dim strEmail As String
Dim db As DAO.Database
Dim rs As DAO.Recordset
Set db = CurrentDb
Set rs = db.OpenRecordset(strQueryName)
MsgBox strQueryName
With rs
' .MoveLast
' .MoveFirst
Do While Not .EOF
strEmail = strEmail & .Fields("Email") & ";"
.MoveNext
Loop
.Close
End With
strEmail = Left(strEmail, Len(strEmail) - 1)
DoCmd.SendObject , , , , , strEmail, , , True, False
'Exit_EmailQuery_Click:
'
' Exit Sub
'
'Err_EmailQuery_Click:
'
' MsgBox Err.Description
'
' Resume Exit_EmailQuery_Click
End Sub
当前SQL
PARAMETERS [PrmID] Long;
SELECT DISTINCT tblSuppliers.SupplierName, IIf( IsNull(BusinessEmail) , PersonalEmail, BusinessEmail) AS Email
FROM (tblSuppliers
INNER JOIN tblSuppliersAgreements ON tblSuppliers.ID = tblSuppliersAgreements.SupplierID)
INNER JOIN tblContacts ON tblSuppliers.ID = tblContacts.SupplierID
WHERE ((tblSuppliersAgreements.AgreementID)=[PrmID]);
我知道 SQL 的完成方式可能存在问题,参数化一半或只是做错了。
你的尝试有几个问题:
命名对象:使用 ADO
Recordset.Open
调用已保存的查询,主要需要 SQL 语句或命令对象而不是命名对象.因此,您的第一个错误的原因。相反,使用Conn.Execute
将标准 SQL 语法添加到命名对象。或者显式传递SELECT * FROM
与查询对象。这不是 DAO 记录集的问题(专门针对 MS Access 对象模型的库,而 ADO 是针对 any 后端进行概括的)。参数:在看不到表单值的后端查询中使用表单控件值。任何非 运行 且
DoCmd
的查询,例如OpenQuery
(对于 select 查询)或RunSQL
(对于操作查询),都无法识别表单控件。因此,第二个错误的原因。使用 ADO Command parameters or DAO QueryDefs parameters 而不是Forms!MyForm!MyControl
。 搜索 my[vba]
tag answers 无数的 ADO 或 DAO 参数解决方案。请参阅下面的用例:Sub EmailQuery(strQueryName As String) On Error GoTo Err_EmailQuery_Click Dim strEmail As String Dim db As DAO.Database Dim qdef As DAO.QueryDef Dim rs As DAO.Recordset Set db = CurrentDb Set qdef = db.QueryDefs(strQueryName) With qdef ' BIND PARAMETER .Parameters("PrmID") = [Forms]![frmMainMenu]![cboAgreement] ' OPEN RECORDSET Set rs = .OpenRecordset() End With '...loop and email... Exit_EmailQuery_Click: rs.Close Set rs = Nothing: Set qdef = Nothing: Set db = Nothing Exit Sub Err_EmailQuery_Click: MsgBox Err.Number & " - " & Err.Description, vbCritical, "RUNTIME ERROR" Resume Exit_EmailQuery_Click End Sub
特殊功能: 运行 只有 MS Access GUI 方法像
NZ
在不识别此类功能的后端查询中。如果您解决以上两个问题,您将 运行 进入此错误。使用IIF
+ISNULL
/IS NULL
。同样,VBA user-defined 函数将无法识别。