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:
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á:
Com a primeira tela feita, fica mais fácil de desenhar a tabela, que para este caso será "PadroesUsuarios":
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):
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:
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:
Componente TKWRCriterios
o componente Critérios tem uma propriedade chamada "Criterios", ao dar dois cliques nele, se deparamos com a seguinte tela:
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:
Ao clicar no item adicionado, na aba "Object Inspector" irão aparecer as propriedades daquele item, iremos alterar algumas delas, sendo elas as seguintes:
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:
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:
iremos obter esse resultado ao voltar para o sistema:
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:
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:
Ao clicar em um usuário, ele já puxa o campo nome para o Edit:
A mesma coisa acontece com o centro de custo:
Ao clicarmos em um centro de custo, ele puxa para a tela, tanto o centro de custo escolhido, como a descrição do mesmo:
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:
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();
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:
DataModule.DataSource.DataSet.Modified;
Faz a verificação se houve alteração nos campos do DataModule
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:
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:
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.
Três desses botões (Novo, Edita e Visualiza), utilizam linhas de código praticamente iguais:
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:
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.
Após isso devemos clicar no componente "CRITERIOS" do DataModule e fazer algumas alterações na propriedade Criterios.
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"
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.
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.
No Comments