Neuigkeiten:

Ist euer Problem gelöst, dann bitte den Knopf "Thema gelöst" drücken!

Mobiles Hauptmenü

Transaktion: Anzahl Datensätze innerhalb einer Schleife ermitteln

Begonnen von trebuh, Januar 09, 2016, 13:50:12

⏪ vorheriges - nächstes ⏩

trebuh

Hallo.

Bei dem Ereignis Button-Klick führe ich diverse Aktionen aus.
Unter anderem werden in einer Do Loop-Schleife (in der eine Aktualisierung der Tabelle per VBA erfolgt) 2 Variabeln mittels DCount ermittelt welche die Anzahl Datensätze nach verschiedenen Kriterien liefern.
Sind die 2 Variabeln gleich, wird eine weitere Aktion ausgeführt.

Das klappt bestens. :)

Nun dachte ich mir, die Aktionen mittels "Transaktion" abzusichern.

Jetzt habe ich aber das Problem, dass mir die 2 Variabeln in der Schleife nur ein mal aktualisiert werden(beim Start), was ja auch logisch ist, weil die Tabellen erst aktualisiert werden, wenn alles erfolgreich ausgeführt wird.

Gibt es da eine Möglichkeit, bei einer Transaktion die Anzahl der Datensätze innerhalb einer Schleife zu ermitteln?

Ansonsten lasse ich das mit der Transaktion.

Gruß Hubert





 

ebs17

Eine Transaktion hat mit Variablen (VBA) und Access-Funktionen (DCount) nicht viel am Hut. Eine Transaktion kann man bspw. in einem DAO-Workspace laufen lassen. Berücksichtigt werden da z.B. Aktionsabfragen und Recordsets, die mit Bezug auf DAO-Databases innerhalb dieses Workspaces laufen.

ZitatGibt es da eine Möglichkeit, bei einer Transaktion die Anzahl der Datensätze innerhalb einer Schleife zu ermitteln?
Die Frage verstehe ich nicht wirklich. Du kannst zu allen Zeitpunkten zählen. Die Zählergebnisse sollten dann irgendwo  niedergelegt werden. Das hat aber mit einer Transaktion  nichts zu tun.
Mit freundlichem Glück Auf!

Eberhard

trebuh

Hallo Eberhard,

es ist so, das ich in der Do-Loop Schleife ein Feld in einer Tabelle aktualisiere.
Innerhalb dieser Schleife zähle ich dann unter anderem die Anzahl der Datensätze welche ausgefüllt worden sind, was je nach Ergebnis eine weitere Aktion ausführt.

Sagen wir jetz mal, die Schleife läuft 5x durch, (5 Datensätze werden nacheinander aktualisiert) dann wird
ohne Transaktion die Anzahl Datensätze innerhalb der Schleife 5x gezählt.

Mache ich das mit Transaktion, wird die Anzahl Datensätze zwar auch 5 mal gezählt, aber der Wert bleibt nach dem ersten mal zählen immer gleich, da die Tabelle ja erst aktualisiert wird, wenn alles erfolgreich abgeschlossen ist.

Sogesehen bleibt mir glaub nichts anderes übrig, als erst nach der Transaktion die Datensätze in einer Schleife zu zählen (weil es ja verschiedene Kriterien sind), und die entsprechende Aktion dann dort ausführen.

Gruß Hubert
 


MzKlMu

Hallo,
Zitates ist so, das ich in der Do-Loop Schleife ein Feld in einer Tabelle aktualisiere.
warum nimmst Du da nicht eine einfache Aktualisierungsabfrage ?
Mit dem gleichen Kriterium kannst Du dann auch zählen.
Gruß Klaus

trebuh

Hallo Klaus,

das liegt daran, das sich bei jedem Schritt in der Schleife ein bzw. auch 2 Kriterien ändert.
Von daher stelle ich mir die Aktualisierungsabfrage per VBA in der Schleife zusammen.

Mal eine andere Frage noch zu den Transaktionen:

Kann man auch mehrere Transaktionen ineinander verschachteln?
Wenn ich z.b. 2 Sub Programmiere
Sub Aktion1()
On Error Goto Fehler
BeginTrans
...
CommitTrans
...

Fehler:
Rollback
...


Sub Aktion2()
On Error Goto Fehler
BeginTrans
...
CommitTrans
...

Fehler:
Rollback
...


und diese dann wiederum in einem Klick-Ereignis einbaue
Private Sub cmdStart_Click()

       On Error GoTo cmdStart_Click_Error

       BeginTrans
            Aktion1
            Aktion2

            ...
       CommitTrans             
            ...
    On Error GoTo 0
      Exit Sub

cmdStart_Click_Error:
      Rollback
      ...
End Sub


Geht sowas auch?

Gruß

MaggieMay

