Skip to main content

Criar um novo Documento

Um documento seria algo que envolve um Cadastro, Manutenção, DataModule e opcionalmente uma Pesquisa.

Ex.:
Clientes
Produtos
Documentos Fiscais (NFe, NFSe..)
Etc.

Para exemplo, usaremos a criação através da DLL, e como base o caso do Mantis 47332 onde cliente solicita a configuração de um CFOP específico por usuário.

O motivo de não ser feito direto na tela de usuários é o fato de ser customizado.

Não existe apenas uma forma de fazer, então o registrado aqui é uma sugestão.

Após fazer a cópia do trunk para uma pasta dentro do seu branch, navegue até a pasta Sistemas, copie o diretório, dê um copy to na dll em FireDac Skin ("Custom" + Sigla do módulo + Cliente), conforme as imagens abaixo:

1.png

2.png

Baixa seu código inteiro para darmos continuidade ao trabalho conforme modelo em Local 

É muito importante entender bem o precisa ser feito, para desenhar a tela e as tabelas da melhor forma.
Também é importante lembrar que formulários novos são feitos através de herança, então no caso de dúvida pergunte.

Planejamento desde caso:

Nomenclatura: Como será uma informação (Centro de Custos) padrão para usuário e futuramente podem vir a acrescentar novos campos, pensamos em algo no sentido de "Padrões do Usuário", isso reflete no nome das telas e da tabela nova.

Com nome definido, inicie desenhando os campos necessários para atender o cadastro, neste caso usuário já é cadastrado, falta informar o Centro de Custos para ele. 

Dica: Olhe alguns exemplos já existentes, isso ajudará muito.

Tela de Inclusão/Edição/Visualização

Crie herdando de "TFORM_EDIT" ou "TFORM_EDI1T", o que muda é o sentido da barra de ferramentas (Vertical ou Horizontal).
A propriedade Name do formulário costuma seguir alguns padrões, neste exemplo "FORM_" + Nome da tabela + "_EDIT".
A propriedade Caption do formulário, neste caso como se trata apenas do Centro de Custos, então chamaremos de "Centro de Custos por Usuário"

Baseado na tela de Usuários já existentes, puxamos algumas informações em ReadOnly apenas para usuário ter certeza que é o usuário correto que escolheu, e o campo que iremos cadastrar, a princípio a tela está:

3.png

Com a primeira tela feita, fica mais fácil de desenhar a tabela, que para este caso será "PadroesUsuarios":

4.png

 

Criar tabela:

Em alguns casos a criação estará na uit uCriaTabDll.pas dentro do fonte da DLL, em outro caso estará dentro de DllSource.pas. Caso não tenha em nenhuma das duas, então crie a uCriaTabDll.pas

A principio será necessário apenas a procedure "RegistraTabelas" e a function "Cria" + Nome da Tabela.

A procedure "RegistraTabelas" será para adicionar uma descrição da tabela nova dentro da tabela "Sistemas". Já a function ""Cria" + Nome da Tabela, é usada para adicionar na tabela "IntegRef" que por sua vez é responsável por simular as chaves estrangeiras do nosso banco.

Os métodos ficaram mais ou menos assim:

function "Cria"+ Nome da Tabela (no caso, CriaPadroesUsuarios):

image-1666808455191.png

Nessa function estamos criando a tabela desejada no banco por linhas de código.

Passamos na "LAuxilar.FieldDefs.Add" os seguintes parâmetros:

('Nome do campo', Tipo do campo, Tamanho de caracteres do campo, True se for uma PK);

Anotações importantes:

- O tipo do campo deve ser adicionado como "ft" + tipo do valor. Exemplo (Varchar no banco-> ftString);

- O ultimo parâmetro,  tem um valor default de "False", sendo assim, caso não seja passado, o campo não sera uma PK;

procedure RegistraTabelas: 

image-1666808277228.png

Nessa procedure, estamos fazendo o vinculo das chaves primarias (PK) e chaves estrangeiras (FK) do banco por linhas de código.

