# Configure Rules Based Narratives

Configure rules based narrative components so users can <a href="/en/lr/01167/">generate case narratives</a> based on your templates. You can create _Narrative Outline_ templates for different _Case_ types, locations, and organizations. _Narrative Outlines_ are composed of _Narrative Statements_, each with _Narrative Statement Options_ where you can add the conditional rules that determine when Vault includes the associated _Narrative Statement_ within a generated narrative and what _Case_ data that statement includes. You can also order each _Narrative Statement_ according to their appropriate alignment and sequence. Conditional rules and formulas allow you to create templates that generate grammatically correct, logical, orderly, and complete narratives, which require minimal editing from users.

If you're interested in discussing whether getting early access to this feature is appropriate for your business needs, contact your Veeva Representative.

<div class="note-border alert-info">
  <div class="alert alert-info" role="alert">
    <div><i class="far fa-info-circle"></i></div>
    <div class="alert-text">
      <p><strong>Note</strong>: At this time, Vault does not support rules based narrative generation for <em>Localized Cases</em> and generates only English narrative documents.</p>
    </div>
  </div>
</div>



When users run the _Generate Narrative from Outline_ action on a _Case_, Vault generates a narrative document based on the type of _Case_. When users run the action on a _Case_ that already has a narrative document, Vault:

* Re-renders and upversions the existing narrative document based on the applicable outline template.
* Generates _Case Follow-Up Statements_ to track changes made since the action last ran, and includes those statements in the upversioned narrative to summarize the changes.
  * When users bulk unblind and enter a value in the _Narrative Document_ field on the <a href="/en/lr/01181/#complete-the-bulk-unblinding-screen">_Bulk Unblinding_ screen</a>, Vault generates a _Case Follow-Up Statement_ with that value populated in the _Follow-Up Summary_ field and sets the _Summary Type_ as _Bulk Unblind_. 
  * Vault copies _Case Follow-Up Statements_ to new _Case_ versions from previous versions.
  * Vault does not generate _Case Follow-Up Statements_ for more than 1,500 child records or for _Cases_ generated using the override merge method during automated _Case_ promotion.

<div class="note-border alert-info">
  <div class="alert alert-info" role="alert">
    <div><i class="far fa-info-circle"></i></div>
    <div class="alert-text">
      <p><strong>Note</strong>: If you do not configure Rules Based Narratives, or if you do not create a <em>Narrative Outline</em> for a specific <a href="#types"><em>Case</em> type</a>, Vault generates narratives based on the applicable <a href="/en/lr/01212/">default narrative templates using merge fields</a>.</p>
    </div>
  </div>
</div>



### Types of Cases {#types}

You can create _Narrative Outline_ templates to which Vault matches _Case_ data for the following types:

* **Post-Market Non-Serious**: Applies to the following types of _Cases_:
  * Postmarket _Cases_ (do not have _Studies_)
  * Non-clinical trial study _Cases_ (_Study Type_ is _Other_) with a _Serious_ value of _No_ or blank
* **Post-Market Serious**: Applies to the following types of _Cases_:
  * Postmarket _Cases_ (do not have _Studies_)
  * Non-clinical trial study _Cases_ (_Study Type_ is _Other_) with a _Serious_ value of _Yes_
* **Clinical**: Applies to clinical trial study _Cases_ (_Study Type_ is not _Other_)

## Prerequisites

Before you can configure this feature in your Vault, you must complete all steps in <a href="/en/lr/832806/">Enable Rules Based Narrative Generation</a>.

In Vaults using Veeva AI for Safety, you must <a href="/en/lr/994270/">enable the Narrative Agent</a> so you can specify the [_Narrative Outlines_][4] for which Vault will automatically run the agent when users run the _Generate Narrative from Outline_ action.

## Overview

Complete the following procedures to configure Rules Based Narratives in your Vault:

1. [Copy the standard _Narrative Outlines_][2], which you can customize as needed.
2. [Review _Narrative Outlines_][3] using the _Narrative Outline Preview_ report.
3. [Define _Narrative Outlines_][4] to use for each type of _Case_ and, optionally, for specific locations and organizations.
4. [Define _Narrative Statements_][5] to specify the statements and their order Vault uses for each outline.
5. [Define _Narrative Statement Options_][6] to specify the content Vault includes in each statement.

## Copy Standard Records {#records}

Vault includes the following standard _Narrative Outlines_ with related _Narrative Statements_ and _Narrative Statement Options_:

* _Post-Market Non-Serious Sample Outline_
* _Post-Market Serious Sample Outline_
* _Clinical Sample Outline_

Copy these standard records using the _Copy Narrative Outline_ action, which deep copies all related child records in their hierarchies (do not use the _Copy Record_ action). After running the _Copy Narrative Outline_ action, you can [review][3] the copied records and customize the [_Narrative Outlines_][4], [_Narrative Statements_][5], and [_Narrative Statement Options_][6] to fit your business needs. Alternatively, you can create new records from scratch.

<div class="note-border alert-info">
  <div class="alert alert-info" role="alert">
    <div><i class="far fa-info-circle"></i></div>
    <div class="alert-text">
      <p><strong>Note</strong>: When migrating <em>Narrative Outlines</em>, <em>Narrative Statements</em>, and <em>Narrative Statement Options</em> between Vaults using <a href="/en/lr/761685/">Record Migration Mode</a>, do not include the <code class="language-plaintext highlighter-rouge">name__v</code> column in CSV files. You must allow Vault to generate names using automated sequential numbering.</p>
    </div>
  </div>
</div>



## Review Narrative Outlines {#review}

You can use the _Narrative Outline Preview_ <a href="/en/lr/3614/">report</a> to review a [_Narrative Outline_][4] and its associated [_Narrative Statements_][5] and [_Narrative Statement Options_][6], including the conditions and formulas that define how Vault determines the narrative output. From within the report, select a record's hyperlink name to open the record and, if applicable, make updates. 

To view the report:
1. Access the report:
   * From a _Narrative Outline_ record, select **Preview Narrative Outline** from the **All Actions** menu.
   * Navigate to **Analytics > Reports > Narrative Outline View**.
2. Select the _Narrative Outline_ you want to review.
3. Select **Continue**.

Alternatively, you can access and create _Narrative Outlines_, _Narrative Statements_, and _Narrative Statement Options_ in **Business Admin**.

## Define Narrative Outlines {#narrative-outlines}

To define _Narrative Outlines_:

1. Navigate to the applicable [custom copied record][2] or <a href="/en/lr/18769/#how-to-create-or-edit-object-records">create a new record</a>.
2. Select the [**Case Type**][1] to which this template applies.
3. Optional: Select the _Organization_ to which this template applies. If this field is blank, Vault does not consider it when matching a template to _Case_ data.
4. Optional: Select the _Localization_ to which this template applies. If this field is blank, Vault does not consider it when matching a template to _Case_ data.
5. Optional: In Vaults using Veeva AI for Safety, you can specify that the <a href="/en/lr/01167/#narrative-agent">Narrative Agent</a> automatically runs and generates the narrative based on the outline's defined rules:
  * **Narrative Agent Initial Case Options**: Select **Summarize on creation** for the agent to generate narratives for initial _Cases_.
  * **Narrative Agent Follow-up Case Options**: Select **Recreate Entire Narrative** for the agent to rewrite narratives for follow-up _Cases_.
6. Select **Save**.
7. Add up to 100 [_Narrative Statements_][5] to this outline.
8. For each _Narrative Statement_, add up to 25 [_Narrative Statement Options_][6] to define the rules for when Vault includes the statement in a narrative. 
9. In the _Narrative Statement_ section, select the record to which you want to add options.
10. In the _Narrative Statement Option_ section, open the applicable record or select **Add**.
11. In the _Search: Narrative Statement Option_ window, select all applicable options.
12. Optional: Use the search bar and **Filters** to find specific records.
13. Optional: Select **Create** to create new records.
14. Select **OK** to add the selected options to the _Narrative Statement_.
15. Select **Save**.


## Define Narrative Statements {#narrative-statements}

To define _Narrative Statements_:

1. Navigate to the applicable [custom copied record][2] or <a href="/en/lr/18769/#how-to-create-or-edit-object-records">create a new record</a>.
2. Optional: Enter a description.
3. Optional: For **Order in Outline**, enter a numeric value to specify where in the template the statement appears.
4. Select a **Paragraph Setting** for the statement in the outline:
   * **New Paragraph**: Statement begins a new paragraph.
   * **Concatenate to previous**: Statement appends to the previously ordered statement.
5. Select **Save** or **Save + Create** to create another record.

## Define Narrative Statement Options {#narrative-statement-options}

To define _Narrative Statement Options_:

1. Navigate to the applicable [custom copied record][2] or <a href="/en/lr/18769/#how-to-create-or-edit-object-records">create a new record</a>.
2. Optional: Update or enter a [**Condition**][7] to specify when Vault includes the associated _Narrative Statement_ in the narrative output. If you leave this field blank, Vault always considers the return to be true and includes the _Narrative Statement_.
3. Optional: Update or enter a [**Statement Formula**][8] to specify what content Vault includes for the associated _Narrative Statement_ if the _Condition_ returns true.
4. Optional: Select a **Topic**. This may help you to organize your options.
5. Optional: Define how you want to order statements in the output when Vault finds multiple records returned by the _Statement Formula_.
   * Select **Multiple Records** to specify the object for which you want to define an order.
   * Select an **Order By** value to specify the object field by which Vault will order statements.
6. Select **Save**.

<div class="note-border alert-info">
  <div class="alert alert-info" role="alert">
    <div><i class="far fa-info-circle"></i></div>
    <div class="alert-text">
      <p><strong>Note</strong>: Vault can reference up to 15,000 child <em>Case Products</em> and 15,000 <em>Case Medical Histories</em> per <em>Narrative Statement Option</em>. If executing a particular <em>Narrative Statement Option</em> would exceed this amount, Vault ignores that option when generating the narrative and notifies the user who ran the <em>Generate Narrative from Outline</em> action which object would have exceeded this limitation.</p>
    </div>
  </div>
</div>



### Conditions {#conditions}

You can define _Conditions_ for when Vault executes a [_Statement Formula_][8] and includes content for the associated _Narrative Statement_ in a narrative. When a _Condition_ returns true, Vault renders output based on the _Statement Formula_. When a _Condition_ returns false, Vault ignores the _Narrative Statement Option_ when generating the narrative. For more details about creating formulas, see <a href="/en/lr/42857/">Creating Formulas in Vault</a>.

As a best practice, only one _Narrative Statement Option_ should return true for each _Narrative Statement_. If multiple options return true based on conditional criteria, Vault concatenates the _Statement Formulas_ when generating the narrative.

When defining _Conditions_, you can use <a href="/en/lr/1037069/">VQL</a>, any of the operators and functions in the <a href="/en/lr/52324/">Vault Formula Reference Guide</a>, and the following <a href="/en/lr/861364/#safety-functions">Safety-specific functions</a>:

* [`VS_ANYOF`][9]
* [`VS_CONTAINS`][10]
* [`VS_HASONE`][11]
* [`VS_HASMANY`][12]
* [`VS_LET`][13]
* [`VS_MATCHES`][14]

#### VS_ANYOF {#vs_anyof}

`VS_ANYOF(array_expression, LAMBDA(array_element_alias, boolean_expression))`

This function returns true or false depending on whether or not the `boolean_expression` is true for any of the array elements (`array_element_alias`) in the `array_expression`. For more information about this function, see <a href="/en/lr/861364/#vs_anyof">Create Formula Expressions</a>.

##### Example

The following example returns true if any _Case Products_ have a _Drug Role_ field value of _Concomitant_: 

`VS_ANYOF(case_version__v.case_products_case_version__vr, LAMBDA(cp, cp.drug_role__vr.api_name__v = 'concomitant__v'))`

#### VS_CONTAINS {#vs_contains}

`VS_CONTAINS(string array, string)`

This function returns true or false depending on whether or not `string` is present inside `string array`. For more information about this function, see <a href="/en/lr/861364/#vs_contains">Create Formula Expressions</a>.

#### VS_HASONE {#vs_hasone}

`VS_HASONE(objectreference)`

This function returns true if there is exactly one  record of the specified object for the _Case_.

##### Example

The following example returns true if the _Case Product_ has a _Drug Role_ field value of _Suspect_, one  _Case Product Dosage_, and one  _Case Product Indication_:

`VS_ANYOF(case_version__v.case_products_case_version__vr, LAMBDA(element, element.drug_role__vr.name__v = "Suspect" && VS_HASONE(element. case_product_dosages_case_product__vr) && VS_HASONE(element. case_product_indications__vr))) `

#### VS_HASMANY {#vs_hasmany}

`VS_HASMANY(objectreference)`

This function returns true if there are multiple records of the specified object for the _Case_.

##### Example

The following example returns true if the _Case Product_ has a _Drug Role_ field value of _Suspect_, multiple _Case Product Dosages_, and multiple _Case Product Indications_:

`VS_ANYOF(case_version__v.case_products_case_version__vr, LAMBDA(element, element.drug_role__vr.name__v = "Suspect" && VS_HASMANY(element.case_product_dosages_case_product__vr) && VS_HASMANY(element.case_product_indications__vr)))`

#### VS_LET {#vs_let}

`VS_LET(var, path_to_validating_records, expression)`

This function returns the result of a validation performed on the records of an object. For more information about this function, see <a href="/en/lr/861364/#vs_let">Create Formula Expressions</a>.

#### VS_MATCHES {#vs_matches}

`VS_MATCHES(string, string)`

This function returns true or false depending on whether or not `string` matches the regular expression (regex) in `string`. For more information about this function, see <a href="/en/lr/861364/#vs_matches">Create Formula Expressions</a>.

### Statement Formulas {#formulas}

Use VQL, expressions, and functions to define _Statement Formulas_ to specify what content Vault includes for the associated _Narrative Statement_ in a narrative if the [_Condition_][7] returns true. When defining _Statement Formulas_, you can use plain text, field references, <a href="/en/lr/1037069/">VQL</a>, <a href="/en/lr/52324/">Vault Platform operators</a>, certain [Vault Platform functions][15], and [Safety narrative functions][16]. For more details about creating formulas, see <a href="/en/lr/42857/">Create Formulas in Vault</a>.

<div class="note-border alert-info">
  <div class="alert alert-info" role="alert">
    <div><i class="far fa-info-circle"></i></div>
    <div class="alert-text">
      <p><strong>Note</strong>:  All <code class="language-plaintext highlighter-rouge">Object</code> references must begin references at the <em>Case</em> level by showing their relationship to the <code class="language-plaintext highlighter-rouge">case_version__v</code> object.</p>
    </div>
  </div>
</div>



#### Vault Platform Functions {#platform-functions}

The _Statement Formula_ field supports the following Vault Platform functions:

* Math Functions:
  * <a href="/en/lr/52324/#trunc">`Trunc`</a>
* Text Functions:
  * <a href="/en/lr/52324/#initcap">`InitCap`</a>
  * <a href="/en/lr/52324/#lower">`Lower`</a>
  * <a href="/en/lr/52324/#trim">`Trim`</a>
  * <a href="/en/lr/52324/#upper">`Upper`</a>

#### Safety Narrative Functions {#safety-functions}

The _Statement Formula_ field supports the following Safety-specific narrative functions:

* [`VS_CaseDocuments`][23]
* [`VS_DoseFrequency`][22]
* [`VS_ExistCheck`][17]
* [`VS_OmitReason`][18]
* [`VS_PrefixDate`][19]
* [`VS_PrefixDateRange`][21]
* [`VS_Repeat`][20]

The following syntax guidelines apply to these functions:

* To reference a field, use the following syntax: `${object_relation.field_api_name}`
* If your function does not specify an object relationship, Vault assumes the specified field exists on the _Case_ (`case_version__v`) object
* Specify object relationships as they relate to the _Case_ (`case_version__v`) object
* To render quotation marks (`"`) and apostrophes (`'`) within any output, include an escape sequence (`\`) before the character

##### VS_CaseDocuments {#vs_casedocuments}

`${VS_CaseDocuments(condition, text/function output)}`

This function renders an output with specified field values from documents related to the _Case_. If multiple documents meet the input criteria, Vault prints outputs for each document in a new line.

This function includes the following inputs:

* `condition`: Specifies the conditions for which Vault considers documents for the output
  * Supports the listed [Vault Platform][15] and [Safety][16] functions as well as field references
  * Supports the `ALL` operator, which allows you to include all _Case_ children within the output
* `text/function output`:  Specifies the text or function to render
  * Supports the listed [Vault Platform][15] functions and the following [Safety][16] functions:
    * `VS_ExistCheck`
    * `VS_PrefixDate`
    * `VS_PrefixDateRange`

###### Example

The following example renders an output based on the values for the _Case Document's_ `literature_classification__v` and `reference_text__v` fields:

`${VS_CaseDocuments(NOT(ISBLANK(case_documents__v.literature_classification__v)), "Literature Classification = " ${case_documents__v.literature_classification__v}`<br>
`Reference Text = " ${case_documents__v.reference_text__v} ")}`

Depending on the returned values, the rendered output may look like the following:

`Literature Classification = Clinical trial/research`<br>
`Reference Text = Smith RA, Roberts JM, Wang M. Efficacy of novel GLP-1 receptor agonists in Type 2 Diabetes management. J Pharm Sci. 2025 Mar 15;114(3):422-481.`

##### VS_DoseFrequency {#vs_dosefrequency}

`${VS_DoseFrequency(Object, FrequencyValue, FrequencyUnit, DecimalPlaces)}`

This function renders a dosage frequency output in the specified format based on the `FrequencyValue` and `FrequencyUnit` values.

This function includes the following inputs:

* `Object`: Specifies the object on which the field exists
* ``FrequencyValue``: Specifies the frequency field value to render
* `FrequencyUnit`: Specifies the _Unit of Measurement_ (`unit_of_measurement_picklist__v`) field value to render 
* `DecimalPlaces`: Specifies if the value is a whole or decimal number, without rounding
  * `0`: Whole number 
  * `[1-8]`: Decimal number with the specified decimal places

Vault uses the following priority order to determine the `FrequencyValue` and `FrequencyUnit` rendering:

* `FrequencyValue` is greater than `1`: `every [FrequencyValue] [FrequencyUnit]`
* `FrequencyValue` is greater than `0` and less than `1`: `1/[FrequencyValue] times per [FrequencyUnit]`
* `FrequencyValue` is `1`: `1 time per [FrequencyUnit, remove "s"]`
* `FrequencyValue` is blank and `FrequencyUnit` value is as necessary, cyclically, or  total:  `[as necessary/cyclically/total]`
* `FrequencyValue` is `0`  or not a number: `every [FrequencyValue] [FrequencyUnit] `
* `FrequencyValue` or `FrequencyUnit` is blank: `at an unknown frequency`

###### Example

The following example returns an output depending on the values for the _Case Product Dosage's_ `dose_number__v`, `dose_unit__v`, `frequency_number__v`, and `frequency_unit__v` fields:

````
"Case product dosage: "
${VS_REPEAT(
    case_product_dosage__v,
    case_product_dosage__v.name__v != "",
"Product with dose " ${case_product_dosage__v.dose_number__v}${case_product_dosage__v.dose_unit__v} " is administered "${VS_DoseFrequency(case_product_dosage__v, frequency_number__v, frequency_unit__v, 2)}".")}
````

Depending on the returned values, the rendered output may look like the following:

`Case product dosage:`\
`Product with dose 10.0000mg is administered every 12.00 hours.`\
`Product with dose 10.0000mg is administered as necessary.`\
`Product with dose 10.0000mg is administered 3.00 times per days.`\
`Product with dose 10.0000mg is administered at an unknown frequency.`

##### VS_ExistCheck {#vs_existcheck}

`${VS_ExistCheck(Object, PrimaryField, "text", "text2")}`

This function renders an output when the specified field contains a value. You can nest up to three (3) `VS_ExistCheck` functions. 

This function includes the following inputs:
* `Object`: Specifies the object on which the field exists 
* `PrimaryField`: Specifies the field to confirm a value exists
* `"text"`: Specifies the output to render if the `PrimaryField` value exists
  * Supports the listed [Vault Platform][15] and [Safety][16] functions as well as field references
* `"text2"`: This optional input specifies the output to render if the  `PrimaryField` value is blank

###### Example

The following example returns an output when a value exists for the _Case's_ `dob_idate__v` field:

````
"The following is the patient\'s data related to birth: 
"${VS_ExistCheck(
    case_version__v,
    dob_idate__v, 
    ${VS_PrefixDate(case_version__v, uppercase, dob_idate__v)} " the patient was born.",
    " the date of birth was not provided.")
    }
````

Depending on the returned values, the rendered output may look like the following:

* When the _Case's_ `dob_idate__v` field contains a value: `The following is the patient's data related to birth: In 2024 the patient was born.`
* When the _Case's_ `dob_idate__v` field is blank: `The following is the patient's data related to birth: the date of birth was not provided.`

##### VS_OmitReason {#vs_omitreason}

`${VS_OmitReason(Object, PrimaryField, ReasonOmitField)}`

This function renders an output depending on if the specified `PrimaryField` or `ReasonOmitField` contains a value. If both fields are blank, the rendered output is `unknown`. 

This function includes the following inputs:

* `Object`: Specifies the object on which the field exists
* `PrimaryField`: Specifies the field value to render
* `ReasonOmitField`: Specifies the field value to render if the `PrimaryField` is blank

###### Example

The following example returns an output depending on the values of _Case's_ `dob_idate__v` and `dob_reason_omitted__v` fields: 

`"The patient date of birth is " ${VS_OMITREASON(case_version__v, dob_idate__v, dob_reason_omitted__v)}`

Depending on the returned values, the rendered output may look like the following:
    
    
* When the `PrimaryField` contains a value: `The patient date of birth is 10-Nov-2024`
* When the `PrimaryField` is blank: `The patient date of birth is "unknown" due to reason omitted "Asked but Unknown"`
* When the `PrimaryField` and `ReasonOmitField` fields are blank: `The patient date of birth is unknown`

##### VS_PrefixDate {#vs_prefixdate}

`${VS_PrefixDate(Object, Case, DateField, ReasonOmitField_optional)}`

This function displays a date value in a specified format and renders an output depending on the specified `DateField` or `ReasonOmitField_optional` values. If both fields are blank, the rendered output is `[On/on] an unknown date`. 

This function includes the following inputs:

* `Object`: Specifies the object on which the `DateField` exists 
* `Case`: Specifies the format of the output's first word
  * `lowercase`: `in`/`on`
  * `uppercase`: `In`/`On`
* `DateField`: Specifies the field value to render
* `ReasonOmitField_optional`: This optional input specifies the date field value to render if the `DateField` is blank

###### Example

The following example returns an output depending on the values of _Case_'s `event_onset_idate__v` and `event_onset_reason_omitted__v` fields: 
 
`${VS_PrefixDate(case_version__v, uppercase, event_onset_idate__v, event_onset_reason_omitted__v)}`

Depending on the returned values, the rendered output may look like the following:
    
* When the `DateField` contains a value that specifies the following:
  * Day, month, and year: `On 26-Sep-2024`
  * Month and year: `In Sep-2024`
  * Year: `In 2024`
* When the `DateField` is blank: `On an unknown date due to reason omitted "Asked But Unknown"`
* When the `DateField` and `ReasonOmitField_optional` fields are blank: `On an unknown date`

##### VS_PrefixDateRange {#vs_prefixdaterang}

`${VS_PrefixDateRange(Object, Case, StartDateField, EndDateField)}`

This function displays a date range value in a specified format and renders an output depending on the specified `StartDateField` and `EndDateField` values. When both fields are populated, the rendered output is `StartDateField [From/from] EndDateField`. If either field is blank, the rendered output for the blank field is `an unknown date`.

This function includes the following inputs:

* `Object`: Specifies the object on which the field exists
* `Case`: Specifies the format of the output
  * `lowercase`: `from`
  * `uppercase`: `From`
* `StartDateField`: This optional input specifies the start <a href="/en/lr/15057/#date-field">Date</a> or <a href="/en/lr/15057/#datetime-field">Date Time</a> field value to render
* `EndDateField`: This optional input specifies the end <a href="/en/lr/15057/#date-field">Date</a> or <a href="/en/lr/15057/#datetime-field">Date Time</a> field value to render

###### Example

The following example returns an output depending on the values of _Case Drug History's_ `name__v`, `name_reported__v`, `startdate_idate__v`, and `end_date_idate__v` fields:

````
"Case Drug History:"
${VS_REPEAT(
    case_drug_history__v,
    case_drug_history__v.name__v != "",
    ${case_drug_history__v.name_reported__v} " is taken " ${VS_PrefixDateRange(case_drug_history__v,lowercase,startdate_idate__v,end_date_idate__v)}
)}
````

Depending on the returned values, the rendered output may look like the following:

`Case Drug History:`\
`Cholecap is taken from 2021 to an unknown date`\
`Cholecap-X is taken from May-2022 to Jun-2022`\
`Wonderdrug is taken from 29-Apr-2024 to an unknown date`\
`Wonderdrug-X is taken from 08-Apr-2025 to 01-May-2025`

##### VS_Repeat {#vs_repeat}

`${VS_Repeat(Object, condition, GroupBy_optional, "textOrFunctionToRepeat")}`

This function allows you to evaluate the same formula multiple times with different values by supporting references to child and grandchild object relationships related to the _Case_ object. When multiple records meet the condition, Vault executes the statement for each record and consolidates the output instead of returning multiple outputs, minimizing repetition in the generated narrative. You can nest up to two `VS_Repeat` functions.

<div class="note-border alert-info">
  <div class="alert alert-info" role="alert">
    <div><i class="far fa-info-circle"></i></div>
    <div class="alert-text">
      <p><strong>Note</strong>:  For <em>Case Product Dosages</em>, Vault orders output values by earliest to latest.</p>
    </div>
  </div>
</div>



This function includes the following inputs:

* `Object`: Specifies the object on which the fields exist
    * Supports objects depending on if your input includes the `GroupBy_optional` input:
        * Excludes input: Supports all _Case_ child and grandchild objects as well as linked _Cases_  and _Transmissions_
            * Supports `case_relationships_case__vr` and `case_relationships_related_case__vr` to reference _Case_ relationships
            * Supports `transmissions_case_version__vr` to reference the _Transmissions_ of the _Case_
        * Includes input: Supports the following objects:
            * `case_adverse_event__v`
            * `case_assessment_result__v`
            * `case_drug_history__v`
            * `case_medical_history__v`
            * `case_product__v`
            * `case_test_result__v`
* `condition`: Specifies the conditions for which Vault considers records for the output
    * Supports the listed [Vault Platform][15] and [Safety][16] functions as well as field references
    * Supports the `ALL` operator, which allows you to include all _Case_ children within the output
* `GroupBy_optional`: This optional input specifies how Vault groups multiple statements when multiple records meet the condition
    * Supports the following fields:
        * `assessment_result__v`
        * `date_normalized__v`
        * `drug_role__v`
        * `indication__v`
        * `onset_normalized__v`
        * `source_type__v`
        * `start_date_normalized__v`
    * Supports the `list` operator, which allows you to list any _Case_ children within the output for unnested `VS_Repeat` functions
    * Vault orders the rendered records by when it encounters the first record of each group
* `"textOrFunctionToRepeat"`: Specifies which text or function repeats
    * Supports the listed [Vault Platform][15] and [Safety][16] functions as well as field references

###### Examples

The following example repeats the phrase `${adverse event reported}` with outcome `${outcome}` when there are multiple _Case Adverse Events_ that meet the specified [condition][7] (_Seriousness_ field is blank):

````
${VS_Repeat(
        case_adverse_event__v,
        isBlank(case_adverse_event__v.seriousness__v),
        onset_normalized__v,
        ${VS_PrefixDate(case_adverse_event__v,uppercase, onset_normalized__v)}" the patient experienced "
        ${VS_Repeat(
                case_adverse_event__v,
                isBlank(case_adverse_event__v.seriousness__v),
                ${case_adverse_event__v.event_reported__v}" with outcome "${case_adverse_event__v.outcome__v}
        )}"."
)} 
````

The rendered output for this example includes all non-serious events with the same onset date in a single sentence and may look like the following:

`On 27-Oct-2024, the patient experienced upset stomach with outcome resolved, sore muscles with outcome ongoing, and fever with outcome resolved.`

The following example repeats the concomitant medications when there are multiple _Case Products_ that meet the specified [condition][7]: 

````
"The patient received concomitant medications "
${VS_Repeat(
    case_product__v,
    case_product__v.drug_role__vr.api_name__v ="concomitant__v",
    list,
    ${case_product__v.product_reported__v}
)}"."
````
The rendered output for this example may look like the following:

`The patient received concomitant medications WonderDrug, Cholecap, VeeProm, and Natevba.`


[1]: #types
[2]: #records
[3]: #review
[4]: #narrative-outlines
[5]: #narrative-statements
[6]: #narrative-statement-options
[7]: #conditions
[8]: #formulas
[9]: #vs_anyof
[10]: #vs_contains
[11]: #vs_hasone
[12]: #vs_hasmany
[13]: #vs_let
[14]: #vs_matches
[15]: #platform-functions
[16]: #safety-functions
[17]: #vs_existcheck
[18]: #vs_omitreason
[19]: #vs_prefixdate
[20]: #vs_repeat
[21]: #vs_prefixdaterang
[22]: #vs_dosefrequency
[23]: #vs_casedocuments