[Gelöst] Variable Zeilen per Mail verschicken

26. Februar 2008 12:05

Ich möchte gern mit Hilfe der Mail Codeunit eine E-Mail an Kunden senden. In dieser E-Mail soll neben normalen Text auch die Bestellte Ware aufgelistet werden. Diese sind ja von Bestellung zu Bestellung unterschiedlich. Mal nur eine Zeile, mal 3 Zeilen oder sogar mehr. Somit habe ich keine feste Variablen die ich füllen könnte.

Gibt es die Möglichkeit diese Zeilen per Mail Codeunit zu verschicken? Mir fällt leider keine Lösung dazu ein. Deswegen hoffe ich das hier vielleicht jemand einen Ansatz hat.
Zuletzt geändert von Heike Bennerscheid am 12. März 2008 14:18, insgesamt 1-mal geändert.

26. Februar 2008 13:18

Hallo Heike,

in der cu397 gibt es die Funktion AddBodyLine(Textline: Text260). Diese kannst Du benutzen, um Textzeilen hinzuzufügen. Du musst lediglich Deine EK-Zeile entsprechend formatieren.

Viele Grüße
MrBurns

26. Februar 2008 13:20

Hallo Heike

Ich habe so etwas schon gelöst und dazu die Codeunit 397 erweitert mit folgender Funktion

Code:
{ Orig.
IF Body <> '' THEN BEGIN
  BSTRConverterBody.ResetBSTR;
  BSTRConverterBody.AppendNextStringPortion(Body);
END;
}

Return := 13;

IF Body <> '' THEN BEGIN
  BSTRConverterBody.ResetBSTR;
  BSTRConverterBody.AppendNextStringPortion(Body + FORMAT(Return) + FORMAT(Return));
END;

IF EmailAddTxtCode.GET(cuGlobalVarMgt.GetEmailAddTxtCode) THEN BEGIN
  BSTRConverterBody.ResetBSTR;
  EmailAddTxtLine.SETRANGE("Email Text Code", EmailAddTxtCode.Code);
  IF EmailAddTxtLine.FIND('-') THEN REPEAT
    BSTRConverterBody.AppendNextStringPortion(EmailAddTxtLine."Body Text" + FORMAT(Return));
  UNTIL EmailAddTxtLine.NEXT = 0;
END;


Anstelle meiner Tabelle EmailAddTxtLine kannst du natürlich irgendeine Tabelle verwenden.

26. Februar 2008 13:31

Danke rotsch für deine Hilfe.

Müsste ich dann EmailAddTxtCode durch Sales Header und EmailAddTxtLine durch Sales Line ersetzen? Sehe ich das so richtig?

26. Februar 2008 13:35

Hallo Heike

Du filterst auf die Tabelle, die du durchlaufen willst und läufst über die Tabelle drüber.

Wenn du Document Type und No. kennst, brauchst du m.E. den SalesHeader nicht.

26. Februar 2008 13:58

Hmm irgendwie versteh ich das noch nicht so ganz. So wie ich das erkennen kann steht dein Code im NewMessage Trigger der CodeUnit oder?

Wie gebe ich diesem Codestück nun mit von welchem Auftrag er die Zeilen nehmen soll?
Irgendwas überseh ich noch :-?

26. Februar 2008 14:03

Damit ich weiss, für welchen Code ich die Zeilen ausgeben muss, verwende ich eine SingleInstance-Codeunit, welcher ich den Wert übergeben und später wieder auslesen kann.

26. Februar 2008 14:06

OK... jetzt bin ich total überfordert (ich merke mal wieder das ich immer noch viel lernen muss). Was ist eine SingleInstance-CodeUnit? Und wie übergibst du ihr den Wert?

26. Februar 2008 14:08

Hallo Heike

Hast du mal die Suche benutzt zum Stichwort SingleInstance? Zu diesem Thema gibt es bereits diverse Beiträge.

26. Februar 2008 17:37

Ich bin schon um einiges weiter gekommen. Danke nochmal rotsch.

Aber eine Frage hätte ich da noch. Und zwar übergebe ich meiner SingleInstance CodeUnit den Dokument-Typ und die Dokument Nummer. In der Mail CodeUnit habe ich jetzt folgenden Code

Code:
IF SalesHeader.GET(cuMailTest.GetDocType,cuMailTest.GetDocNo) THEN BEGIN


Ich weiß gar nicht ob das so korrekt ist.. ich bekomme nämlich folgende Fehlermeldung

Die Beziehung zu dem Teil SetDocType der Variable konnte nicht gelöst werden.


Beim kompilieren hat er nicht gemeckert. Oder ist vllt. etwas in meiner SI-Codeunit falsch? SetDocType bekommt eine Variable vom Typ Option.. GetDocType liefert eine Integer Variable zurück. Bei einem anderen Code habe ich das auch verwendet und es gab keine Probleme. Aber irgendwo muss ich wohl noch einen Fehler haben. Jemand eine Idee?

26. Februar 2008 17:45

Ist das korrekt, oder hast du dich vertippt? Einmal schreibst du SetDocType einmal GetDocType.

Vielleicht liegt es daran?

26. Februar 2008 17:49

