如何在 Microsoft Access 中通过 VBA 设置 INSERT SQL 查询的参数值?
Posted
技术标签:
【中文标题】如何在 Microsoft Access 中通过 VBA 设置 INSERT SQL 查询的参数值?【英文标题】:How can one set parameter values of an INSERT SQL query through VBA in Microsoft Access? 【发布时间】:2012-08-04 18:01:39 【问题描述】:我是 Access 新手,我来自 C#、SQL Server 和 .Net。我遇到了一个项目,我必须完成一些部分。
场景可以描述为:
-
带有子表单的 Access 表单
Access 查询是上述子表单的数据源,有两个参数,显示为:
Parametername1 String(255),Parametername2 String(255)
。
VBA 代码模块
我的计划是在我的 VBA 代码模块的过程中设置上述查询参数的值。我相信这应该刷新我的子表单,因为查询是子表单的数据源。
问题是我不知道如何实施这个计划。
我想使用查询,因为我不想用内联 SQL 搞乱我的 VBA 代码。
我正在使用 Access 2010。
【问题讨论】:
VBA 模块中的内联 SQL 是一个坏主意,不仅出于可读性目的,而且因为它可能引发意外错误并造成 security threat。 【参考方案1】:我正好有这个问题,我想使用相同的“存储”更新查询,但从两种不同的形式执行它,所以想在运行时将参数传递给查询。这是我(在另一个论坛中)发现的,完全符合我的要求:
With CurrentDb.QueryDefs("qry_YourQuery")
.Parameters("yourParam") = yourVBAvar
.Execute
End With
【讨论】:
“qry_YourQuery”是什么样的?你只是把?
放在参数值应该放的地方吗?
你有链接到你找到这个sn-p的论坛吗?我搜索了,但我只能找到对这篇文章的引用。
对于那些想知道的人。 “qry_YourQyery”是您在访问数据库中的查询列表中保存的查询的名称,例如 qryUpdateSalary。 “yourParam”是您在查询中的参数名称,即更新 tblSalary 设置 Salary = 工资*工作小时,其中 PersonId = [人]。在这种情况下,参数是人,所以上面的例子看起来像code With CurrentDb.QueryDefs("qryUpdateSalary") .Parameters("person") = personID 'this variable comes from another step in the VBA code .Execute End With
【参考方案2】:
子表单的全部意义在于它由记录源以及链接子字段和主字段控制。假设表单是公司,子表单是员工,子表单的记录源可能是:
SELECT EmployeeID, CompanyID, Position, Etc FROM Employees
链接子字段和主字段将为 CompanyID。当您在主表单中移动时,只会显示与当前公司相关的那些记录。假设您只想显示那些技术职位的员工,您可以在运行时更改记录源:
SELECT EmployeeID, CompanyID, Position, Etc FROM Employees
WHERE Position = "Technical"
或者,如果这始终是表单上的过滤器,请在主表单中添加一个组合框,并将其用作第二个链接主字段,这样您就有了:
Link Master Fields: CompanyID; cboPosition
Link Child Fields : CompanyID; Position
最后,您可以简单地从主窗体中设置过滤器属性:
Me.Employees_subform.Form.Filter = "Position=""Tecnical"""
Me.Employees_subform.Form.FilterOn = True
如果这不是您的想法,请在您的问题中添加一些注释。
编辑
您可以通过引用表单上的控件来为查询提供参数:
SELECT EmployeeID, CompanyID, Position, Etc FROM Employees
WHERE Position = Forms!MyMainForm!cboPosition
您可以完全更改查询的 SQL,并且可以使用 ADO,但是,更改 SQL 类似于设置记录源,因为 SQL 是在代码中更改的,并且使用 ADO 通常不是表单的最佳选择。
你不能做的是改变一个参数并让它“粘”在一个表单或子表单上。
例如:
DoCmd.SetParameter "@SomeID", "1"
' This works
DoCmd.OpenQuery ("Queryx")
' This will give a prompt for @SomeID and then run
Me.SomeSubform.Form.RecordSource = "Queryx"
【讨论】:
Remou 谢谢。这肯定会有所帮助。但我不想使用过滤器。我已经有一个查询,它是子表单的记录源。我需要知道是否有任何方法可以更改/设置 VBA 代码中的查询参数。我正在寻找在 SQL 服务器中使用存储过程和在.net 中使用 SqlCommand (System.data.sqlclient) 类的解决方案。我什至不知道这是否可能。否则我只会将我的 sql 嵌入到我的 VBA 代码中,并使用 SQL stateemnt 作为我的记录/数据源并继续生活。访问不同! 访问是不同的,主要区别在于你可以在没有任何代码的情况下做很多事情,这是人们经常忘记的。在这种情况下,查询的参数应该来自表单,我指出了可能发生这种情况的方式。我错过了其他选项,我会添加它们。 再次感谢 Remou...我认为我们已经接近解决方案了。唯一的事情是我不希望应用程序提示查询中定义的参数。我想在我的 VBA 代码中设置参数的值....以你的例子 - where position = "Technical",我想在我的 VBA 代码中提供 "Technical" 的值 也许您想重新阅读我的回答?我说你不能在你设定的范围内这样做。如果您想提供“技术”,请将其写入控件并在查询中引用该控件,它可以是隐藏控件。 “技术”从何而来?如果用户正在提供它,那么您已经有了一个控件。 嗨 Remou 我认为我无法正确解释这个问题。我们已经偏离正题了。完全是我的错。查询的值将来自窗体上的控件。我需要的是一种避免将 SQL 语句嵌入到我正在编写的 VBA 代码中的方法。我想在存储过程 sql 中使用存储过程参数的行,如下所示选择您可以创建一个函数并在表单的记录源查询中使用该函数(而不是常规参数)。
Public Function PositionParam(Optional ByVal P1 As Variant) As Variant
Static varP As Variant
If Not IsMissing(P1) Then
If IsNull(P1) Then
varP = Null
Else
varP = CStr(P1)
End If
ElseIf VarType(varP) = vbEmpty Then
varP = Null
End If
PositionParam = varP
End Function
记录来源查询:
SELECT y.id_fld, y.another_fld, y.position_fld
FROM YourTable AS y
WHERE
y.position_fld = PositionParam()
OR PositionParam() Is Null
ORDER BY y.id_fld, y.another_fld;
稍后当您想在子表单中显示一组不同的行时,更改分配给子表单PositionParam()
和Requery
的值。
PositionParam "technician"
Forms("YourForm").Requery
【讨论】:
这可行。对我来说,我想我更愿意按照 Remou 的建议从表单中获取查询参数。但是,既然您似乎不想那样做,这是另一种方式。【参考方案4】:子表单绑定到一个查询,该查询根本不应该有任何参数。
您当然可以将子表单的 SQL 存储在查询中,这样就消除了内联 sql,但是转而编写 WHACKS 代码来解决这个问题完全没有意义,不是吗?
如前所述,子表单重新编码的过滤和显示是自动的,如果您从控件设置子表单的主链接和子设置,则无需代码即可发生。您可能在这里不需要任何代码。
但是,如果出于某种真正原因您需要编写代码或想要更多的计费时间,那么您可以使用此代码:
Dim strSql As String
strSql = Split(CurrentDb.QueryDefs("name of query").SQL, ";")(0)
strSql = strSql & "where Field1 = " & "'your p1 value'" & _
" and Field2 = " & "' your p2 value'"
Me.custChild.Form.RecordSource = strSql
因此您不需要在 sql 中使用任何参数,而只需使用子表单所基于的 CURRENT 和 SAME 查询。此外,如果您添加参数,那么您将在查询中对 2 个值进行硬编码,然后该查询不能用于其他代码和任务,除非您提供 2 个 SAME 硬编码参数(因此,在其他地方使用该查询时,这几乎没有灵活性有不同的选择)。
因此,将参数排除在查询之外,并保留相同的金钱和时间以及计费时间。
按照上述方法拉取查询 SQL 并将条件添加到 SQL 是一件简单的事情。但是,如果您希望将数据插入子表单,则可以直接使用子表单数据源和 reocrdset。例如:
Dim rst As DAO.Recordset
Set rst = Me.custChild.Form.RecordsetClone
rst.AddNew
rst!SomeField = "some valjue"
rst!SomeField2 = "some value"
rst.Update
Me.custChild.Requery
【讨论】:
以上是关于如何在 Microsoft Access 中通过 VBA 设置 INSERT SQL 查询的参数值?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 MS Access 2007 或 MS SQL Server 2005 中通过 SQL 将字段转换为行
如何在 C# 中通过 lpEnvironment 调用 CreateProcess()