[Gelöst] Abfrage auf Validate

18. Dezember 2007 15:51

Habe leider nix passendes über die Suche gefunden (vielleicht übersehen, oder falsche Suchwörter benutzt). Falls es also so ein Thema schon gibt, verzeiht es mir bitte.

Ich wollte mal fragen ob es eine Möglichkeit gibt abzufragen ob ein Validate ausgeführt wurde?
Also zum Beispiel:

Code:
//OnModify
IF Validate(Feld) ausgeführt = True THEN
führe Code1 aus
ELSE
führe Code2 aus


Hoffe mir kann da einer auf die Sprünge helfen :wink:
Zuletzt geändert von Heike Bennerscheid am 19. Dezember 2007 10:14, insgesamt 1-mal geändert.

18. Dezember 2007 15:58

Hallo Heike,
warum rufst du code 1 nicht im OnValidateTrigger auf?

18. Dezember 2007 16:07

Ich versuch das mal zu erklären.

Wir haben auf der Debitorenkarte ein Feld für ein Passwort hinzugefügt. Dazu einen Button "Passwort ändern".
Zudem haben wir 2 Reports. Ein Report erzeugt eine XML Datei ohne Passwort und ein Report eine XML Datei mit Passwort.
Wenn der Debitor geändert wird (aber nicht das Passwort) soll der Report ohne Passwort ausgeführt werden. Wenn nun aber das Passwort geändert wird und der Button geklickt wird, soll der Report mit Passwort ausgeführt werden.
Wenn ich den Reportaufruf in den OnValidate Trigger des Feldes schreiben würde, würde ja einmal der Report mit Passwort aufgerufen werden, und einmal der Report ohne (da ja sobald ich den Datensatz verlasse ein Modify ausgeführt wird).
Ich dachte mit dem obrigen Code könnte ich das dann verhindern.

18. Dezember 2007 16:15

Nein, der Modify wird nach der Änderung jedes Feldes ausgeführt, nicht erst, wenn du den Datensatz verläßt.
Das Datensatz verlassen kannst du nur im OnNextRecord bzw im OnNewRecord oder OnQueryCloseForm abfangen.
Du könntest allerdings eine globale Boolean Variable erzeugen, die im OnValidate des Passwortfeldes gesetzt und bei Ausführung des Reports wieder zurückgesetzt wird.

18. Dezember 2007 16:21

Eine weitere Möglichkeit wäre, im OnModify-Trigger folgenden Code zu hinterlegen:

Code:
IF xRec.Password<>Password THEN
  REPORT.RUN('XML erstellen mit Password')
ELSE
  REPORT.RUN('XML erstellen ohne Password);


Gruß, Marc

18. Dezember 2007 16:42

Danke Marc. Die Abfrage klappt.

Leider steh ich jetzt vor dem Problem das er mir das falsche Passwort exportiert. Also das welches im Feld stand bevor ich es geändert habe.

18. Dezember 2007 16:59

Eventuell hilft vor dem Aufrufen der Reports ein COMMIT;

18. Dezember 2007 17:03

Hilft leider auch nichts.

Hier mal mein Code. Vielleicht hab ich ja irgendwas anderes vergessen, auf das ich grad nicht komme.

Code:
IF xRec.Passwort <> Passwort THEN BEGIN
   COMMIT;
   CLEAR(ReportmitPW);
   Cust.RESET;
   Cust.SETRANGE("No.","No.");
   ReportmitPW.SETTABLEVIEW(Cust);
   ReportmitPW.RUN;
END ELSE BEGIN
   COMMIT;
   CLEAR(ReportohnePW);
   Cust.RESET;
   Cust.SETRANGE("No.","No.");
   ReportohnePW.SETTABLEVIEW(Cust);
   ReportohnePW.RUN;
END;

18. Dezember 2007 17:20

machst du das auf der Table oder der Form?
Auf der Table hast du immer den alten Wert, solange der Trigger nicht abgeschlossen ist. da könnte es vielleicht helfen, wenn du nicht Cust sondern Rec an den Report übergibst.
Auf der Form könntest du vorher ein Currform.Saverecord versuchen.

18. Dezember 2007 17:24

Ich mache das auf der Tabelle. Hmm.. ich probiere das mit dem Rec mal aus. Wenn das nicht das gewünschte Ergebnis bringt, probier ich es mal auf der Form.

18. Dezember 2007 17:31

Rec tut es leider auch nicht. Zudem hab ich dann wieder das Problem das er kurzzeitig einen leeren Debitor anzeigt.

Auch in der Form mit Currform.Saverecord klappt es nicht.

Vielleicht muss ich nochmal ne Nacht drüber schlafen.

18. Dezember 2007 18:15

Die Ursache des Problems (altes Password wird ausgegeben) dürfte sein, dass zum Zeitpunkt der Report-Ausführung der geänderte Datensatz noch nicht in die Datenbank zurückgeschrieben wurde. Der Report holt sich aber aufgrund des Filters den Customer neu aus der Datenbank und hat hier noch den alten Wert. Hier müßte also vorher ein Modify erfolgen (ob Commit notwendig, muss man dann mal austesten).

Aber werden in dem Report nicht generell die alten Daten ausgegeben, da der OnModify-Trigger noch nicht komplett durchlaufen ist? Das wäre dann mal wieder eine typische Anwendung, für die man einen "OnAfterModify"-Trigger benötigen würde... :-)

