Zum Inhalt

Eingabezeilenereignis

Business Portals kann ein Ereignis auslösen, wenn in einer Zeile im Frontend eine Eingabe erfolgt. Diese Eingabe wird an Business Central gesendet, wo sie von einer benutzerdefinierten Codeunit verarbeitet werden kann, um Werte neu zu berechnen oder ein bestimmtes Ergebnis zurückzugeben.

Dieser Abschnitt bietet ein Beispiel dafür, wie man eine benutzerdefinierte Codeunit implementiert, die durch ein Ereignis basierend auf der Benutzereingabe ausgelöst wird.

Codebeispiel

In diesem Beispiel verwenden wir die Tabelle der Verkaufsauftragszeilen in einem Szenario, in dem der Benutzer eine Menge für die in einer Zeile aufgeführten Artikel eingeben kann. Die Eingabe aktualisiert den Artikelpreis, indem die Menge mit dem Stückpreis multipliziert wird.

Die Benutzereingabe löst ein Ereignis aus, indem der Wert an Business Central gesendet wird, wo er in einer Business Central-Codeunit verarbeitet wird.

AL
'INPUTLINE':
    begin
        LocalEventXmlElement := XmlElement.Create('EREIGNIS');
        LocalRootXmlElement.Add(LocalEventXmlElement);
        LocalRootXmlElement.SetAttribute('EREIGNISTYP', ParamRecordSIMDPSOL."Sub Function Event");
        LocalRootXmlElement.SetAttribute('EREIGNISWERT', LocalEventValueText);
        LocalRootXmlElement.SetAttribute('EREIGNISNACHRICHT', 'Alle Zeilen mit der gleichen Anzahl wurden abgewählt.');
        LocalRootXmlElement.SetAttribute('EREIGNISNACHRICHTTYP', 'default');
        LocalRootXmlElement.SetAttribute('EREIGNISNACHRICHTMOBILE', '');
        LocalRootXmlElement.SetAttribute('EREIGNISNACHRICHTMOBILETYP', 'default');

        if Evaluate(LocalRecordId, LocalEventValueText, 9) then
            if LocalRecordRef.Get(LocalRecordId) then begin
                LocalLineRecordSIMDPSOL.Reset();
                LocalLineRecordSIMDPSOL.SetRange("Entry No.", ParamRecordSIMDPSOL."Entry No.");
                LocalLineRecordSIMDPSOL.SetRange("Sub Entry No.", ParamRecordSIMDPSOL."Sub Entry No.");
                LocalLineRecordSIMDPSOL.SetRange("Dataset Code", ParamRecordSIMDPSOL."Dataset Code");
                LocalLineRecordSIMDPSOL.SetRange("Dataset Table Code", ParamRecordSIMDPSOL."Dataset Table Code");
                LocalLineRecordSIMDPSOL.SetRange("Dataset Table Type", ParamRecordSIMDPSOL."Dataset Table Type"::Line);
                LocalLineRecordSIMDPSOL.SetRange("Dataset Table Record", LocalRecordId);

                // Dies wird den Wert dessen abrufen, was im Frontend eingegeben wurde,
                if LocalLineRecordSIMDPSOL.FindSet() then
                    LocalInputText := GlobalCodeunitSIMDPSOrderFunctionLibrary.GetDPSOrderLineInputFieldByCode(LocalLineRecordSIMDPSOL, 'QUANTITY');

                // Filtern Sie die genaue Zeile, die das Ereignis auslöst, und holen Sie den Wert anderer Felder zur Berechnung, und geben Sie dann den Wert an das Frontend zurück. Es ist nur ein Beispiel basierend auf dem Mengenfeld, es können auch andere Felder und Berechnungen basierend auf den Anforderungen sein. Es wird empfohlen, direkt die Zeile zu holen, die das Ereignis auslöst, und den Wert nur für diese Zeile zurückzugeben, und dann die Berechnung auf der Client-Seite durchzuführen, wenn es Leistungsprobleme gibt, wenn es viele Zeilen mit der gleichen Menge gibt.
                LocalRecordRef.SetTable(LocalRecordSalesLine);
                Local2RecordSalesLine.SetRange("Document Type", LocalRecordSalesLine."Document Type");
                Local2RecordSalesLine.SetRange("Document No.", LocalRecordSalesLine."Document No.");
                Local2RecordSalesLine.SetRange("Line No.", LocalRecordSalesLine."Line No.");
                Local2RecordSalesLine.SetRange(Quantity, LocalRecordSalesLine.Quantity);
                if Local2RecordSalesLine.FindFirst() then begin
                    // Dieser Codeblock gibt den Eingabewert an das Frontend zurück.
                    LocalInfoXmlElement := XmlElement.Create('INFO');
                    LocalEventXmlElement.Add(LocalInfoXmlElement);
                    LocalInfoXmlElement.SetAttribute('VALUE', Format(Local2RecordSalesLine.RecordId, 0, 9));

                    LocalInputXmlElement := XmlElement.Create('INPUT');
                    LocalInfoXmlElement.Add(LocalInputXmlElement);
                    LocalInputXmlElement.SetAttribute('NAME', 'QUANTITY');
                    LocalInputXmlElement.SetAttribute('VALUE', LocalInputText);

                    // Dieser Codeblock gibt andere Feldwerte basierend auf dem Eingabewert an das Frontend zur Berechnung zurück. In diesem Beispiel gibt es den Stückpreis zurück und führt eine Multiplikation im Backend durch, um dann das Ergebnis an das Frontend zurückzugeben, aber es können auch andere Felder und Berechnungen basierend auf den Anforderungen sein.
                    LocalInfoXmlElement := XmlElement.Create('INFO');
                    LocalEventXmlElement.Add(LocalInfoXmlElement);
                    LocalInfoXmlElement.SetAttribute('VALUE', Format(Local2RecordSalesLine.RecordId, 0, 9));

                    LocalInputXmlElement := XmlElement.Create('INPUT');
                    LocalInfoXmlElement.Add(LocalInputXmlElement);
                    Evaluate(LocalMultiplierDecimal, LocalInputText);

                    LocalSumDecimal := LocalMultiplierDecimal * Local2RecordSalesLine."Unit Price";

                    LocalInputXmlElement.SetAttribute('NAME', 'PRICE');
                    LocalInputXmlElement.SetAttribute('VALUE', Format(LocalSumDecimal, 0, 9));
                end;
            end;
    end;

