C# DLL als Code direkt einbinden?

21. November 2016 11:10

Hallo,

wir haben in NAV2009 eine DLL aus C# als Automation eingebunden und verwendet. Da NAV2016 nun C# deutlich besser unterstützt, wäre es irgendwie auch möglich den gesamten C#-Code aus der DLL direkt in eine Codeunit zu stecken?
Wie wäre es alternativ möglich, die DLL/den Code optimal zu nutzen? Ich finde dazu leider kaum was, vielleicht habt ihr auch ein paar Links, bei denen ich mich informieren kann :)

Danke!

Re: C# DLL als Code direkt einbinden?

21. November 2016 11:45

bennyb hat geschrieben:Da NAV2016 nun C# deutlich besser unterstützt, wäre es irgendwie auch möglich den gesamten C#-Code aus der DLL direkt in eine Codeunit zu stecken?

Direkt nicht, nur über die zugehörigen Objektmetadaten.
Ein Beispiel, wie man das durch Import in diese manipulieren kann, ist hier:
http://vjeko.com/c-injection-dont-trust-fob/
Für normale Anwendung ist so etwas tabu, ein Neukompilieren des Codeunits würde die Metadaten auch wieder überschreiben.

Re: C# DLL als Code direkt einbinden?

21. November 2016 11:51

Kowa hat geschrieben:Direkt nicht, nur über die zugehörigen Objektmetadaten.
Für normale Anwendung ist so etwas tabu, ein Neukompilieren des Codeunits würde die Metadaten auch wieder überschreiben.


Das ist natürlich nicht Sinn der Sache, was wäre denn die bessere Lösung die DLL/den Code zu nutzen? Damit wird im Grunde eine Mail generiert und verschickt.
Zuletzt geändert von bennyb am 21. November 2016 12:02, insgesamt 1-mal geändert.

Re: C# DLL als Code direkt einbinden?

21. November 2016 12:02

Forumsknigge beachten, bitte keine Vollzitate!

Die obige Webseite ist die umfangreichste Quelle zum Thema, hier z.B.
http://vjeko.com/sorting-out-the-dll-hell-part-1-the-problem/
http://vjeko.com/sorting-out-the-dll-hell-part-2-the-solution/
http://vjeko.com/sorting-out-the-dll-hell-part-3-the-code/

Re: C# DLL als Code direkt einbinden?

22. November 2016 12:44

Kowa hat geschrieben:Die obige Webseite ist die umfangreichste Quelle zum Thema


Danke, also ich habe nun dort auch dieses dieser hier ausprobiert: http://vjeko.com/vstemplate
Nur ich verstehe nicht ganz, wie ich meine DLL entsprechend ändern muss bzw dort einbinden kann, weil dies dort nicht mehr aufgeführt wird

EDIT

Wäre das so korrekt und müsste ich dann das Interface nutzen oder die MainClass (ich glaube das Interface oder)?:

IControlAddIn.cs

Code:

namespace Reporting
{
    [ControlAddInExport("Reporting")]
    public interface IControlAddIn
    {
        void doSomething(bool bla);
        [ApplicationVisible]
        event EmptyEventHandler ControlReady;
    }
    [ClassInterface(ClassInterfaceType.None), Guid("xxx")]
    public class MainClass : IControlAddIn
    {
       
        public event EmptyEventHandler ControlReady;

