# Programação em C# - Na Regra de Negócio

<p class="callout danger">IMPORTANTE: as variáveis e métodos descritos aqui só funcionarão na programação C# na **Regra de Negócio** do formulário. Para a programação C# nas **APIs** [clique aqui.](https://wiki.agilityflow.io/books/manual-de-customiza%C3%A7%C3%A3o/page/programa%C3%A7%C3%A3o-em-c---na-api-de-integra%C3%A7%C3%A3o "Programação em C# - Na API de integração")</p>

O agilityflow permite a customização em C#, além de já disponibilizar diversas bibliotecas e funções para facilitar sua programação, incluindo acesso a dados, validações, envio de e-mail, notificação, entre outras.

Abaixo mostramos alguns exemplos, se o material abaixo não for suficiente , entre em contato com nossa equipe.

##### C# - Propriedades

<table border="1" id="bkmrk-vari%E3%A1vel-tipo-%E2%A0-fo" style="border-collapse: collapse; width: 150.864%; height: 540px;"><tbody><tr style="height: 31px;"><td style="width: 35.1824%; height: 31px;">**Variável**</td><td style="width: 34.3841%; height: 31px;">**Tipo**</td><td style="width: 81.2977%; height: 31px;"> </td></tr><tr style="height: 94px;"><td style="width: 35.1824%; height: 41px;">IsNovoFormulario</td><td style="width: 34.3841%; height: 41px;">bool</td><td style="width: 81.2977%; height: 41px;">retorna true, caso seja um novo formulário, e false caso contrário.</td></tr><tr style="height: 147px;"><td style="width: 35.1824%; height: 28px;">IdFormulario</td><td style="width: 34.3841%; height: 28px;"><span class="csharp_custom_class_var">Guid</span> </td><td style="width: 81.2977%; height: 28px;">retorna o ID do formulário

</td></tr><tr style="height: 400px;"><td style="width: 35.1824%; height: 400px;">CurrentStatusFluxo</td><td style="width: 34.3841%; height: 400px;"><span class="csharp_custom_class_var">StatusFluxo? (<span style="color: #999999;">Enum</span>)</span></td><td style="width: 81.2977%; height: 400px;">Variável disponível apenas para <span style="text-decoration: underline;">Workflow</span>

Nessa ENUM será retornado o Status do fluxo.

As opções podem ser:

- **StatusFluxo.Pendente -** Enquanto o fluxo ainda estiver pendente em alguma das etapas.
- **StatusFluxo.Aprovado -** Depois do fluxo encerrado e completamente aprovado
- **StatusFluxo.Reprovado -** Depois do fluxo encerrado e completamente reprovado

Exemplo de utilização:

`<span style="color: #0000ff;">if</span>(CurrentStatusFluxo == <span style="color: #00ccff;">StatusFluxo</span>.Aprovado){    <span style="color: #339966;">//restante do código</span>}`

</td></tr><tr style="height: 31px;"><td style="width: 35.1824%; height: 40px;"><span style="color: #ff00ff;">(**deprecated)**</span>

<span style="text-decoration: line-through;"><span style="color: #999999; text-decoration: line-through;">FormularioCamposPreenchidos</span></span>

</td><td style="width: 34.3841%; height: 40px;"><span style="color: #ff00ff;">(**deprecated)**</span>

<span style="text-decoration: line-through;"><span style="color: #999999; text-decoration: line-through;">dynamic (Json)</span></span>

</td><td style="width: 81.2977%; height: 40px;"><span style="color: #ff00ff;">(**deprecated**: utilizar o método FormContext.GetValue descrito mais abaixo)</span>

retorna um json com os campos do preenchidos no formulário, exemplo:

{

 "campo1": "xxxxx",

 "campo2": "yyyyy",

 "campo3": "zzzzz",

}

Para resgatar a informação do campo1, utilize:

`<span style="color: #3366ff;">var</span> campo1 = FormularioCamposPreenchidos[<span style="color: #993300;">"campo1"</span>];`

</td></tr></tbody></table>

##### C# - Buscar e preencher valor de um campo

<table border="1" id="bkmrk-op%E3%A7%E3%A3o-retorno-%E2%A0-g" style="border-collapse: collapse; width: 119.753%; height: 942px;"><tbody><tr style="height: 31px;"><td style="width: 61.7256%; height: 31px;">**Método**</td><td style="width: 12.0385%; height: 31px;">**Retorno**</td><td style="width: 51.2976%; height: 31px;"> </td></tr><tr><td style="width: 61.7256%;">**FormContext.SetValue(**string idCampo, string value)

