LogoLogo
ClausesDatafieldsSpecial FunctionsStylingQ&AAPI
  • Welcome!
  • Getting started
    • What is Clause9?
    • Structuring your clause library
    • Structuring your clauses
    • Drafting modes in Clause9
    • Creating a questionnaire
    • Sample clauses
    • Videos
      • Concepts and datafields
      • Conditions
      • Q&As
      • Binders
      • Styling
      • Enumerations
      • Tables
      • Definitions
      • Snippets
      • Cross-references
      • Special functions
      • Examples of common clauses
      • Import clauses from MS Word
      • Grammatical conjugations
      • Action buttons
      • Alternative clauses
  • Assemble document
    • Document toolbar
    • Clause hierarchies
    • Focus Mode
    • Bulk generation of documents
    • Exporting documents
    • Assemble Document - FAQ
    • How to: Assemble Document
      • Insert images
  • Assemble Document Operations Panel
    • Operations panel
    • File pane
    • Edit pane
    • Document pane
    • Binder pane in the operations panel
    • Search pane
    • Browse pane
    • Terms pane
    • Data dashboard
    • Advanced pane
    • Styling pane
    • Miscellaneous pane
    • Visibility settings & actions menu
  • Binders
    • Binders: general
    • Styling cross-references to subdocuments
    • Global and local definition lists
    • Document and binder properties
    • Styling of a Binder versus subdocuments
    • (Un)locking documents in a binder
    • Binders - FAQ
    • How to: binders
      • Make a subdocument in a binder conditional
  • Clauses
    • Introduction to clauses
    • Clause structure
    • Grammar sheet
    • Writing conditions
    • Examples of conditions
    • Using codes instead of text fragments
    • Bold, italic and underline
    • Special codes
    • Enabled?
    • Links
    • Cross-references
    • Introduction to tables
    • Deviating table styling
    • Shrinking clauses
    • Action buttons
    • Enumerations
    • File position
    • Snippets
    • Parameters
    • Conjugations
    • Mixing data types
    • For-loops
    • Clause versioning
    • Abstract article references
    • Advanced multi-language features
    • Clauses - FAQ
    • How to: clauses
      • Create an ad-hoc clause
      • Create a library clause
      • Make a clause repeat
      • Make a paragraph within a clause conditional
      • Use a shortcut to refer to a concept
      • Insert a line break or page break
      • Creating a list with both predefined options and free input
      • Defining alternative clauses
      • Creating cross-references
      • Creating signature blocks
      • Creating advanced party introduction clauses
      • Automatically numbered annexes or schedules
      • Reuse any clause in a different context
      • Setting MS Word document properties
      • Add action buttons to clauses
      • Electronically signing documents
  • concepts
    • Introduction to concepts
    • Creating concepts
    • Concept labels
    • Links
    • Organising concepts
    • Concepts - FAQ
    • How to: concepts
      • Add predefines to a datafield
  • Datafields
    • Introduction to datafields
    • Types of datafields
    • Rules of thumb for using datafields
    • Data-expressions
    • Datafield aliases
    • Datafield labels
    • Datafield special tags
    • Datafield descriptions
    • Repeating list datafields
    • Datafield predefines
    • Datafields - FAQ
    • How to: datafields
      • Change datafield type
      • Change the datafield's name or alias
  • Definitions
    • Introduction to definitions
    • How to: definitions
      • How do definitions work?
      • Create a definition
  • Files
    • How files are organised
    • Browse files
    • File types
    • Custom styling
    • Legal comments
    • File description
    • Attributes
    • Reporting
    • File name
    • File category
    • Access rights
    • How to: files
      • Creating advanced folders
      • Naming your files
      • Shortcuts to folders or files
  • Q&A
    • About cards
    • Cards pane
    • About changes
    • Changes pane
    • Types of changes
    • Adding conditions
    • Question options
    • Copying & pasting answers
    • Comments, notes & documentation
    • Interactive Q&A inspection
    • Embedding questions into a document
    • “Changes” button
    • Batch create pane
    • Identifiers pane
    • Import pane
    • Edit clauses pane
    • Q&A options
    • Q&A - FAQ
    • How to: Q&A
      • Create predefined answers to a question
      • Add disclaimers
      • Create categories of questions
      • Modify the exported filename
      • Create a question to change the language of a document
      • Send a questionnaire to someone without a ClauseBase account
      • Create questions for repeating list datafields
      • Selecting legal entities & addresses
      • Create a questionnaire using "batch create"
      • Launch other Q&As
    • Leveraging ClauseBuddy Smart Templates in Clause9
  • Import
    • Introduction to importing clauses
    • Uploading clauses
    • Defined terms in Import mode
    • Datafields in Import mode
    • Cross-references in Import mode
    • Assigning folders
    • Conversion process
    • Exporting
    • Stashing intermediate results
    • Tips, tricks & limitations
  • Styling
    • Styling overview
    • Base styling
    • Numbering
    • Definitions styling
    • Enumerations styling
    • Locale styling
    • References styling
    • Page styling
    • Styling of a Binder versus subdocuments
    • Styling: tips and tricks
    • Advanced styling topics
    • Copying headers and footers from an MS Word file
    • How to: styling
      • Using custom fonts
      • Change bullet styling
  • Special functions
    • Introduction
    • Calculations
    • Concepts
    • Conditions
    • Conjugations
    • Content Control Elements
    • Datafields
    • Dates & durations
    • Languages
    • Lists
    • Numbers
    • References
    • Repeating (looping)
    • Special items
    • Text structure
    • Text modification
    • User
    • Q&A
  • Settings
    • Account
    • Preferences
    • Access bundles
    • Favourites
    • Saved searches
    • Saved datafields
    • Styles
    • Default styles
  • Admin
    • General
    • Users
    • User rights
    • Profiles
    • Groups
    • Styles
    • Default styles
    • Attribute models
    • Usage page
    • Custom homepage
    • Global placeholders
    • Access rights
    • How to: admin
      • Adding a new user
      • Disabling a user
      • Managing group memberships
  • Miscellaneous
    • Advanced tips & tricks
    • Typing special symbols on your keyboard
    • Shortcuts
    • Grammar style guide
    • Inserting MS Word files
    • Globo-panel
    • Creating high-quality documents
    • Excel calculations and lookups
  • Integrations
    • Overview
    • Spreadbases
    • E-signing documents
    • Drag & drop integrations
  • For developers
    • Clause9 API
    • Custom functions
    • Example custom functions
