Adding Tables (Like Products or Contacts) to Your Document
Build a simple related-record table pattern you can adapt to many S-Docs templates.
Example output
Your finished document can look like this:
Renewal - Northwind
Proposal/Price Quote
2026-05-15
25000
Expansion - Northwind
Negotiation/Review
2026-06-01
40000
Services Add-On
Qualification
2026-06-20
12000
What You'll Learn
Build a related list table from a parent record
Query
Opportunityrecords from anAccounttemplateMatch table headers to
<column>tags in the right orderTest the output before adding filters
Reuse the same pattern with other object pairs
What You'll Build
In this tutorial, you will build an account pipeline summary that lists related opportunities in a table.
This walkthrough uses Account as the base object and Opportunity as the child object.
The finished template will include:
An account summary header
A four-column opportunity table
A related list query tied to the current account
One safe variation that only shows open opportunities
Estimated time: 15 minutes
Prerequisites
Before you start, make sure you have:
Access to S-Docs Templates in Salesforce
Permission to create or edit templates
A template related to
AccountA test account with at least two related
OpportunityrecordsBasic familiarity with merge fields such as
{{!Account.Name}}
If you want a shorter intro first, use Insert Data Tables.
Step 1: Open or create the template
Start with an Account template so the query can use the current account ID.
Go to S-Docs Templates.
Open an existing template or click New Template.
Set Related To Type to
Account.Open the template editor.
You now have a base template that can query child records from the current account.
Step 2: Add the account summary header
Add a small header first.
This confirms your base merge fields resolve before you add the related list.
What you just did:
Confirmed the template runs from
AccountAdded visible fields to test the base record context
Created a simple header above the opportunity table
Step 4: Add the related list block
This example uses Opportunity as the child object.
It pulls records related to the current Account.
What this does:
Queries
Opportunityrecords for the current accountTies the query to the base record with
WHERE AccountId = '{{!Account.Id}}'Sorts the rows by
CloseDatePrints one field per
<column>tag
How to read the block:
<lineitemsSOQL>starts the related list query<class>controls the output style<soql>defines which child rows to returnEach
<column>prints one value in the row
Step 5: Match the headers and columns
The table only works cleanly when the header order matches the <column> order.
In this example:
Opportunitymaps toNameStagemaps toStageNameClose Datemaps toCloseDateAmountmaps toAmount
Rules to follow:
Every displayed value needs a matching
<column>tagEvery
<column>value must appear in theSELECTclauseThe first header must match the first
<column>
If the order does not match, the wrong values appear under the wrong headers.
Step 6: Save and test the template
Test the base version before you add any variations.
Click Save.
Open a test account with related opportunities.
Generate the document.
Compare the document rows with the related records in Salesforce.
Verify these results:
The header shows the expected account
The table shows one row per related opportunity
The rows belong to the current account only
The values appear under the correct headers
Once this works, you have a reusable starting pattern.
Common Issues and Solutions
"My table shows no rows"
Check these items:
Confirm the template runs from
AccountConfirm the test account has related
OpportunityrecordsVerify the
WHEREclause usesAccountId = '{{!Account.Id}}'Test with a record you know has child records
"My values are under the wrong headers"
Check these items:
Compare the header order with the
<column>orderMake sure each header has one matching query field
Add fields one at a time when expanding the table
"One column is blank"
Check these items:
Verify that field appears in the
SELECTclauseVerify the same field appears in the matching
<column>tagConfirm the returned records actually contain data in that field
"The wrong records are returned"
Check these items:
Review the relationship field in the
WHEREclauseConfirm the base merge field points to the current record
Remove extra filters and test the base query first
"How do I adapt this to another object pair?"
Use this swap pattern:
Change the base template object
Change the child object in
FROMChange the relationship field in
WHEREChange the selected fields, headers, and
<column>tags together
Keep the overall table structure the same.
What You've Learned
✅ Built a related list table from an Account template
✅ Queried Opportunity records with <lineitemsSOQL>
✅ Tied the query to the current base record
✅ Matched headers to <column> tags in the correct order
✅ Reused one example pattern that can scale to other objects
Next Steps
Adapt the pattern
Replace
OpportunitywithContacton anAccounttemplateChange the visible columns for a different use case
Add one more field and test it by itself
Combine it with other features
Use Getting Started with Conditional Logic to show the table only when related opportunities exist
Use Template Attributes Tutorial to format dates, numbers, and output values inside the table
Use Creating Your First Named Query when you need one reusable result outside a table
Practice Exercise
Build an Account template that includes:
A header with
Account.NameandAccount.Owner.NameA four-column related list table for opportunities
One query tied to the current account
A test run against an account with related opportunities
One filtered variation that only shows open opportunities
Bonus challenges:
Rebuild the same pattern for
AccountandContactChange the sort order
Add one more displayed field
Last updated
Was this helpful?