Nein. Im Code in der Mail CodeUnit steht ja GetDocType.. da will ich mir ja die Variable holen die ich mit SetDocType der SI-CodeUnit übergeben habe. Oder sehe ich das falsch?

Und der Fehler den ich bekomme gibt SetDocType aus.

Die SI-CodeUnit sieht derzeit so aus:

Code:
//SetDocNo(NewDocNo : Code[20])
var_DocNo := NewDocNo;

//GetDocNo() : Code[20]
EXIT(var_DocNo);

//SetDocType(NewDocType : Option)
var_DocType := NewDocType;

//GetDocType() : Integer
EXIT(var_DocType);

26. Februar 2008 18:02

Hast du var_DocNo als globale Variable deklariert?

26. Februar 2008 18:03

var_DocNo und var_DocType sind beides globale Variablen, ja.

26. Februar 2008 18:08

Der inzige Unterschied zu meinen Funktionen ist noch, dass ich die Variablen VAR übergebe.

Sonst kommt mir auch nichts mehr in den Sinn.

26. Februar 2008 18:27

Vllt. übergebe ich die Variable falsch?

Code:
cuMailTest.SetDocNo("No.");
cuMailTest.SetDocType("Document Type");


Muss ich vllt. zuerst "Document Type" übergeben und dann "No."? Macht die Reihenfolge was aus?

26. Februar 2008 18:29

Ich glaube nicht, dass die Reihenfolge etwas ausmacht. Aber du könntest beide Variablen in einer einzigen Funktion übergeben, das wäre sicher einfacher.

26. Februar 2008 18:31

Sprich nur eine Set Funktion? Aber noch immer 2 Get Funktionen oder? Mal schaun ob das was hilft.

26. Februar 2008 18:33

Du kannst auch das GET in einer einzigen Funktion abhandeln indem du der Funtkion die beiden Variablen VAR übergibst und dann die Werte in derselben Funktion zuweist.

26. Februar 2008 18:39

Aber die eine Variable ist vom Typ Code und die andere Option. Das passt dann doch gar nicht mit dem Rückgabewert(?).

Aber langsam komm ich mir einfach nur dumm vor. Irgendwie kann ich mit den Fehlermeldungen die ich bekomme nix anfangen.

Ich habe jetzt die SI-CodeUnit so geänder:
Code:
//SetDocTypeNo(VAR NewDocType : Option;VAR NewDocNo : Code[20])
var_DocType := NewDocType;
var_DocNo := NewDocNo;


und versuche jetzt die Variablen folgendermaßen zu übergeben
Code:
cuMailTest.SetDocTypeNo("Document Type","No.");


aber das scheint falsch zu sein da ich folgende Fehlermeldung erhalte
Die benutzerdefinierte C/AL-Funktion, die 1 Parameter aufnimmt, wurde mit 2 Parametern aufgerufen.


Ich hoffe bald macht es mal "klick" und mir fällt es wie Schuppen von den Augen :-?

26. Februar 2008 19:49

Ich vermute mal, dass du die DB nach einer Änderung in der CU neu öffnen musst, damit die Änderungen wirksam werden. Das ist wie bei Codeunit 1. SingleInstance CU's werden in den Speicher geladen beim Start und bleiben dort so, wie beim Start waren.

26. Februar 2008 20:35

Was ist eine SingleInstance-CodeUnit?


Eine SingleInstance-Codeunit ist eine Codeunit, die wie ein Highlander ist. Sie wird nur einmal in den Speicher geladen und bleibt dort, d.h. nach verlassen des Objekts wird es nicht defererenziert und der Speicher wieder freigegeben. Mit SingleInstance-Codeunits lassen sich u.a. Anwendungs-Globale-Variablen, sog. "Shared-Variablen", mit allen Vor- und Nachteilen erzeugen. Die Idee von Rotsch ziel genau auf so eine Shared-Variable ab.

27. Februar 2008 09:57

OK... ich glaube man muss wirklich die DB neu öffnen wie Rotsch gesagt hat. Nämlich Heute nachdem ich die DB neu geöffnet habe, bekomme ich keine der obrigen Meldungen..sondern gleich ein Runtime Error *seufz* Ich werde mal schauen ob ich das wieder hin bekomme.

Danke MrBurns für die Erklärung.

27. Februar 2008 11:00

Genau das mit dem Neustart des Clients wollte ich vorhin auch schon vorschlagen, als das erste mal "die Beziehung zu setdoctype" angemeckert wurde.
grundsätzlich kann man sagen, dass bei änderungen an einer SI-CU immer der Client neu gestartet werden muss, um die Änderungen testen zu können.

27. Februar 2008 11:16

Weiß jemand was an diesem Aufruf falsch sein könnte? Der führt nämlich zum besagten Runtime Error. Wenn ich ihn auskommentiere bleibt der Fehler weg. Ich habe diesen Aufruf von einer anderen Form kopiert wo das ganze reibungslos funktioniert.

Code:
Mail.NewMessage(EMail,'','Zahlungserinnerung für Bestellung '+BestNummer,'','',TRUE);


Ja den Client werde ich jetzt jedes mal neu starten sobald ich an der SI-Codeunit was ändere.