Ich möchte ein Formular erstellen das im Wesentlichen eine Rechnung erstellt, aber einige andere verwandte Daten als Eingaben oder Grenzen verwendet; Beim Hinzufügen von Artikeln zur Rechnung muss ich die Artikel in einer anderen Tabelle reduzieren. Da der Benutzer mehrere Elemente gleichzeitig eingeben wird, möchte ich beim Laden des Formulars eine "START TRANSACTION" -Ausgabe vornehmen und dann ein "COMMIT" ausführen, wenn das Formular aktualisiert wird. Wenn sie das Formular abbrechen, werden die anderen verwandten Tabellen (die über Unterformulare angezeigt werden) auf die vorherigen Werte zurückgesetzt.Kann ich ein Access-Formular mit einer Transaktion umbrechen?
Antwort
Kann nicht mit gebundenen Formularen verwendet werden. Sie können temporäre Tabellen zum Speichern der Daten verwenden und dann die Haupttabellen aktualisieren. Ein bisschen Klumper, aber das habe ich in der Vergangenheit gemacht.
Siehe TempTables.MDB page at my website, die zeigt, wie eine temporäre MDB in Ihrer Anwendung zu verwenden.
Ja, es kann getan werden, die Kontrolle über die Transaktion in Form nehmen Sie diesen Code verwenden müssen:
Private Sub Form_Open(Cancel As Integer) Set Me.Recordset = CurrentDb.OpenRecordset("NAME_OF_YOUR_TABLE_OR_QUERY") End Sub
Danach können Sie DBEngine verwenden, um die Transaktion zu steuern.
Es ist für mich arbeiten (Im mit Access 2007)
Hinweis: Wenn Sie einen neuen Datensatz der Formular-Schnittstelle setzen Sie sich sichtbar sind, wenn das Form_AfterInsert Ereignis ausgelöst wird, daher können Sie DbEngine.Rollback in diesem Fall verwenden um die Änderungen rückgängig zu machen.
Das Festlegen des Re-Cord-Sets eines Formulars zu einem Re-Cord-Set, das in Code erstellt wird, kann problematisch sein. Außerdem sehe ich nicht, wie Ihr Vorschlag funktioniert, da Sie ein Datenbankobjekt verwenden müssen, das mit einem anderen Arbeitsbereich als dem Standardarbeitsbereich initialisiert wird. Ich bin auch skeptisch, CurrentDB.OpenRecordset() direkt so zu verwenden - sieht aus wie eine offene Einladung für implizite Referenzprobleme oder eine defekte Recordset. –
Ich habe herausgefunden, es ist möglich, es auf gebundenen Formen zu haben. Alles, was Sie benötigen, um eine Variable mit einer ID-Nummer beim Änderungsereignis eines übergeordneten Steuerelements zuzuweisen. Dann müssen Sie diesen ID-Wert in das verbundene Feld des Unterformulars übertragen und auf beiden Formularen das Primär- und das Unterformular ausführen. Hier ist das Beispiel, wie ich es gemacht habe.
Primary Form VBA
Option Compare Database
Option Explicit
Private boolFrmDirty As Boolean
Private boolFrmSaved As Boolean
Private Sub EmpolyeesID_Change()
Dim ordID As Integer
Dim subFormOrdID As Object
Set subFormOrdID = Forms!Order.OrderInstallation.Form!OrderID
ordID = Me.Form!OrderID
subFormOrdID.DefaultValue = ordID
End Sub
Private Sub Form_AfterDelConfirm(Status As Integer)
If Me.Saved = False Then Me.Saved = (Status = acDeleteOK)
End Sub
Private Sub Form_AfterUpdate()
Me.Saved = True
End Sub
Private Sub Form_Delete(Cancel As Integer)
If Me.Dirtied = False Then DBEngine.BeginTrans
Me.Dirtied = True
End Sub
'Check if form has got new values in it
Private Sub Form_Dirty(Cancel As Integer)
If Me.Dirtied = False Then DBEngine.BeginTrans
Me.Dirtied = True
End Sub
'Open Form as a Record Set and set the variables for it
Private Sub Form_Open(Cancel As Integer)
Dim db As DAO.Database
Dim rs As DAO.Recordset
Set db = CurrentDb
Set rs = db.OpenRecordset("SELECT * FROM Orders", dbOpenDynaset, dbAppendOnly)
Set Me.Recordset = rs
End Sub
Private Sub Form_Unload(Cancel As Integer)
Dim msg As Integer
If Me.Saved Then
msg = MsgBox("Do you want to commit all changes?", vbYesNoCancel)
Select Case msg
Case vbYes
DBEngine.CommitTrans
Case vbNo
DBEngine.Rollback
Case vbCancel
Cancel = True
End Select
Else
If Me.Dirtied Then DBEngine.Rollback
End If
End Sub
Public Property Get Dirtied() As Boolean
Dirtied = boolFrmDirty
End Property
Public Property Let Dirtied(boolFrmDirtyIn As Boolean)
boolFrmDirty = boolFrmDirtyIn
End Property
Public Property Get Saved() As Boolean
Saved = boolFrmSaved
End Property
Public Property Let Saved(boolFrmSavedIn As Boolean)
boolFrmSaved = boolFrmSavedIn
End Property
Private Sub ProductID_AfterUpdate()
'Calculations of VAT and Floor Price
Dim clcVAT As Integer
Dim sqlQry As String
Dim instID As Integer
instID = Me.Form!ProductID.Value
sqlQry = "SELECT Products.Price FROM Products WHERE Products.ProductID =" & instID & ""
Me.flPrice.RowSource = sqlQry
End Sub
Sub Form VBA
Option Compare Database
Option Explicit
'Transaction for sub-form
Private Sub Form_Open(Cancel As Integer)
Dim db As DAO.Database
Dim rs As DAO.Recordset
Set db = CurrentDb
Set rs = db.OpenRecordset("SELECT * FROM OrderInstallation")
Set Me.Recordset = rs
End Sub
Private Sub Form_AfterUpdate()
Dim emplID As Object
Dim cstmID As Object
Dim prdcID As Object
Dim DataArray As Variant
Dim RqrdFieldErorr As String
Dim qry As String
Set emplID = Me.Parent!EmpolyeesID
Set cstmID = Me.Parent!CustomerID
Set prdcID = Me.Parent!ProductID
If IsNull(emplID.Value) Or IsNull(cstmID.Value) Or IsNull(prdcID.Value) Then
MsgBox ("Please enter select required fields first")
Else
End If
End Sub
'Restrict updates of Installation subform if Employee, Customer and Product is not selected
Private Sub InstallationID_AfterUpdate()
Dim instID As Integer
Dim instPrice As Integer
Dim strQry As String
' Create query based on InstallationID value
instID = InstallationID.Value
strQry = "SELECT Installation.Price, Installation.InstallationID FROM Installation WHERE Installation.InstallationID =" & instID & ""
Me.Price.RowSource = strQry
End Sub
böse, aber es scheint die einzige Antwort zu sein. – DGM