Hallo,
ZitatKann man auch mehrere Transaktionen ineinander verschachteln?
Ja, das kann man machen.

Zuvor wäre aber zu klären, was genau du vorhast. Was passiert in der dritten Transaktion im Klick-Ereignis?
Kann es sein, dass du einfach nur Aktion-1 und Aktion-2 in eine Transaktion packen willst?
Freundliche Grüße
MaggieMay

ebs17

Zitatda die Tabelle ja erst aktualisiert wird, wenn alles erfolgreich abgeschlossen ist
Davon wäre ich nicht überzeugt. Du kannst das aber leicht überprüfen, indem Du nach einer Änderung prüfst, was das bearbeitete Feld real zurückgibt.
Mit freundlichem Glück Auf!

Eberhard

trebuh

Hallo Eberhard und MaggieMay,

hier mal mein Code. Vielleicht habe ich ja einen Fehler in meinem Code (das erste mal für mich Schleife mit Recordset)
Läuft soweit prima.

Private Sub cmdRech_erstellen_Click()

10       On Error GoTo cmdRech_erstellen_Click_Error
         
          Dim rs As DAO.Recordset
          Dim rcsHolzLos As Recordset
          Dim rcsHolzlisteFertig As Recordset
          Dim db_1 As DAO.Database
          Dim lngRech_ID As Long
          Dim lngHolzID As Long
          Dim lngLosNr As Long
          Dim lngAnzHolz_f_id As Long
          Dim lngAnzRechLos As Long
          Dim strSQL_1 As String
          Dim strSQl As String
          Dim lngRechNeu As Long
         
20        bolsichern = True
30        lngRech_ID = Me!txtrech_nr
40        lngRechNeu = Me!txtrech_nr + 1
         
50        Me!rech_erstellt = Now
60        DoCmd.RunCommand acCmdSaveRecord

70            Set rcsHolzLos = CurrentDb.OpenRecordset("qry_Rech_HolzID_und_Los_ermitteln", dbOpenDynaset)
80            Set rcsHolzlisteFertig = CurrentDb.OpenRecordset("tblHolzliste", dbOpenDynaset)
90            Set db_1 = CurrentDb
             
100               Do Until rcsHolzLos.EOF
110                   lngHolzID = rcsHolzLos.Fields("LHA_Holzliste_f_id").Value
120                   lngLosNr = rcsHolzLos.Fields("LHA_Los").Value
                                                           
130                   strSQL_1 = "UPDATE tblLosdaten SET tblLosdaten.LosDaten_ReNr = " & Me!txtrech_nr _
                                  & " WHERE tblLosdaten.LosDaten_Holzliste_f_id=" & lngHolzID & _
                                  " AND tblLosdaten.LosDaten_LosNr=" & lngLosNr & ";"

140                   db_1.Execute strSQL_1, dbFailOnError
150                   DoEvents
                                                     
        '****************************************************************************************************************
        '*  Auslesen der Gesamtanzahl Lose von Holzliste und die der abgerechneten Lose von Holzliste                   *
       
160                   lngAnzHolz_f_id = DCount("LosDaten_Holzliste_f_id", "tblLosdaten", "LosDaten_Holzliste_f_id=" & lngHolzID)
170                   lngAnzRechLos = DCount("LosDaten_Holzliste_f_id", "tblLosdaten", "LosDaten_Holzliste_f_id=" & lngHolzID & _
                                      " AND [LosDaten_ReNr] Is Not NUll")
     
       
180                   MsgBox "Anzahl Lose: " & lngAnzHolz_f_id & " | Anzahl lose Abgerechnet: " & lngAnzRechLos
        '****************************************************************************************************************
       
190                   If lngAnzRechLos = lngAnzHolz_f_id Then
200                       rcsHolzlisteFertig.FindFirst "Holzliste_ID=" & lngHolzID
210                       rcsHolzlisteFertig.Edit
220                       rcsHolzlisteFertig.Fields("Holzliste_abgerechnet").Value = True
230                       rcsHolzlisteFertig.Update
240                   End If

250                   rcsHolzLos.MoveNext
260               Loop
                 
270           rcsHolzLos.Close
280           rcsHolzlisteFertig.Close
290           Set rcsHolzLos = Nothing
300           Set rcsHolzlisteFertig = Nothing
310           Set db_1 = Nothing
         
320         Set rs = CurrentDb.OpenRecordset("tblEinstellungen", dbOpenDynaset)
330             rs.Edit
340             rs!einst_naechst_Rech_Nr = lngRechNeu
350             rs.Update
360         rs.Close
370       Set rs = Nothing
         
380       CurrentDb.QueryDefs("qry_Rechzusammfass_fuellen").Execute
390       DoEvents
         
400       DoCmd.Close acForm, "frm_Rechnung_Popup"