Powered by GitBook
On this page
  • Basic structure
  • Looping through dates
  • Looping through indexed values
  • Debt payments table
Export as PDF
  1. Clauses

For-loops

PreviousMixing data typesNextClause versioning

Last updated 1 year ago

Using the @for and @for-calc functions, you can generate a list of items (snippets of text, numbers, dates, …) by iterating through another list of values. Programmers will be very familiar with this idea, as for-loops are essential ingredients of most programming languages. For legal professionals, this idea will sound much more abstract — we will therefore explain the idea through relevant examples.

Basic structure

When using @for and @for-calc, you have to specify three different parameters: a placeholder, a list of elements to iterate (“loop”) with, and an internal snippet that will be used in each iteration. For example,

@for(?X, @list("alpha", "beta", "gamma"), @SNIP)

SNIP = this is element ?X

This code will loop through the bottom snippet three different times, each time replacing the placeholder ?X with the next element of the list. Accordingly, the result will be a list of texts containing “this is element alpha”, “this is element beta” and “this is element gamma”. You can then use this resulting list in any way possible, for example convert it into bullets using @bullets( ... ) or into an inline-enumeration using @enumerate.

The difference between @for and @for-calc is that @for will always resulting in a list of text snippets (i.e., a word, a part of a sentence, or even entire paragraphs), while @for-calc will result in a list of values, whereby each value must be a whole/floating number, a currency value, a duration, undefined, or a list itself. If @for-calc cannot extract such value (e.g., because the intermediate result is a text snippet), then it will result in an error.

In addition to the placeholder you specify yourself (?X in the example above), the software will also allow you to use the following implicit placeholders:

  • ?INDEX will contain the current iteration number, starting from 1 and increased with each iteration.

  • ?MAX-INDEX will contain the total number of iterations that will be performed. Note that this value will remain constant throughout all iterations.

  • ?PREVIOUS will contain the result of the previous iteration

  • ?ACC (for “accumulator”) will contain the list of results up to (but not yet including) the current iteration

In the example below, three iterations are shown, whereby ?X will be assigned the value 10, 11 and 12 respectively, while the ?INDEX will be assigned the value 1, 2 and 3 respectively. Note that the ?PREVIOUS value will not contain a value in the first iteration (for obvious reasons). In the second iteration, it will contain the bullet that resulted from the previous iteration; in the third iteration, it will contain the bullet of the first iteration, as well as the sub-bullet of the second iteration. The example in the screenshot below is contrived, but you will see in the real examples below how the ?PREVIOUS value can be used.

Looping through dates

In a loan agreement, we want to create a list of bullets that contains an overview of all the monthly repayment dates, starting from a certain commencement. The parameters of the loan are saved into the datafields loan^start-date, #loan^frequency (a duration — e.g., one month or 2 weeks) and #loan^instalments (the number of repayments, e.g. 5).

Using a for-loop, we could then write:

@bullets(@for(?INSTALMENT-NR, @range(1, #loan^instalments), @BULLET))

BULLET = ~@ord(?INSTALMENT-NR) repayment~ on {#loan^start-date + (#loan^frequency * ?INSTALMENT-NR) }

In human language, this roughly means the following:

  • create a list (range) of items, starting from 1, up to (but including) the number of instalments — e.g. from 1 to 5

  • create a resulting list in memory, that will hold all the intermediate results

  • do the following 5 times:

    • set placeholder ?INSTALMENT-NR to the current item (i.e., the first time set it to 1, the next time to 2, etc.)

    • take internal snippet @BULLET, and replace placeholder ?INSTALMENT-NR with its current value

    • put the intermediate result into the resulting list

  • take the resulting list, and convert it into bullets.

Looping through indexed values

Let’s assume that in a rental agreement you need to show the indexed rent amount over a certain period. For example, with a starting amount 1000 EUR and a yearly indexation of 5%, you may be tempted to write the following:

Unfortunately, this is not how most real-world indexation clauses work, as the indexation should take the then-applicable amount as the starting point each time. This can be solved using the ?PREVIOUS placeholder. In the example below, we use @for-calc to calculate a list of all rental amounts, which is then shown in another @for-loop. (The reason being that a @for loop results in a piece of text, that cannot be used in further mathematical calculations):

The AMOUNT snippet essentially says “if no previous value exists (i.e., we are at the first iteration), then simply use the base amount; however, if a previous value exists (which should be the case as from the second iteration), then use the previous value and apply the indexation to it”.

Note that we use curly braces around the result in the AMOUNT snippet in order to force the result to become a number. If you leave these curly braces, you immediately get errors, because the software would then treat the result of that snippet as a piece of text, while@for-calc can only work with a number / currency value / duration / list / undefined value.

Debt payments table

As another example, let’s assume that a contract wants to show a table that illustrates how an amount of 1000 EUR is paid back over five months. The calculation per period is deliberately kept very simple, but the idea is clear that you could also use the various types of mortgage payment calculations here.

What we’re doing here, essentially, is to construct a table that consists of six different rows (a header row, and one row per repayment-period), merged together using @merge-tables. Each repayment period’s row then contains a cell with the calculated date, the amount (in the example always 200), and then a cell with the remaining value. The remaining value is extracted using @get from a list of repayment amounts that is generated by the @AMOUNTS-LIST snippet, which uses a simple @for-calc loop.

Note that when the loan amount, number of periods, starting date, etc. are placed in datafields, this kind of table can even be interactively shown within a Q&A, allowing end-users to experiment with these values.

The results can be seen in the following screenshot, when using the . You are strongly recommended to use this focus mode, because it allows you to interactively experiment with the for-loops.

Particularly interesting in the focus mode is its ability to a particular snippet. For example, when you isolate snippet @BULLET, and then assign values to the ?INSTALMENT-NR placeholder through the button, you can interactively “step through” each iteration. (Programmers sometimes call this “debugging”, i.e. a mode dedicated to removing potential “bugs” from their software code).

focus mode
isolate