Zum Inhalt

Beispiel für Report over Codeunit

Die Codeunit 5138176 "SIM_DPS Sample Report over CU" zeigt, wie der Business-Portals-Action-Typ Report over Codeunit über benutzerdefinierte Logik einen Datensatz auswählt und einen Business-Central-Bericht als PDF-Download zurückgibt.

Das Beispiel verwendet SIM_DPS OL, ermittelt einen Datensatz, wendet gespeicherte Berichtseinstellungen an, rendert den Bericht in SIM_DPS OL."File Blob" und stellt ihn dem Frontend bereit.

Verwendung von Report over Codeunit

Eine normale Report-Action führt einen Bericht für den Dataset-Datensatz aus. Verwenden Sie Report over Codeunit, wenn AL-Logik entscheiden soll, welcher Datensatz an den Bericht übergeben wird.

Funktion Datensatzquelle
PrintOrderConfirmation Liest eine Datensatz-ID aus dem Action-Eingabefeld SALESORDER.
PrintOrderConfirmationFromTable Verwendet SIM_DPS OL."Dataset Table Record".

Funktionsermittlung und Dispatch

Ohne Action-Code verwendet OnRun den Standardwert GETFUNCTIONS und gibt beide Funktionsnamen kommagetrennt zurück.

AL
'GETFUNCTIONS':
    Rec."Function List" := 'PrintOrderConfirmation,PrintOrderConfirmationFromTable';

Während der Ausführung lädt OnRun die Dataset-Tabellen-Action und die zugehörige Action. Deren Param bestimmt die auszuführende Prozedur.

Berichtsdatensatz ermitteln

Aus einem Eingabefeld

PrintOrderConfirmation liest SALESORDER und wertet den Inhalt als Business-Central-RecordId aus. Der Wert muss eine formatierte RecordId sein, nicht nur eine Auftragsnummer wie SO-1001. Fehlende oder ungültige Werte führen bei Evaluate zu einem Fehler.

Aus der Dataset-Tabelle

PrintOrderConfirmationFromTable übergibt Dataset Table Record direkt an PrintReport. Verwenden Sie diese Funktion, wenn Berichts- und Dataset-Datensatz identisch sind.

PDF erstellen

PrintReport:

  1. Öffnet die übergebene ID als RecordRef.
  2. Filtert sie mit SIM_DPS Order Function Library.FilterRecRefByKey nach dem Primärschlüssel.
  3. Lädt SIM_DPS Action anhand von Action Code.
  4. Liest optionales Request-Page-XML aus Report Settings.
  5. Leert File Blob und erstellt den Ausgabestream.
  6. Ruft Report.SaveAs mit Report ID, PDF-Format, Einstellungen und gefiltertem Datensatz auf.

Danach liest Business Portals File Blob, konvertiert das PDF in Base64 und gibt es als Download zurück. Dateiname und Platzhalter werden über die Dataset-Tabellen-Action gesteuert.

Konfiguration

  1. Öffnen Sie die Actions der erforderlichen Dataset-Tabelle.
  2. Erstellen Sie eine Action und setzen Sie Type auf Report over Codeunit.
  3. Setzen Sie ID auf 5138176 oder die ID der kundenspezifischen Kopie.
  4. Wählen Sie in Param PrintOrderConfirmation oder PrintOrderConfirmationFromTable.
  5. Wählen Sie den Bericht in Report Caption oder setzen Sie Report ID.
  6. Speichern Sie optional über Set Report Settings Filter und Request-Page-Optionen.
  7. Konfigurieren Sie Dateiname und Platzhalter.
  8. Für PrintOrderConfirmation konfigurieren Sie SALESORDER mit einer gültigen RecordId.

Der Bericht muss die Tabelle des ermittelten Datensatzes unterstützen und für unbeaufsichtigtes Report.SaveAs geeignet sein.

Implementierungshinweise

  • Behalten Sie TableNo = "SIM_DPS OL" bei und ergänzen Sie Funktionen in GETFUNCTIONS und der case-Anweisung.
  • Business Portals übergibt den Action-Kontext über Rec.
  • Validieren Sie Eingaben, Action Code, Report ID und Datensatz.
  • Das Beispiel wiederholt denselben Report.SaveAs-Aufruf bis zu dreimal und beendet sich ohne spezifischen Fehler. Ersetzen Sie dies durch geeignete Fehlerbehandlung und Protokollierung.
  • Da File Blob vor dem Rendern geleert wird, bleibt nach einem Fehler keine vorherige Datei erhalten.
  • Testen Sie gespeicherte Einstellungen nach Änderungen an Layout, Request Page oder Business-Central-Version.
  • Prüfen Sie Berechtigungen und vermeiden Sie interaktive Berichtslogik.