</td><td style="width: 12.0385%;">void</td><td style="width: 51.2976%;">Esse método preencherá um campo com um novo **Valor** (passado por paramêtro)

Para valores que são **Datas**, utilizar o padrão dd/MM/aaaa HH:mm:ss:

Exemplo:<span style="text-decoration: underline;"> ***31/12/2010 22:55***</span>

```C#
var data_e_hora = "31/01/2023 22:55";
FormContext.SetValue("data_e_hora",data_e_hora);
```

Para valores **Numéricos**, o número deve estar no formato com ponto no separador decimal e sem utilização de virgulas.

Exemplo para 2 milhões e 50 centavos**:**

<span style="text-decoration: underline;">***2000000.50***</span>

```
<strong><code class="language-C#">var moeda = "2000000.50";
FormContext.SetValue("moeda",moeda);</code></strong>
```

[Veja exemplo](https://wiki.agilityflow.io/link/82#bkmrk-atualizar-um-outro-f)

</td></tr><tr style="height: 94px;"><td style="width: 61.7256%; height: 94px;">**FormContext**.**GetValue**(string idCampo)</td><td style="width: 12.0385%; height: 94px;">string</td><td style="width: 51.2976%; height: 94px;">Esse método retornará o **Valor** de um determinado campo

</td></tr><tr style="height: 147px;"><td style="width: 61.7256%; height: 147px;">**FormContext.GetText(**string idCampo**)**</td><td style="width: 12.0385%; height: 147px;">string</td><td style="width: 51.2976%; height: 147px;">Esse método retornará o **Texto** de um determinado campo, utilizado apenas se o campo for um campo de **lista dinâmica**, exemplo: Combo, Auto complete, Campo de Múltipla escolha, radio etc.

[Veja exemplo](#bkmrk-para-recuperar-o-tex)

</td></tr><tr><td style="width: 61.7256%;">**FormContext.GetInt**(string idColuna)  
</td><td style="width: 12.0385%;">int?</td><td style="width: 51.2976%;">Retorna o valor da coluna no tipo INT (inteiro), caso esse campo no formulário seja um número, se o valor for 10.000,99

Será retornado: 10000

[Veja exemplo](https://wiki.agilityflow.io/link/82#bkmrk-atualizar-um-outro-f)

</td></tr><tr><td style="width: 61.7256%;">**FormContext.GetDecimal**(string idColuna)</td><td style="width: 12.0385%;">decimal?</td><td style="width: 51.2976%;">Retorna o valor da coluna no tipo Decimal, caso esse campo no formulário seja um número, se o valor for 10.000,99

Será retornado: 10000.99

[Veja exemplo](https://wiki.agilityflow.io/link/82#bkmrk-atualizar-um-outro-f)

</td></tr><tr><td style="width: 61.7256%;">**FormContext.GetDateTime**(string idColuna)</td><td style="width: 12.0385%;">DateTime?</td><td style="width: 51.2976%;">Retorna o valor da coluna no tipo DateTime para valores que estão no formato de data dd/MM/yyyy ou dd/MM/yyyy hh:mm

[Veja exemplo](https://wiki.agilityflow.io/link/82#bkmrk-atualizar-um-outro-f)

</td></tr></tbody></table>

##### C# - Buscar Rascunho por Id

<table border="1" id="bkmrk-m%E3%A9todo-retorno-%E2%A0-f" style="border-collapse: collapse;"><tbody><tr style="height: 31px;"><td style="width: 61.7256%; height: 31px;">**Método**</td><td style="width: 14.0138%; height: 31px;">**Retorno**</td><td style="width: 44.0137%; height: 31px;"> </td></tr><tr style="height: 31px;"><td style="width: 61.7256%; height: 31px;">**FormContext**.**GetDrafJsontById**(string draftid)  
ou

**FormContext**.**GetDrafJsontById**(Guid?draftid)

</td><td style="width: 14.0138%; height: 31px;">dynamic</td><td style="width: 44.0137%; height: 31px;">```
`var str_preco_de_venda = "";var str_quantidade = "";var temRascunho = false;var rascunho_json = PageContext.GetDraftJsontById(str_draftid);if(rascunho_json != null){	temRascunho = true;	str_preco_de_venda = rascunho_json.preco_de_venda;	str_quantidade = rascunho_json.quantidade;}`
```

</td></tr></tbody></table>

##### C# - Executar uma consulta SQL (Query SQL)

<table border="1" id="bkmrk-m%E3%A9todo-retorno-%E2%A0-f-0" style="border-collapse: collapse;"><tbody><tr style="height: 31px;"><td style="width: 61.7256%; height: 31px;">**Método**</td><td style="width: 14.0138%; height: 31px;">**Retorno**</td><td style="width: 44.0137%; height: 31px;"> </td></tr><tr style="height: 31px;"><td style="width: 61.7256%; height: 31px;">**await FormContext**.**GetDataTableAsync**(string sql, params DbParameter\[\] parameters)</td><td style="width: 14.0138%; height: 31px;">DataTable</td><td style="width: 44.0137%; height: 31px;">Permite retornar informações dos bancos de dados através de uma query.

[Veja exemplo](#bkmrk-recuperando-dados-do "Veja exemplo")

</td></tr></tbody></table>


##### C# - Inserir (salvar/criar), alterar, deletar e aprovar outros formulários

<table border="1" id="bkmrk-m%E3%A9todo-retorno-%E2%A0-f-1" style="border-collapse: collapse; width: 119.753%; height: 942px;"><tbody><tr style="height: 31px;"><td style="width: 61.7256%; height: 31px;">**Método**</td><td style="width: 14.0138%; height: 31px;">**Retorno**</td><td style="width: 44.0137%; height: 31px;"> </td></tr><tr><td style="width: 61.7256%;">**await FormContext.SaveEntityAsync**(Guid estruturaformularioid\_ASerCriadoOuAtualizado, DataDictionary campos\_e\_valores)</td><td style="width: 14.0138%;">Guid</td><td style="width: 44.0137%;">Salva (Insere e Atualiza) as informações de um formulário no bancos de dados.

Para atualizar um registro, no parâmetro **campos\_e\_valores**, apenas adicione um parâmetro chamado "**id**" com o id do elemento que você deseja atualizar.

Obs: Para cadastrar valores numéricos, o números devem estar no formato com ponto no separador decimal: 999999.99 sem utilização de virgulas.

[Veja exemplo](https://wiki.agilityflow.io/link/82#bkmrk-salvando-os-dados-re "Veja exemplo")

</td></tr><tr><td style="width: 61.7256%;">**await FormContext.ApproveEntityAsync(**Guid estruturaformularioid\_ASerAprovado, DataDictionary campos\_e\_valores)</td><td style="width: 14.0138%;">Guid</td><td style="width: 44.0137%;">Avança uma etapa em um formulário com Workflow.

As regras de usuário aprovador, permissão de aprovação e responsabilidade por uma etapa devem ser validadas antes desse método ser executado.

Obs: Para cadastrar valores numéricos, o números devem estar no formato com ponto no separador decimal: 999999.99 sem utilização de virgulas.

[Veja exemplo](https://wiki.agilityflow.io/link/82#bkmrk-aprovando-uma-etapa-)

</td></tr><tr><td style="width: 61.7256%;">**await FormContext.DeleteEntityAsync(Guid formularioid)**</td><td style="width: 14.0138%;">void</td><td style="width: 44.0137%;">Deletar um um registro

</td></tr></tbody></table>

##### C# - Apresentar mensagem para o usuário

<table border="1" id="bkmrk-m%E3%A9todo-retorno-%E2%A0-f-2" style="border-collapse: collapse; width: 119.753%; height: 942px;"><tbody><tr style="height: 31px;"><td style="width: 61.7256%; height: 31px;">**Método**</td><td style="width: 14.0138%; height: 31px;">**Retorno**</td><td style="width: 44.0137%; height: 31px;"> </td></tr><tr style="height: 59px;"><td style="width: 61.7256%; height: 59px;">**FormContext.WarningMessage**(string message)

</td><td style="width: 14.0138%; height: 59px;">void</td><td style="width: 44.0137%; height: 59px;">Apresenta um aviso para o usuário

[veja detalhes aqui](https://wiki.agilityflow.io/link/82#bkmrk-a-execu%E3%A7%E3%A3o-do-c%E3%B3d)

</td></tr></tbody></table>

##### C# - Buscar informações do usuário logado

<table border="1" id="bkmrk-m%E3%A9todo-retorno-%E2%A0-f-3" style="border-collapse: collapse; width: 119.753%; height: 193px;"><tbody><tr style="height: 31px;"><td style="width: 61.7256%; height: 31px;">**Método**</td><td style="width: 14.0138%; height: 31px;">**Retorno**</td><td style="width: 44.0137%; height: 31px;"> </td></tr><tr style="height: 29px;"><td style="width: 61.7256%; height: 29px;">**FormContext.**GetUsuarioLogadoNome();  
</td><td style="width: 14.0138%; height: 29px;">string</td><td style="width: 44.0137%; height: 29px;">Nome Completo do usuário logado</td></tr><tr style="height: 29px;"><td style="width: 61.7256%; height: 29px;">**FormContext.**GetUsuarioLogadoPrimeiroNome();</td><td style="width: 14.0138%; height: 29px;">string</td><td style="width: 44.0137%; height: 29px;">Primeiro nome do usuário logado</td></tr><tr style="height: 46px;"><td style="width: 61.7256%; height: 46px;">**FormContext.**GetUsuarioLogadoPrimeiroESegundoNome();</td><td style="width: 14.0138%; height: 46px;">string</td><td style="width: 44.0137%; height: 46px;">Primeiro e Segundo nome do usuário logado</td></tr><tr style="height: 29px;"><td style="width: 61.7256%; height: 29px;">**FormContext.**GetUsuarioLogadoEmail();</td><td style="width: 14.0138%; height: 29px;">string</td><td style="width: 44.0137%; height: 29px;">E-mail do usuário logado</td></tr><tr style="height: 29px;"><td style="width: 61.7256%; height: 29px;">**FormContext.**GetUsuarioLogadoId();</td><td style="width: 14.0138%; height: 29px;">Guid</td><td style="width: 44.0137%; height: 29px;">Id do usuário logado</td></tr></tbody></table>

##### C# - Buscar variáveis de ambiente

<table border="1" id="bkmrk-m%E3%A9todo-retorno-%E2%A0-f-4" style="border-collapse: collapse; width: 119.753%; height: 942px;"><tbody><tr style="height: 31px;"><td style="width: 61.7256%; height: 31px;">**Método**</td><td style="width: 14.0138%; height: 31px;">**Retorno**</td><td style="width: 44.0137%; height: 31px;"> </td></tr><tr style="height: 153px;"><td style="width: 61.7256%; height: 153px;">**FormContext.GetEnvironmentVariable**(string nomeVariavel)

ou

**FormContext.GetEnvironmentVariable\_Text**(string nomeVariavel) \*\*

</td><td style="width: 14.0138%; height: 153px;">string</td><td style="width: 44.0137%; height: 153px;">Recupera o Valor de uma variável de ambiente.

\*\* Recupera a Descrição (texto), no caso de variáveis do Tipo "Query com Id + Descrição":

</td></tr></tbody></table>

##### C# - Formatação Numérica

<p class="callout info">***Se você está utilizando o método GetValue(..) para buscar o valor de um campo numérico, esse método já retornará o número formatado e não será necessário nenhuma formatação adicional.  
  
Se você está utilizando o método GetDecimal(..) ele não virá formatado pois ele retorna o tipo DECIMAL do C#, sendo assim, se você precisa do dado formatado você pode utilizar o GetText(..)***</p>

<table border="1" id="bkmrk-string-formatdecimal"><tbody><tr><td>string **FormContext.FormatDecimalToString**(object numDecimal, string mascaraTipo = "dec2")</td><td>formata object 999999999.55 para o formato da mascara de acordo com o idioma.

\- se for ingles, será 999,999,999.55  
\- se for portugues, será 999.999.999,55

</td></tr><tr><td>string **FormContext.FormatNumberToString\_EnglishFormat**(object num, \[optional\]int? qtdCasasDecimais)</td><td>converte decimal para string, porém sempre a string vem no formato Inglês.

coloca a a mesma qtd de casas decimais, caso o parâmetro qtdCasasDecimais estivar em branco

</td></tr></tbody></table>

##### C# - Gerar log

<table border="1" id="bkmrk-m%E3%A9todo-retorno-%E2%A0-f-5" style="border-collapse: collapse; width: 119.753%; height: 942px;"><tbody><tr style="height: 31px;"><td style="width: 61.7256%; height: 31px;">**Método**</td><td style="width: 14.0138%; height: 31px;">**Retorno**</td><td style="width: 44.0137%; height: 31px;"> </td></tr><tr style="height: 130px;"><td style="width: 61.7256%; height: 130px;">**FormContext.Log**(string log, string logTipo)

</td><td style="width: 14.0138%; height: 130px;">void</td><td style="width: 44.0137%; height: 130px;">Cria um log na tabela de log geral, o log pode ser consultado entrando na Área de Customização e clicando na opção "Log Geral &gt;&gt; consultar Log"

</td></tr></tbody></table>

##### C# - Métodos Úteis

<table border="1" id="bkmrk-m%E3%A9todo-retorno-%E2%A0-f-6" style="border-collapse: collapse; width: 119.753%; height: 942px;"><tbody><tr style="height: 31px;"><td style="width: 61.7256%; height: 31px;">**Método**</td><td style="width: 14.0138%; height: 31px;">**Retorno**</td><td style="width: 44.0137%; height: 31px;"> </td></tr><tr style="height: 177px;"><td style="width: 61.7256%; height: 177px;">**FormContext.GetUrlBase()**  
</td><td style="width: 14.0138%; height: 177px;"> </td><td style="width: 44.0137%; height: 177px;">Retorna a URL base da sua aplicação

exemplo:

[https://suaempresa.agilityflow.io/](https://suaempresa.agilityflow.io/)

\*A url sempre virá com uma barra no final **/**

</td></tr></tbody></table>

#### Método principal para utilização da Programação em C# na opção "Regra de Negócio"

A única regra é que o método se chame Execute, não tenha parâmetros de entrada e o retorno seja void.

Exemplo:

```C#
public void Execute(){            



  //aqui você pode programar   



}

  //aqui você pode programar outros métodos
```

#### Exemplos

##### Recuperando dados do banco de dados através de uma query SQL

```C#
//parametros da query
var paramsQuery = new List<NpgsqlParameter>();
paramsQuery.Add(new NpgsqlParameter("@param1", "xxx"));
paramsQuery.Add(new NpgsqlParameter("@param2", "yyy"));
paramsQuery.Add(new NpgsqlParameter("@param3", "zzz"));

//query usando (nolock) nas tabelas para evitar problema com a transação que está ativa
var sql = "select column1,column2,column3 from table (nolock) where column1 = @param1 or  column2 = @param2 or  column3 = @param3 ";

//executar no banco de dados
var dt = await FormContext.GetDataTableAsync(sql, paramsQuery.ToArray());

//percorrendo as linhas de retorno da tabela
foreach (DataRow dr in dt.Rows)
{
  if (dr["column1"] != DBNull.Value)
  	FormContext.WarningMessage(dr["column1"].ToString());
}
```

##### Modificando os campos do próprio formulário que está sendo salvo

```C#
//concatenando o texto "abcdef" ao campo de texto chamado "texto_simples" 
var texto_simples = FormContext.GetValueField("texto_simples");
texto_simples += " abcdef ";
FormContext.SetValue("texto_simples",texto_simples);

//colocando uma data fixa em um campo de data chamado "data_e_hora" 
var data_e_hora = "31/01/2023 22:55";
FormContext.SetValue("data_e_hora",data_e_hora);


//colocando um valor decimal fixo em um campo de data chamado "moeda" 
var moeda = "2000000.50";
FormContext.SetValue("moeda",moeda);



//somando 200 dias a um campo de data chamado "data_e_hora_2" 
var dt_data_e_hora = FormContext.GetDateTime("data_e_hora_2");
if(dt_data_e_hora != null){
  var nova_data = dt_data_e_hora.Value.AddDays(200);
  FormContext.SetValue("data_e_hora_2", nova_data);
}

//somando 900.12 a um campo de moeda chamado "moeda2" 
var num_moeda = FormContext.GetDecimal("moeda2");
if(num_moeda != null){
  var novo_valor = num_moeda.Value + 9000000.12m;

  FormContext.SetValue("moeda2",novo_valor);
}
```

##### Salvando/Criar um outro formulário através do método SaveEntityAsync

\* Para cadastrar valores numéricos, o números devem estar no formato com ponto no separador decimal: 999999.99 sem utilização de virgulas.

```C#
//guarda em uma variável o ID da  E S T R U T U R A  do formulário de pessoa
var idEstruturaFormulario_PESSOA = Guid.Parse("0b56b66a-4f6f-4ded-ad04-016d7c0724e1");

var values = new DataDictionary();
values.Add("nome", FormContext.GetValue("nome"));
values.Add("email", FormContext.GetValue("email"));


//salva a informação no banco de dados
await FormContext.SaveEntityAsync(idEstruturaFormulario_PESSOA, values);

```

##### Atualizar um outro formulário através do método SaveEntityAsync

\* Para cadastrar valores numéricos, o números devem estar no formato com ponto no separador decimal: 999999.99 sem utilização de virgulas.

```C#
//guarda em uma variável o ID da  E S T R U T U R A  do formulário de pessoa
var idEstruturaFormulario_PESSOA = Guid.Parse("0b56b66a-4f6f-4ded-ad04-016d7c0724e1");

var values = new DataDictionary();
values.Add("id", "33f6bdf8-26d9-42b9-94ae-ad44c62725b5"); //insere aqui o ID do registro que você deseja atualizar
values.Add("nome", FormContext.GetValue("nome"));
values.Add("email", FormContext.GetValue("email"));


//salva a informação no banco de dados
await FormContext.SaveEntityAsync(idEstruturaFormulario_PESSOA, values);

```

<p class="callout warning">Caso você queira atualizar informações do próprio formulário que está sendo salvo, utilize a função SetValue, descrita mais acima nos métodos da Classe FormContext</p>

##### Aprovar um outro formulário através do método ApproveEntityAsync

\* Para cadastrar valores numéricos, o números devem estar no formato com ponto no separador decimal: 999999.99 sem utilização de virgulas.

```C#
//guarda em uma variável o ID da  E S T R U T U R A  do formulário de pessoa
var idEstruturaFormulario_PESSOA = Guid.Parse("0b56b66a-4f6f-4ded-ad04-016d7c0724e1");

var values = new DataDictionary();
values.Add("nome", FormContext.GetValue("nome"));
values.Add("email", FormContext.GetValue("email"));



//salva a informação no banco de dados
await FormContext.ApproveEntityAsync(idEstruturaFormulario_PESSOA, values);

```

##### Salvando um outro formulário com Tabela Associativa através do método SaveEntityAsync

\* Para cadastrar valores numéricos, o números devem estar no formato com ponto no separador decimal: 999999.99 sem utilização de virgulas.

```C#
//guarda em uma variável o ID da  E S T R U T U R A  do formulário de pessoa
var idEstruturaFormulario_PESSOA = Guid.Parse("0b56b66a-4f6f-4ded-ad04-016d7c0724e1");

var values = new DataDictionary();
values.Add("nome", json["nome"].ToString());
values.Add("email", json["email"].ToString());


        //no caso do campo do formulário ser uma tabela associativa (tabela relacional N:N)
        var idCampoTabelaAssociativa = "70b6f362-2587-4fd2-a2fb-148bd0caf437";

        //itens da tabela associativa que serão adicionados
        var idItem1 = "51cf02f1-3787-4dca-8a2c-e219a5ce1298";
        var idItem2 = "f999f103-c775-4245-92d3-034cb3ded5e4";                          
        var idItem3 = "XXXXf103-c775-4245-92d3-034cb3ded5e4";                          
        var idItem4 = "YYYYf103-c775-4245-92d3-034cb3ded5e4";                          
        var idsJuntos_ConcatenadosComVirgula = idItem1 + "," + idItem2 + "," + idItem3 + "," + idItem4 + ",";

        //adiciona
        values.Add(idCampoTabelaAssociativa, idItem1); //adiciona idItem1
        values.Add(idCampoTabelaAssociativa, idItem2); //adiciona idItem2
        values.Add(idCampoTabelaAssociativa, idItem3); //adiciona idItem3
        values.Add(idCampoTabelaAssociativa, idItem4); //adiciona idItem4
        values.Add("tabela_associativa_added-"+idCampoTabelaAssociativa,idsJuntos_ConcatenadosComVirgula);// itens concatenados com virgula
        values.Add("tabela_associativa_removed-"+idCampoTabelaAssociativa,"");//em branco
        values.Add("tabela_associativa_colunas_adicionais-"+idCampoTabelaAssociativa,"");//em branco
        //---------------------------------------



//salva a informação no banco de dados
await FormContext.SaveEntityAsync(idEstruturaFormulario_PESSOA, values);

```

##### Para recuperar o Texto de um campo que seja uma Lista Dinâmica (Combo, Auto completar, Múltipla seleção, Radio):

Suponhamos que você tenha um formulário de Pedido e nesse formulário você tenha um campo chamado 'Produto'.  
Esse campo é do tipo 'Pesquisa com Auto Completar' e listará os 'Produtos' por 'Nome'.  
Quando o usuário salvar o formulário, no Json de envio não retornará o Nome do Produto, apenas o Id do produto selecionado (Esse id estará no formato de um GUID).  
Para recuperar o Nome do produto, você precisará executar o método **GetText** da seguinte forma:

```C#
var nomeProduto = FormContext.GetText("produto");
```

##### Recuperar os valores das "Variáveis de Ambiente"

Para saber mais sobre variáveis de ambiente entre em [Variáveis de ambiente](https://wiki.agilityflow.io/link/88#bkmrk-page-title)

```JavaScript
var valorDaVariavel = FormContext.GetEnvironmentVariable("var_nomeDaVariavel");
```

Recuperar a Descrição (texto), no caso de variáveis do Tipo "Query com Id + Descrição":

```JavaScript
var textDaVariavel = FormContext.GetEnvironmentVariable_Text("var_nomeDaVariavel");
```

##### Enviar Mensagem para o usuário: A execução do código abaixo apresentará uma mensagem para o usuário

```C#
FormContext.WarningMessage("Exemplo de mensagem para o usuário");
```

<p class="callout danger">O código C# se encerrará no exato momento em que for chamado o método para apresentação de mensagem.</p>

Retorno da mensagem

![](https://wiki.agilityflow.io/uploads/images/gallery/2019-09-Sep/scaled-840-0/image-1569710675959.png)

#### Envio de e-mail

Responsável pelo envio de e-mail

<table border="1" id="bkmrk-op%E3%A7%E3%A3o-retorno-%E2%A0-s" style="border-collapse: collapse; width: 121.652%; height: 137px;"><tbody><tr style="height: 31px;"><td style="width: 70.1206%; height: 31px;">**Método**</td><td style="width: 14.0139%; height: 31px;">**Retorno**</td><td style="width: 35.6186%; height: 31px;"> </td></tr><tr style="height: 31px;"><td style="width: 70.1206%; height: 31px;">**EmailSender.SendToGrupoUsuario**(Guid grupoUsuarioId, string subject, string htmlContent)</td><td style="width: 14.0139%; height: 31px;">void</td><td style="width: 35.6186%; height: 31px;">Enviar um e-mail para um determinado Grupo de Usuario</td></tr><tr style="height: 46px;"><td style="width: 70.1206%; height: 46px;">**EmailSender.SendEmail**(string toEmail, string subject, string htmlContent)</td><td style="width: 14.0139%; height: 46px;">void</td><td style="width: 35.6186%; height: 46px;">Enviar um e-mail </td></tr><tr style="height: 29px;"><td style="width: 70.1206%; height: 29px;">**EmailSender.SendEmail**(string toEmail, string subject, string htmlContent, string ccEmail**)**</td><td style="width: 14.0139%; height: 29px;">void</td><td style="width: 35.6186%; height: 29px;">Enviar um e-mail, com copia (CC)</td></tr></tbody></table>

##### Enviar e-mail para um Grupo de Usuário

Antes de iniciar, crie um "Grupo de Usuário" no menu "Segurança e Acesso". Depois de criado, associe os usuários que receberão e-mail ao novo grupo de usuário que você acabou de criar.

Pegue o ID desse novo Grupo de usuário. Você vai precisar dele para enviar o e-mail.

```C#
var grupoUsuarioId = Guid.Parse("af7c9275-0e23-4b64-a433-f238bb457005"); //substitua o ID "af7c9275-0e23-4b64-a433-f238bb457005" pelo Id do grupo de usuario que você deseja enviar o e-mail
var assunto = "Novo E-mail para um Grupo de usuario ";
var html = "Olá Grupo, <BR><BR> Teste para envio de e-mail para um Grupo de Usuário no AgilityFlow!";

EmailSender.SendToGrupoUsuario(grupoUsuarioId, assunto, html);
```

##### Enviar e-mail 

```C#
var htmlContent = "<strong>Olá,</strong> teste envio de e-mail.";
var emailTo = "john@email.com";
var subject = "Subject do E-mail";

EmailSender.SendEmail(emailTo, subject, htmlContent);
```