Anhang Download
Diese Dokumentation bietet umfassende Anleitung für externe AL-Entwickler zum Abrufen und Herunterladen einzelner Anhänge aus DXP Freeze für verknüpfte Business Central Datensätze.
Überblick
Die DXP Freeze Result Management Codeunit bietet Methoden zum direkten Zugriff auf einzelne Anhänge archivierter Datensätze:
GetAttachments- Lädt Metadaten aller Anhänge eines DatensatzesGetSpecificRecordAttachment- Lädt den Inhalt eines spezifischen Anhangs als Base64- Kombinierte Verwendung ermöglicht gezielte Filterung und Download einzelner Dateien
Diese Methoden ermöglichen präzise Kontrolle über welche Anhänge abgerufen werden und wie sie verarbeitet werden, ohne ZIP-Archive zu erstellen.
Methode 1: GetAttachments
Zweck
Ruft Metadaten aller Anhänge eines archivierten Datensatzes ab. Diese Methode füllt einen temporären DXP FRZ Attachment Result Record mit Informationen über verfügbare Anhänge ohne den eigentlichen Dateiinhalt herunterzuladen.
Verfügbare Überladungen
1. Standard-Verwendung
procedure GetAttachments(RecordHeaderID: Guid; RecordHeaderFileLink: Text[2048]; var TempFrzAttachmentResult: Record "DXP FRZ Attachment Result" temporary)
2. Mit Kontrolle über Datenlöschung
procedure GetAttachments(RecordHeaderID: Guid; RecordHeaderFileLink: Text[2048]; var TempFrzAttachmentResult: Record "DXP FRZ Attachment Result" temporary; ClearAttachmentTable: Boolean)
Parameter
| Parameter | Typ | Beschreibung |
|---|---|---|
RecordHeaderID |
Guid | Eindeutige ID des Freeze-Datensatzes |
RecordHeaderFileLink |
Text[2048] | API-Link zum Datensatz (aus DXP FRZ Record Result Header."File Link") |
TempFrzAttachmentResult |
Record (temporary, var) | Temporärer Record, der mit Anhang-Metadaten gefüllt wird |
ClearAttachmentTable |
Boolean | true = Record vor Befüllung löschen; false = zu bestehenden Einträgen hinzufügen |
Rückgabewert
Keine - Die Methode füllt den übergebenen temporären Record mit Anhang-Metadaten.
Anhang-Metadaten-Felder
Jeder Eintrag in TempFrzAttachmentResult enthält:
| Feld | Beschreibung |
|---|---|
ID |
Eindeutige Anhang-ID (Guid) |
Record Header Id |
Verknüpfung zum übergeordneten Datensatz |
Filename |
Dateiname mit Erweiterung |
File Extension |
Dateierweiterung (automatisch aus Filename extrahiert) |
Filesize |
Größe in Bytes |
Author |
Ersteller des Anhangs |
Archived at |
Archivierungszeitpunkt |
File Link |
API-Link zum Datensatz |
Verwendungsbeispiel
procedure ListAttachmentsForSalesInvoice(SalesInvoiceNo: Code[20])
var
SalesInvoiceHeader: Record "Sales Invoice Header";
TempFrzResultQueryHeader: Record "DXP FRZ Query Result Header" temporary;
TempFrzResultRecordHeader: Record "DXP FRZ Record Result Header" temporary;
TempFrzResultRecordField: Record "DXP FRZ Result Record-Field" temporary;
TempFrzAttachmentResult: Record "DXP FRZ Attachment Result" temporary;
FrzSearchMgt: Codeunit "DXP Freeze Search Mgt.";
FrzResultMgt: Codeunit "DXP FRZ Result Mgt.";
FrzApiMgt: Codeunit "DXP Freeze API Mgt.";
QueryResult: JsonObject;
SearchQuery: Text;
begin
if not SalesInvoiceHeader.Get(SalesInvoiceNo) then
Error('Rechnung %1 nicht gefunden.', SalesInvoiceNo);
// Suchanfrage für diesen Datensatz erstellen
SearchQuery := FrzSearchMgt.GetSearchCombinationForTable(
SalesInvoiceHeader.SystemId,
Database::"Sales Invoice Header"
);
// Freeze durchsuchen
QueryResult := FrzApiMgt.SubmitSearch(SearchQuery);
// Ergebnisse verarbeiten - dies füllt den Record Header
FrzResultMgt.CreateResult(
QueryResult,
TempFrzResultQueryHeader,
TempFrzResultRecordHeader,
TempFrzResultRecordField,
TempFrzAttachmentResult,
SearchQuery
);
// Prüfen ob Datensatz gefunden wurde
if TempFrzResultRecordHeader.FindFirst() then begin
// Anhänge für diesen Record Header abrufen
FrzResultMgt.GetAttachments(
TempFrzResultRecordHeader.ID,
TempFrzResultRecordHeader."File Link",
TempFrzAttachmentResult
);
// Anhänge durchlaufen
if TempFrzAttachmentResult.FindSet() then
repeat
//Verarbeitung der Anhänge
until TempFrzAttachmentResult.Next() = 0;
end else
Message('Keine archivierten Anhänge für Rechnung %1 gefunden.', SalesInvoiceNo);
end;
Methode 2: GetSpecificRecordAttachment (Freeze API Mgt.)
Zweck
Lädt den tatsächlichen Inhalt eines spezifischen Anhangs als Base64-kodierten String herunter. Diese Methode wird typischerweise nach GetAttachments verwendet, um ausgewählte Anhänge herunterzuladen.
Verfügbare Überladungen
1. Mit automatischem Browser-Download
procedure GetSpecificRecordAttachment(FileLink: Text; AttachmentID: Guid; pFileName: Text): Text
2. Mit Kontrolle über Browser-Download
procedure GetSpecificRecordAttachment(FileLink: Text; AttachmentID: Guid; pFileName: Text; DownloadFromStream: Boolean): Text
Parameter
| Parameter | Typ | Beschreibung |
|---|---|---|
FileLink |
Text | API-Link zum Datensatz (aus TempFrzAttachmentResult."File Link") |
AttachmentID |
Guid | Eindeutige Anhang-ID (aus TempFrzAttachmentResult.ID) |
pFileName |
Text | Dateiname für Download (aus TempFrzAttachmentResult.Filename) |
DownloadFromStream |
Boolean | true = Sofortiger Browser-Download; false = Nur Base64 zurückgeben |
Rückgabewert
Text: Base64-kodierter Inhalt der Datei- Leerer String wenn Anhang nicht gefunden oder Fehler auftritt
Verwendungsbeispiele
Beispiel 1: Einzelnen Anhang sofort herunterladen
procedure DownloadFirstPDFAttachment(SalesInvoiceNo: Code[20])
var
SalesInvoiceHeader: Record "Sales Invoice Header";
TempFrzResultRecordHeader: Record "DXP FRZ Record Result Header" temporary;
TempFrzResultRecordField: Record "DXP FRZ Result Record-Field" temporary;
TempFrzResultQueryHeader: Record "DXP FRZ Query Result Header" temporary;
TempFrzAttachmentResult: Record "DXP FRZ Attachment Result" temporary;
FrzSearchMgt: Codeunit "DXP Freeze Search Mgt.";
FrzResultMgt: Codeunit "DXP FRZ Result Mgt.";
FrzApiMgt: Codeunit "DXP Freeze API Mgt.";
QueryResult: JsonObject;
SearchQuery: Text;
begin
if not SalesInvoiceHeader.Get(SalesInvoiceNo) then
Error('Rechnung %1 nicht gefunden.', SalesInvoiceNo);
// Suchanfrage erstellen
SearchQuery := FrzSearchMgt.GetSearchCombinationForTable(
SalesInvoiceHeader.SystemId,
Database::"Sales Invoice Header"
);
// Freeze durchsuchen
QueryResult := FrzApiMgt.SubmitSearch(SearchQuery);
// Ergebnisse verarbeiten
FrzResultMgt.CreateResult(
QueryResult,
TempFrzResultQueryHeader,
TempFrzResultRecordHeader,
TempFrzResultRecordField,
TempFrzAttachmentResult,
SearchQuery
);
// Nach PDF-Anhängen filtern
TempFrzAttachmentResult.SetRange("File Extension", 'pdf');
if TempFrzAttachmentResult.FindFirst() then begin
// Direkter Download im Browser
FrzApiMgt.GetSpecificRecordAttachment(
TempFrzAttachmentResult."File Link",
TempFrzAttachmentResult.ID,
TempFrzAttachmentResult.Filename
);
Message('PDF-Anhang %1 wird heruntergeladen.', TempFrzAttachmentResult.Filename);
end else
Message('Keine PDF-Anhänge für Rechnung %1 gefunden.', SalesInvoiceNo);
end;
Beispiel 2: Base64-Inhalt für weitere Verarbeitung
procedure GetAttachmentAsBase64(RecordRef: RecordRef; var AttachmentBase64: Text; var AttachmentFilename: Text): Boolean
var
TempFrzResultRecordHeader: Record "DXP FRZ Record Result Header" temporary;
TempFrzResultRecordField: Record "DXP FRZ Result Record-Field" temporary;
TempFrzResultQueryHeader: Record "DXP FRZ Query Result Header" temporary;
TempFrzAttachmentResult: Record "DXP FRZ Attachment Result" temporary;
FrzSearchMgt: Codeunit "DXP Freeze Search Mgt.";
FrzResultMgt: Codeunit "DXP FRZ Result Mgt.";
FrzApiMgt: Codeunit "DXP Freeze API Mgt.";
SystemIdFieldRef: FieldRef;
QueryResult: JsonObject;
SystemId: Guid;
SearchQuery: Text;
begin
// SystemId aus RecordRef extrahieren
SystemIdFieldRef := RecordRef.Field(RecordRef.SystemIdNo());
SystemId := SystemIdFieldRef.Value();
// Suchanfrage erstellen
SearchQuery := FrzSearchMgt.GetSearchCombinationForTable(SystemId, RecordRef.Number());
// Freeze durchsuchen
QueryResult := FrzApiMgt.SubmitSearch(SearchQuery);
// Ergebnisse verarbeiten
FrzResultMgt.CreateResult(
QueryResult,
TempFrzResultQueryHeader,
TempFrzResultRecordHeader,
TempFrzResultRecordField,
TempFrzAttachmentResult,
SearchQuery
);
if TempFrzAttachmentResult.FindFirst() then begin
// Base64-Inhalt abrufen OHNE Browser-Download
AttachmentBase64 := FrzApiMgt.GetSpecificRecordAttachment(
TempFrzAttachmentResult."File Link",
TempFrzAttachmentResult.ID,
TempFrzAttachmentResult.Filename,
false // Kein automatischer Download
);
AttachmentFilename := TempFrzAttachmentResult.Filename;
exit(AttachmentBase64 <> '');
end;
exit(false);
end;
Spezialszenario: Ältesten PDF-Anhang herunterladen
Dieses Beispiel zeigt, wie Sie den ältesten (zuerst archivierten) PDF-Anhang eines Datensatzes finden und herunterladen.
Vollständiges Beispiel
procedure DownloadOldestPDFAttachment(RecordVariant: Variant): Boolean
var
TempFrzResultRecordHeader: Record "DXP FRZ Record Result Header" temporary;
TempFrzResultRecordField: Record "DXP FRZ Result Record-Field" temporary;
TempFrzResultQueryHeader: Record "DXP FRZ Query Result Header" temporary;
TempFrzAttachmentResult: Record "DXP FRZ Attachment Result" temporary;
FrzSearchMgt: Codeunit "DXP Freeze Search Mgt.";
FrzResultMgt: Codeunit "DXP FRZ Result Mgt.";
FrzApiMgt: Codeunit "DXP Freeze API Mgt.";
RecordRef: RecordRef;
SystemIdFieldRef: FieldRef;
QueryResult: JsonObject;
SystemId: Guid;
SearchQuery: Text;
OldestArchiveDate: DateTime;
AttachmentBase64: Text;
begin
// RecordRef aus Variant erstellen
RecordRef.GetTable(RecordVariant);
// SystemId extrahieren
SystemIdFieldRef := RecordRef.Field(RecordRef.SystemIdNo());
SystemId := SystemIdFieldRef.Value();
// Suchanfrage für diesen Datensatz erstellen
SearchQuery := FrzSearchMgt.GetSearchCombinationForTable(SystemId, RecordRef.Number());
// Freeze durchsuchen
QueryResult := FrzApiMgt.SubmitSearch(SearchQuery);
// Ergebnisse mit Anhängen abrufen
FrzResultMgt.CreateResult(
QueryResult,
TempFrzResultQueryHeader,
TempFrzResultRecordHeader,
TempFrzResultRecordField,
TempFrzAttachmentResult,
SearchQuery
);
// Nach PDF-Anhängen filtern
TempFrzAttachmentResult.SetRange("File Extension", 'pdf');
if TempFrzAttachmentResult.IsEmpty() then begin
Message('Keine PDF-Anhänge für diesen Datensatz gefunden.');
exit(false);
end;
// Nach Archivierungsdatum aufsteigend sortieren (älteste zuerst)
TempFrzAttachmentResult.SetCurrentKey("Archived at");
TempFrzAttachmentResult.Ascending(true);
// Ersten (ältesten) Anhang abrufen
if TempFrzAttachmentResult.FindFirst() then begin
OldestArchiveDate := TempFrzAttachmentResult."Archived at";
Message('Ältester PDF-Anhang gefunden:\Datei: %1\Größe: %2 KB\Archiviert am: %3\Autor: %4',
TempFrzAttachmentResult.Filename,
Round(TempFrzAttachmentResult.Filesize / 1024, 1),
OldestArchiveDate,
TempFrzAttachmentResult.Author);
// Anhang herunterladen
AttachmentBase64 := FrzApiMgt.GetSpecificRecordAttachment(
TempFrzAttachmentResult."File Link",
TempFrzAttachmentResult.ID,
TempFrzAttachmentResult.Filename,
true // Sofortiger Browser-Download
);
exit(AttachmentBase64 <> '');
end;
exit(false);
end;
Verwendung des Beispiels
// Von einer Verkaufsrechnung aus
var
SalesInvoiceHeader: Record "Sales Invoice Header";
begin
SalesInvoiceHeader.Get('SI-001');
DownloadOldestPDFAttachment(SalesInvoiceHeader);
end;
// Von einer gebuchten Einkaufsrechnung aus
var
PurchInvHeader: Record "Purch. Inv. Header";
begin
PurchInvHeader.Get('PI-001');
DownloadOldestPDFAttachment(PurchInvHeader);
end;
Zusammenfassung
Typischer Workflow
- Datensatz identifizieren: SystemId und TableNo des BC-Datensatzes ermitteln
- Suchanfrage erstellen:
FrzSearchMgt.GetSearchCombinationForTable() - Freeze durchsuchen:
FrzApiMgt.SubmitSearch() - Ergebnisse verarbeiten:
FrzResultMgt.CreateResult() - Anhänge filtern: Filter auf
TempFrzAttachmentResultsetzen - Anhänge herunterladen:
FrzApiMgt.GetSpecificRecordAttachment()
No Comments