Skip to main content
Version: 4.1 (2026 H2)

Letter with a recipient from an address data source

A user creates a letter and selects the recipient in the Forms dialog from a central address data source, here a CSV file on a file share. The address appears as a fully formatted address block in the letter. If the recipient is not found, the user enters the details manually.

Result​

  • Forms dialog: search by name and city in the address data source, take over a hit or enter the recipient manually; plus subject and date.
  • Address block in the letter: company or first and last name, street, postal code and city; the country only for recipients outside Switzerland.
  • The address data source is interchangeable (SQL, HTTP, Excel) without changing the field or the template.

Building blocks​

Building blockTask in this exampleReference
Forms (content template)Object Recipient with schema, result list and DataProvider; plus subject and dateForms
CsvDataProvidersearches the CSV file and maps its columns to the schemaCsvDataProvider
Fields (content template)Text field RecipientAddressBlock formats the addressFields
Word content templateinsert the field and the Forms fields via «Bind field»Accessing primedocs fields

Data flow​

Step 1: Forms with the recipient object and the address data source​

Activate the Forms document function on the content template:

<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>
  • Schema defines the fields of each recipient, independent of the source.
  • Summary determines the columns of the result list in the dialog.
  • SearchParameters are the search fields; their Id is the column name in the CSV file.
  • Mapping connects columns (Source) with schema ids (Target).
  • Required="true" prevents a letter without a recipient.

The labels are set directly in Label so that the configuration works without preparation. For multilingual templates, use translate-Label and translate-Format with keys from the global translations instead.

Why an Object: It groups the address fields into one recipient to which the DataProvider is attached. If the source is replaced, only the DataProviders block changes; schema, field and template stay the same.

Step 2: Field for the address block​

Activate the Fields document function on the content template:

<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>

Why a field: An Object cannot be inserted into the document directly. The field delivers the finished text; $.joinNonEmpty drops empty lines, for example for persons without a company or addresses without a country.

Step 3: Bind the fields in the Word template​

  1. Open the content template in the editor.
  2. Place the cursor where the address block goes, click «Bind field» and select RecipientAddressBlock.
  3. Insert subject and date the same way: Forms.Subject and Forms.Date.

The address block is inserted as a plain-text content control; the line breaks from \n produce the lines of the address block.

Testing​

  • Without the address data source: Test the template in the template editor. In the Forms dialog, the test-data button fills all fields, including the recipient object, with sample values; for text fields this is the field id. The address block therefore shows four lines, including the country, because the test value Country is not CH.
  • With the address data source: Provide a CSV file with the header Firma;Vorname;Name;Strasse;PLZ;Ort;Land. The path is resolved on the server; the file must be reachable for the server. Search for a name in the dialog and take over the hit.
  • Country: Select a recipient with country DE. The address block shows four lines; with CH it stays at three.

Variants​

Other address data source: Replace the DataProviders block with a SqlDataProvider, HttpDataProvider or ExcelDataProvider. The Target ids in the mapping stay; field and template do not change.

Recipient from the business application: A third-party system passes the recipient via Connect in the Forms element as an Object with Key="Recipient". The Forms dialog shows it prefilled; the user can still change it. See Connect: Structure.

Allow hits from the source only: <DataProviders DisableManualCreate="true"> prevents manual entry.

Several recipients and mail merge: Use an ObjectCollection with SelectedObjectId instead of an Object. See Forms, section on SelectedObjectId.

Pitfalls​

SymptomCauseSolution
The recipient cannot be inserted via «Bind field»An Object cannot be inserted directlyText field as in step 2
The search always returns all rowsThe Id of a search parameter is not a column name, so the filter does not applyCompare the header of the CSV file with the search parameter ids
The search returns no data or reports an errorThe file is not reachable for the serverCheck the UNC path and the access of the server process
The fields of a hit stay emptySource in the mapping is not a column name, or Target is not a schema idCompare the mapping with header and schema
Error in the field when no recipient is enteredThe object is nullCheck if (!recipient) as in step 2, or Required="true"
The country appears for Swiss addresses tooThe source delivers «Schweiz» instead of CHAdapt the comparison value in the field to the source