将Report的Open事件中的参数传递给参数查询(Access 2007)

时间:2010-05-15 04:39:20

标签: ms-access parameters report

我想知道是否有办法使用VBA在Access 2007查询中设置参数。我是在Access中使用VBA的新手,我的任务是为现有应用添加一些功能。

我遇到的问题是可以在应用程序的两个不同位置调用相同的报告。第一个是数据输入表单上的命令按钮,另一个是交换机按钮。报告本身基于一个参数查询,该查询要求用户输入供应商ID。

用户希望不必在数据输入表单上输入供应商ID(因为表单已经显示供应商ID),但是从交换机,他们希望提示他们输入供应商ID。

我遇到的问题是如何调用报告的查询(在报告的打开事件中)并将表单中的SupplierID作为参数传递。我已经尝试了一段时间,我无法正常工作。到目前为止,这是我的代码,但我显然很难过。

私人子报告_打开(取消为整数)

Dim intSupplierCode As Integer

'Check to see if the data entry form is open
If CurrentProject.AllForms("frmExample").IsLoaded = True Then

    'Retrieve the SupplierID from the data entry form
    intSupplierCode = Forms![frmExample]![SupplierID]

    'Call the parameter query passing the SupplierID????
    DoCmd.OpenQuery "qryParams"


Else

    'Execute the parameter query as normal

    DoCmd.OpenQuery "qryParams"?????


End If

End Sub

我已经尝试了Me.SupplierID = intSupplierCode,虽然它编译了,但是当我运行它时它会爆炸。这是我的参数查询的SQL代码:

PARAMETERS [输入供应商] Long; SELECT Suppliers.SupplierID,Suppliers.CompanyName,Suppliers.ContactName,Suppliers.ContactTitle 来自供应商 WHERE(((Suppliers.SupplierID)= [输入供应商]));

我知道有解决这个问题的方法(也可能是一种简单的方法),但就像我说的那样,我缺乏使用Access和VBA的经验会让事情变得困难。如果你们中的任何人能提供帮助,那就太好了!

2 个答案:

答案 0 :(得分:7)

此处提出的建议是100%从查询中删除参数。这不仅解决了你的问题,而且意味着你可以使用查询代码,其他形式,而不是让你的整个设计崩溃,因为一个愚蠢的形式没有打开(因此你的问题的非常原因)。

因此,从查询中删除参数。这也意味着您的报告现在不需要已经打开的表单。而且,如果没有打开一些愚蠢的表格,为什么你的报告无法运作?

因此,删除参数。现在,在打开报表的表单中,它可以传递过滤器,更多的是使用所谓的“where”子句。这个“where”子句是在MS访问中设计的,用于解决必须提前知道需要什么样的参数和过滤器的问题。它在运行时发生,因此许多不同的表单可以调用并打开该报告。

现在,在调用并打开表单的表单中,您可以:

Docmd.OpenReport "rptSuppliers",acViewPreview, , _
                "SupplierCode = " & me.SupplierCode

因此,在上面,参数是动态创建的。最大的好处是明天你可以用另一个表单打开同一个报表,也许按地区过滤。

如果NO where子句被传递并且用户只是打开表单,则不会使用任何过滤器,也不会出现提示并显示所有记录。这可能是你最好的方法。

但是,如果出于某些奇怪的原因,当一个愚蠢的表单恰好没有打开时,你仍然认为有必要提供一些报告提示,那么将以下代码放在表单on-open事件中。

If CurrentProject.AllForms("form1").IsLoaded = False Then
   Me.Filter = "SupplierID = " & InputBox("Enter Supplier ID")
   Me.FilterOn = True
End

但是,我真的会努力避免在报告打开事件中对一些愚蠢的表单名称进行硬编码。这不仅意味着您现在附加到报表的某些愚蠢形式的硬编码依赖关系,而且如果您稍后复制该报表,甚至复制原始表单(甚至重命名任何这些对象),那么您必须进入应用程序并进行搜索,现在找到您作为开发人员引入依赖项的地方。这种方法可以大大增加应用程序的维护成本,因此应该提出建议。

所以,这里的建议是转储参数查询。只需提供表单或一些提示系统即可启动报告。这些表单应提示用户输入您要过滤的信息。或者在您的情况下,绑定表单和当前记录提供该信息。这个系统的美妙之处在于,报告中没有任何重要性。

任何形式,甚至任何代码都可以免费传递给pramaeter,它不仅限于SupplierID,也可以是您希望的任何类型的过滤器或参数。

请记住,用户可能不希望该表单打开,也许他们不希望提示。根据您的设计和问题,即使在没有打开任何表单的情况下启动报表,用户也将被迫输入参数值,并且不希望提示他们查看该报表中的所有reocrds。

答案 1 :(得分:3)

正如我在a recent post中所概述的那样,我倾向于永远不会将任何参数或控件引用硬连接到报告或表单的记录源中。相反,我在运行时设置它们。最简单的方法是在DoCmd.OpenForm / DoCmd.OpenReport中传递WhereCondition属性:

DoCmd.OpenReport "MyReport", , , "[SupplierID]=" & Me!SupplierID

假设您正在从其记录源中已存在相关SupplierID的表单中运行它(即,您正在使用该SupplierID记录)。

更复杂的是使用报告的OnOpen事件来设置报告的记录源。这就是我概述的in the cited post above。但是,该示例将选择硬连接到选择表单,而您可能希望根据上下文提供不同的选择集。有两种方法可以解决这个问题:

  1. 如果是A2003及更高版本,则传递一个OpenArg(DoCmd.OpenReport的最后一个参数)来告诉OnOpen事件如何收集有关过滤内容的信息。

  2. 使用类似独立类模块的外部结构来存储OnOpen事件将读取并相应地执行操作的条件。

  3. 我怀疑DoCmd.OpenReport中的WhereCondition是最简单的解决方案,但如果你想了解其他两个的详细信息,请问。