[gelöst]Individualprogrammierung mit minmalen Eingriffen

16. April 2009 18:08

Ein neues Projekt verlangt, möglichst wenig Änderungen am Standard vorzunehmen. Um das umzusetzen habe ich mir folgendes überlegt:

Forms: Original in eine neue Form kopieren und nur die Menüleiste entsprechend anpassen.

Tables: Eine eine Referenztabelle erstellen, die z.B. zusätzliche Stammdaten enthält.

Beispiel:

Stammdatentabelle

Field No. Field Name Data Type
10 Source Type Integer (hier kommt die Nummer der Referenztabelle rein, z.B. 27 für Artikel))
11 Source Subtype Option (Für etwaige Optionen, z.B. für Status freigegeben)
12 Source ID Code 20 (Das ist das die Nummer des Bezugs, z.B. die Artikelnummer)

Bei "OnModify" eine Codeunit aufrufen, die ggf. verschiedenste Funktionen ausführen kann.

Beispiel:

Trigger Artikel OnModify

Aufruf einer Codeunit, deren Funktion über Parameter gesteuert wird.

Trigger CU Modifyausführen

Übergabeparameter: Ähnlich wie oben mit Referenztabelle, Option, Referenznummer, Feldnummer, Änderungsart (einfügen, ändern, löschen), alter + neuer Wert.

Dann eine Aktion ausführen, die z.B. beim Einfügen einer Artikelkategorie direkt auch eine Einheit einfügt.

Alternativ könnte man das ganze auch von der Änderungsprotokollierung aus triggern, dort hat man den alle Angaben wie Tabelle, Feld, alter + neuer Feldinhalt.

Dann könnte es doch so sein, dass die Originaltabelle völlig unverändert bleiben kann, und lediglich in der CU für das Änderungsprotokoll ein Aufruf der CU für die Individualprogrammierung eingefügt werden muss.

Sorry, aber ich habe das Thema im Forum nicht gefunden.
Wie macht Ihr das?
Zuletzt geändert von rallnus am 14. Mai 2009 10:19, insgesamt 1-mal geändert.

Re: Individualprogrammierung mit minmalen Eingriffen

16. April 2009 18:27

Meine ganz persönliche Meinung als NAV-Programmierer:

rallnus hat geschrieben:Ein neues Projekt verlangt, möglichst wenig Änderungen am Standard vorzunehmen.

Den Ansatz unterstütze ich vollkommen, aber ...

Forms: Original in eine neue Form kopieren und nur die Menüleiste entsprechend anpassen.

Möchtest du zu ändernde Forms grundsätzlich dublizieren? Auch solche, die du gar nicht aus dem Menu heraus aufrufen kannst (zum Beispiel die Auftrags-Subform)?

Tables: Eine eine Referenztabelle erstellen, die z.B. zusätzliche Stammdaten enthält.

Damit habe ich negative Erfahrungen gemacht. Beispiel: Erweiterung der Artikel-Tabelle in neue Tabelle. Du kannst keinen Sortierschlüssel bilden, der Felder beider Tabellen enthält. Dies ist beim Reportdesign von großem Nachteil. Du musst sicher stellen, dass beide Tabellen absolut synchron sind. Es darf vielleicht eine Artikel-Tabelle ohne Zusatztabelle geben (was aber Nachteile hätte), aber nie umgekehrt. Wenn der Kunde auf der Zusatztabelle Infos der Ursprungstabelle sehen möchte, müssen entweder zig neue FlowFields angelegt werden oder viel geklickt werden.
Eine Universal-Zusatztabelle kann es nicht geben, da die Stamm-Tabellen unterschiedlich aufgebaute Primärschlüssel haben und die hinzuzufügenden Felder natürlich individueller Natur sind.

Bei "OnModify" eine Codeunit aufrufen, die ggf. verschiedenste Funktionen ausführen kann.

Dann aber pro Ziel-Tabelle eine Codeunit ...
Außerdem enthalten Standard-Trigger mitunter viel Standard-Quelltext, und du musst dich in mehrere Stellen des gleichen Triggers einhängen -> noch mehr Funktionen in deiner neuen Codeunit. Das kann unübersichtlich werden.
Wenn die Gesamtanforderung durchdacht und überschaubar ist, dann ist der Ansatz durchaus zu unterstützen.

Alternativ könnte man das ganze auch von der Änderungsprotokollierung aus triggern, dort hat man den alle Angaben wie Tabelle, Feld, alter + neuer Feldinhalt.

Der Kunde will aber nicht alles oder gar nichts protokollieren - und dann? Und was tun mit dem ganzen Datenmüll?

Am Ende hast du zig neue Objekte, die alle lizensiert sein müssen und die Übersichtlichkeit für den Programmierer schmälern. Wenn der Kunde meldet, dass er ein Problem mit der Auftragsmaske habe, kann der Programmierer eben nicht sofort sagen, dass er in Form XY nachschauen muss - er muss erst suchen.