Vollständiger Beispielcode

AL
codeunit 5138176 "SIM_DPS Sample Report over CU"
{
    TableNo = "SIM_DPS OL";

    trigger OnRun()
    var
        LocalRecordSIMDPSDTAction: Record "SIM_DPS DT Action";
        LocalRecordSIMDPSAction: Record "SIM_DPS Action";
        LocalParamText: Text;
    begin
        LocalParamText := 'GETFUNCTIONS';

        if Rec."Action Code" <> '' then begin
            if not LocalRecordSIMDPSDTAction.Get(Rec."Dataset Code", Rec."Dataset Table Code", Rec."Dataset Table Type", Rec."Action Code") then exit;
            if not LocalRecordSIMDPSAction.Get(LocalRecordSIMDPSDTAction."Action Code") then exit;
            LocalParamText := LocalRecordSIMDPSAction.Param;
        end;

        case LocalParamText of
            'PrintOrderConfirmation':
                PrintOrderConfirmation(Rec);

            'PrintOrderConfirmationFromTable':
                PrintOrderConfirmationFromTable(Rec);

            'GETFUNCTIONS':
                Rec."Function List" := 'PrintOrderConfirmation,PrintOrderConfirmationFromTable';
        end;
    end;

    var
        GlobalCodeunitSIMDPSOrderFunctionLibrary: Codeunit "SIM_DPS Order Function Library";
        GlobalRecIdLabelErr: Label 'You have not selected a valid record.';

    procedure PrintOrderConfirmation(var ParamRecordSIMDPSOL: Record "SIM_DPS OL")
    var
        LocalRecordId: RecordId;
    begin
        Evaluate(LocalRecordId, Format(GlobalCodeunitSIMDPSOrderFunctionLibrary.GetDPSOrderLineInputFieldByCode(ParamRecordSIMDPSOL, 'SALESORDER')));
        PrintReport(ParamRecordSIMDPSOL, LocalRecordId);
    end;

    procedure PrintOrderConfirmationFromTable(var ParamRecordSIMDPSOL: Record "SIM_DPS OL")
    var
        LocalRecordId: RecordId;
    begin
        LocalRecordId := ParamRecordSIMDPSOL."Dataset Table Record";
        PrintReport(ParamRecordSIMDPSOL, LocalRecordId);
    end;

    procedure PrintReport(var ParamRecordSIMDPSOL: Record "SIM_DPS OL"; ParamRecordId: RecordId)
    var
        LocalRecordSIMDPSAction: Record "SIM_DPS Action";
        LocalRecordRef: RecordRef;
        Local2RecordRef: RecordRef;
        LocalVariant: Variant;
        LocalReportRequestPageText: Text;
        LocalInStream: InStream;
        LocalOutStream: OutStream;
    begin
        if LocalRecordRef.Get(ParamRecordId) then begin
            GlobalCodeunitSIMDPSOrderFunctionLibrary.FilterRecRefByKey(LocalRecordRef, Local2RecordRef);
            LocalVariant := Local2RecordRef;

            if LocalRecordSIMDPSAction.Get(ParamRecordSIMDPSOL."Action Code") then begin
                LocalReportRequestPageText := '';
                if LocalRecordSIMDPSAction."Report Settings".HasValue() then begin
                    LocalRecordSIMDPSAction.CalcFields("Report Settings");
                    LocalRecordSIMDPSAction."Report Settings".CreateInStream(LocalInStream);
                    LocalInStream.Read(LocalReportRequestPageText);
                end;

                Clear(LocalOutStream);
                Clear(ParamRecordSIMDPSOL."File Blob");
                ParamRecordSIMDPSOL."File Blob".CreateOutStream(LocalOutStream);
                if not Report.SaveAs(LocalRecordSIMDPSAction."Report ID", LocalReportRequestPageText, ReportFormat::Pdf, LocalOutStream, LocalVariant) then
                    if not Report.SaveAs(LocalRecordSIMDPSAction."Report ID", LocalReportRequestPageText, ReportFormat::Pdf, LocalOutStream, LocalVariant) then
                        if not Report.SaveAs(LocalRecordSIMDPSAction."Report ID", LocalReportRequestPageText, ReportFormat::Pdf, LocalOutStream, LocalVariant) then
                            exit;
            end;
        end else
            Error(GlobalRecIdLabelErr);
    end;
}