簡體   English   中英

Access 2007 VBA和SQL-更新指向動態創建的查詢的子窗體

[英]Access 2007 VBA & SQL - Update a Subform pointed at a dynamically created query

摘要:每當用戶從下拉菜單中選擇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

結束子

2)用戶從組合框中選擇項目的主窗體。

主窗體和子窗體的圖片http://i48.tinypic.com/25pjw2a.png

3)子窗體指向在步驟1中創建的查詢。

事件鏈:1)用戶從主窗體的下拉列表中選擇項目。 2)刪除舊查詢,生成新查詢(名稱相同)。 3)指向查詢的子窗體不會更新,但是如果您自己打開查詢,則會顯示正確的結果。

查詢的名稱:qryAllOpenJobs子窗體的名稱:subQryAllOpenJobs另外,subQryAllOpenJobs的行源= qryAllOpenJobs主窗體的名稱:frmManagement

我認為您對部門下拉檢查有邏輯。

您可以檢查strWhere是否為null,如果是,則將strWhere與cboDepartment的值連接在一起。

您應該為Date做些什么。

' 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是子窗體的名稱。

空字符串與Null不同。 當聲明這樣的String變量時:

Dim strWhere As String

strWhere初始化為空字符串(或“零長度字符串”)。 該值有時稱為空字符串,甚至還有一個VBA常量vbNullString ,它代表空字符串。 但是,無論使用哪種名稱,空字符串變量都不為Null。 此外,VBA字符串變量永遠不能為Null。 例如,此代碼將導致錯誤94,“無效使用Null”:

Dim strWhere As String
strWhere = Null

我強調這一點的原因是因為您的代碼測試了strWhere是否為Null。 這是一個邏輯缺陷,因為strWhere永遠不會為Null。 例如,我不認為這種情況永遠可以成立:

If IsNull(strWhere) Then

如果要通過測試確定何時未為strWhere賦值(它仍然是空字符串),請使用Len函數:

If Len(strWhere) = 0 Then

這是BuildQuery的另一種方法。 假設[Date]字段的數據類型為String(如原始代碼所示)。 如果[Date]實際上是日期/時間數據類型,則此代碼將不起作用。 另外,請注意,日期是保留字(請參閱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

我的解決方案分為以下三個部分。 (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()子項所示,填充子表單以根據用戶從下拉過濾器和表單右側輸入框中選擇的內容構建查詢。 用戶無法訪問表本身中的數據,僅供他們參考。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM