PDA

Vollständige Version anzeigen : undo funktion über recordset steuern


roadrenner
09.09.2003, 10:51
hi leute,
ich habe folgendes problem

gegeben ist ein formular mit unterformular.

alle felder sind standardmäßig gesperrt. per knopfdruck werden sowohl unterformular als auch hauptformular freigegeben.

der user kann jetzt änderungen vornehmen. darüber hinaus existieren zwei weitere knöpfe:

"änderungen annehmen" und "änderungen verwerfen"

bei annehmen, sperre ich die felder einfach wieder und wechsele mit dem focus auf ein anderes element, d.h. der ds mit allen unter ds wird einfach gespeichert.

bei "änderungen verwerfen" reicht mir ein einfache sme.undo aber leider nicht. da ja damit nur ein änderungsschritt rückgängig gemacht werden kann. wenn jetzt aber der user im ufo 5 ds ändert (ufo ist endlosformular) bringt mir das nichts.

ich habe also zwei dao.recordsets definiert, die mir sowohl den haupt ds als auch alle unter ds speichern, wenn ich auf den knopf ändern gehe (sind public deklariert in einem modul)

ich bekomme aber den nächsten schritt nicht hin. "änderungen verwerfen" drücken und die geänderten ds mit den ds aus dem recordset überschreiben.

es können dabei neue detail ds hinzugekommen oder aber auch weiniger als vorher sein.

wer kann mir helfen?? :top:

danke schonmal im voraus

mfg richi

MRR
09.09.2003, 10:58
Hi,
mag ja sein, dass ich völlig falsch liege, aber: Wäre das Problem mit BeginTrans und CommitTrans / Rollback eher zu lösen (s. OLH)?

Nouba
09.09.2003, 11:02
@Matthias

er hat leider die falsche Access-Version, um Transaktionen in gebundenen Formularen zu implementieren.

roadrenner
09.09.2003, 11:09
hmmm,

also wenn ich die olh richtig verstanden habe, kann man diese aktionen ja nur innerhalb einer prozedur aufrufen :confused:

oder kann ich es so auch machen


sub btnÄndern_Click()

begintrans

end sub


sub btnJa_Click()

committrans

end sub


sub btnNein_Click

rollback

end sub


so vom prinzip.
es wäre super, wenn jemand nen beispiel hätte.

mfg richi

roadrenner
09.09.2003, 11:10
@nouba: wie meinst du das. in der olh finde ich begintrans...

aber wie gesagt, nähere infos wären sehr hilfreich :biggrinl:

mfg richi

Sascha Trowitzsch
09.09.2003, 11:12
Da sehe ich nur einen etwas umständlichen Workaround:

Definiere in der zugrundeliegenden Tabelle ein zusätzliches Feld "Changed" (boolean) mit dem Standardwert True.

Wenn der User neue Daten in das (U-) Formular schreibt, so wird ja dann automatisch auch dieses Feld auf True gesetzt.

Mit "Änderungen annehmen" lässt du dann eine Aktualisierungsabfrage ablaufen, die das Changed-Feld überall auf False setzt.

Mit "Änderungen verwerfen" lässt du eine Löschabfrage ablaufen, die alle Datensätze löscht, in denen "Changed" auf True gesetzt ist.

Dann noch ein Requery auf das (U-) Formular.

Ciao, Sascha

PS: Transaktionen funktionieren nicht in Formularen, sondern nur auf Recordsets bzw. CurrentDB. Execute "... "; und das steht nicht in der OLH!

MRR
09.09.2003, 11:14
Ich kann's mir noch nicht so ganz vorstellen, warum es nicht funktionieren sollte.
Wenn ich 2 Recordsets habe (HF und UF) und jedes Mal die Zuweisung eines RS an die beiden Quellen erfolgen sollte, dann müsste ich doch zu Beginn mit BeginTrans die Protollierung einschalten können. Und wenn dann einer der Buttons betätigt wird, ließe sich der Inhalt doch dann übernehmen bzw. zuschrückschreiben.
Was kann man hier nicht machen (nouba)?

Nouba
09.09.2003, 11:18
Hallo Richi,

Transaktionen können in A97 verwendet werden, jedoch nicht in Verbindung mit gebundenen Formularen. Schließlich benötigt das Recordset einen eigenen Workspace für Transaktionen und ein Recordset kann erst ab A2K einem Formular zugewiesen werden.

roadrenner
09.09.2003, 13:40
also ich habe das ganze jetzt anders gelöst.

ich habe zwei tabellen erstellt, die von der struktur identisch mit den tabellen des hf und ufo`s sind.

wenn ich btnÄndern drücke werden in diese tabelle der ds das hf und alle ds des ufo`s gesichert.

wenn ich die änderungen annehme, lösche ich den inhalt der dummy tabelle, wenn die änderungen verworfen werden, lösche ich den (geänderten) inhalt in der ausgangstabelle und mache ein insert into wobei als grundlage die dummy tabelle dient.

ist zwar nicht ganz formschön, aber es läuft.

wenn jemand von euch nen verbesserungsvorschlag hat.... her damit ;)

also mfg richi

Sascha Trowitzsch
09.09.2003, 13:57
Den Vorschlag, den ich oben gemacht habe, gefällt mir besser!

Mit deinen "temporären" Zusatztabellen blähst du mit der Zeit deine DB auf.

Ciao, Sascha

roadrenner
09.09.2003, 14:04
@ sascha:

das problem bei deiner variante ist aber folgendes. das unterformular ist ein endlosfurmular, d.h. wenn ich 5 ds ändere, und dann merke: mist alles falsch, dann sind die daten ja schon unwiederbringlich verändert, da das formular ja direkt auf die tab zugreift.

für einen ds ist das problemlos möglich aber für mehrer geht das ja nicht. oder verstehe ich dich einfach falsch?

wenn ja, bring licht in mein dunkel :biggrinl: denn eine rückgängig funktion über das interne undo hinaus (rückgängig it immer nur für aktuellen ds möglich) ist ja bei usereingabe immer nützlich

mfg richi

ps: zum thema aufblähen, am ende der aktion lösche ich alle ds der dummy tabelle, und komprimieren muss man bei 97 eh ab und an manuell :bawling:

Sascha Trowitzsch
09.09.2003, 16:31
Also gut...

Deine Tabelle für das UForm sähe z.B. so aus:

Feld ID | Feld Nachname | Feld Vorname

Daraus machst du jetzt:

Feld ID | Feld Nachname | Feld Vorname | Feld Changed

wobei letzteres als Ja/Nein-Feld angelegt und als Standardwert Ja eingetragen wird.

Wenn nun neue Datensätze ins UForm eingetragen werden, so steht in jedem neuen Datensatz im (unsichtbaren) Feld Changed ein Ja.

12 | Maier | Hans | Nein
13 | Müller | Jörg | Nein
14 | Peters | Martin | Nein
18 | Kaiser | Peter | Ja
19 | Huser | Jürgen | Ja

Bei Betätigen des Buttons "Übernehmen" wird die folgende Aktualisierungsabfrage ausgelöst:

CurrentDb.Execute "UPDATE Tabelle Set Tabelle.Changed = False;"
>>
12 | Maier | Hans | Nein
13 | Müller | Jörg | Nein
14 | Peters | Martin | Nein
18 | Kaiser | Peter | Nein
19 | Huser | Jürgen | Nein


Oder: Bei Betätigen des Buttons "Verwerfen" wird die folgende Löschabfrage ausgelöst:

CurrentDb.Execute "DELETE * FROM Tabelle WHERE Staaten.Changed = True;"
>>
12 | Maier | Hans | Nein
13 | Müller | Jörg | Nein
14 | Peters | Martin | Nein


und jeweils noch ein Me.Unterformular.Requery angehängt.

Das Hilfsfeld "Changed" ist also da, um quasi zu markieren, welche Datensätze ungültig sind.


Ciao, Sascha

Sascha Trowitzsch
11.09.2003, 12:02
Und? Hab ich mir die Arbeit umsonst gemacht?

roadrenner
11.09.2003, 12:40
entschuldige sascha,

ich hatte gerade noch nen anderes prob beseitigt und da dieses über nen hilfsweg schon läuft (hilfsweg, was nen schreckliches wort) ist das in den hintergrund getreten.

problem bei deinem lösungsvorschlag ist folgendes.

was wenn der user datensätze fälschlicherweise löscht (ich kann es nicht immer verbieten, da teilweise gelöscht werden muss) dann sind diese ds verloren (zumindestens nach einer bestimmetn anzahl von weiteren änderungen)

ich muss also schon den kompletten stand vor der änderung aufheben, so dass dieser notfalls wieder hergestellt werden kann. ich hatte da an sowas wie nen recordset gedacht, damit fehlt mir aber einfach die erfahrung.

wenn du da ne bessere lösung hast als meine dummy tabellen, dann her damit :tausch:

mfg richi

Sascha Trowitzsch
11.09.2003, 12:48
Das stimmt natürlich; für das Löschen von DS gibt es bei meiner Lösung kein Rollback.

Ja, sicher lässt sich das mit einem Recordset als Zwischenspeicher auch lösen, aber wenn dein Verfahren mit den Dummy-Tabellen läuft, so lass es halt dabei. Wenn du regelmäßig komprimierst, so sollte das mit dem Aufblähen auch kein Problem sein.

Ciao, sascha

roadrenner
11.09.2003, 13:01
wenn du meinst, dass dadurch keine weiteren probleme entstehen...

ich hätte mir auch nicht vorstellen können welche, aber rat nimmt man ja gerne an.

danke für deine hilfe

mfg richi