我在MS Access數據庫中有一個查詢。我如何創建一個具有按鈕來運行查詢並以相同形式顯示結果的表單,以便它看起來更加用戶友好。 (結果是兩列表中只有5條記錄)訪問表單以運行查詢並顯示結果
我不需要一個完整的解決方案。只是關於按鈕的代碼和顯示結果的空間的一些建議。
我在MS Access數據庫中有一個查詢。我如何創建一個具有按鈕來運行查詢並以相同形式顯示結果的表單,以便它看起來更加用戶友好。 (結果是兩列表中只有5條記錄)訪問表單以運行查詢並顯示結果
我不需要一個完整的解決方案。只是關於按鈕的代碼和顯示結果的空間的一些建議。
基礎上的答案,我想我不明白的問題。這聽起來像OP有一個DML查詢(或「訪問條款」中的「動作查詢」),用於修改數據並希望在表單中顯示結果。當前的答案解釋瞭如何顯示結果,但不知道如何運行查詢。
所以,這裏有一個基於我對問題的解釋的答案。
首先,創建一個與結果綁定的連續或數據表格。
這是很容易的部分。 「硬」部分正在執行SQL來更新要顯示的結果。您不會給出任何啓動環境,也不知道如何確定要更新哪些特定記錄,因此我將給出兩個相當通用的答案。
方法1.創建兩個部分宏:
的第一個命令是OPENQUERY,你會提供您保存查詢作爲參數的名稱。
第二個命令是OpenForm,它打開您創建的窗體以顯示結果。
現在,我還沒有提供任何執行宏的方法,但那是因爲您沒有提供任何上下文。
方法2窗體上從它是適當的啓動這一過程:
創建COMAND按鈕。
使用OnClick事件執行所需的操作。
a。使用您使用方法1編寫的宏作爲命令按鈕的OnClick事件的參數。
b。編寫VBA代碼來完成這兩項任務:
CurrentDB.Execute "MySaveQueryThatUpdatesData", dbFailOneError
DoCmd.OpenForm "MyFormThatDisplaysTheResults"
但這一切真的乞討的問題,因爲這是所有漂亮該死的基礎。這種事情的難點在於當你的SQL更新操作記錄的一個子集時,你只需要顯示記錄的子集。
很可能您的原始查詢將被鎖定到原始上下文。例如,假設您想從顯示公司的表單中啓動整個流程,並且您的SQL對當前顯示的公司記錄的員工進行操作。在這種情況下,您需要更新限於您當前正在查看的公司的Employees表。有兩種方法可以做到這一點:
使用您保存的QueryDef的WHERE子句中的CompanyID參考本公司形式:
UPDATE Employees
SET [blah, blah, blah]
WHERE Employees.CompanyID = Forms!Company!CompanyID
,而不是使用保存的QueryDef硬連接到要求你的公司形式是開放的,它的工作,寫上飛SQL在命令按鈕背後的代碼:
Dim strSQL As String
strSQL = "UPDATE Employees "
strSQL = strSQL & "SET [blah, blah, blah] "
strSQL = strSQL & "WHERE Employees.CompanyID = "
strSQL = strSQL & Me!CompanyID
CurrentDB.Execute strSQL, dbFailOneError
現在,對於它的第二部分,您需要打開結果表單以僅顯示已更新的記錄。這意味着您希望使用與用於更新相同的WHERE子句打開表單。對此也有兩種方法。
第一是非常喜歡你的結果窗體的記錄的WHERE子句中的WHERE子句中進行更新,即硬連線參考本公司的形式第一種方法。因此,記錄源爲您的結果形式是這樣的:
SELECT Employees.*
FROM Employees
WHERE Employees.CompanyID = Forms!Company!CompanyID
那麼你還是開結果形成最初規定的相同的方式:
DoCmd.OpenForm "MyFormThatDisplaysTheResults"
第二種方法避免了硬連線的記錄源您的結果表單需要公開表格,而您只需在OpenForm命令的相應參數中提供WHERE子句(不帶WHERE關鍵字):
DoCmd.OpenForm "MyFormThatDisplaysTheResults", , , "[CompanyID] = " & Me!CompanyID
學習這樣做是使用Access的最強大和最容易的方面之一,因爲您可以創建一個表單來返回表中的所有記錄,然後通過提供適當的WHERE參數來打開該表單並顯示數據的子集在OpenForm命令中。請記住,Access非常高效地應用了這些操作,也就是說,它不會打開表單並加載整個記錄集,然後將WHERE參數應用於該記錄集,而是將WHERE參數應用於記錄源之前任何記錄加載表格。
現在,考慮什麼是最好的辦法了所有的替代品:我會寫上飛了更新的SQL和使用的OpenForm命令的WHERE參數做
過濾。所以,在我的應用程序之一,公司表單上的命令按鈕的OnClick事件背後的代碼是這樣的:
Dim strSQL As String
strSQL = "UPDATE Employees "
strSQL = strSQL & "SET [blah, blah, blah] "
strSQL = strSQL & "WHERE Employees.CompanyID = "
strSQL = strSQL & Me!CompanyID
CurrentDB.Execute strSQL, dbFailOneError
DoCmd.OpenForm "MyFormThatDisplaysTheResults", , , "[CompanyID] = " & Me!CompanyID
現在,因爲dbFailOnError論據CurrentDB.Execute的,你需要錯誤處理程序。如果你想知道有多少記錄,其中改變了,你需要使用比CurrentDB等,所以更可能是一個數據庫對象,我會做這樣的:
On Error GoTo errHandler
Dim strSQL As String
Dim db As DAO.Database
strSQL = "UPDATE Employees "
strSQL = strSQL & "SET [blah, blah, blah] "
strSQL = strSQL & "WHERE Employees.CompanyID = "
strSQL = strSQL & Me!CompanyID
Set db = CurrentDB
db.Execute strSQL, dbFailOneError
Debug.Print "Updated " & db.RecordsAffect & " Employee records."
DoCmd.OpenForm "MyFormThatDisplaysTheResults", , , "[CompanyID] = " & Me!CompanyID
exitRoutine:
Set db = Nothing
Exit Sub
errHandler:
MsgBox Err.Number & ": " & Err.Description, _
vbExclamation, "Error in Forms!Company!cmdMyButton.OnClick()"
Resume exitRoutine
我的理由爲構建SQL在命令按鈕的OnClick事件中動態添加更多條件是非常容易的,如果它們變得必要的話。我喜歡避免將保存的QueryDefs與UI對象依賴關係重載,所以我傾向於在它正在使用的地方即時寫這樣的SQL。
有些人擔心,由於數據庫引擎的查詢優化程序沒有對動態SQL進行優化,因此會降低性能。這可能會也可能不會是真實的。許多服務器數據庫引擎緩存動態SQL命令的優化計劃,由於Jet/ACE像這樣解析SQL命令並將其交給服務器,因此很可能將其作爲通用存儲過程發送。因此,像SQL Server這樣的服務器將緩存該查詢計劃,並且每次執行即時SQL時都能重新使用它,即使每次有不同的CompanyID值。
對於Jet/ACE後端,沒有像這樣的高速緩存,但是在沒有在非常大的數據集上操作的情況下,優化SQL和未優化SQL之間的執行時間差異會非常小。甚至更新,比如說1000個員工記錄並不是Jet/ACE的大數據集。所以我認爲從動態編寫SQL來證明將它移動到保存的QueryDef是很少有性能問題的。但是,在個案基礎上,我可能會選擇這樣做 - 這不會是我的第一選擇。
然而,更重要的反對意見是,你會在整個代碼中散佈一堆SQL字符串,這可能會成爲維護的噩夢。我不知道該說些什麼,除了有辦法處理這種情況,以便通過將基本SELECT查詢保存爲已保存的QueryDef並使用這種方式來消除儘可能多的重複代碼是唯一唯一的特定於在特定情況下采取的操作的部分,或者通過在代碼中使用定義的常量來保存您使用的基本SQL語句(例如,您只需更改常量的定義以更改結果在任何地方使用)。
這相當薄弱,但與Access,我沒有看到任何替代方案。如果將每個SQL語句另存爲QueryDef,則最終會產生一種不可管理的混亂狀態,其中包含太多保存的查詢,而每個保存的查詢都與另一個略有不同,並且可能與代碼中重複的SQL一樣重複。
但這是另一個問題,我可能不應該通過嘗試解決它在這裏!
我建議使用帶連續窗體的子窗體來顯示結果。我想查詢的一些描述一個選擇查詢,到子窗體的記錄源可以被設置爲SQL字符串:
strSQL="SELECT ID, Description, Count(SomeVal) " _
& "FROM Table " _
& "GROUP BY ID, Description " _
& "HAVING SomeVal=" & Me.txtSomeVal
Me.[Subform Control Name].Form.RecordSource = strSQL