5

我是 Access 新手,我来自 C#、SQL Server 和 .Net。我遇到了一个项目,我必须完成一些部分。

场景可以描述为:

  1. 带有子表单的 Access 表单
  2. 作为上述子表单的数据源的 Access 查询,带有两个参数,显示为:Parametername1 String(255),Parametername2 String(255)
  3. VBA 代码模块

我的计划是在我的 VBA 代码模块的过程中设置上述查询参数的值。我相信这应该刷新我的子表单,因为查询是子表单的数据源。

问题是我不知道如何实施这个计划。

我想使用查询,因为我不想用内联 SQL 弄乱我的 VBA 代码。

我正在使用 Access 2010。

4

4 回答 4

6

我正好有这个问题,我想使用相同的“存储”更新查询,但从两种不同的形式执行它,所以想在运行时将参数传递给查询。这就是我发现的(在另一个论坛中),它完全符合我的要求:

With CurrentDb.QueryDefs("qry_YourQuery")
   .Parameters("yourParam") = yourVBAvar
   .Execute
End With
于 2013-02-18T04:18:54.780 回答
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"
于 2012-08-04T19:49:01.623 回答
1

您可以创建一个函数并在表单的记录源查询中使用该函数(而不是常规参数)。

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
于 2012-08-06T15:55:46.427 回答
0

子表单绑定到一个查询,该查询根本不应该有任何参数。

您当然可以将子表单的 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
于 2013-12-13T21:55:05.867 回答