410       DoCmd.OpenForm "frm_Rechnung", , , "rech_nr=" & lngRech_ID

420      On Error GoTo 0
430      Exit Sub

cmdRech_erstellen_Click_Error:

440       MsgBox "Error " & Err.Number & " in Zeile " & Erl & " (" & Err.Description & ") in procedure cmdRech_erstellen_Click of VBA Dokument Form_frm_Rechnung_Popup"
End Sub


Der Versuch mittels Transaktion funktioniert nur teilweise: Hier der Code
Private Sub cmdRech_erstellen_Click()

10       On Error GoTo cmdRech_erstellen_Click_Error
         
BeginTrans
          Dim rs As DAO.Recordset
          Dim rcsHolzLos As Recordset
          Dim rcsHolzlisteFertig As Recordset
          Dim db_1 As DAO.Database
          Dim lngRech_ID As Long
          Dim lngHolzID As Long
          Dim lngLosNr As Long
          Dim lngAnzHolz_f_id As Long
          Dim lngAnzRechLos As Long
          Dim strSQL_1 As String
          Dim strSQl As String
          Dim lngRechNeu As Long
         
20        bolsichern = True
30        lngRech_ID = Me!txtrech_nr
40        lngRechNeu = Me!txtrech_nr + 1
         
50        Me!rech_erstellt = Now
60        DoCmd.RunCommand acCmdSaveRecord

70            Set rcsHolzLos = CurrentDb.OpenRecordset("qry_Rech_HolzID_und_Los_ermitteln", dbOpenDynaset)
80            Set rcsHolzlisteFertig = CurrentDb.OpenRecordset("tblHolzliste", dbOpenDynaset)
90            Set db_1 = CurrentDb
             
100               Do Until rcsHolzLos.EOF
110                   lngHolzID = rcsHolzLos.Fields("LHA_Holzliste_f_id").Value
120                   lngLosNr = rcsHolzLos.Fields("LHA_Los").Value
                                                           
130                   strSQL_1 = "UPDATE tblLosdaten SET tblLosdaten.LosDaten_ReNr = " & Me!txtrech_nr _
                                  & " WHERE tblLosdaten.LosDaten_Holzliste_f_id=" & lngHolzID & _
                                  " AND tblLosdaten.LosDaten_LosNr=" & lngLosNr & ";"

140                   db_1.Execute strSQL_1, dbFailOnError
150                   DoEvents
                                                     
        '****************************************************************************************************************
        '*  Auslesen der Gesamtanzahl Lose von Holzliste und die der abgerechneten Lose von Holzliste                   *
       
160                   lngAnzHolz_f_id = DCount("LosDaten_Holzliste_f_id", "tblLosdaten", "LosDaten_Holzliste_f_id=" & lngHolzID)
170                   lngAnzRechLos = DCount("LosDaten_Holzliste_f_id", "tblLosdaten", "LosDaten_Holzliste_f_id=" & lngHolzID & _
                                      " AND [LosDaten_ReNr] Is Not NUll")
     
       
180                   MsgBox "Anzahl Lose: " & lngAnzHolz_f_id & " | Anzahl lose Abgerechnet: " & lngAnzRechLos
        '****************************************************************************************************************
       
190                   If lngAnzRechLos = lngAnzHolz_f_id Then
200                       rcsHolzlisteFertig.FindFirst "Holzliste_ID=" & lngHolzID
210                       rcsHolzlisteFertig.Edit
220                       rcsHolzlisteFertig.Fields("Holzliste_abgerechnet").Value = True
230                       rcsHolzlisteFertig.Update
240                   End If

250                   rcsHolzLos.MoveNext
260               Loop
                 
270           rcsHolzLos.Close
280           rcsHolzlisteFertig.Close
290           Set rcsHolzLos = Nothing
300           Set rcsHolzlisteFertig = Nothing
310           Set db_1 = Nothing
         
320         Set rs = CurrentDb.OpenRecordset("tblEinstellungen", dbOpenDynaset)
330             rs.Edit
340             rs!einst_naechst_Rech_Nr = lngRechNeu
350             rs.Update
360         rs.Close
370       Set rs = Nothing
         
380       CurrentDb.QueryDefs("qry_Rechzusammfass_fuellen").Execute
390       DoEvents
         
CommitTrans
400       DoCmd.Close acForm, "frm_Rechnung_Popup"

410       DoCmd.OpenForm "frm_Rechnung", , , "rech_nr=" & lngRech_ID

420      On Error GoTo 0
430      Exit Sub

cmdRech_erstellen_Click_Error:
Call MsgBox("Hallo" _
            & vbCrLf & "" _
            & vbCrLf & "Du" _
            , vbExclamation, Application.Name)