Codebeispiel 2

Mit einem ähnlichen Szenario wie im ersten Codebeispiel zeigt dieses Codebeispiel, wie man alle Zeilen aktualisiert, anstatt nur die ausgewählte Zeile

AL
'INPUTLINE':
    begin
        LocalEventXmlElement := XmlElement.Create('EVENT');
        LocalRootXmlElement.Add(LocalEventXmlElement);
        LocalRootXmlElement.SetAttribute('EVENTTYPE', ParamRecordSIMDPSOL."Sub Function Event");
        LocalRootXmlElement.SetAttribute('EVENTVALUE', LocalEventValueText);
        LocalRootXmlElement.SetAttribute('EVENTMESSAGE', 'Alle Zeilen mit der gleichen Anzahl wurden abgewählt.');
        LocalRootXmlElement.SetAttribute('EVENTMESSAGETYPE', 'default');
        LocalRootXmlElement.SetAttribute('EVENTMESSAGEMOBILE', '');
        LocalRootXmlElement.SetAttribute('EVENTMESSAGEMOBILETYPE', 'default');

        if Evaluate(LocalRecordId, LocalEventValueText, 9) then
            if LocalRecordRef.Get(LocalRecordId) then begin
                LocalLineRecordSIMDPSOL.Reset();
                LocalLineRecordSIMDPSOL.SetRange("Entry No.", ParamRecordSIMDPSOL."Entry No.");
                LocalLineRecordSIMDPSOL.SetRange("Sub Entry No.", ParamRecordSIMDPSOL."Sub Entry No.");
                LocalLineRecordSIMDPSOL.SetRange("Dataset Code", ParamRecordSIMDPSOL."Dataset Code");
                LocalLineRecordSIMDPSOL.SetRange("Dataset Table Code", ParamRecordSIMDPSOL."Dataset Table Code");
                LocalLineRecordSIMDPSOL.SetRange("Dataset Table Type", ParamRecordSIMDPSOL."Dataset Table Type"::Line);
                LocalLineRecordSIMDPSOL.SetRange("Dataset Table Record", LocalRecordId);

                // Dies wird den Wert dessen abrufen, was im Frontend eingegeben wurde,
                if LocalLineRecordSIMDPSOL.FindSet() then
                    LocalInputText := GlobalCodeunitSIMDPSOrderFunctionLibrary.GetDPSOrderLineInputFieldByCode(LocalLineRecordSIMDPSOL, 'QUANTITY');

                // Um durch alle Zeilen mit der gleichen Menge zu iterieren, kann der Code wie folgt aussehen, aber es kann Leistungsprobleme geben, wenn es viele Zeilen gibt, daher ist es besser, direkt die Zeile zu holen, die das Ereignis auslöst, und den Wert nur für diese Zeile zurückzugeben, und dann die Berechnung auf der Client-Seite durchzuführen.

                LocalRecordRef.SetTable(LocalRecordSalesLine);
                Local2RecordSalesLine.SetRange("Document Type", LocalRecordSalesLine."Document Type");
                Local2RecordSalesLine.SetRange("Document No.", LocalRecordSalesLine."Document No.");
                Local2RecordSalesLine.SetRange(Quantity, LocalRecordSalesLine.Quantity);
                if Local2RecordSalesLine.FindSet() then
                    repeat
                        LocalInfoXmlElement := XmlElement.Create('INFO');
                        LocalEventXmlElement.Add(LocalInfoXmlElement);
                        LocalInfoXmlElement.SetAttribute('VALUE', Format(Local2RecordSalesLine.RecordId, 0, 9));

                        LocalInputXmlElement := XmlElement.Create('INPUT');
                        LocalInfoXmlElement.Add(LocalInputXmlElement);
                        LocalInputXmlElement.SetAttribute('NAME', 'QUANTITY');
                        LocalInputXmlElement.SetAttribute('VALUE', LocalInputText);

                        LocalInputXmlElement := XmlElement.Create('INPUT');
                        LocalInfoXmlElement.Add(LocalInputXmlElement);
                        Evaluate(LocalMultiplierDecimal, LocalInputText);

                        LocalSumDecimal := LocalMultiplierDecimal * Local2RecordSalesLine."Unit Price";

                        LocalInputXmlElement.SetAttribute('NAME', 'PRICE');
                        LocalInputXmlElement.SetAttribute('VALUE', Format(LocalSumDecimal, 0, 9));

                    until Local2RecordSalesLine.Next() = 0;
            end
    end;

Codebeispiel 3

Mit einem ähnlichen Szenario wie im ersten Codebeispiel zeigt dieses Codebeispiel, wie die Zeilen der ausgewählten Zeile mit weiteren Feldern aktualisiert werden können sowie wie eine Aktualisierung blockiert wird, wenn ein bestimmtes Feld geändert wird.

In diesem Beispiel werden zwei zusätzliche Felder hinzugefügt, nämlich BRUTTO und NETTO. Diese Felder verwenden eine statische Dummy-Zahl, da die Standardtabelle „Sales Order Line“ diese Werte/Felder nicht in der Datenbank enthält. Diese Felder können durch beliebige andere ersetzt werden.

AL
'INPUTLINE':
    begin
        LocalEventXmlElement := XmlElement.Create('EVENT');
        LocalRootXmlElement.Add(LocalEventXmlElement);
        LocalRootXmlElement.SetAttribute('EVENTTYPE', ParamRecordSIMDPSOL."Sub Function Event");
        LocalRootXmlElement.SetAttribute('EVENTVALUE', LocalEventValueText);
        LocalRootXmlElement.SetAttribute('EVENTMESSAGE', 'Alle Zeilen mit der gleichen Anzahl wurden abgewählt.');
        LocalRootXmlElement.SetAttribute('EVENTMESSAGETYPE', 'default');
        LocalRootXmlElement.SetAttribute('EVENTMESSAGEMOBILE', '');
        LocalRootXmlElement.SetAttribute('EVENTMESSAGEMOBILETYPE', 'default');

        if Evaluate(LocalRecordId, LocalEventValueText, 9) then
            if LocalRecordRef.Get(LocalRecordId) then begin
                LocalLineRecordSIMDPSOL.Reset();
                LocalLineRecordSIMDPSOL.SetRange("Entry No.", ParamRecordSIMDPSOL."Entry No.");
                LocalLineRecordSIMDPSOL.SetRange("Sub Entry No.", ParamRecordSIMDPSOL."Sub Entry No.");
                LocalLineRecordSIMDPSOL.SetRange("Dataset Code", ParamRecordSIMDPSOL."Dataset Code");
                LocalLineRecordSIMDPSOL.SetRange("Dataset Table Code", ParamRecordSIMDPSOL."Dataset Table Code");
                LocalLineRecordSIMDPSOL.SetRange("Dataset Table Type", ParamRecordSIMDPSOL."Dataset Table Type"::Line);
                LocalLineRecordSIMDPSOL.SetRange("Dataset Table Record", LocalRecordId);

                // Dies holt den Wert, der im Frontend eingegeben wurde
                if LocalLineRecordSIMDPSOL.FindSet() then
                    LocalQuantityInputText := GlobalCodeunitSIMDPSOrderFunctionLibrary.GetDPSOrderLineInputFieldByCode(LocalLineRecordSIMDPSOL, 'QUANTITY');
                if LocalLineRecordSIMDPSOL.FindSet() then
                    LocalBruttoInputText := GlobalCodeunitSIMDPSOrderFunctionLibrary.GetDPSOrderLineInputFieldByCode(LocalLineRecordSIMDPSOL, 'BRUTTO');
                if LocalLineRecordSIMDPSOL.FindSet() then
                    LocalNettoInputText := GlobalCodeunitSIMDPSOrderFunctionLibrary.GetDPSOrderLineInputFieldByCode(LocalLineRecordSIMDPSOL, 'NETTO');
                if LocalLineRecordSIMDPSOL.FindSet() then
                    LocalPriceInputText := GlobalCodeunitSIMDPSOrderFunctionLibrary.GetDPSOrderLineInputFieldByCode(LocalLineRecordSIMDPSOL, 'PRICE');

                // Absicherung für leere Eingaben: Wenn die Eingabe leer ist, wird sie in Berechnungen als 0 behandelt. Dies gilt für numerische Eingaben; bei Texteingaben kann sie als leerer String behandelt werden und muss nicht in 0 umgewandelt werden.
                if LocalQuantityInputText = '' then
                    LocalQuantityInputText := '0';
                if LocalBruttoInputText = '' then
                    LocalBruttoInputText := '0';
                if LocalNettoInputText = '' then
                    LocalNettoInputText := '0';
                if LocalPriceInputText = '' then
                    LocalPriceInputText := '0';

                // Filtert exakt die Zeile, die das Ereignis ausgelöst hat, und holt die Werte anderer Felder zur Berechnung, anschließend wird der Wert an das Frontend zurückgegeben. Dies ist nur ein Beispiel basierend auf dem Feld Quantity; es kann sich um beliebige andere Felder und Berechnungen gemäß Anforderungen handeln. Es wird empfohlen, direkt die auslösende Zeile zu verwenden und nur deren Wert zurückzugeben und die Berechnung clientseitig durchzuführen, falls es Performanceprobleme bei vielen Zeilen mit gleicher Quantity gibt.
                LocalRecordRef.SetTable(LocalRecordSalesLine);
                Local2RecordSalesLine.SetRange("Document Type", LocalRecordSalesLine."Document Type");
                Local2RecordSalesLine.SetRange("Document No.", LocalRecordSalesLine."Document No.");
                Local2RecordSalesLine.SetRange("Line No.", LocalRecordSalesLine."Line No.");
                Local2RecordSalesLine.SetRange(Quantity, LocalRecordSalesLine.Quantity);
                if Local2RecordSalesLine.FindFirst() then begin
                    // Dieser Codeblock gibt den Eingabewert an das Frontend zurück
                    LocalInfoXmlElement := XmlElement.Create('INFO');
                    LocalEventXmlElement.Add(LocalInfoXmlElement);
                    LocalInfoXmlElement.SetAttribute('VALUE', Format(Local2RecordSalesLine.RecordId, 0, 9));

                    LocalInputXmlElement := XmlElement.Create('INPUT');
                    LocalInfoXmlElement.Add(LocalInputXmlElement);
                    LocalInputXmlElement.SetAttribute('NAME', 'QUANTITY');
                    LocalInputXmlElement.SetAttribute('VALUE', LocalQuantityInputText);

                    // Wert der Eingabe auswerten und in lokale Variablen übertragen
                    Evaluate(LocalMultiplierDecimal, LocalQuantityInputText);
                    Evaluate(LocalBruttoDecimal, LocalBruttoInputText);
                    Evaluate(LocalNettoDecimal, LocalNettoInputText);
                    Evaluate(LocalPriceDecimal, LocalPriceInputText);

                    //PRICE
                    // Dieser Codeblock gibt andere Feldwerte basierend auf dem Eingabewert zur Berechnung an das Frontend zurück. In diesem Beispiel wird der Unit Price verwendet und serverseitig multipliziert, dann das Ergebnis an das Frontend zurückgegeben. Es können jedoch beliebige Felder und Berechnungen gemäß Anforderungen verwendet werden.
                    LocalInfoXmlElement := XmlElement.Create('INFO');
                    LocalEventXmlElement.Add(LocalInfoXmlElement);
                    LocalInfoXmlElement.SetAttribute('VALUE', Format(Local2RecordSalesLine.RecordId, 0, 9));

                    LocalInputXmlElement := XmlElement.Create('INPUT');
                    LocalInfoXmlElement.Add(LocalInputXmlElement);

                    LocalSumDecimal := LocalMultiplierDecimal * Local2RecordSalesLine."Unit Price";

                    if LocalPriceDecimal <> LocalSumDecimal then
                        LocalQuantityChangeBoolean := true;

                    LocalInputXmlElement.SetAttribute('NAME', 'PRICE');
                    LocalInputXmlElement.SetAttribute('VALUE', Format(LocalSumDecimal, 0, 9));

                    // Prüfen, ob das Feld QUANTITY geändert wurde oder andere Felder nicht initialisiert sind; dann werden berechnete BRUTTO- und NETTO-Werte zurückgegeben, andernfalls werden die eingegebenen Werte ohne Berechnung zurückgegeben
                    if LocalQuantityChangeBoolean or (LocalBruttoDecimal = 0) or (LocalNettoDecimal = 0) then begin
                        //BRUTTO
                        // Dieser Codeblock gibt den Eingabewert an das Frontend zurück
                        LocalInfoXmlElement := XmlElement.Create('INFO');
                        LocalEventXmlElement.Add(LocalInfoXmlElement);
                        LocalInfoXmlElement.SetAttribute('VALUE', Format(Local2RecordSalesLine.RecordId, 0, 9));

                        LocalInputXmlElement := XmlElement.Create('INPUT');
                        LocalInfoXmlElement.Add(LocalInputXmlElement);

                        // Die Berechnungslogik dient nur als Beispiel und kann je nach Anforderungen angepasst werden
                        // Berechnet den Multiplikator basierend auf der eingegebenen QUANTITY und multipliziert ihn mit einem Wert (hier 10), um den BRUTTO-Wert zu erhalten. Wenn QUANTITY geändert wurde oder BRUTTO nicht initialisiert ist, wird dieser Wert verwendet; andernfalls wird der eingegebene BRUTTO-Wert ohne Berechnung zurückgegeben.
                        LocalSumDecimal := LocalMultiplierDecimal * 10;
                        if not LocalQuantityChangeBoolean then
                            if (LocalBruttoDecimal <> LocalSumDecimal) and (LocalBruttoDecimal <> 0) then
                                LocalSumDecimal := LocalBruttoDecimal;

                        LocalInputXmlElement.SetAttribute('NAME', 'BRUTTO');
                        LocalInputXmlElement.SetAttribute('VALUE', Format(LocalSumDecimal, 0, 9));

                        //NETTO
                        // Dieser Codeblock gibt den Eingabewert an das Frontend zurück
                        LocalInfoXmlElement := XmlElement.Create('INFO');
                        LocalEventXmlElement.Add(LocalInfoXmlElement);
                        LocalInfoXmlElement.SetAttribute('VALUE', Format(Local2RecordSalesLine.RecordId, 0, 9));

                        LocalInputXmlElement := XmlElement.Create('INPUT');
                        LocalInfoXmlElement.Add(LocalInputXmlElement);

                        // Die Berechnungslogik dient nur als Beispiel und kann je nach Anforderungen angepasst werden
                        // Berechnet den Multiplikator basierend auf der eingegebenen QUANTITY und multipliziert ihn mit einem Wert (hier 5), um den NETTO-Wert zu erhalten. Wenn QUANTITY geändert wurde oder NETTO nicht initialisiert ist, wird dieser Wert verwendet; andernfalls wird der eingegebene NETTO-Wert ohne Berechnung zurückgegeben.
                        LocalSumDecimal := LocalMultiplierDecimal * 5;

                        if not LocalQuantityChangeBoolean then
                            if (LocalNettoDecimal <> LocalSumDecimal) and (LocalNettoDecimal <> 0) then
                                LocalSumDecimal := LocalNettoDecimal;

                        LocalInputXmlElement.SetAttribute('NAME', 'NETTO');
                        LocalInputXmlElement.SetAttribute('VALUE', Format(LocalSumDecimal, 0, 9));
                    end;
                end;
            end;
        end;