SOG-Helpcenter Logo SOG Business - Software

Metadatenfelder in Masken


Mit einer speziellen Containertechnik ist es möglich, #Metadatenfelder in Verwaltungsmasken zu legen, sodass für den Benutzer der Eindruck entsteht, die Metadatenfelder seinen normaler Bestandteil der SOG ERP Maske. #Metadaten können auf diese Weise mit dem Pflegen eines SOG ERP Datenobjekte implizit mit gepflegt werden, ohne das ein PropertyGrid-Control oder eine eigene Dialogverarbeitung notwendig wären.

Das Programm muss dazu einen Meta Container bereitstellen, und entsprechend seiner Verarbeitungslogik in der gleichen Transaktion behandeln, wie die restlichen Verwaltungsdatenfelder.

Über einen Eintrag in der Relationskonfiguration wird konfiguriert, über welche Relation und welche Maskenfelder der Zugriff auf die möglichen Metadatentabellen erfolgt.
Damit ist gleichsam sichergestellt, dass nicht beliebige Metadaten als Datenfelder auf beliebige Masken gelegt werden können. Vielmehr sind nur jeweils solche Metadatentabellen verwendbar, die in einer 1:1 Beziehung zu der für den Container der Maske konfigurierten Relation stehen.

So können auf der Personenverwaltungsmaske (persv2 und persv3) nur Metadaten zu Personen verwaltet werden.
Auf der Aufgabenbearbeitungsmaske (DlgAufgabenEdit) nur Metadaten zu einer Aufgabe.
In der Artikelverwaltung p841 - Artikel (art) können auf der Maske p941v1 nur Metadaten zum Artikel verwaltet werden.
In den Masken der p102 - Auftragsbearbeitung (aufbea) (p102v1 und p102v2 ) können nur Metadaten zu Auftragsleitzsatz und Auftragspositionen verwaltet werden.
In den Masken der p202 - Bestellbearbeitung (bebea) (p202v1 und p202v2 ) können nur Metadaten zu Auftragsleitzsatz und Auftragspositionen verwaltet werden.

Die Funktionalität kann vom Programmierer in weiteren SOG ERP Verarbeitungsmasken realisiert werden, indem folgende Punkte abgearbeitet werden:

Definition des Metadatencontainers


Als Beispiel kann die Quelle Sources\SOG.ERP.Modules.CobRtm\pers\persv2_manu.cs dienen:

    public partial class persv2_msk : ISOGRelationHandler, ISOGMaskFieldProtectionHandler
    {
        private SOGDialogMaskMetaContainer _meta;

        /// <summary>
        /// Container für Metadaten auf der Maske
        /// </summary>
        [InputPrompt("Metadatencontainer")]
        [NotNull]
        public SOGDialogMaskMetaContainer SOGRefObject_Meta() => _meta ??= new SOGDialogMaskMetaContainer(this, nameof(SOGRefObject_Meta));

        /// <summary>
        /// Datenfelder, die in der Relationskonfiguration verwendet werden, jedoch eigentlich nicht Bestandteil der Maske sind
        /// </summary>
        // ReSharper disable once InconsistentNaming
        public int m_firma=> Aph.Firma;

        public Type BaseType => null;
        /// <summary>
        /// Definiert, unter welchem Klassennamen in der Relationskonfiguration die Relation der Maske festgelegt wird.
        /// </summary>
        /// <returns></returns>
        public string GetConfigName() => nameof(persv2_msk);

        /// <summary>
        /// Erlaubt das Schalten von MaskStates für Maskenfelder
        /// </summary>
        /// <param name="fldname"></param>
        /// <param name="state"></param>
        public void SetFieldState(string fldname, SOGMaskState state)
        {
            if ( fldname.StartsWith("#Meta.", StringComparison.Ordinal))
                if (SOGRefObject_Meta().ProtectFields)
                    state.Enabled = false;
        }
    }

In dieser Quelle wird das Containerobjekt als Instanz der Klasse SOGDialogMaskMetaContainer bereitgestellt.
Die SOGRefObject Funktion stellt sicher, dass der Container in der Konfiguration von Datenfeldern als Referenzobjekt erscheint.

Das Datenfeld m_firma wird hier deklariert, damit es in der Relationskonfiguration verwendet werden kann.

GetConfigName liefert den Namen, unter dem die Maske in der Relationskonfiguration konfiguriert wird.

SetFieldState kann implementiert werden, wenn die verwendeten Metadatenfelder alle gemeinsam variable geschützt werden sollen.

Relationskonfiguration