Ich möchte deine Ansätze nicht schlecht reden, aber ich kenne keinen, der sie so rigoros praktiziert - und das nicht ohne Grund.
Vielleicht probierst du es ja einfach selbst aus und berichtest uns von deinen Erfahrungen?

Re: Individualprogrammierung mit minmalen Eingriffen

17. April 2009 10:06

mit dem Änderungsprotokoll CU ist schon ein schöner Ansatz.
Aber leider wird diese CU NUR (was ich übrigens für falsch halte) bei manuellen Änderungen der Tabellen durchlaufen.
Bsp: Dimensionszuweisung für mehrere Stammdatensätze, wird nirgends protokolliert.

Dazu kommt, dass auch der Standard nicht in jedem Fall und mit guten Grund überall ein modify(TRUE) verwendet, sondern nur ein Modify.
was dafür sorgt das deine Trigger leider manchmal wirkungslos bleiben.

Re: Individualprogrammierung mit minmalen Eingriffen

27. April 2009 17:45

Hallo fleissige Natalie, vielen Dank für deine umfassenden Darstellungen.
Anbei siehe meine Antworten.

Natalie hat geschrieben:Meine ganz persönliche Meinung als NAV-Programmierer:

Ein neues Projekt verlangt, möglichst wenig Änderungen am Standard vorzunehmen.

Den Ansatz unterstütze ich vollkommen, aber ...

Forms: Original in eine neue Form kopieren und nur die Menüleiste entsprechend anpassen.

Möchtest du zu ändernde Forms grundsätzlich dublizieren? Auch solche, die du gar nicht aus dem Menu heraus aufrufen kannst (zum Beispiel die Auftrags-Subform)?
Antwort:ja, das müsste man dann so machen.

Tables: Eine eine Referenztabelle erstellen, die z.B. zusätzliche Stammdaten enthält.

Damit habe ich negative Erfahrungen gemacht. Beispiel: Erweiterung der Artikel-Tabelle in neue Tabelle. Du kannst keinen Sortierschlüssel bilden, der Felder beider Tabellen enthält.

Antwort:Ich wüsste nicht, warum ich nach Stammdaten sortieren sollte. Ansonsten würde ich in der Generaltabelle Sortierfelder vorsehen, die man mit den für die Sortierung notwendigen Felder füllen kann.

Dies ist beim Reportdesign von großem Nachteil. Du musst sicher stellen, dass beide Tabellen absolut synchron sind. Es darf vielleicht eine Artikel-Tabelle ohne Zusatztabelle geben (was aber Nachteile hätte), aber nie umgekehrt.

Antwort:Da ich ja die Originaltabellen nicht anfassen möchte kann hierzu nur ein Job dienen, der die Daten zyklisch bereinigt.

Wenn der Kunde auf der Zusatztabelle Infos der Ursprungstabelle sehen möchte, müssen entweder zig neue FlowFields angelegt werden oder viel geklickt werden.


Antwort:Hier könnte ich mir eine "Build Form"-Funktion vorstellen, die die notwendigen Daten holt. Hier muss dann aber auch wieder eine aufwendige Einrichtungstabelle dahinter liegen.

Eine Universal-Zusatztabelle kann es nicht geben, da die Stamm-Tabellen unterschiedlich aufgebaute Primärschlüssel haben und die hinzuzufügenden Felder natürlich individueller Natur sind.


Antwort:Stammdaten-Tabellen sind i.d.R. primär nach Nummer sortiert, das sollte also nicht das Problem sein.

Bei "OnModify" eine Codeunit aufrufen, die ggf. verschiedenste Funktionen ausführen kann.

Dann aber pro Ziel-Tabelle eine Codeunit ...

Antwort:..einverstanden

Außerdem enthalten Standard-Trigger mitunter viel Standard-Quelltext, und du musst dich in mehrere Stellen des gleichen Triggers einhängen -> noch mehr Funktionen in deiner neuen Codeunit. Das kann unübersichtlich werden.
Wenn die Gesamtanforderung durchdacht und überschaubar ist, dann ist der Ansatz durchaus zu unterstützen.

Alternativ könnte man das ganze auch von der Änderungsprotokollierung aus triggern, dort hat man den alle Angaben wie Tabelle, Feld, alter + neuer Feldinhalt.

Der Kunde will aber nicht alles oder gar nichts protokollieren - und dann? Und was tun mit dem ganzen Datenmüll?


Antwort:Wir machen es ohnehin so, dass wir spezielle Regeln haben, nach denen die Änderungseinträge zyklisch ausgelagert werden. Das könnte hier auch zum Einsatz kommen.

