2012-10-18 151 views
5

在Microsoft Access表單中,無論何時當前記錄更改,綁定控件中的任何更改都會以靜默方式保存到數據庫表中。這很好,但我不希望在用戶關閉表單時發生這種情況,因爲這與許多人所期望的直接相反。防止關閉按鈕以保存MS Access中的記錄

最好的例子是,當您嘗試關閉一個未保存更改的Excel文件時,它會詢問是否應該放棄更改。這正是我試圖在Access中實現的,但無法找到任何方法來捕獲VBA中的關閉按鈕事件。

窗體的Unload事件是有人單擊關閉按鈕時觸發的第一個事件,但此時更改已寫入數據庫。

這是完全可能的,還是我必須創建我自己的關閉按鈕?我很喜歡爲這樣的小事寫大量的代碼,但我討厭不得不弄亂GUI。

+1

這可能不是嚴格的幫助,但是這就是爲什麼綁定表單的是偉大的工作。我把它看作是這樣的:用綁定的形式,你必須防止你不想要的任何改變,並且在沒有綁定的情況下,你只提交你想要的改變,取決於你想從哪個方面攻擊問題。然而綁定形式可能是有用的,但當我需要連續形式時,我真的只會爲他們服務。 –

+1

在某種程度上,我正在尋找,但我不想失去所有爲我完成的代碼管道工作,當我綁定我的控件時。 –

+0

可能存在未綁定表單問題的地方,安裝期間有更多的代碼工作,但最終是一個更容易控制的產品。 –

回答

0

實際上,您無法捕獲這一點,Access直接在桌子上工作,當字段移動到另一個字段,記錄或按鈕時,每個更改都已被保存。

其實恕我直言,這是相對於Excel的

如果你真的想類似Excel中的行爲,你需要對錶的副本和更新一些代碼工作的一個很大的優勢。

+0

我總是有這樣的印象:綁定的議會實際上與表單的RecordSet屬性的字段相關聯。這是一個錯誤的假設? –

+0

@StevenDotNet,直到執行保存或執行到不同(或新)記錄的移動或表單關閉時纔會保存記錄。 – SeanC

+0

這與您必須調用'RecordSet.Update()'以應用更改類似。除非表單更新記錄集,即使我不希望它。 –

5

您必須使用Form_BeforeUpdate事件。下面是一個例子;但它確實會創建一個典型的警告消息:「此時不能保存此記錄,Microsoft Access可能在嘗試保存記錄時遇到錯誤......」 - 這取決於您的數據庫設置。您可以使用下面的簡單解決方法來避免顯示該消息。

Private Sub Form_BeforeUpdate(Cancel As Integer) 
    Cancel = True 
    'Or even better you can check certain fields here (If Then...) 

End Sub 


Private Sub Form_Error(DataErr As Integer, Response As Integer) 
    If DataErr = 2169 Then 
     Response = True 
    End If 
End Sub 
+0

我忘記了BeforeUpdate事件,但不會觸發任何表單的關閉事件之前? –

+0

爲了澄清,我只想在用戶單擊表單關閉按鈕時取消= true。 –

+1

您可以輕鬆禁用窗體上的關閉(X)按鈕(窗體屬性)。 – salih0vicX

2

這是代碼我有檢查,看看是否正在關閉或保存窗體。

Private Sub Form_BeforeUpdate(Cancel As Integer) 

If Not UsingSaveButton Then 
    If MsgBox("Abandon Data?", vbInformation + vbYesNo) = vbNo Then 
     Cancel = True 
    Else 
     DoCmd.RunCommand acCmdUndo 
    End If 
End If 
End Sub 

我有一個設置爲False上裝載,然後在使用我的保存按鈕布爾標誌,我把它設置爲true,允許更新運行通過。
如果該標誌沒有設置,那麼他們將離開記錄(通過轉到不同的記錄或關閉表單),所以我問他們是否真的想保存更改。
如果有任何更改,Cancel = True會中止退出表單或轉移到其他記錄。
DoCmd.RunCommand acCmdUndo撤銷任何更改,以免它們保存。

+0

這聽起來很不錯。我假設'UsingSaveButton = False'進入'Form_AfterUpdate'? –

+0

我在保存例程中使用它。在開始處放置'UsingSaveButton = True',並在末尾設置爲false(確保任何錯誤處理也將該值設置爲false。在**表單加載**或**上設置值爲當前值**事件 – SeanC

3

肖恩給出了一個幾乎正確的答案,但它留下了空白。

一般來說,FORM的BeforeUpdate是最重要的形式事件。這是您的最後一道防線,並且始終在保存記錄之前運行,無論提示保存的是什麼(表格關閉,新記錄,您自己的保存按鈕,點擊子窗體等)。雖然我偶爾使用控件的BeforeUpdate事件只是這樣用戶才能更早得到錯誤消息,我寫入的驗證代碼的大部分都在Form_BeforeUpdate事件中運行。如果您想確保某些控件不爲空,則必須使用這個事件。沒有控制級別的事件可以在所有情況下都可靠地進行。主要是因爲如果控制從未獲得焦點,則不會發生控制級別事件。 Form_BeforeUpdate也是您使用的事件,如果您的驗證涉及多個字段。如果您正在使用任何其他控件或事件級別的事件,則會浪費您的時間。在你的「陷阱」周圍總會有一些東西,你的表幾乎肯定會包含無效的數據。

關於OP的問題。如果你想強制人們使用自己的保存按鈕,並提示他們,如果他們不這樣做,你需要一個表單級別的變量,因爲肖恩的建議暗示。唯一的區別是,您需要將其設置爲False,在窗體的當前事件而非打開事件中。您希望標誌爲每條新記錄重新設置,而不僅僅是在表單打開時。然後在保存按鈕單擊事件中將其設置爲True,然後在強制記錄保存爲DoCmd.RunCommand acCmdSaveRecord之前。

於是最後,在Form_BeforeUpdate事件,你檢查變量的值。

If bClose = False Then 
`If msgbox("Do you want to save the changes?", vbYesNo) = vbNo Then 
`  Cancel = True 
     If msgbox("Do you want to discard the Changes?", vbYesNo) = vbYes Then   
      Me.Undo 
     End If 
     Exit Sub 
    End If 
End If 
+1

格式化你的代碼更好會改善你的回答。 – ryanyuyu

+1

這真的很聰明。太糟糕了,這在3年前沒有得到。 –

-1

**你可以使用退出按鈕,這個代碼**

Private Sub Button_Click() 
If Me.Dirty = True Then 
    If MsgBox(" Save Change ", vbYesNo) = vbYes Then 
     Me.Dirty = False 
    Else 
     Me.Undo 
    End If 
End If 
DoCmd.Close acForm, "FormName" 
End Sub 
+1

我沒有downvote這個答案,但我想這是downvoted,因爲它只是代碼沒有描述 –

+0

感謝您的評論 – user3003395