        public void doSomething(bool bla)
        { /// }
    }

Re: C# DLL als Code direkt einbinden?

22. November 2016 17:20

Hallo,

bevor du mit dem Controladdin anfängst.
Was macht deine Automation eigentlich. Evtl kannst du Sie ja weiter verwenden!? oder es wird auch als Addin nicht funktionieren.

Gruß Fiddi

Re: C# DLL als Code direkt einbinden?

23. November 2016 09:19

fiddi hat geschrieben:Was macht deine Automation eigentlich.


Moin,

also um es oberflächlich zu sagen, geht es darum, dass Mails verschickt werden und eine HTML-Tabelle generiert wird mit Daten aus NAV. Das war in NAV2009 ein ziemlicher Abbrecher und in C# mit deutlich weniger Code zu lösen.
Die Automation soll komplett wegfallen und als C# Code in C/AL oder als DotNet-Objekt eingebunden werden. Da die Umstellung auf C/AL ziemlich aufwendig und zeitintensiv ist, wäre die DotNet-Variante besser.
Also ich habe es zumindest schon hinbekommen, dass das AddIn angezeigt wird und ich es auch ansprechen kann, wie vorher die Automation. Mein Problem liegt nur darin, dass es kein CREATE gibt und ich keinen Konstruktor habe und deshalb ein Fehler angezeigt wird. Im Interface lässt sich kein Konstruktor erwirken und in der MainClass bringt das nichts, er springt auf einen anderen Fehler.
Ich müsse wohl den Konstruktor mit myDotNet := MyDotNet.Constructor aufrufen, aber ich finde nichts dazu, wie ich den ordnungsgemäß in das ControlAddIn hinzufüge.

Re: C# DLL als Code direkt einbinden?

23. November 2016 09:36

Hallo,

was du willst, ist kein Controlladdin (Es sei denn du möchtest es auf dem Bildschirm anzeigen).
Mail kann kann NAV eigentlich auch in NAV 2009 schon ganz gut verschicken (evtl. Patch nachziehen) (Cu400 bzw. CU397). und es ist dringend anzuraten das auch in 2016+ mit diesen CUs zu machen.
Ob es ein großes Problem ist deine HTML-Tabelle in C/AL zu programmieren, kann ich jetzt nicht sagen. Es sollte kein so großer Aufwand wie eine passende Dotnet- Assembly zu erstellen.
Seit NAV 2GB große Textvariablen kennt (Textvariable ohne Länge), ist das sicherlich kein Problem mehr einen HTML-String zu erstellen, den man per Mail verschickt. :wink:
Außerdem kannst du DotNet direkt in NAV nutzen, d.h. du programmierst in C/AL nutzt aber DotNet- Funktionen.

Gruß Fiddi

Re: C# DLL als Code direkt einbinden?

23. November 2016 09:53

fiddi hat geschrieben:was du willst, ist kein Controlladdin (Es sei denn du möchtest es auf dem Bildschirm anzeigen).
Außerdem kannst du DotNet direkt in NAV nutzen, d.h. du programmierst in C/AL nutzt aber DotNet- Funktionen.


Oh, dann habe ich das mit dem ControlAddIn wohl falsch verstanden, ich wollte eigentlich nur die Automation, die im Hintergrund genutzt wird, auf eine passende Variante in 2016 bringen. Ich glaube wir sind auf 2016 bei CU 11 momentan.
Das "konvertieren" haben wir versucht, ist aber extrem aufwendig und zeitintensiv. Das größere Problem dabei ist die Modularität. Ich arbeite in C# mit einem Struct, dass in einer Liste gesammelt wird.
Ich versuche es mal zu erklären. Es geht um eine Auswertung von Essensbestellungen. Es gibt z.B. 3 Menüs, die dann an die Automation übergeben werden (könnten aber auch 2 oder 5 sein). Jedes Struct hat den Menu Code, eine Beschreibung und verschiedene Varianten von Anzahlen (Anzahl Zeile/gesamt, bewirtet/nicht bewirtet). Diese Structs werden anhand des Menu Codes eindeutig und in die Liste verfrachtet. NAV pumpt quasi zeilenweise Daten rein und eine LINQ-Anweisung aktualisiert dann die Anzahlen der einzelnen Menüs. Dazu kann man modular einstellen, in welchem Zeitraum die Auswertung erfolgen soll wie z.B. alle 15 Minuten von 12-14 Uhr. Durch diese ganzen dynamischen Sachen ist die Übernahme in C/AL relativ kompliziert.

Wie sollte ich denn nun am sinnvollsten die Automation zu etwas funktionierendem in 2016 bringen? Also das ControlAddin war dann schon mal falsch. Ich glaube Übernahme als C/AL Code wäre kompliziert zu realisieren + zeitintensiv hm :-x

#EDIT

Also, wenn ich eine Möglichkeit finde, eine Klasse/Struct in eine Liste zu packen im C/AL Code und mit foreach dessen Inhalt aktualisiert bekomme, würde es möglich sein den Code in C/AL abzubilden. Das ist nämlich mein größtes Problem dabei.

Code:
private class Menu
        {
            public string menu;
            public string description;
            public int count;
            public int countHosp;
            public int countAllnotHosp;
            public int countAllHosp;
        }


private List<Menu> menuListe = new List<Menu>();

public void addMenuCode(string menux, string desc)
        {
            menuListe.Add(new Menu
            {
                count = 0,
                countHosp = 0,
                menu = menux,
                description = desc
            });
        }

public void refreshMenuCounts(string menu, int c, int ch)
        {
            menuListe.Where(w => w.menu == menu).ToList().ForEach(s => s.count = c);
            menuListe.Where(w => w.menu == menu).ToList().ForEach(s => s.countHosp = ch);
            //menuListe.Where(w => w.menu == menu).ToList().ForEach(s => s.countAll += ch + c);
            menuListe.Where(w => w.menu == menu).ToList().ForEach(s => s.countAllnotHosp += c);
            menuListe.Where(w => w.menu == menu).ToList().ForEach(s => s.countAllHosp += ch);
        }

Re: C# DLL als Code direkt einbinden?

23. November 2016 10:33

Beispiele für den Konstruktor bzw. externen Programmstart sind hier.

Re: C# DLL als Code direkt einbinden?

23. November 2016 10:40

Hallo,

von wo wird denn "refreshMenuCounts" aufgerufen, aus NAV oder von wo anders?

Gruß Fiddi

Re: C# DLL als Code direkt einbinden?

23. November 2016 10:43

Kowa hat geschrieben:Konstruktor


Das habe ich schon probiert, leider erfoglos.
Also ich habe meine DotNet Variable mit "Reporting.MainClass" ausgewählt aus dem Addin und versuche auch so zu instanzieren: DotNetVar := DotNetVar.MainClass
"Die Instanz des folgenden .NET Framework-Objekts kann nciht geladen werden: Montage Reporting....."

fiddi hat geschrieben:aus NAV oder von wo anders


In NAV wird das Menü gezählt nach Datum und Zeitraum (z.B. 12 bis 12.15), getrennt nach bewirtet und nicht bewirtet und dann die Funktion aufgerufen, damit die Anzahl in der DLL passt und in die Tabelle miteinbezogen werden kann. Dieses wiederholt sich für jedes Menü und jeden eingestellten Zeitraum.

Re: C# DLL als Code direkt einbinden?

23. November 2016 10:48

Hallo,

wenn ich dich jetzt richtig verstehe, kommen die Daten, die dort Zählst aus NAV!?

Hast du dich schon mal mit NAV-Tabellen und vor allem FlowFields auseinander gesetzt?

Gruß Fiddi

Re: C# DLL als Code direkt einbinden?

23. November 2016 11:01

fiddi hat geschrieben:wenn ich dich jetzt richtig verstehe, kommen die Daten, die dort Zählst aus NAV!?


Korrekt, die Daten sind aus NAV.

fiddi hat geschrieben:Hast du dich schon mal mit NAV-Tabellen und vor allem FlowFields auseinander gesetzt?


Ja natürlich, nur auf Grund der Einfachheit bei C# vorallem beim Generieren der dynamischen Tabellen, wurde auf eine Automation gesetzt.
Es wäre jetzt natürlich unschön nochmal alles komplett in C/AL neu zu verfassen. Deshalb der Wunsch nach Fortführung als DotNet-Komponente oder eine Möglichkeit den Code zu mischen, wo halt die Frage nach Ersatz einer Klasse ist, die in C/AL verwendet werden kann. Ich glaube mit einer Tabelle ist das nicht so einfach zu realisieren, dass ich diese in eine Liste getrennt nach Menü stecken kann.

Re: C# DLL als Code direkt einbinden?

23. November 2016 11:14

Ich glaube mit einer Tabelle ist das nicht so einfach zu realisieren, dass ich diese in eine Liste getrennt nach Menü stecken kann.


Wenn ich das richtig sehe, benötigst du noch nicht mal eine neue Tabelle, die hast du wahrscheinlich schon.
Also die Felder
Code:
   public int count;
            public int countHosp;
            public int countAllnotHosp;
            public int countAllHosp;


als Flowfields in deine wahrscheinlich vorhandene Tabelle mit den Menüs einfügt, und das ganze ist fast erledigt. Dann noch die passenden Flowfilter (Uhrzeit, Datum) eingefügt, und du hast das gleiche ohne den Umweg über DotNet, und du kannst mit NAV- Bordmitteln und Pages auf die Daten zugreifen.

Gruß Fiddi

Re: C# DLL als Code direkt einbinden?

23. November 2016 11:33

fiddi hat geschrieben:Flowfields in deine wahrscheinlich vorhandene Tabelle mit den Menüs einfügt, und das ganze ist fast erledigt. Dann noch die passenden Flowfilter (Uhrzeit, Datum) eingefügt


Da ich noch ziemlicher Anfänger in NAV bin, muss ich mich da nochmal reinlesen. Bin mir noch nicht ganz sicher, wie ich das realisieren kann. Also ich nehme mal folgendes Beispiel als HTML-Tabelle:

Code:
Von   Bis    Menu 1   Menu 1 bewirtet    Menu 2   Menu 2 bewirtet    Menu3   Menu 3 bewirtet    Gesamt
12:00:00   12:14:59   14   0   0   0   0   0   14
12:15:00   12:29:59   18   0   1   0   12   0   31
12:30:00   12:44:59   24   0   1   0   6   0   31
12:45:00   12:59:59   13   4   0   0   7   0   24
13:00:00   13:14:59   9   0   0   0   3   0   12
13:15:00   13:29:59   0   0   0   0   3   0   3
13:30:00   13:44:59   8   0   1   0   5   0   14
13:45:00   13:59:59   1   0   0   0   0   0   1
14:00:00   14:14:59   1   0   0   0   0   0   1
Gesamt                88   4   3   0   36   0   131
                                          davon Chipzahlungen   127
                                             davon Bewirtungen   4


Ich gehe dann folgendermaßen vor:

SETRANGE bei den Besuchsinformationen (zB Besuchstag, Zeit, Name, Menü, Anzahl, Preis, Bewirtung? - Ein Menu Code ist eine Zeile, also bei Bestellung von verschiedenen Menüs, entstehen auch mehrere Zeilen) mit dem Datum, der Zeit (12 - 12.15) und natürlich dem Menu Code. So nun prüfe ich, ob es eine Bewirtung ist oder nicht, dementsprechend erhöre ich den einen oder anderen Counter. Nachdem das Menü durch ist, wird die Anzahl in der DLL aktualisiert (durch die zeilenweise Verarbeitung, um die Tabelle aufbauen zu können, ich aber natürlich am Ende jeweils alle Zahlen benötige). Sobald jedes Menü einmal den Filter durchlaufen ist (ändert sich ja nur der Menu Code), wird die Zeilen der HTML-Tabelle hinzugefügt. Das Ganze wiederholt sich bis das Intervall (zb 15 Minuten) die angegebene Endzeit (zB 14 Uhr erreicht). Danach wird das Ende der Tabelle (Gesamt und folgendes) angehangen und die Mail versandt.

Wärst du eventuell so nett mir nur zu beschreiben, wie ich es theoretisch realisieren kann? Also die Flowfields wären dann ja auch in jeder Zeile der Tabelle oder nicht?

Re: C# DLL als Code direkt einbinden?

23. November 2016 11:49

Hallo,

zunächst ein paar Fragen, ob wir das ganze simpel lösen können oder doch etwas mehr Aufwand treiben müssen?

1. gibt es eine Menü-Posten- Tabelle?
2. Sind die Zeiträume die du anzeigst fix, also immer 12.00 - 1215, 12.15 -12.30., und es sind nur diese neun?
3. Könnte man die Achsen vertauschen, also Zeit auf der X-Achse und Menüs auf der Y-Achse?

Gruß Fiddi

Re: C# DLL als Code direkt einbinden?

23. November 2016 11:57

Zunächst einmal danke für die Hilfe :)
fiddi hat geschrieben:1. gibt es eine Menü-Posten- Tabelle?

Es gibt die Besuchsposten, Bewirtungsposten und Abrechnungsposten als Tabelle, außerdem gibt es eine Tabelle mit den Menüs (Code, Beschreibung, etc).
fiddi hat geschrieben:2. Sind die Zeiträume die du anzeigst fix, also immer 12.00 - 1215, 12.15 -12.30., und es sind nur diese neun?

Nein, diese sind auch dynamisch. Ich kann sowohl das Intervall festlegen (15 Minuten, 25 Minuten, wie auch immer) als auch den Zeitraum in dem das Intervall sich durchrechnet (zB 10 bis 14 alle 25 Minuten), dafür gibt es eine Einrichtungstabelle.
#EDIT
Ich habe es auch so gemacht, dass die Zeile nicht angelegt wird, falls alles bei 0 liegt. Also könnte es 12-12.15 12.45-13 sein.
fiddi hat geschrieben:3. Könnte man die Achsen vertauschen, also Zeit auf der X-Achse und Menüs auf der Y-Achse?

Ja, das sollte möglich sein (wobei ich da noch eine Absegnung bräuchte), muss man halt schauen, dass man alles umgestellt bekommt.

Re: C# DLL als Code direkt einbinden?

23. November 2016 12:14

Hallo,

meine Lösung würde jetzt aus einer Matrix-Page bestehen, die in den Zeilen einen Integer hat (Anzahl Perioden + für die Summe) und in den Spalten mit der Anzahl (Menüs+1) x2 (+1 für Summe und x2 für bewirtet oder nicht) .

Beispiele für die Matrix- Page findest du genügend in NAV (einfach Page- Namen auf *Matrix* filtern).
Eine solche Page kannst du dir einfach kopieren. Du musst dann die Füllfunktionen und die Filter- Felder im Kopf anpassen, und du hast eine Online- Übersicht.

Gruß Fiddi

Re: C# DLL als Code direkt einbinden?

23. November 2016 15:29

fiddi hat geschrieben:Eine solche Page kannst du dir einfach kopieren. Du musst dann die Füllfunktionen und die Filter- Felder im Kopf anpassen, und du hast eine Online- Übersicht.


Ich versuche mich gerade etwas daran, wirkt etwas verwirrend am Anfang. Kann ich das dann trotzdem noch im Hintergrund ausführen lassen und die E-Mail daraus bauen/versenden :-o Und eine größere Frage, es sieht so aus, dass man doch in der Page alle Zellen vordefinieren muss und nicht dynamisch hinzufügen kann, ist das korrekt?

Re: C# DLL als Code direkt einbinden?

25. November 2016 09:15

Hallo,

entschuldige meine verspätete Antwort.

Das ganze kannst du auch mit einem Bericht machen, den du oder der Empfänger planen kann planen kann. Im RDLC ist das sogar noch etwas einfacher, da dort sowohl Zeilen (Zeiträume) als auch Spaltengruppen (Menüs) möglich sind.

Wenn es nicht zu viele Datensätze sind (Das was du oben gezeigt hast ist kein Problem) kannst du einfach alle "Menüposten" an den Bericht übergeben, und den Rest dem Bericht überlassen. Sollten es allerdings mehr als einige 1000 Posten werden, solltest du vorher aufsummieren.

Gruß Fiddi

Re: C# DLL als Code direkt einbinden?

28. November 2016 10:42

fiddi hat geschrieben:Das ganze kannst du auch mit einem Bericht machen, den du oder der Empfänger planen kann planen kann. Im RDLC ist das sogar noch etwas einfacher, da dort sowohl Zeilen (Zeiträume) als auch Spaltengruppen (Menüs) möglich sind


Danke schon mal für alles, aber das scheint echt ziemlich großer Aufwand zu sein, alles neuzuprogrammieren, dazu sind es ja weitere DLLs, die dort eingebracht werden müssten.
Gibt es keine Möglichkeit, weiterhin eine DLL zu nutzen? Das Control Addin war ja schon der falsche Ansatz, da es sich nur um Background-Arbeit handelt. Das ist zeitlich alles sehr knapp, deshalb wäre Neuprogrammierung nur der allerletzte Schritt :-x .

Re: C# DLL als Code direkt einbinden?

28. November 2016 10:50

Hallo,

wenn du das als Background, d.h. auf dem Servicetier laufen lassen willst bzw. musst, dann muss alles in DotNet sein, keine Automations. D.h. da hast du sicherlich auch was zu tun. :-?

Da du dich mit dem Reporting sowieso auseinander setzen musst, ist das schon mal eine gute Übung. :-D

Gruß Fiddi

Re: C# DLL als Code direkt einbinden?

28. November 2016 10:54

fiddi hat geschrieben:wenn du das als Background, d.h. auf dem Servicetier laufen lassen willst bzw. musst, dann muss alles in DotNet sein, keine Automations. D.h. da hast du sicherlich auch was zu tun. :-?


Oh man, wieso haben die das denn so kompliziert gemacht. Es war so bequem eine DLL zu schreiben mit C# und jetzt muss man alles irgendwie in C/AL schieben, ah man .__.
Danke dir schon mal, wäre es nicht auch irgendwie möglich mit den ganzen DotNet-Komponenten in C/AL den Code darzustellen? Da ist bisher mein einziges Problem eine Klasse darzustellen, die ich in eine Liste packen kann und den Inhalt der Objekte in der Liste updaten kann. Also z.B. Auto-Klasse mit Speed, Gewicht.. Davon mehrere Objekte generieren in eine Liste und dann mit foreach z.B. durch jedes Objekt durch und Speed/Gewicht anpassen - da fehlt mir so die Idee, wie ich das mit den DotNet-Typen in C/AL umsetzen kann. So würde ich mir zumindest etwas Zeitaufwand sparen können mit kompletter Neuprogrammierung ^^
Natürlich hat das Ganze einen Lerneffekt, aber Zeit ist ein ziemlich wichtiger Faktor.

Re: C# DLL als Code direkt einbinden?

28. November 2016 11:42

bennyb hat geschrieben:Also z.B. Auto-Klasse mit Speed, Gewicht.. Davon mehrere Objekte generieren in eine Liste und dann mit foreach z.B. durch jedes Objekt durch und Speed/Gewicht anpassen - da fehlt mir so die Idee, wie ich das mit den DotNet-Typen in C/AL umsetzen kann.


Stell dir vor eine Tabelle ist die Ansammelung von Autos und ein Record ist ein Auto... diese kannst du mit 'ner Schleife durchgehen und verändern.