Am Ende hast du zig neue Objekte, die alle lizensiert sein müssen und die Übersichtlichkeit für den Programmierer schmälern. Wenn der Kunde meldet, dass er ein Problem mit der Auftragsmaske habe, kann der Programmierer eben nicht sofort sagen, dass er in Form XY nachschauen muss - er muss erst suchen.

Ich möchte deine Ansätze nicht schlecht reden, aber ich kenne keinen, der sie so rigoros praktiziert - und das nicht ohne Grund.
Vielleicht probierst du es ja einfach selbst aus und berichtest uns von deinen Erfahrungen?


Antwort:In der heutigen Anwendung haben wir 3000 von 3500 Objekten modifiziert. In einer neuen Anwendung möchte ich das stark reduzieren. Ich werde über die Erfahrungen berichten.

Und: Beim nächsten Mal übe ich das mit dem Zitat...hat noch icht so ganz geklappt.
Zuletzt geändert von Natalie am 27. April 2009 18:28, insgesamt 1-mal geändert.
Grund: Quote-Tags "optimiert" ;-)

Re: Individualprogrammierung mit minmalen Eingriffen

27. April 2009 19:23

Da ich gerade selber an einem Kunden-Projekt arbeite, wo "möglichst standard-nah" programmiert werden soll (d. h. so wenig wie möglich Individualanpassung), kenne ich das Problem ebenfalls.

Ganz ohne Anpassungen der Standardobjekte geht es definitiv nicht.
Deine Idee ist natürlich nicht schlecht, aber wenn ich an die daraus resultierenden Lizenzkosten für die ganzen Individualobjekte denke, dann dürfte das die Kosten für das Mergen bei einem Versions-Upgrade übersteigen.

Kompromis:
Ändere nicht den Standard, sondern erweitere ihn nur.
Beispiel: Anstatt die Preisfindung im Verkauf an die Bedürfnisse des Kunden anzupassen (oder gar eine komplett eigene Codeunit dafür zu schreiben), programmiere die Anforderungen als Zusatz-Feature hinzu (darf auch gerne - sofern möglich - in einer eigenen Codeunit abgelegt werden).

Setze Anforderungen nicht wortwörtlich um, sondern versuche zuerst herauszufinden, was der Kunde damit erreichen möchte (z. B. Koppelung bestimmter Verkaufspreise an bestimmte Verkaufsrabatte).

Versuche die Anforderungen so modular wie möglich zu programmieren, damit du bei zukünftigen Erweiterungen nicht in einer Sackgasse landest, sondern deine Programmierung erweitern kannst, ohne in "Spaghetti-Code" zu enden.

Das Wichtigste ist jedoch eine einheitliche und durchgängige Dokumentation der Änderungen im C/AL-Code sowie im Documentation-Trigger, um die angepassten Stellen bei einem Merge auf eine neue Version auf Anhieb als solche erkennen zu können.
Darüber hinaus sollte man sich strikt an sämtliche Style-Guides (GUI-Guide, C/AL-Guide, Application Designers Guide, interne Style-Guides) halten, damit nicht nur der originäre Programmierer den Programmcode lesen kann.

Re: Individualprogrammierung mit minmalen Eingriffen

28. April 2009 09:42

Hallo,

ich kann Timo da nur voll und ganz zustimmen.

  • Ohne Änderungen am Standard wirst du deine Anpassungen nicht pflegen können (Verweise auf Subforms, aus Menüs,Pflegen der Zusatztabellen,...)
  • Deim Merge auf eine neue Version behindert dich die Duplizierung der Objekte beim Mergen nur.
  • Der Aufwand die zusätzlichen Tabellen zu pflegen beim Löschen, Umbenennen, bzw. Einfügen von Datensätzen ist riesig, da du nie alle Stellen herausfindest, an denen du Programmänderungen durchführen müsstest.
  • Du kannst die zusätzlichen Stammdaten nicht einem normalen Form verwenden, da die nur eine Tabelle pro Form unterstützen. Du müsstest das Form mit Programmierung vollstopfen, damit die Daten immer korrekt sind.
Zusammengefasst:
  • Bei Tabellen baue lieber die Felder in den Standardtabellen ein.
  • Bei Forms und Reports würde ich auch die Standards anpassen, es sei denn es passt gar nicht (ist beim Mergen auf eine neue Version einfacher)
  • Beim Code versuche möglichst wenig Code in den Standardcode einzufügen, verwende möglichst Funktionsaufrufe, die ruhig im gleichen Objekt liegen dürfen (bei einigen Funktionalitäten geht das auch nicht anders :wink: )

Alles andere führt zu einer Neuprogrammierung von NAV, bei der die Standards nicht mehr benutzt werden, was sicherlich auch nicht im Sinne des Erfinders ist. :wink:

Gruß, Fiddi