# Como fazer a cópia completa de um registro de um formulário? Incluindo as tabelas filhas

## **Cópia Simples, sem considerar tabelas filhas**

Em todos os formulários por padrão já existe uma opção de duplicar/copiar o registro, através do botão representado pelo icone: ![image.png](https://wiki.agilityflow.io/uploads/images/gallery/2025-04/scaled-1680-/e6oimage.png) que fica na barra de botões do formulário:

<p class="callout warning">Essa opção não copia os registos dos formulários filhos ou tabelas. Caso seja necessário, utilize a técnica demonstrada no tópico abaixo nesse mesmo artigo.</p>

[![image.png](https://wiki.agilityflow.io/uploads/images/gallery/2025-04/scaled-1680-/image.png)](https://wiki.agilityflow.io/uploads/images/gallery/2025-04/image.png)


## **Cópia Completa, considerando tabelas filhas**

#### **Crie e configure o botão para copiar**

1. **Entre no formulário que você deseja colocar o botão de "Copiar"**
2. **Crie um botão chamado "Copiar", marque para que esse botão**
3. **Marque para esse botão ser mostrado na barra de botões do formulario**
4. **[![image.png](https://wiki.agilityflow.io/uploads/images/gallery/2025-04/scaled-1680-/Vvbimage.png)](https://wiki.agilityflow.io/uploads/images/gallery/2025-04/Vvbimage.png)**
5. **Marque para esse botão Não ser mostrado dentro do formulario**
6. **Deixa o botão fora do layout do formulario, ele nao precisa ser arrastado para dentro do formularío, caso esteja, remova**
7. **no clique do botão em javascript, confiure para chamar a função js: copiarRegistro()**

[![image.png](https://wiki.agilityflow.io/uploads/images/gallery/2025-04/scaled-1680-/Fm8image.png)](https://wiki.agilityflow.io/uploads/images/gallery/2025-04/Fm8image.png)

### No Visual Code Editor do Formulário

Adicione o Javascript abaixo

```javascript
function copiarRegistro() {


    //só deixa copiar caso nao seja um form novo
    if (formContext.form.isNew())
    {
        pageMsg.formContext.msg.showMsgWarning("Salve o formulário antes de copiar", "Falha ao copiar")
        return;
    }

    //chama o cshtml "CopiarRegistro" que fará a copia
    formContext.loadAjax("CopiarRegistro", {
        onSuccess: function (response) {

            //em caso de sucesso, mostra a msg de sucesso e já redireciona o usuario para a proxima pagina
            pageMsg.showMsgSuccess("Orçamento Duplicado", "Sucesso");

            //em caso de sucesso, redireciona para a url que foi criado
            //importante mudar aqui para o id da estrutura do formulario correto
            window.parent.location = window.parent.base_url + "fluxo/index/74ad209b-ee6a-4ae3-9920-2caad2bc7451/" + response.trim() ;
                        
        },
        onError: function (err) {
            pageMsg.formContext.msg.showMsgWarning("Falha: " + err, "Falha ao copiar")
            console.error("Erro ao carregar o registro:", err);
        }
    });
}
```

Crie um cshtml chamado **CopiarRegistro**

[![image.png](https://wiki.agilityflow.io/uploads/images/gallery/2025-04/scaled-1680-/6psimage.png)](https://wiki.agilityflow.io/uploads/images/gallery/2025-04/6psimage.png)

Cole o código cshtml / C# abaixo:

```c#
@{

    /*

      NESSE EXEMPLO, ESTOU COPIANDO O FORMULARIO ORÇAMENTO E OS ORÇAMENTO ITEM QUE É FILHO DE ORÇAMENTO
  
     */

   //MUDAR AQUI PARA OS IDS DAS ESTRUTURA DOS FORMULARIOS 
    var idEstruturaFormularioOrcamento = Guid.Parse("74ad209b-ee6a-4ae3-9920-2caad2bc7451");
    var idEstruturaFormularioItemOrcamento = Guid.Parse("0c114359-8cb1-4d42-85b4-9882417c386a");    

    //CRIAR O DICTIONARY COM OS DADOS DO FORM PAI, ORÇAMENTO
    var values = new DataDictionary();
    values.Add("numero",PageContext.GetValue("numero"));
    values.Add("cliente",PageContext.GetValue("cliente"));

    //SALVAR O ORÇAMENTO E RECUPERA O ID CRIADO
    var orcamentoId = await PageContext.SaveEntityAsync(idEstruturaFormularioOrcamento, values);

    var paramsQueryItemOrcamento = new List<NpgsqlParameter>();
    paramsQueryItemOrcamento.Add(new NpgsqlParameter("@orcamento", new Guid(PageContext.FormId.ToString())));

    //FAZ UMA QUERY PARA BUSCAR TODOS OS ITENS DO ORÇEMANTO ITEM
    var sqlItemOrcamento = "select * from x_tbl_orcamento__item where deletado = false and idorcamento = @orcamento limit 100";
    var dtItemOrcamento = await PageContext.GetDataTableAsync(sqlItemOrcamento, paramsQueryItemOrcamento.ToArray());
    

    //CASO TENHA ITENS, FAZ UM LOOP PARA COPIAR TODOS E SALVAR
    if (dtItemOrcamento != null && dtItemOrcamento.Rows.Count >= 1)
    {
        foreach (DataRow itemOrcamento in dtItemOrcamento.Rows)
        {

            //CRIAR O DICTIONARY COM OS DADOS DO FORM FILHO, ORÇAMENTO ITEM
            var valuesItemOrcamento = new DataDictionary();

            //AQUI COLOCAR O ID DO ORÇAMENTO QUE FAZ A LIGAÇÃO ENTRE O ORÇAMENTO (PAI) E ORÇAMENTO ITEM (FILHO)
            valuesItemOrcamento.Add("idorcamento", orcamentoId);
          
            valuesItemOrcamento.Add("detalhes_do_item",itemOrcamento["detalhes_do_item"].ToString());
            valuesItemOrcamento.Add("nome_do_item",itemOrcamento["nome_do_item"].ToString());

            //SALVAR O ORÇAMENTO ITEM
            await PageContext.SaveEntityAsync(idEstruturaFormularioItemOrcamento, valuesItemOrcamento);

        }
    }

}
@orcamentoId
```

Nas configuraçoes de botões do formulário, marque para o botão padrão de "**duplicar/copiar**" não aparecer. Em algumas versões essa opção de nao aparecer pode não estar disponível, sendo assim, você pode usar o css abaixo na opção de CSS para deixar o botão invisível

```css
#btnCopyForm{
    display: none
}
```