Brief mit Empfänger aus einer Adressdatenquelle
Ein Sachbearbeiter erstellt einen Brief und wählt den Empfänger im Forms-Dialog aus einer zentralen Adressdatenquelle, hier einer CSV-Datei auf einem Fileshare. Die Adresse erscheint als fertig formatierter Adressblock im Brief. Wird der Empfänger nicht gefunden, erfasst ihn der Sachbearbeiter von Hand.
Ergebnis
- Forms-Dialog: Suche nach Name und Ort in der Adressdatenquelle, Treffer übernehmen oder Empfänger manuell erfassen; dazu Betreff und Datum.
- Adressblock im Brief: Firma oder Vor- und Nachname, Strasse, PLZ und Ort; das Land nur bei Empfängern ausserhalb der Schweiz.
- Die Adressdatenquelle ist austauschbar (SQL, HTTP, Excel), ohne Änderung an Field und Vorlage.
Bausteine
| Baustein | Aufgabe in diesem Beispiel | Referenz |
|---|---|---|
| Forms (Inhaltsvorlage) | Object Recipient mit Schema, Trefferliste und DataProvider; dazu Betreff und Datum | Forms |
| CsvDataProvider | sucht in der CSV-Datei und bildet ihre Spalten auf das Schema ab | CsvDataProvider |
| Fields (Inhaltsvorlage) | Text-Field RecipientAddressBlock formatiert die Adresse | Fields |
| Word-Inhaltsvorlage | Field und Forms-Felder über «Feld binden» einfügen | Zugriff auf primedocs-Felder |
Datenfluss
Schritt 1: Forms mit Empfänger-Objekt und Adressdatenquelle
In der Inhaltsvorlage die Dokumentfunktion Forms aktivieren:
<FormsConfiguration>
<Elements>
<Object Id="Recipient" Label="Empfänger" Required="true">
<Schema>
<Text Id="CompanyName" Label="Firma" />
<Text Id="FirstName" Label="Vorname" />
<Text Id="LastName" Label="Name" />
<Text Id="Street" Label="Strasse" />
<Text Id="PostalCode" Label="PLZ" />
<Text Id="City" Label="Ort" />
<Text Id="Country" Label="Land" />
</Schema>
<Summary>
<Field Id="CompanyName" />
<Field Id="FirstName" />
<Field Id="LastName" />
<Field Id="City" />
</Summary>
<DataProviders>
<CsvDataProvider DisplayName="Adressen">
<Options>
<FilePath>\\fileserver\primedocs\addresses.csv</FilePath>
<HasHeaders>true</HasHeaders>
<Delimiter>;</Delimiter>
</Options>
<SearchParameters>
<!-- Id = Spaltenname in der CSV-Datei -->
<Text Id="Name" Label="Name" />
<Text Id="Ort" Label="Ort" />
</SearchParameters>
<Mapping>
<!-- Source = Spaltenname in der CSV-Datei, Target = Id im Schema -->
<Map Source="Firma" Target="CompanyName" />
<Map Source="Vorname" Target="FirstName" />
<Map Source="Name" Target="LastName" />
<Map Source="Strasse" Target="Street" />
<Map Source="PLZ" Target="PostalCode" />
<Map Source="Ort" Target="City" />
<Map Source="Land" Target="Country" />
</Mapping>
</CsvDataProvider>
</DataProviders>
</Object>
<Text Id="Subject" Label="Betreff" Required="true" />
<Date Id="Date" Label="Datum" Format="d. MMMM yyyy" RelativeDate="Today" />
</Elements>
</FormsConfiguration>
Schemadefiniert die Felder jedes Empfängers, unabhängig von der Quelle.Summarybestimmt die Spalten der Trefferliste im Dialog.SearchParameterssind die Suchfelder; ihreIdist der Spaltenname in der CSV-Datei.Mappingverbindet Spalten (Source) mit Schema-Ids (Target).Required="true"verhindert einen Brief ohne Empfänger.
Die Beschriftungen stehen direkt im Label, damit die Konfiguration ohne Vorarbeit läuft. Für mehrsprachige Vorlagen stattdessen translate-Label und translate-Format mit Schlüsseln aus den globalen Übersetzungen verwenden.
Warum ein Object: Es fasst die Adressfelder zu einem Empfänger zusammen, an dem der DataProvider hängt. Wird die Quelle ausgetauscht, ändert sich nur der Block DataProviders; Schema, Field und Vorlage bleiben gleich.
Schritt 2: Field für den Adressblock
In der Inhaltsvorlage die Dokumentfunktion Fields aktivieren:
<FieldsConfiguration>
<Fields>
<Text Name="RecipientAddressBlock">
<Code><![CDATA[
function main() {
const recipient = $("Forms.Recipient");
if (!recipient) {
return "";
}
const name = recipient.CompanyName
? recipient.CompanyName
: $.joinNonEmpty(" ", recipient.FirstName, recipient.LastName);
const country = recipient.Country && recipient.Country !== "CH" ? recipient.Country : "";
return $.joinNonEmpty("\n",
name,
recipient.Street,
$.joinNonEmpty(" ", recipient.PostalCode, recipient.City),
country);
}
]]></Code>
</Text>
</Fields>
</FieldsConfiguration>
Warum ein Field: Ein Object lässt sich nicht direkt ins Dokument einfügen. Das Field liefert den fertigen Text; $.joinNonEmpty lässt leere Zeilen weg, etwa bei Personen ohne Firma oder Adressen ohne Land.
Schritt 3: Felder in der Word-Vorlage binden
- Die Inhaltsvorlage im Editor öffnen.
- Den Cursor an die Stelle des Adressblocks setzen, auf «Feld binden» klicken und
RecipientAddressBlockwählen. - Betreff und Datum auf dieselbe Weise einfügen:
Forms.SubjectundForms.Date.
Der Adressblock wird als Nur-Text-Inhaltssteuerelement eingefügt; die Zeilenumbrüche aus \n ergeben die Zeilen des Adressblocks.
Testen
- Ohne Adressdatenquelle: Vorlage im Vorlageneditor testen. Im Forms-Dialog füllt die Schaltfläche für Testdaten alle Felder, auch das Empfänger-Objekt, mit Beispielwerten; für Textfelder ist das jeweils die Feld-Id. Der Adressblock zeigt darum vier Zeilen, inklusive Land, weil der Testwert
CountrynichtCHist. - Mit Adressdatenquelle: Eine CSV-Datei mit der Kopfzeile
Firma;Vorname;Name;Strasse;PLZ;Ort;Landbereitstellen. Der Pfad wird serverseitig aufgelöst; die Datei muss für den Server erreichbar sein. Im Dialog nach einem Namen suchen und den Treffer übernehmen. - Land: Einen Empfänger mit Land
DEwählen. Der Adressblock zeigt vier Zeilen; beiCHbleiben es drei.
Varianten
Andere Adressdatenquelle: Den Block DataProviders durch einen SqlDataProvider, HttpDataProvider oder ExcelDataProvider ersetzen. Die Target-Ids im Mapping bleiben, Field und Vorlage ändern sich nicht.
Empfänger von der Fachanwendung: Ein Drittsystem übergibt den Empfänger über Connect im Element Forms als Object mit Key="Recipient". Der Forms-Dialog zeigt ihn vorbefüllt; der Sachbearbeiter kann ihn noch ändern. Siehe Connect: Struktur.
Nur Treffer aus der Quelle zulassen: <DataProviders DisableManualCreate="true"> verhindert die manuelle Erfassung.
Mehrere Empfänger und Serienbrief: Statt Object eine ObjectCollection mit SelectedObjectId verwenden. Siehe Serienerstellung über SelectedObjectId.
Stolpersteine
| Symptom | Ursache | Lösung |
|---|---|---|
| Empfänger lässt sich nicht über «Feld binden» einfügen | Ein Object kann nicht direkt eingefügt werden | Text-Field wie in Schritt 2 |
| Suche liefert immer alle Zeilen | Die Id eines Suchparameters ist kein Spaltenname; der Filter greift dann nicht | Kopfzeile der CSV-Datei mit den Suchparameter-Ids vergleichen |
| Suche liefert keine Daten oder meldet einen Fehler | Die Datei ist für den Server nicht erreichbar | UNC-Pfad und Zugriff des Serverprozesses prüfen |
| Felder des Treffers bleiben leer | Source im Mapping ist kein Spaltenname, oder Target keine Schema-Id | Mapping mit Kopfzeile und Schema abgleichen |
| Fehler im Field, wenn kein Empfänger erfasst ist | Das Objekt ist null | Prüfung if (!recipient) wie in Schritt 2, oder Required="true" |
| Land erscheint auch bei Schweizer Adressen | Die Quelle liefert «Schweiz» statt CH | Vergleichswert im Field an die Quelle anpassen |