Access 2007 VBA& SQL - 更新指向动态创建的查询的子表单

时间:2010-05-25 20:03:40

标签: sql ms-access ms-access-2007 access-vba

摘要: 每次用户从下拉菜单中选择3个选项中的一个时,我都会使用VB重新创建查询,该菜单附加WHERE子句如果他们从组合框中选择了任何内容。然后,我试图获取表单上显示的信息进行刷新,从而根据用户输入过滤表格中显示的内容。

1)使用VB动态创建查询。

Private Sub BuildQuery()
' This sub routine will redefine the subQryAllJobsQuery based on input from
' the user on the Management tab.

Dim strQryName As String
Dim strSql As String            ' Main SQL SELECT statement
Dim strWhere As String          ' Optional WHERE clause
Dim qryDef As DAO.QueryDef
Dim dbs As DAO.Database

strQryName = "qryAllOpenJobs"
strSql = "SELECT * FROM tblOpenJobs"
Set dbs = CurrentDb

' In case the query already exists we should deleted it
' so that we can rebuild it.  The ObjectExists() function
' calls a public function in GlobalVariables module.
If ObjectExists("Query", strQryName) Then
    DoCmd.DeleteObject acQuery, strQryName
End If

' Check to see if anything was selected from the Shift
' Drop down menu.  If so, begin the where clause.
If Not IsNull(Me.cboShift.Value) Then
    strWhere = "WHERE tblOpenJobs.[Shift] = '" & Me.cboShift.Value & "'"
End If

' Check to see if anything was selected from the Department
' drop down menu.  If so, append or begin the where clause.
If Not IsNull(Me.cboDepartment.Value) Then
    If IsNull(strWhere) Then
        strWhere = strWhere & " AND tblOpenJobs.[Department] = '" & Me.cboDepartment.Value & "'"
    Else
        strWhere = "WHERE tblOpenJobs.[Department] = '" & Me.cboDepartment.Value & "'"
    End If
End If

' Check to see if anything was selected from the Date
' field.  If so, append or begin the Where clause.
If Not IsNull(Me.txtDate.Value) Then
    If Not IsNull(strWhere) Then
        strWhere = strWhere & " AND tblOpenJobs.[Date] = '" & Me.txtDate.Value & "'"
    Else
        strWhere = "WHERE tblOpenJobs.[Date] = '" & Me.txtDate.Value & "'"
    End If
End If

' Concatenate the Select and the Where clause together
' unless all three parameters are null, in which case return
' just the plain select statement.
If IsNull(Me.cboShift.Value) And IsNull(Me.cboDepartment.Value) And IsNull(Me.txtDate.Value) Then
    Set qryDef = dbs.CreateQueryDef(strQryName, strSql)
Else
    strSql = strSql & " " & strWhere
    Set qryDef = dbs.CreateQueryDef(strQryName, strSql)
End If

End Sub

2)主表单,用户从组合框中选择项目。

主要表格和子表格的图片 http://i48.tinypic.com/25pjw2a.png

3)子表单指向在步骤1中创建的查询。

事件链: 1)用户从主表单的下拉列表中选择项目。 2)删除旧查询,生成新查询(同名)。 3)指向查询的子表单不会更新,但如果您自己打开查询,则会显示正确的结果。

查询名称:qryAllOpenJobs 子表单的名称:subQryAllOpenJobs 此外,subQryAllOpenJobs = qryAllOpenJobs的Row Source 主要表格的名称:frmManagement

3 个答案:

答案 0 :(得分:2)

我认为你在部门的逻辑下拉向后检查。

你检查strWhere是否为null,如果是,则将strWhere与cboDepartment的值连接起来。

你应该做你的日期。

' Check to see if anything was selected from the Department
' drop down menu.  If so, append or begin the where clause.
If Not IsNull(Me.cboDepartment.Value) Then
    If Not IsNull(strWhere) Then
        strWhere = strWhere & " AND tblOpenJobs.[Department] = '" & Me.cboDepartment.Value & "'"
    Else
        strWhere = "WHERE tblOpenJobs.[Department] = '" & Me.cboDepartment.Value & "'"
    End If
End If

您可能还想这样做:

If Nz(strWhere,"") = "" then

除了执行IsNull之外,您还可以捕获除零变量之外的零长度字符串。

至于设置记录源,请使用

Me.sfrmJobs.Form.RecordSource = strSQL

其中sfrmJobs是子表单的名称。

答案 1 :(得分:2)

空字符串与Null不同。当声明一个String变量时,例如:

Dim strWhere As String

strWhere初始化为空字符串(或“零长度字符串”)。该值有时被称为空字符串,甚至还有一个VBA常量 vbNullString ,它表示空字符串。但是,无论使用哪个名称,空字符串变量都不是Null。此外,VBA字符串变量永远不会为空。例如,此代码将导致错误94,“无效使用空”:

Dim strWhere As String
strWhere = Null

我强调这一点的原因是因为你的代码测试strWhere是否为Null。这是一个逻辑缺陷,因为strWhere永远不会是空的。例如,我不相信这种情况永远是真的:

If IsNull(strWhere) Then

如果你想测试确定strWhere什么时候没有赋值(它仍然是一个空字符串),请使用Len函数:

If Len(strWhere) = 0 Then

这是BuildQuery的另一种方法。它假定[Date]字段的数据类型为String(如原始代码所示)。如果[Date]实际上是日期/时间数据类型,则此代码将不起作用。另请注意,日期是保留字(请参阅Problem names and reserved words in Access)。我将字段名称括在方括号中以避免歧义。如果它是我自己的数据库,我会更改字段名称。

Private Sub BuildQuery()
'* Update subform RecordSource based on input from *'
'* the user on the Management tab. *'

Dim strSql As String        ' Main SQL SELECT statement '
Dim strWhere As String      ' Optional WHERE clause '
Dim i As Integer
Dim strControl As String
Dim strField As String

strSql = "SELECT * FROM tblOpenJobs AS oj"

strWhere = vbNullString
For i = 1 To 3
    Select Case i
    Case 1
        strControl = "cboShift"
        strField = "Shift"
    Case 2
        strControl = "cboDepartment"
        strField = "Department"
    Case 3
        strControl = "txtDate"
        strField = "[Date]"
    End Select
    If Not IsNull(Me.Controls(strControl).Value) Then
        strWhere = strWhere & _
            IIf(Len(strWhere) > 0, " AND ", "") & _
            "oj." & strField & " = '" & _
            Me.Controls(strControl).Value & "'"
    End If
Next i

If Len(strWhere) > 0 Then
    strSql = strSql & " WHERE " & strWhere
End If
'* use the name of the subform CONTROL for sfrmJobs *'
'* (may not be the name of the subform) *'
Me.sfrmJobs.Form.RecordSource = strSql

End Sub

答案 2 :(得分:1)

我的解决方案分为三部分。 (1)构建查询,(2)主要表格,(3)子表单。 `Private Sub OpenJobsQuery()     '此子程序将在首页上为用户构建查询     '基于他们是谁以及他们从上面的组合框中选择什么     '通过重新定义子表单的行源来进行过滤的表     'subQryOpenJobs

Dim strSql As String            ' Main SQL SELECT statement
Dim strWhere As String          ' Where clause containing user specified parameters.

strSql = "SELECT * FROM tblOpenJobs"
strWhere = ""

' Check to see if anything was selected from the Shift
' combo box.  If so, begin the Where clause.
If Not IsNull(Me.cboOpenJobShift.Value) Then
    strWhere = "WHERE tblOpenJobs.[Shift] = '" & Me.cboOpenJobShift.Value & "'"
End If

' Check to see if anything was selected from the Department
' combo box.  If so, append or begin the where clause.
If Not IsNull(Me.cboOpenJobDepartment.Value) Then
    If strWhere = "" Then
        strWhere = "WHERE tblOpenJobs.[Department] = '" & Me.cboOpenJobDepartment.Value & "'"
    Else
        strWhere = strWhere & " AND tblOpenJobs.[Department] = '" & Me.cboOpenJobDepartment.Value & "'"
    End If
End If

' Check to see if anything was selected from the Date
' field.  If so, append or begin the Where clause.
If Not IsNull(Me.cboOpenJobDate.Value) Then
    If strWhere = "" Then
        strWhere = "WHERE tblOpenJobs.[JobDate] = #" & Me.cboOpenJobDate.Value & "#"
    Else
        strWhere = strWhere & " AND tblOpenJobs.[JobDate] = #" & Me.cboOpenJobDate.Value & "#"
    End If
Else
    ' If nothing was entered in the date field, make sure the user
    ' only sees future jobs.
    If strWhere = "" Then
        strWhere = "WHERE tblOpenJobs.[JobDate] > #" & FormatDateTime(Date, vbShortDate) & "#"
    Else
        strWhere = strWhere & " AND tblOpenJobs.[JobDate] > #" & FormatDateTime(Date, vbShortDate) & "#"
    End If
End If

' Always include as part of the where clause, a section that
' will narrow the results based on who the user is
If strWhere = "" Then
    strWhere = "WHERE tblOpenJobs.[OpenJobID] Not In " & _
               "(SELECT tblSignUps.[OpenJobID] FROM tblSignUps WHERE tblSignUps.[EUID] = '" & strEUID & "');"

Else
    strWhere = strWhere & " AND tblOpenJobs.[OpenJobID] Not In " & _
               "(SELECT tblSignUps.[OpenJobID] FROM tblSignUps WHERE tblSignUps.[EUID] = '" & strEUID & "');"
End If

' Concatenate the Select and the Where clause together
strSql = strSql & " " & strWhere

' Set the recordsource of the subform to the SQL query generated
' and refresh the form.
Me.subQryOpenJobs.Form.RecordSource = strSql

' In addition, synchronize the JobID's in the Edit Job box to match those
' filtered by this Build Query.
Me.cboSelectJOBID.RowSource = "SELECT tblOpenJobs.[OpenJobID] FROM tblOpenJobs" & " " & strWhere

Me.Refresh

结束Sub`

(2)主要表格。 http://j.imagehost.org/view/0385/Form。 (3)如BuildQuery()子中所示填充子表单,根据用户从下拉过滤器和表单右侧的输入框中选择的内容构造查询。表中的数据本身是用户无法访问的,这只是供他们参考。