CurrentInputForm oder CurrentRecord

Hallo,

ich habe das Problem, dass ich mir zwar aus einem Record alle Daten holen kann mit „CurrentRecord.GetContentsValueByName“, jedoch beim zurückschreiben per „CurrentRecordSet.CurrentRecord.SetContentsValueByName“ hakt es. Ich bekomme zwar die Rückmeldung:
combit.cRM.COM.Record.SetContentsValueByName zurückgegeben = true

Jedoch werden die Werte nicht in meine Registerkarte übertragen. Dies funktionert nur mit „CurrentInputForm(0).SetContentsValueByName“.

Gibt es irgendwo weitere Erklärungen oder Tutorials außerhalb des SDK Handbuchs?

Viele Grüße

Thomas

jedoch

Vorab: Falls Sie tatsächlich diese ganze Objekt-Kaskade benutzen (und es nicht nur aus Übersichtlichkeitsgründen hier im Beitrag so geschrieben haben): Bitte benutzen Sie UNBEDINGT Objektvariablen. So eine Kaskade legt für jeden Kaskadenschritt eine Objekt-Variable an (und verwirft diese danach direkt wieder) - jedes Mal. Das ist zum einen richtig schlimm für die Performance, zum anderen könnte das auch eine pot. Ursache für den von Ihnen beschrieben Effekt sein, weil beim Setzen von Feldern eine Abfolge von Methoden auf ein-und-dasselbe Scripting-Record-Objekt angewendet werden muss. Siehe unten.

Zur Frage: CurrentInputForm ermöglicht den direkten Zugriff auf die Eingabeelemente der Eingabemaske. Schreibender Zugriff - sofern der:die Anwender:in im Bearbeiten-Modus ist - setzt den Inhalt nur im Control, die Änderung wird daher auch direkt angezeigt (gleichsam als wäre der Wert manuell per Tastatur eingegeben worden), der Inhalt ist NICHT autom. im Datensatz gespeichert. Wenn der:die Anwender:in danach nicht speichert, dann ist die Änderung hinfällig. Typischerweise benutzt man CurrentInputForm in Scripten, die Benutzer:innen kompliziertere Änderungen beim Bearbeiten des aktuellen Datensatzes in der Eingabemaske abnehmen sollen, aber die eigentliche Hoheit der Änderung („Speichern“) weiterhin den Benutzer:innen überlassen bleiben sollen/müssen. In Scripten dieses Kontextes ist auch das pragma „keep-editmode“ wichtig (siehe SDK Doku).

CurrentRecord ermöglicht den Zugriff auf einen in der Datenbank gespeicherten Datensatz. Dieser muss nicht unbedingt visuell dem Benutzer gerade präsentiert werden! Er kann z.B. auch über ViewConfig.CreateRecordSet und einem entsprechendem Such-Filter komplett unsichtbar aus einer ganz anderen Ansicht stammen, komplett unabhängig von der in der Oberfläche gerade dargestellten Ansicht und Datensatz.

Das Setzen eines Feldes erfolgt immer nach folgendem Schema:

Record.Lock();
Record.SetContentsByName("Feld", "Wert"); // oder SetContentsValueByName
Record.Save();
Record.Unlock();

Essentiell wichtig ist ein sauberes Fehlerhandling durch Check des Rückgabewertes mindestens bei Lock und Save. Ersteres schlägt fehl, wenn der:die Benutzer ggf. keine Rechte hat, diesen Datensatz zu ändern. Save schlägt fehl, wenn z.B. der Datenbankserver aufgrund von irgendwelchen Integritätsregeln (Constraints) das Speichern ablehnt.

Was jetzt noch fehlt, FALLS es sich um einen visuellen auch gerade tatsächlich dargestellten Datensatz handelt: die Anzeige zu aktualisieren (analog zu ‚Fenster > Aktualisieren‘). Dies geschieht durch die Update Methode für das aktuell angezeigte ActiveView Objekt.

Ein mitgeliefertes C# Scripting Beispiel finden Sie in Ihrem cRM Installationsordner unter .\Scripts\Examples\C#Script\ChangeFieldContent.csscript. (Bitte aber noch das Fehlerhandling ergänzen, best-practice siehe SDK Doku bei der LockMethode.)

Wenn Sie jetzt mit einer Objekt-Kaskade arbeiten, statt einer Record Variablen, dann laufen Lock, SetContentsByName und Save in drei unterschiedliche (nämlich jeweils temporäre) Scripting-Record-Objekte und nicht auf ein-und-dasselbe. Und da die Save Methode für „ihr“ temporäres Objekt keinerlei Änderungen „bemerkt“ (weil das SetContents ja in ein anderes temp. Objekt gelaufen ist), gibt es aus dessen Sicht auch nichts zu speichern.

Ich hoffe, Sie können damit das Problem einkreisen und lösen. :nerd_face:

1 „Gefällt mir“

Das ist ja wirklich sehr verständlich erklärt. Hat mir sehr geholfen. Vielen Dank!

Es lag wirklich an der Objekt-Kaskade. Jetzt kann ich sperren, lesen, schreiben und wieder entsperren. Das einzige, was noch hakt ist die Ansicht zu aktualisieren. Da bekomme ich den Wert false zurück. Im Programm aktualisiert er aber die Ansicht. Es erscheinen die aktuellen Werte in den Textfeldern.

Ich habe die Objekte aus dem Beispiel übernommen:

Project oProject = cRM.CurrentProject;
combit.cRM.COM.View oActiveView = oProject.ActiveViews.ActiveView;
RecordSet oRecordSet = oActiveView.CurrentRecordSet;
Record oRecord = oRecordSet.CurrentRecord;

Und mittels dem Befehl

oActiveView.Update();

versucht die Ansicht zu aktualisieren, nachdem ich den Datensatz wieder freigegeben habe. Im Prinzip wie im Beispielskript.

Was sind die üblichen Fehler, die bei der Aktualisierung der Ansicht vorkommen können?

Ups. Das ist unbeabsichtigt und wird mit dem nächsten Service Pack geändert werden:

Der Update Befehl wird aktuell „immer funktionieren“, es gibt aktuell keinen Programmpfad, der hier überhaupt einen Fehler liefern würde. Daher wäre es natürlich im Sinne der Konsistenz der ganzen Rückgabewerte besser, die Methode würde grundsätzlich true liefern. => wird korrigiert werden

Sie können auf Fehlerhandling bei Update verzichten.

Sorry für die Umstände.

1 „Gefällt mir“