Rollback
440       MsgBox "Aktion abgebrochen!" _
                 & vbCrLf _
                 & vbCrLf & "Error " & Err.Number & " in Zeile " & Erl & " (" & Err.Description _
                 & ") in procedure cmdRech_erstellen_Click of VBA Dokument Form_frm_Rechnung_Popup" _
                 , vbCritical, "Hinweis!"
End Sub


Der Bereich Zeilenr. 190 bis 240 kommt nicht zum tragen, da die Variabeln lngAnzHolz_f_id und lngAnzRechLos
immer gleich sind (Laut Ausgabe MsgBox Zeile180)

Gruß trebuh

MaggieMay

#8
Hallo,

ohne den Code jetzt im Einzelnen angeschaut zu haben kann ich sagen, dass der Einsatz einer Transaktion so keinen Sinn macht, es fehlt der Bezugspunkt auf den die Transaktion bezogen werden soll, auf ein Database-Objekt oder einen Workspace.

Ich wiederhole also meine bereits gestellte Frage nach dem Sinn den Vorhabens.
Mit welchen Fehlern muss gerechnet werden, was kann die Transaktion zum Abbruch führen?

Und was genau ist hiermit gemeint:
Zitatfunktioniert nur teilweise
???

ZitatDer Bereich Zeilenr. 190 bis 240 kommt nicht zum tragen, da die Variabeln lngAnzHolz_f_id und lngAnzRechLos
immer gleich sind
Naja, was willst du damit sagen? Immerhin kommt der Code zur Ausführung - was hättest du erwartet?
Wenn du dir die Zeilen
160                   lngAnzHolz_f_id = DCount("LosDaten_Holzliste_f_id", "tblLosdaten", "LosDaten_Holzliste_f_id=" & lngHolzID)
170                   lngAnzRechLos = DCount("LosDaten_Holzliste_f_id", "tblLosdaten", "LosDaten_Holzliste_f_id=" & lngHolzID & _
                                      " AND [LosDaten_ReNr] Is Not NUll")

anschaust musst du dich nicht wundern, dass die Zähler übereinstimmen, schließlich hast du doch gerade eben erst die "LosDaten_ReNr" mit der "Rech_Nr" gefüllt!

BTW:
Einen Zähler mit einer Datensatz-ID vergleichen zu wollen macht IMHO wenig Sinn. Was bezweckst du damit?
Freundliche Grüße
MaggieMay

trebuh

Hallo MaggieMay,

Zitat
Ich wiederhole also meine bereits gestellte Frage nach dem Sinn den Vorhabens.

Nun es geht um das Verwalten von Rechnungen.
Aus einem Listenfeld kann ich Holzlisten auswählen (Mehrfachauswahl). Eine Holzliste kann wiederum aus mehreren Losen bestehen. Also wähle ich im Anschluß der Holzlistenauswahl die gewünschten Lose aus (Mehrfachauswahl).
Diejenigen Holzlisten und Lose, welche Abgerechnet wurden, erscheinen in den Listenfeldern nicht mehr.
Dazu wird in der Tabelle Lose, der entsprechende Datensatz mit der Rechnungsnummer versehen. Sind alle Lose einer Holzliste abgerechnet, wird in der Tabelle Holzliste ein Feld des entsprechenden Datensatzes auf "True" gestellt.

Ebenso wird in einer Tabelle die nächste Rechnungsnummer vermerkt.

Das klappt soweit alles. Mir kam nur der Gedanke, das falls bei dem Vorgang was schief gehen sollte (Stromausfall etc.), die Aktion abgebrochen wird. Somit wollte ich es mal mit der Transaktion versuchen, bzw. Einfach mal probieren ;).

Ich glaube, daß ich den Aufbau der Aktion komplett überdenken müsste, wenn ich es mit der Transaktion beibehalten wollte.
Es funktioniert ohne Transaktion ja sehr gut.

Zitates fehlt der Bezugspunkt auf den die Transaktion bezogen werden soll, auf ein Database-Objekt oder einen Workspace.

Was meinst Du damit? In meinem Buch ist das mit der Transaktion nur kurz angesprochen.

Gruß Hubert

MaggieMay

Hallo Hubert.
ZitatIn meinem Buch ist das mit der Transaktion nur kurz angesprochen.
Dann schau doch mal in die Access-Hilfe.

Und auf meine Fragen bist du wieder einmal nicht eingegangen...
Zitatfunktioniert nur teilweise
???
Zitatkommt nicht zum tragen
???
Freundliche Grüße
MaggieMay

trebuh

Hallo MaggieMay,

Dann schau doch mal in die Access-Hilfe.

da hät ich selbst drauf kommen können  ::)
Gibt ja einiges mehr an Möglichkeiten als in dem Buch erwähnt. Auch das mit der Verschachtelung ist erklärt. :) 

Habe meinen Code jetzt abgeändert. Eine tolle Sache das mit der Transaktion.

Gruß Hubert