- Visão geral
- Atividades personalizadas
- Migrando Atividades para o .NET 6
- Notas de Versão
- Como Criar Regras do Analisador de Fluxo de Trabalho
- Como criar as configurações de projeto de atividades
- Como criar assistentes personalizados
- Priorizar atividades por escopo
- UiPath.Activities.Api.Base
- UiPath.Studio.Activities.Api
- UiPath.Studio.Activities.Api.Activities
- UiPath.Studio.Activities.Api.BusyService
- UiPath.Studio.Activities.Api.ExpressionEditor
- UiPath.Studio.Activities.Api.Expressions
- UiPath.Studio.Activities.Api.Licensing
- UiPath.Studio.Activities.Api.Mocking
- UiPath.Studio.Activities.Api.ObjectLibrary
- UiPath.Studio.Activities.Api.PackageBindings
- UiPath.Studio.Activities.Api.ProjectProperties
- UiPath.Studio.Activities.Api.ScopedActivities
- UiPath.Studio.Activities.Api.Settings
- UiPath.Studio.Activities.Api.Wizards
- UiPath.Studio.Activities.Api.Workflow
- UiPath.Studio.Api.Controls
- UiPath.Studio.Api.Telemetry
- UiPath.Studio.Api.Theme
- Robot JavaScript SDK
- Gatilhos SDK
Guia do desenvolvedor
Escrever o código da atividade
Para exemplificar como escrever código de atividade, recriaremos uma atividade Calculator simples que está incluída na solução de exemplo UiPath.Examples.Activities que você pode baixar do GitHub. Esta atividade leva dois números e uma operação (adicionar, subtrair, multiplicar ou dividir) como entrada e retorna o resultado da operação selecionada.
O código da atividade consiste de duas partes: a lógica da atividade e o design da atividade.
Começando com UiPath.Activities.Template, vamos renomear a solução e todos os arquivos e referências relacionados para UiPath.Examples.Activities.
- Renomeie o arquivo que contém a lógica da atividade de ActivityTemplate.cs para Calculator.cs.
-
Atualize as referências e o namespace da seguinte forma:
using System.Activities; using System.Diagnostics; using UiPath.Examples.Activities.Helpers; namespace UiPath.Examples.Activities { }
using System.Activities; using System.Diagnostics; using UiPath.Examples.Activities.Helpers; namespace UiPath.Examples.Activities { } -
Declarar os argumentos de entrada — dois números (
FirstNumber
eSecondNumber
comoint
) e a operação a ser realizada (SelectedOperation
comoenum
, com um valor padrão opcional definido comoMultiply
). Marque todos os três argumentos como obrigatórios usando o atributo[RequiredArgument]
. O valor retornado será usado para definir o valor do argumento de Resultado.public class Calculator : CodeActivity<int> // This base class exposes an OutArgument named Result { [RequiredArgument] public InArgument<int> FirstNumber { get; set; } //InArgument allows a varriable to be set from the workflow [RequiredArgument] public InArgument<int> SecondNumber { get; set; } [RequiredArgument] public Operation SelectedOperation { get; set; } = Operation.Multiply; // default value is optional /* * The returned value will be used to set the value of the Result argument */ }
public class Calculator : CodeActivity<int> // This base class exposes an OutArgument named Result { [RequiredArgument] public InArgument<int> FirstNumber { get; set; } //InArgument allows a varriable to be set from the workflow [RequiredArgument] public InArgument<int> SecondNumber { get; set; } [RequiredArgument] public Operation SelectedOperation { get; set; } = Operation.Multiply; // default value is optional /* * The returned value will be used to set the value of the Result argument */ } -
Começando a parte de execução, adicionaremos registros de log, obteremos os valores dos números do contexto do fluxo de trabalho e adicionaremos lógica para lidar com o cenário de uma divisão por zero.
protected override int Execute(CodeActivityContext context) { // This is how you can log messages from your activity. logs are sent to the Robot which will forward them to Orchestrator context.GetExecutorRuntime().LogMessage(new Robot.Activities.Api.LogMessage() { EventType = TraceEventType.Information, Message = "Executing Calculator activity" }); var firstNumber = FirstNumber.Get(context); //get the value from the workflow context (remember, this can be a variable) var secondNumber = SecondNumber.Get(context); if (secondNumber == 0 && SelectedOperation == Operation.Divide) { throw new DivideByZeroException("Second number should not be zero when the selected operation is divide"); } return ExecuteInternal(firstNumber, secondNumber); }
protected override int Execute(CodeActivityContext context) { // This is how you can log messages from your activity. logs are sent to the Robot which will forward them to Orchestrator context.GetExecutorRuntime().LogMessage(new Robot.Activities.Api.LogMessage() { EventType = TraceEventType.Information, Message = "Executing Calculator activity" }); var firstNumber = FirstNumber.Get(context); //get the value from the workflow context (remember, this can be a variable) var secondNumber = SecondNumber.Get(context); if (secondNumber == 0 && SelectedOperation == Operation.Divide) { throw new DivideByZeroException("Second number should not be zero when the selected operation is divide"); } return ExecuteInternal(firstNumber, secondNumber); } -
Adicione os cálculos a serem executados para cada operação selecionada.
public int ExecuteInternal(int firstNumber, int secondNumber) { return SelectedOperation switch { Operation.Add => firstNumber + secondNumber, Operation.Subtract => firstNumber - secondNumber, Operation.Multiply => firstNumber * secondNumber, Operation.Divide => firstNumber / secondNumber, _ => throw new NotSupportedException("Operation not supported"), }; }
public int ExecuteInternal(int firstNumber, int secondNumber) { return SelectedOperation switch { Operation.Add => firstNumber + secondNumber, Operation.Subtract => firstNumber - secondNumber, Operation.Multiply => firstNumber * secondNumber, Operation.Divide => firstNumber / secondNumber, _ => throw new NotSupportedException("Operation not supported"), }; } -
Defina as operações.
public enum Operation { Add, Subtract, Multiply, Divide }
public enum Operation { Add, Subtract, Multiply, Divide }
int
das propriedades FirstNumber
e SecondNumber
resulta em um editor de números como o campo de entrada para as propriedades, enquanto que para Operation
, que tem o tipo de dados enum
, um menu suspenso estará disponível na atividade.
Os rótulos e dicas de ferramentas das propriedades podem ser definidos no arquivo Resources.resx.
A tabela a seguir descreve as propriedades mais comuns disponíveis para cada propriedade de atividade.
Propriedade | Description |
---|---|
NomeDeExibição | O rótulo da propriedade. |
Dica de ferramenta | O texto a ser exibido ao passar o mouse sobre a propriedade |
É Necessário1 | Se a propriedade é necessária. As propriedades obrigatórias também devem ser marcadas na atividade usando o atributo [RequiredArgument] .
|
ÉPrincipal2 | Determina se a propriedade deve estar sempre visível na categoria principal da atividade. Se definida como false , a propriedade é exibida no menu Mostrar opções avançadas que é recolhido por padrão.
|
ÍndiceDeOrdem | A ordem de exibição da propriedade. |
1 Não disponível para as propriedades de saída, que nunca são obrigatórias.
2 Por convenção, as propriedades de saída são colocadas no final da atividade, em opções avançadas.
- Renomeie o arquivo ActivityTemplateViewModel.cs para CalculatorViewModel.cs e adicione o código para a interface do usuário da atividade a ele.
-
Atualize as referências e o namespace da seguinte forma:
using System.Activities.DesignViewModels; using System.Diagnostics; namespace UiPath.Examples.Activities.ViewModels { }
using System.Activities.DesignViewModels; using System.Diagnostics; namespace UiPath.Examples.Activities.ViewModels { } -
Declarar as propriedades de entrada. A propriedade result vem da classe base da atividade. Os nomes e argumentos de tipo devem corresponder aos da atividade.
public class CalculatorViewModel : DesignPropertiesViewModel { /* * Properties names must match the names and generic type arguments of the properties in the activity * Use DesignInArgument for properties that accept a variable */ public DesignInArgument<int> FirstNumber { get; set; } public DesignInArgument<int> SecondNumber { get; set; } /* * Use DesignProperty for properties that accept a constant value */ public DesignProperty<Operation> SelectedOperation { get; set; } /* * The result property comes from the activity's base class */ public DesignOutArgument<int> Result { get; set; } public CalculatorViewModel(IDesignServices services) : base(services) { } }
public class CalculatorViewModel : DesignPropertiesViewModel { /* * Properties names must match the names and generic type arguments of the properties in the activity * Use DesignInArgument for properties that accept a variable */ public DesignInArgument<int> FirstNumber { get; set; } public DesignInArgument<int> SecondNumber { get; set; } /* * Use DesignProperty for properties that accept a constant value */ public DesignProperty<Operation> SelectedOperation { get; set; } /* * The result property comes from the activity's base class */ public DesignOutArgument<int> Result { get; set; } public CalculatorViewModel(IDesignServices services) : base(services) { } } -
Adicione o código para o design de atividade. Opcionalmente, podemos adicionar um ponto de interrupção para depurar a inicialização de ViewModel descomentando a linha que contém
Debugger.Break();
. Vamos inicializar as propriedades do ViewModel, adicionar umaPersistValuesChangedDuringInit()
chamada que é obrigatória quando você altera os valores das propriedades durante a inicialização e definir as propriedades de entrada e saída da atividade.O código deve ter a seguinte aparência:
protected override void InitializeModel() { //Debugger.Break(); /* * The base call will initialize the properties of the view model with the values from the xaml or with the default values from the activity */ base.InitializeModel(); PersistValuesChangedDuringInit(); // just for heads-up here; it's a mandatory call only when you change the values of properties during initialization var orderIndex = 0; FirstNumber.DisplayName = Resources.Calculator_FirstNumber_DisplayName; FirstNumber.Tooltip = Resources.Calculator_FirstNumber_Tooltip; /* * Required fields will automatically raise validation errors when empty. * Unless you do custom validation, required activity properties should be marked as such both in the view model and in the activity: * -> in the view model use the IsRequired property * -> in the activity use the [RequiredArgument] attribute. */ FirstNumber.IsRequired = true; FirstNumber.IsPrincipal = true; // specifies if it belongs to the main category (which cannot be collapsed) FirstNumber.OrderIndex = orderIndex++; // indicates the order in which the fields appear in the designer (i.e. the line number); SecondNumber.DisplayName = Resources.Calculator_SecondNumber_DisplayName; SecondNumber.Tooltip = Resources.Calculator_SecondNumber_Tooltip; SecondNumber.IsRequired = true; SecondNumber.IsPrincipal = true; SecondNumber.OrderIndex = orderIndex++; SelectedOperation.DisplayName = Resources.Calculator_SelectedOperation_DisplayName; SelectedOperation.Tooltip = Resources.Calculator_SelectedOperation_Tooltip; SelectedOperation.IsRequired = true; SelectedOperation.IsPrincipal = true; SelectedOperation.OrderIndex = orderIndex++; /* * Output properties are never mandatory. * By convention, they are not principal and they are placed at the end of the activity. */ Result.DisplayName = Resources.Calculator_Result_DisplayName; Result.Tooltip = Resources.Calculator_Result_Tooltip; Result.OrderIndex = orderIndex; }
protected override void InitializeModel() { //Debugger.Break(); /* * The base call will initialize the properties of the view model with the values from the xaml or with the default values from the activity */ base.InitializeModel(); PersistValuesChangedDuringInit(); // just for heads-up here; it's a mandatory call only when you change the values of properties during initialization var orderIndex = 0; FirstNumber.DisplayName = Resources.Calculator_FirstNumber_DisplayName; FirstNumber.Tooltip = Resources.Calculator_FirstNumber_Tooltip; /* * Required fields will automatically raise validation errors when empty. * Unless you do custom validation, required activity properties should be marked as such both in the view model and in the activity: * -> in the view model use the IsRequired property * -> in the activity use the [RequiredArgument] attribute. */ FirstNumber.IsRequired = true; FirstNumber.IsPrincipal = true; // specifies if it belongs to the main category (which cannot be collapsed) FirstNumber.OrderIndex = orderIndex++; // indicates the order in which the fields appear in the designer (i.e. the line number); SecondNumber.DisplayName = Resources.Calculator_SecondNumber_DisplayName; SecondNumber.Tooltip = Resources.Calculator_SecondNumber_Tooltip; SecondNumber.IsRequired = true; SecondNumber.IsPrincipal = true; SecondNumber.OrderIndex = orderIndex++; SelectedOperation.DisplayName = Resources.Calculator_SelectedOperation_DisplayName; SelectedOperation.Tooltip = Resources.Calculator_SelectedOperation_Tooltip; SelectedOperation.IsRequired = true; SelectedOperation.IsPrincipal = true; SelectedOperation.OrderIndex = orderIndex++; /* * Output properties are never mandatory. * By convention, they are not principal and they are placed at the end of the activity. */ Result.DisplayName = Resources.Calculator_Result_DisplayName; Result.Tooltip = Resources.Calculator_Result_Tooltip; Result.OrderIndex = orderIndex; } - Adicione os valores da string para os rótulos e dicas de ferramentas no arquivo Resources.resx como na imagem a seguir. Para fins de localização, você deve usar comentários específicos para o nome da atividade (
Activity name
) e a descrição da atividade (Activity description
). Para outras strings, adicionar comentários é recomendado, mas não obrigatório.
No Studio, a configuração resulta no seguinte:
1 – Rótulos (nomes de exibição) das três propriedades de entrada.
FirstNumber
.