Andere Möglichkeit ist vielleicht noch, den "neuen" Rec per Funktion an den Report zu übergeben, dort in einer glob. Variablen speichern und im Report dann im OnAfterGetRecord den gelesenen Customer durch die glob. Variable zu ersetzen.

@Michael:
Bist Du Dir wirklich sicher, dass der OnModify-Trigger nach jeder Feldänderung durchlaufen wird? Ich bin der Meinung, dass er nur beim Verlassen des Records durchlaufen wird (oder wenn ich explizit einen Modify durchführe oder CurrForm.Saverecord oder ...).

mfg
woger

18. Dezember 2007 18:21

woger hat geschrieben:Die Ursache des Problems (altes Password wird ausgegeben) dürfte sein, dass zum Zeitpunkt der Report-Ausführung der geänderte Datensatz noch nicht in die Datenbank zurückgeschrieben wurde. Der Report holt sich aber aufgrund des Filters den Customer neu aus der Datenbank und hat hier noch den alten Wert. Hier müßte also vorher ein Modify erfolgen (ob Commit notwendig, muss man dann mal austesten).

Aber werden in dem Report nicht generell die alten Daten ausgegeben, da der OnModify-Trigger noch nicht komplett durchlaufen ist? Das wäre dann mal wieder eine typische Anwendung, für die man einen "OnAfterModify"-Trigger benötigen würde... :-)

Andere Möglichkeit ist vielleicht noch, den "neuen" Rec per Funktion an den Report zu übergeben, dort in einer glob. Variablen speichern und im Report dann im OnAfterGetRecord den gelesenen Customer durch die glob. Variable zu ersetzen.


Wie gesagt. Werd mir das alles nochmal durch den Kopf gehen lassen und dann Morgen mal weiter probieren. Aber hast recht. So ein OnAfterModify Trigger wär schon nicht schlecht :wink:

woger hat geschrieben:@Michael:
Bist Du Dir wirklich sicher, dass der OnModify-Trigger nach jeder Feldänderung durchlaufen wird? Ich bin der Meinung, dass er nur beim Verlassen des Records durchlaufen wird (oder wenn ich explizit einen Modify durchführe oder CurrForm.Saverecord oder ...).

mfg
woger


Der Meinung bin ich auch. Schon allein deswegen, weil wenn man in den jeweiligen Trigger nen Message macht, das die Meldung zu OnModify erst erscheint wenn man zum nächsten Datensatz geht oder die Form schließt.

18. Dezember 2007 21:14

Stimmt, Ihr habt recht, ich habe das gerade noch mal probiert....
kommt wirklich erst beim Verlassen des Datensatzes. Also scheint es so zu sein, dass der komplette geänderte Datensatz erst nach dem Verlassen desselben für andere zur Verfügung steht....
Das würde dann bedeuten, dass du im On Modify nur den zu druckenden Report festlegen, den Report aber erst später starten kannst. Also auf der Form in OnModifyRecord festlegen und im OnNextRecord bzw im OnQueryCloseForm ausführen.

18. Dezember 2007 21:40

Ich vermisse OnAfterInsert-, OnAfterModify- usw- Trigger schon lange.
Bisher habe ich es so gelöst, dass meine Objekte (z.B. ein Report) nicht direkt auf meine Echtdaten zugreifen, sondern auf eine von mir übergebene temp. Recordvariable.