Passamos na "LMatVal" os seguintes valores: 

(tabela pai, tipo da checagem que será feita, tabela filha, chaves primarias na tabela pai, chaves estrangeiras da tabela filha, se vai ser eliminado da tabela pai, se vai ser eliminada da tabela filha e a sigla do sistema)

*Lembrando que para a criação da tabela seja efetuada é necessário que o sistema ao ser aberto passe pela tela de atualizações, ou seja, é necessário mudar no banco, na tabela "Global" + sigla do módulo para versões anteriores *

Explicando o DLG nos Edits:

Basicamente o componente dlg tem algumas propriedades específicas, elas são:

-TabelaPesq:

Seleciona a tabela que o dlg do edit vai buscar os dados, por exemplo: usuários;

-CampoPesq:

Deve ser inserido um campo da tabela selecionada no TabelaPesq para efetuar a busca no banco, por exemplo: NomeLog;

-DataSource:

Deve ser passado o DataModule.DataSource, por exemplo: DM_PADROESUSUARIOS.DS_MANUT;

-DataField:

O campo que será buscado no DataSource selecionado, por exemplo: NomeLog;

Exemplos do caso 0047322:

image-1666811653806.png       image-1666811687964.png            

Componente TKWRCriterios

o componente Critérios tem uma propriedade chamada "Criterios", ao dar dois cliques nele, se deparamos com a seguinte tela:

image-1666812697371.png

Ao clicarmos no único botão disponível, criamos um novo critério, ele será adicionado com índice 0 e com um nome padrão:

 

image-1666813084641.png

Ao clicar no item adicionado, na aba "Object Inspector" irão aparecer as propriedades daquele item, iremos alterar algumas delas, sendo elas as seguintes: 

image-1666813486423.png

Na propriedade Campo iremos adicionar o campo da tabela nova que criamos;

Na propriedade Chave iremos deixar marcado caso o campo seja uma PK e iremos desmarcar caso não seja;

Na propriedade Descrição é o título de onde os dados daquele campo vão ser inseridos;

Na propriedade Tabela vai ser inserido o nome da tabela que criamos;

Exemplo

No componente critérios do caso 0047332, as propiedades alteradas ficaram dessa maneira: 

image-1666814058421.png            image-1666814151185.png 

Devemos lembrar de adicionar também as chaves estrangeiras que estarão na nossa nova tabela, no exemplo citado, sendo os itens Usuarios.Nome e CenCust.Custo;

Podemos ver de maneira mais exemplificada como o critérios funciona realizando o debug do código, vamos lembrar que até o momento nenhuma query de SQL foi feita, porem ao usarmos o "MostraParams" no nosso DataModule com a QManut por exemplo:

image-1666868761074.png

iremos obter esse resultado ao voltar para o sistema: 

image-1666868934303.png

 

resumindo, o próprio componente ao ser configurado, monta essa query.

Evento OnSelect do Dlg:

Podemos utilizar a criação do Evento OnSelect do Dlg para escrever trechos que possam ser úteis na tela, por exemplo:

image-1666869196119.png

Nesse trecho estamos fazendo uma validação para verificar se o usuário selecionado já tem um centro de custo vinculado a ele naquela empresa. Caso ele não tenha, trazemos não só o Campo NomeLog para o Field, mas trazemos também o campo nome(que seria o nome completo) para o Edit de nome do usuário. Exemplificando na tela do sistema:

Ao clicar no Dlg do Edit

 

Nos deparamos com a tela de usuários:

image-1666869610498.png

Ao clicar em um usuário, ele já puxa o campo nome para o Edit:image-1666869655947.png

 

A mesma coisa acontece com o centro de custo:

image-1666869717195.png

 

Ao clicarmos em um centro de custo, ele puxa para a tela, tanto o centro de custo escolhido, como a descrição do mesmo:

image-1666869771450.png

Validações:

É importante lembrar que mesmo já esteja funcional, devemos validar algumas informações, como o botão gravar, o botão fechar, validar se o usuário selecionado já tem um centro de custo cadastrado. Para essas validações, podemos usar eventos, como o FormClose, OnClick, OnSelect entre outros, Por exemplo:

         

image-1666871182647.png                image-1666871221340.png

Aqui vemos que ao tentar selecionar um usuário que já tinha centro de custo cadastrado, então o sistema deve dar um alerta e impedir que eu continue o processo.

Algumas functions/procedures que podem ajudar nesse passo de validações, são por exemplo:

TVerificaCampos.Verificar();

image-1666871904221.png

Ela basicamente verificaquais campos do DataModule foram alterados, sendo passados como parâmetros o DataModule em si e uma variável para os campos alterados, declarada no "private" do tipo Variant, da seguinte forma:image-1666872062988.png

DataModule.DataSource.DataSet.Modified;

Faz a verificação se houve alteração nos campos do DataModule

image-1666872644069.png

TExisteRegistro.Verificar()

A função TExisteRegistro, faz a verificação se já existe um registro em uma tabela específica com campos específicos passados por parâmetros, sendo 4 ao total, os parâmetros que são passados os seguintes:

- Tabela que vai buscar;

-Os campos que serão verificados;

-Os conteúdos que serão buscados

-O tipo primitivo dos dados

Ficando no código dessa maneira:

image-1666873816785.png

DataModule.Gravar()

É inserido no BT_GRAVA da tela, basicamente salva no banco o que foi adicionado no DataModule, pode ser utilizado dentro de um try para facilitar a manipulação:

image-1666874201692.png

 

Tela de manutenção

A tela pai FORM_BROWSE já vem com os botões criados por herança porem as funções de cada botão devem ser adicionadas manualmente, pois diversas funções usam o DataModule individual  do documento, sendo assim, os botões não fazem nada quando criados.

image-1666956215506.png

Três desses botões (Novo, Edita e Visualiza), utilizam linhas de código praticamente iguais:image-1666956696867.png

 

Eles tem o mesmo código, pois abrem o mesmo formulário, a única mudança é em um dos parâmetros, mudando o Modo, usado da unit uAberturaTipo e a partir disso fazer as mudanças necessárias no Evento OnCreate da tela de cadastro, deixando informações em ReadOnly ou deixando todas com a propriedade Enabled como "False" para que o usuário apenas visualize as informações (AtVisualiza).

O botão de Excluir, é necessário muito cuidado pois muitas validações devem ser feitas antes de um registro ser excluído, como por exemplo, no caso da tela "Usuários", não é possível permitir que o SUPERVISOR seja excluído, então essa validação é usada:

image-1666957414238.png

Botão "Avançar" da tela de manutenção:

Para fazermos o botão de selecionar próximo na tela de manutenção funcionar, não é necessário montar uma query específica para isso, o próprio componente "CRITERIOS" faz isso para nós.

inicialmente temos que declarar a unit de manutenção no DataModule.

image-1667307605582.png

Após isso devemos clicar no componente "CRITERIOS" do DataModule e fazer algumas alterações na propriedade Criterios.

image-1667307713543.png

a tela que será aberta já foi documentada aqui porem vamos alterar algumas propriedades que não foram citadas ainda.

Primeiramente vamos selecionar o campo que queremos fazer a busca, no nosso exemplo, O PadroesUsuarios.NomeLog.

Agora vamos nos atentar as propriedades "Inicio" e "Fim"

image-1667308024563.png

 

Clicando na seta no fim do campo, serão exibidos todos os componentes da unit que foi declarada e a partir desse ponto, temos apenas que ligar o inicio e o fim ao mesmo componente.

image-1667308325432.png

e após isso, ao clicar no botão Avançar, na tela de manutenção, ele já faz a pesquisa sozinho com base nos componentes ligados ao componente que foi relacionado ao campo, não necessitando a montagem de uma query só pra isso.

Após fazer esses passos, a unit de manutenção, pode ser retirada das declarações de uses do DataModule.