In einer der Relationskonfigurationsdateien muss festgelegt werden, über welche Relationen Metadaten in dieser Maske gepflegt werden können.
Dazu muss in einer oder in mehreren Relationsgruppen ein Eintrag in der Form

     <Relation Table="#persv2_msk" Fields="firma 1 konto" Uniq="false" Hide="true"/>

erfolgen. Der Tabellenname muss mit einer Raute (#) beginnen, und dem von GetConfigName() gelieferten Namen entsprechen.
Die Feldnamen entsprechen den Datenfeldern der Maske (die Feldnamen werden um ein m_ erweitert).
Die Option Hide="true" legt fest, dass es sich um eine interne Relation handelt, die nicht in Oberflächenauswahlen auftauchen soll.

Programmcode


Im Programm (hier: Sources\SOG.ERP.Modules.CobRtm\pers\pers_mod.cs ) muss festgelegt werden, wann die Daten im Container erneuert werden sollen, und wann das Speichern der Daten erfolgen soll:

 

persv2.SOGRefObject_Meta().Clear();

Verwirft die aktuellen Metadaten im Container. Änderungen werden nicht gespeichert. Sollte aufgerufen werden, wenn ein neuer Grunddatensatz angelesen, oder eine Funktion zum Verwerfen von Änderungen ausgelöst wird.

if (!persv2.SOGRefObject_Meta().CheckInput(out SOGLogText message, out string fieldname))

Prüft, ob alle Konsistenz-Bedingungen des Datenobjektes eingehalten wurden. Dabei wird das VIntegrity-Attribut berücksichtig (Zwangsfelder) und ggf. programmierte "CheckInput" Bedingungen der Metadatenklasse. Im Fehlerfall wird "false" zurückgeliefert, sowie ein Fehlermeldungstext und eine Datenfeldname.
Siehe auch: Beispiel CheckInput unten.

persv2.SOGRefObject_Meta().Changed

Liefert true, wenn der Benutzer Inhalte von Metadatensätzen geändert hat und ein Speichern erforderlich ist. Kann verwendet werden wenn das Programm eine Logik implementiert die in einer Verarbeitungsschleife bleibt, solange noch Daten geändert werden.

persv2.SOGRefObject_Meta().Update();

Speichert die aktuellen Metadaten, sofern sie sich verändert haben. Metadaten werden entweder eingefügt oder aktualisiert. Anschließend befindet sich der Container im Zustand "Clear". Sollte es beim Speichern der Metadaten zu Fehlern kommen, wird der Fehler protokolliert und die Verabreitung fortgestezt. Die Metadaten sind dann ggf. nicht aktualisiert worden. Dies kann z. B. passieren, wenn der Metadatensatz parallel von einem anderen Benutzer verändert wurde.

persv2.SOGRefObject_Meta().RelationObjectChanged();

Sollte aufgerufen werden, wenn sich das Basisobjekt auf der Maske geändert hat. z. B. bei einem Insert, wenn dadurch erst der Key festgelegt wird, oder während eines Duplizierens, wenn dabei der Key verändert wird. Die vorhandenen Metaobjekte werden verworfen und auf Basis der neuen Relationsbasis neu erzeugt. Maskeninhalte bleiben erhalten.

  

persv2.SOGRefObject_Meta().ProtectFields

Kann gesetzt werden, um die Datenfelder des Containers vor Eingaben logisch zu schützen, sofern das Interface "ISOGMaskFieldProtectionHandler" in der Maske implementiert wurde.

Beispiel CheckInput

 

            if (!persv2.SOGRefObject_Meta().CheckInput(out SOGLogText message, out string fieldname))

            {

                if (!fieldname.IsNullOrEmpty())

                    VSetCursor(persv2, fieldname);

                VMsg(persv2, message.GetTranslation().Translation);

 

                s_ch.Value = 2;

            }

 

In diesem Beispiel werden alle Prüfungen für alle Metadatenobjekte auf der Maske durchlaufen. Im Fehlerfall wird der Cursor auf das fehlerhafte Datenfeld gesetzt, und die Meldung per VMsg ausgegeben.

Konfiguration der Datenfelder zur Laufzeit


Wird z. B. eine Textbox konfiguriert, kann über die Datenfeldauswahl eine Liste der möglichen Datenfelder abgerufen werden.
Hier sollte nach Implementierung des Containers ein Eintrag "==> Meta" erscheinen.
Nach Doppelklick auf diesen Eintrag erscheint eine Liste aller möglichen, relational verbundenen Metadatentabellen.
Nach Auswahl einer Metadatentabelle erscheint die Liste aller ihrer Datenfelder.
Nach Auswahl eines Datenfeldes wird ein Feldname in der Form

#Meta.#Person_meta_beispiel_kunde.m_geschenk

als Datenfeldname der Textbox festgelegt.