Diese temp. Recordvariable stelle ich ungefähr so zusammen (vereinfacht):
Zunächst einmal lese ich in diese temp. Variable alle bisherigen Datensätze ein (TempRec.INSERT).
Wird das Objekt aus einem OnDelete-Trigger aufgerufen, so suche ich den Zwillingsdatensatz im temp. Record (TR) und lösche ihn einfach.
Wird ein Datensatz hinzugefügt, so füge ich ihn im TR ein.
Wird ein Datensatz geändert, so ändere ich den Datensatz im TR entsprechend.

Funktioniert wunderbar ...

19. Dezember 2007 10:04

Das verwunderliche an der Sache ist, wenn ich den Code um den Report auszuführen im OnModify Trigger der Customer Tabelle stehen habe, einen Debitor änder und dann den Datensatz verlasse, dann gibt er mir auch eine XML Datei mit den geänderten Daten raus.

Im OnModify Trigger steht noch folgender Code
Code:
IF (Name <> xRec.Name) OR
   ("Search Name" <> xRec."Search Name") OR
   ("Name 2" <> xRec."Name 2") OR
   (Address <> xRec.Address) OR
   ("Address 2" <> xRec."Address 2") OR
   (City <> xRec.City) OR
   ("Phone No." <> xRec."Phone No.") OR
   ("Telex No." <> xRec."Telex No.") OR
   ("Territory Code" <> xRec."Territory Code") OR
   ("Currency Code" <> xRec."Currency Code") OR
   ("Language Code" <> xRec."Language Code") OR
   ("Salesperson Code" <> xRec."Salesperson Code") OR
   ("Country Code" <> xRec."Country Code") OR
   ("Fax No." <> xRec."Fax No.") OR
   ("Telex Answer Back" <> xRec."Telex Answer Back") OR
   ("VAT Registration No." <> xRec."VAT Registration No.") OR
   ("Post Code" <> xRec."Post Code") OR
   (County <> xRec.County) OR
   ("E-Mail" <> xRec."E-Mail") OR
   ("Home Page" <> xRec."Home Page") OR
   (Contact <> xRec.Contact)
THEN BEGIN
  MODIFY;
  UpdateContFromCust.OnModify(Rec);
END;


Könnte dieser Code vielleicht dafür zuständig sein, das er die richtigen Daten dann raus gibt? Weil er dürfte diese Daten ja nicht rausgeben, da der OnModify Trigger nicht komplett durchlaufen wurde theoretisch.
Dann könnte es ja eventuell reichen wenn ich diesen Code um mein Passwort Feld erweitere. Wäre das eine Möglichkeit?
Ich glaub das probiere ich gleich mal aus.

19. Dezember 2007 10:10

Ja, das liegt an dem MODIFY (fast ganz unten) im OnModify-Trigger.
Durch dieses MODIFY werden die Änderungen tatsächlich in die Datenbank geschrieben (noch bevor der Trigger beendet wird), damit der zugehörige Firmenkontakt synchronisiert werden.

Nur als Hinweis am Rande: Versuch dieses Prinzip nicht im OnInsert- oder im OnDelete-Trigger durchzuführen (also dort ein INSERT bzw. DELETE ausführen) - das knallt in der Regel.

19. Dezember 2007 10:14

Ha jetzt hab ichs.

Einfach den obrigen Code um das Passwort Feld erweitert. Dann im OnValidate Trigger des Passwortfeldes den xRec-Wert einer globalen Variable zugewiesen, und dann die Abfrage von Marc verwendet im OnModify Trigger. Und schon hab ich das gewünschte Ergebnis.

Danke euch allen.

@Natalie

Sowas würd ich mich warscheinlich noch nicht mal trauen. Aber danke für den Tip.

19. Dezember 2007 10:24

Heike Bennerscheid hat geschrieben:Sowas würd ich mich warscheinlich noch nicht mal trauen. Aber danke für den Tip.


Ich habe in meiner Verzweiflung schon ALLES ausprobiert und bin gegen die Wand gelaufen ;-)

19. Dezember 2007 10:27

So lange man nur im Testsystem gegen die Wand läuft und nicht im Echtsystem, gehts ja noch :wink: