REFramework Documentation-EN-2021.10
REFramework Documentation-EN-2021.10
REFramework Documentation-EN-2021.10
Enterprise
Framework
Contents
Overview.............................................................................................................................4
Main Features.....................................................................................................................5
Settings ...........................................................................................................................5
Logging ............................................................................................................................9
Architecture ......................................................................................................................12
States ............................................................................................................................12
Workflows .....................................................................................................................17
Framework\InitAllSettings.xaml ...............................................................................17
Framework\KillAllProcesses.xaml ............................................................................18
Framework\InitAllApplications.xaml ........................................................................19
Framework\GetTransactionData.xaml .....................................................................19
Framework\Process.xaml .........................................................................................21
Framework\SetTransactionStatus.xaml ...................................................................22
Framework\RetryCurrentTransaction.xaml .............................................................24
Framework\TakeScreenshot.xaml ...........................................................................25
Framework\CloseAllApplications.xaml ....................................................................25
Data\Config.xlsx........................................................................................................26
Main.xaml.................................................................................................................27
Framework\GetTransactionData.xaml .....................................................................28
Framework\Process.xaml .........................................................................................29
Framework\SetTransactionStatus.xaml ...................................................................30
Practical Example 1: Using Queues..........................................................31
Although different RPA implementations can have their own unique traits, a common
set of practices can usually be seen in successful projects. Among those, flexible
configuration, robust exception handling and meaningful logging make projects easier
to implement, understand and maintain. In addition, in the case of large
implementations, scalability also becomes an important factor due to the volume of data
processed.
This guide describes the framework in detail with realistic use cases and practical
examples. Firstly, section Transaction Processing introduces different types of
processes and explains how they are related to the REFramework. After that, an
overview of the main aspects of the framework is offered in section Main Features. Next,
the workflows that compose the framework are detailed in Architecture section. Section
Using the Framework clarifies how to use the framework in practice and includes two
step-by-step examples. Moreover, the Test Framework section outlines how to use the
unit testing capabilities of the framework. The last section, Distribution and Support to
Extensions , presents the framework’s license and policies related to distribution and
support.
Transaction Processing
Although business processes can have different characteristics, it is usually possible to
classify them based on how they repeat certain steps when processing data.
For example, consider a business process that extracts certain data from a PDF file
specified by a user and inputs that data into a web system. In this scenario, to extract
data from a different PDF file, the user must execute the process again
and pass the new file as input.
However, if a user specifies a batch of PDF files instead of just one, the same processing
steps are repeated for each of the files in the batch. In this case, if each of the PDF files
can be processed independent of each other, then it is possible to say that each file is a
transaction within the whole process. In other words, a transaction represents a single
unit of work that can be independently processed.
Main Features
Other than naturally enabling transactional processing, the REFramework also has other
features that are helpful in the implementation of stable and scalable automation
projects: settings, logging, and exception handling.
Settings
To make it easier to maintain a project and quickly change configuration values, it is a
good practice to keep them separated from the workflows themselves. In such cases, a
configuration file can be used to define parameters that are used throughout the project
and to avoid hardcoded values in workflows.
The REFramework offers a configuration file, named Config.xlsx and located in the Data
folder, which can be used to define project configuration parameters.
Table 1 - Examples of constants.
For easier manipulation, this configuration file is an Excel workbook with three sheets:
• Settings: Configuration values to be used throughout the project
and that usually depend on the environment being used. For example,
names of queues, folder paths or URLs for web systems.
• Constants: Values that are supposed to be the same across all deployments of
the workflow. For example, the department name or the bank name to be used
as input in a certain screen.
For instance, if a process needs to define a constant for a department name, then that
can be added to the Constants sheet: the name is Department, the value is Accounting,
and the explanation is Default name for department . Then, during the implementation
of workflows, developers can use Config(“Department”) to retrieve the value
Accounting. Figure 1 illustrates this relationship between the configuration file
Config.xlsx and the Config dictionary.
Config Dictionary
Key Value Usage
The Assets sheet behaves differently than the other two, since the Name column
establishes the key to be included in the Config dictionary, and the Value column
determines the name of the asset as defined in Orchestrator.
Figure 2 shows the relationship between the assets defined in Orchestrator, their
definition in the Assets sheet of the Config.xlsx file and their usage in workflows by
means of the Config dictionary.
Orchestrator Asset
Config Dictionary
Key Value Usage
For example, if there is an asset in Orchestrator called CountryName, there can be a row
in the Assets sheet whose Name is CountryAsset and whose Value is CountryName.
During the initialization phase, the framework retrieves the contents of the
CountryName asset and inserts it as a value corresponding to the key CountryAsset in
the Config dictionary.
The above example uses different names for the asset name in Orchestrator
(CountryName) and the corresponding dictionary key ( CountryAsset), but it is common
to use the same name for both. By doing so, it becomes easier to maintain the
configuration file and to reduce naming mistakes during development.
The Assets sheet from the Config.xlsx file contains the OrchestratorAssetFolder column.
This column stores the path of the Orchestrator folder where the asset is located and
must be retrieved from.
In case one of the Assets is not found in Orchestrator, an exception will be thrown,
resulting in the Job being stopped.
Although the Assets sheet can be used for most types of assets, it cannot be used for
assets of type credential, since credentials have two values: username and password. To
use credential assets defined in Orchestrator, include them in the Settings sheet instead
(Figure 3): the Name column defines the key in the Config dictionary, the Value column
determines the name of the credential asset, and the Description column provides an
explanation about the credential. During the implementation, use the Get Credential
activity to retrieve the credential from Orchestrator.
If the credential asset is stored in a different Orchestrator folder than the one where the
process is running, an additional row in the Settings sheet might be needed in order to
store the folder name.
Config Dictionary
Figure 3 - Relationship Between Orchestrator Credential Assets, Config.xlsx and Config Dictionary.
As a final note about Config.xlsx, since the configuration file is not encrypted, it should
not be used to directly store credentials. Instead, it is safer to use Orchestrator assets or
Windows Credential Manager to save sensitive data.
Logging
The proper use of logging in an automation project has several benefits, such as better
visibility of actions and events, easier debugging and more meaningful auditing.
The REFramework has a comprehensive logging structure that uses different levels of
the Log Message activity to output the statuses for the transactions, the exceptions, and
the transition between states. Most of the used log messages have static parts that are
configured in the Constants sheet of the Config.xlsx file.
Other than the regular log fields included in messages generated by robots (e.g., robot
name and timestamp), the REFramework uses additional custom log fields to add more
data about each transaction. When retrieving a new transaction to be processed, in the
file GetTransactionData.xaml, it is possible to define values for the custom log fields
TransactionId, TransactionField1 and TransactionField2.
Figure 4 - Addition and Removal of Custom Log Fields.
Figure 4 shows part of the SetTransactionStatus.xaml file, which adds custom fields to
log messages using the Add Log Fields activity. Note that, after the Log Message activity
is used, the added fields are removed using the Remove Log Fields activity. This
guarantees that the custom fields previously defined are used just inside the desired log
message activity and not in all the following ones, as well.
Although the use of custom log fields is optional, they can be used to include extra
information about transactions, which might be helpful during debugging and
troubleshooting.
Additionally, these custom log fields can be leveraged for business reporting purposes.
For example, in a process which considers invoices as transactions, the invoice number
can be assigned to the TransactionId field, the invoice date to TransactionField1 and the
total amount to TransactionField2. By using logs generated with such data, it is possible
to construct visualizations displaying the days in a month in which a large number of
invoices were processed or showing the aggregated total amount processed during a
certain period of time (Figure 5).
Figure 5 - Example of Reporting Using Custom Log Fields.
Note that sensitive data should not be included in logs, since they are not encrypted and
might lead to privacy issues if leaked.
Exceptions that happen during the framework’s execution are divided into two
categories:
• System Exceptions: If an exception is not related to the rules of the process itself,
it is considered a system exception. Examples of system exceptions include an
activity that timed-out due to slow network connection or a selector not
found because of a browser crash.
Note that both business exceptions and system exceptions are concepts that also exist
in Orchestrator under the names Business Exceptions and Application Exceptions. In
fact, if the source of transactions is an Orchestrator queue, then the number of retries
in the case of system exceptions can be set directly on Orchestrator. If the Orchestrator
is not used, the configuration for retries is done in the Config.xlsx file, as mentioned in
Settings section.
To avoid consuming all queue items when a persistent error occurs (e.g. application is
unavailable), the constant MaxConsecutiveSystemExceptions should be used. If the
MaxConsecutiveSystemExceptions setting is different than 0 and the number of
consecutive system exceptions is reached, the job is stopped. To enable this feature, the
value of the constant should be set to an integer greater than 0.
By default, all Exceptions are handled by the REFramework, resulting in the Job being
marked as Successful even when an exception occurs in the Init State. However, if the
value of ShouldMarkJobAsFaulted constant is changed to TRUE and an error occurs in
the Initialization state or the MaxConsecutiveSystemExceptions is reached, the job is
marked as Faulted. This enables organizations to make use of the Media Recording
feature from Orchestrator to easily identify the error cause.
Architecture
The REFramework is implemented as a state machine workflow, which is a kind of
workflow that defines states. Each state represents a particular circumstance of the
execution. Depending on certain conditions, the execution can transition from one state
to another.
States
The states of the REFramework can be seen in Figure 6, and they are detailed as follows:
• Initialization: Read the configuration file and initialize the
applications used in the process. If the initialization is successful, the
execution moves to the Get Transaction Data state; in case of failure, it moves
to the End Process state. If a system exception occurs during the processing of a
transaction, the framework attempts to recover from the error by closing all
applications used and returning to the Initialization state so the applications can
be initialized again.
• End Process: Finalize the process and close all applications used.
Figure 6 - State Machine with the States of the REFramework.
Table 2 - Workflows Invoked in States.
Initialization
InitAllSettings.xaml
KillAllProcesses.xaml
InitAllApplications.xaml
SetTransactionStatus.xaml
• RetryCurrentTransaction.xaml
• TakeScreenshot.xaml
• CloseAllApplications.xaml
• KillAllProcesses.xaml
End Process
CloseAllApplications.xaml
KillAllProcesses.xaml
Each state invokes one or more workflows, which are listed in Table 2 and detailed in
the section Workflows .
Shared Variables
Table 3 shows the variables declared in the Main.xaml file and which are passed as
arguments to the workflows invoked in different states.
One important variable that is passed to almost all the workflows invoked in Main.xaml
is the Config dictionary. This variable is initialized by the InitAllSettings.xaml workflow
in the Initialization state, and it contains all the configuration declared in the Config.xlsx
file. Since it is a dictionary, the values in Config can be accessed by its keys, like
Config(“Department”) or Config(“System1_URL”). Note that, although it is present in
the Config.xlsx file, the Description of each value is not included in the dictionary.
Table 3 - Shared Variables.
TransactionNumber Int32
Sequential counter of
transaction items.
TransactionField1 String
Optionally used to include
additional information about
the transaction item.
TransactionField2 String
Optionally used to include
additional information about
the transaction item.
Workflows
This section details the workflows that compose the REFramework, including overview,
purpose and arguments. When applicable, it is also mentioned what parts need to be
modified if the transaction type is not QueueItem.
Framework\InitAllSettings.xaml
This workflow, located in the Framework folder, initializes, populates and outputs a
configuration dictionary, Config, to be used throughout the project. Settings and
constants are read from the local configuration file, Data\Config.xlsx, and assets are
fetched from Orchestrator. Asset values overwrite settings and constant
values if they are defined with the same name. Table 4 shows the
arguments used by
InitAllSettings.xaml.
Table 4 - Arguments of InitAllSettings.xaml.
in_ConfigFile “Data\Config.xlsx”
Path to the configuration file that
defines settings, constants and
assets.
in_ConfigSheets {"Settings","Constants"}
Names of the sheets corresponding
to settings and constants in the
configuration file.
If an exception occurs during the execution of this workflow - for example, if the
configuration file is not found, it is caught by the Try Catch activity in the Initialization
state and the execution transitions into the End Process state.
Framework\KillAllProcesses.xaml
After the initialization of settings, the framework can perform actions to make sure that
the system is in a clean state before the main process starts. This can be done by using
the Kill Process activity, which forces the termination of a Windows process
representing an application used in the business process. Note that killing processes
might have undesirable outcomes, such as losing unsaved changes to files. The
KillAllProcesses.xaml workflow, located in the Framework folder, can be used to
implement such cleanup steps.
Also, despite the name of this workflow, it is not mandatory to always kill all the
processes used, and other steps might be more appropriate to return the system to a
clean state. Ultimately, such steps depend on the requirements of the business process.
Table 5 - Argument of InitAllApplications.xaml.
Argument Description Default Value
Framework\InitAllApplications.xaml
The InitAllApplications.xaml workflow, located in the Framework folder, can be used to
initialize applications operated during the execution of the process. It can contain
activities like Open Application activities and Open Browser, or it can also invoke other
workflows that implement actions like login and authentication.
Table 5 shows that this workflow receives only one argument, the configuration
dictionary, Config, which can contain data necessary to start certain applications (e.g.,
URL of a web application).
Framework\GetTransactionData.xaml
This workflow, located in the Framework folder, attempts to retrieve a transaction item
from a specified source (e.g., Orchestrator queues, spreadsheets, databases, mailboxes
or web APIs).
For cases in which there is only a single transaction (i.e., a linear process), the developer
should add an If activity to check whether the argument in_TransactionNumber has the
value 1 (meaning it is the first and only transaction) and assign the transaction item to
out_TransactionItem. In such cases, for any other value of in_TransactionNumber,
out_TransactionItem should be set to Nothing (Figure 7).
Table 6 - Arguments of GetTransactionData.xaml
If there are multiple transactions from a source other than an Orchestrator queue, use
the argument in_TransactionNumber as an index to retrieve the correct transaction to
be processed. If there are no more transactions left, it is necessary to set
out_TransactionItem to Nothing, thus leading to the end of the process.
The GetTransactionData.xaml workflow assumes the use of Orchestrator queues by
default, and the first activity tries to retrieve a new transaction item from an
Orchestrator queue. This situation is illustrated by the example in section Practical
Example 1: Using Queues .
If Orchestrator queues are not used, replace the Get Transaction Item activity with the
appropriate logic to retrieve the transaction items. For example, if the transactions are
rows from a DataTable, the row corresponding to the current transaction is retrieved at
this point. Section Practical Example 2: Using Tabular Data offers an example of this
case.
Lastly, note that this workflow contains an optional step that can be used to include
more information about a transaction item, and it is used mainly for logging and
visualization purposes. For example, if the transaction items for a given process are
invoices, then out_TransactionID can be the invoice number, out_TransactionField1 can
be the invoice date and out_TransactionField2 can be the invoice amount. The Logging
section offers more information about logging with custom log fields.
Framework\Process.xaml
The Process.xaml workflow is used to invoke the major steps of the business process,
which are commonly implemented by multiple sub-workflows. Its main argument is
in_TransactionItem, which represents the piece of data to be processed. The default
type for the argument in_TransactionItem is QueueItem (Table 7), and it should be
changed in case other types are used (e.g., DataRow, String or MailMessage).
On the other hand, system exceptions are characterized by exceptions whose types are
different than BusinessRuleException. When this kind of exception happens, the
transaction item can be retried after closing and reopening the applications involved in
the process. The idea behind this behavior is that the exception was caused by a problem
in the applications being automated (e.g., a system that freezes), which might be solved
by restarting them.
If an Orchestrator queue is the source of transactions, the Set Transaction Status activity
is used to update their status. In addition, the retry mechanism is also managed by
Orchestrator.
If Orchestrator queues are not used, the status can be set, for example, by writing to a
specific column in a spreadsheet. In such cases, the retry mechanism is managed by the
framework itself and the number of retries is defined in the configuration file.
in_Config No default
Dictionary structure to store
value
configuration data.
in_SystemException Exception variable that is used No default
during transitions between value
states.
io_TransactionNumber No default
Sequential counter of
value
transaction items.
in_TransactionField1 No default
Allow the optional addition of
value
information about the
transaction item.
in_TransactionField2 No default
Allow the optional addition of
value
information about the
transaction item.
Framework\RetryCurrentTransaction.xaml
Table 9 provides details about the arguments of RetryCurrentTransaction.xaml, located
in the Framework folder. This workflow manages the retrying mechanism for the
framework, and it is invoked in SetTransactionStatus.xaml when a system exception
occurs.
Framework\TakeScreenshot.xaml
This workflow, located in the Framework folder, captures a screenshot of the whole
screen and saves it with the PNG extension in a folder specified by the argument
in_Folder (Table 10).
If an Orchestrator queue is used and a transaction item fails due to a System Exception,
the path of the screenshot is saved in the Transaction Item Details.
Framework\CloseAllApplications.xaml
This workflow, located in the Framework folder, does the necessary procedures for
ending the process and closing the used applications. Similar to
OpenAllApplications.xaml, activities can be placed directly in this workflow or,
preferably, sub-workflows can be invoked to perform more complex steps, such as
logging out of a system.
Using the Framework
The REFramework is available as a UiPath Studio project template (Figure 8), and when
creating a new project starting from the REFramework template, it will automatically
include all the files explained above.
Data\Config.xlsx
Other than adding the necessary settings, constants and assets that depend on the
process, make the following modifications:
Main.xaml
First, set the type of the TransactionItem variable according to the type of the process
transaction. The default type is QueueItem, but it can be changed, for example, to
DataRow in case rows are being read from an Excel file or to MailMessage in case emails
are retrieved from an email account.
If queues are used, there is no need for further modifications. However, if the type is
changed, the following workflows should also be updated, since they expect the variable
TransactionItem to be of type QueueItem: GetTransactionData.xaml, Process.xaml and
SetTransactionStatus.xaml. Section Practical Example 2: Using Tabular Data provides
an example of how to do such updates.
After the above workflows are adjusted, it is also necessary to update the arguments
passed by the corresponding Invoke Workflow File activities: GetTransactionData.xaml
is invoked in the Get Transaction Data state, and both Process.xaml and
SetTransactionStatus.xaml are invoked in the Process Transaction state. Updating
arguments can be done by clicking the Import Arguments button of the Invoke Workflow
File activity and entering the variables that are passed to the adjusted arguments, as
shown in Figure 9.
Framework\GetTransactionData.xaml
If Orchestrator queues are used, the transaction retrieval is handled by the Get
Transaction Item activity included by default, and it is not necessary to make any
modifications to the GetTransactionData.xaml workflow.
If transactions are of types other than QueueItem, change the type of the
out_TransactionItem argument to match the process’s transaction type (for example,
DataRow or MailMessage). To define a new data source, replace the first activity of this
workflow, Get Transaction Item, with appropriate data retrieval. For example, use the
Read Range activity to retrieve data from a spreadsheet and save it to the
io_dt_TransactionData argument. After that, make sure that the new type of
out_TransactionItem is reflected in the Invoke Workflow File activity that invokes this
workflow in the Get Transaction Data state of Main.xaml.
Once the data source is defined, it is necessary to include steps to get transaction items.
For cases in which there is only a single transaction, check whether the argument
in_TransactionNumber has the value 1 (meaning it's the first and only transaction) and
assign the transaction item to out_TransactionItem. For any other value of
in_TransactionNumber, out_TransactionItem should be set to Nothing (Figure 10).
If there are multiple transactions, use the argument in_TransactionNumber as an index
to retrieve the correct transaction to be processed. If there are no more transactions
left, it is necessary to set out_TransactionItem to Nothing, thus ending the process
(Figure 11).
Figure 11 - Configuration for Transactional Process (Multiple Transactions).
Optionally, it is possible to add information about the transaction item using the Assign
activities in the sequence named Add transaction information to log fields at the end of
this workflow. For example, for creating reports about an invoice processing
automation, one might use out_TransactionID to store invoice number,
out_TransactionField1 to store invoice date and out_TransactionField2 to store the
total amount, as mentioned in section Logging and illustrated in Figure 12.
Framework\Process.xaml
No special changes need to be made to Process.xaml if Orchestrator queues are used.
Each transaction item is accessible in this workflow via the argument
in_TransactionItem. For instance, in an invoice processing automation
project, in_TransactionItem.SpecificContent("InvoiceNumber") can be
used to retrieve the invoice number and
in_TransactionItem.SpecificContent("TotalAmount") may be used to obtain the total
amount.
If Orchestrator queues are not used, set the type of the in_TransactionItem argument
to match the type defined for the variable TransactionItem in Main.xaml. After that,
make sure that the new type of in_TransactionItem is reflected in the Invoke Workflow
File activity that invokes this workflow in the Process Transaction state of Main.xaml.
Framework\SetTransactionStatus.xaml
As mentioned in section Framework\SetTransactionStatus.xaml, this workflow is called
after the Process.xaml workflow is executed, and it sets the status of the transaction
according to the result of the processing step.
If the process’s data source is an Orchestrator queue, the status of the queue item is
updated by the Set Transaction Status activity by default and no further changes are
necessary.
For processes that do not use an Orchestrator queue, in addition to adjusting the type
of the in_TransactionItem argument, the appropriate steps must be implemented to set
the transaction status. After that, make sure that the new type of in_TransactionItem is
reflected on the Invoke Workflow File activity that invokes this workflow in the Process
Transaction state of Main.xaml.
If it is not desirable to track statuses of transactions, then it is possible to keep the type
of the in_TransactionItem argument as it is (i.e., QueueItem) and simply pass the value
Nothing to the corresponding argument of the Invoke Workflow File activity in the
Process Transaction state of Main.xaml, as illustrated by Figure 13.
Figure 13 - Configuring Arguments when Invoking SetTransactionStatus.xaml.
As detailed in the Changes to Framework Files section, the processing of invoices can
be implemented by the following steps:
1. In the Settings sheet of the file Data\Config.xlsx, change the value of the
OrchestratorQueueName parameter to Invoices and the value of
logF_BusinessProcessName to InvoiceProcessingSample.
Note that in case an Orchestrator queue is used as data source, only a few modifications
are necessary to be implemented into the framework. It automatically communicates
with the queue set in the configuration file, retrieves one transaction item at a time and
updates the status of the item according to the result of the processing (Figure 15).
Figure 16 - Invoice Data in a Spreadsheet.
1. Similar to the first example, in the Settings sheet of the file Data\Config.xlsx,
change the value of logF_BusinessProcessName to InvoiceProcessingSample.
However, since the data source is not an Orchestrator queue, delete the row
corresponding to OrchestratorQueueName. Add a new setting parameter by
using SampleDataFilepath as the name and, as the value, specify the path for
the input Excel file that has data about invoices to be processed, such as
Data\Input\InvoiceSampleData.xlsx (Figure 17).
Figure 18 - Initializing Data Source (io_dt_TransactionData).
a. Add an If activity that checks whether the data source was initialized with
the condition io_dt_TransactionData Is Nothing (Figure 18). If it was not
initialized, read the spreadsheet from the designated Excel file by using
the Read Range activity and the path defined in the configuration file:
in_Config(“SampleDataFilepath”).ToString .
b. After that, it is necessary to implement the logic to retrieve one row each
time the GetTransactionData.xaml is executed. To do so, add another If
activity and use the condition io_dt_TransactionData.Rows.Count >=
in_TransactionNumber , which verifies whether there are rows to be
processed. If there are unprocessed rows, use an Assign activity to set the
appropriate row to be the current
transaction item:
io_dt_TransactionData.Rows(in_TransactionNumber - 1). Note that
the argument in_TransactionNumber is used to track the row currently
being processed. If there is no unprocessed row left, set
out_TransactionItem to Nothing (Figure 11). This action is necessary to
prevent the framework from attempting to retrieve new transactions.
To summarize, the steps above read data about invoices from an Excel file and use each
row of the file as a transaction. After processing a transaction, the framework updates
the Processed column according to the result of the processing (i.e., success, business
exception and system exception).
Lastly, note that the same steps can be applied for other types of transactions, such as
emails (MailMessage) and paths to files (String).
Test Framework
The REFramework also includes a testing feature that makes it easier to do automatic
testing of workflows. Instead of testing them one by one and checking the results
manually, it is possible to specify the predicted outcome of a workflow (i.e., successful
execution, business exception and system exception) and see whether
the actual results matched the expected results.
Tests\Tests.xlsx - an Excel file that contains a sheet: Tests. In the Tests sheet, the
developer will write the workflow paths of the workflows to be tested and the expected
exception - SystemException, BusinessRuleException or Success.
We identified the need to test each part of the REFramework individually with the right
context set, therefore a set of unit tests per part of process were created:
Tests\MainTestCase.xaml - This test case assumes that the process has a reporting
system in place. It should be configured to verify if the obtained output is the same as
the expected output.
The Test Cases presented above should be treated as samples. Please
modify them and add new ones as required by your process.
UiPath team highly recommends having a CI/CD pipeline in place for each project.
Regarding the adaptation of the framework to particular use cases and transaction
types, it is encouraged that customers and partners understand the steps for extensions
and implement such modifications to better suit their needs. For an example of
extension using spreadsheet data, refer to section Practical Example 2: Using Tabular
Data. Alternatively, templates based on the REFramework can be downloaded from the
UiPath Marketplace (https://marketplace.uipath.com/).