Convenções. Este recurso traz informes específicos de determinado assunto abordado em um tópico, dando ao usuário conselhos e informações extras.

Tamanho: px
Começar a partir da página:

Download "Convenções. Este recurso traz informes específicos de determinado assunto abordado em um tópico, dando ao usuário conselhos e informações extras."

Transcrição

1

2 Desenvolvido por

3 Convenções Este manual está dividido em sete capítulos e recomenda-se sua leitura sequencial, contudo existem alguns tópicos onde você é orientado a navegar para uma página específica, onde determinado assunto mencionando em um tópico, é descrito de forma detalhada. São utilizados outros recursos didáticos para uma melhor compreensão por parte do leitor. Eles são identificados por figuras, e estão divididos em: Dicas: Este recurso traz informes específicos de determinado assunto abordado em um tópico, dando ao usuário conselhos e informações extras. Alertas: Informa ao usuário cuidados ou restrições na utilização de algum recurso. Deve-se sempre lê-los com atenção. Navegação: Orienta o leitor a navegar até determinado tópico, necessário à compreensão do assunto tratado no momento. Notas: São pequenas dicas ou alertas destacadas em amarelo.

4 ÍNDICE C A P Í T U L O 1 - Apresentação O que é o Entity Como Funciona Entity+ x Programação Convencional Entity+ x Microsoft Entity Framework A Quem se Destina? Requisitos Básicos Criando um Projeto Entity Requisitos do Banco de Dados Chaves Compostas x Chaves Simples Simbologia dos Campos Salvando o Seu Projeto Entity Publicação do Projeto Principais Classes, Propriedades, Métodos, Funções e Eventos das Classes Entity Classes de Registro Principais Propriedades, Métodos e Funções Propriedades-Campo Foreign-Key Métodos de Consulta Propriedades, Funções e Métodos Pertinentes Salvamento em Lote Propriedades, Funções e Métodos Pertinentes Propriedades da Classe clsrelacionamentos Propriedades da Classe clscamposrelacao Métodos Winforms Eventos das Classes de Registro Outras Propriedades Coleções de Registros Como Instanciá-la Principais Propriedades, Métodos e Funções Eventos das Coleções de Registro Propriedades, Métodos e Funções Windows Aplication Propriedades, Métodos e Funções da Classe clswinpesquisapopup C A P Í T U L O 2 - Customizando o Seu FrameWork Comentários e Descrições de Campos Definição de Auto incremento Validações de Campos Validações de Datas Domínio de Campos Encadeamento das Classes de Registro Propriedades Totalizadoras Consultas Personalizadas Métodos de Consulta de Coleção

5 Overloads dos Métodos de Consulta de Coleção Rotinas-View Critérios de Consulta Testando a consulta Salvando Sua Rotina View Parâmetros da Função Gerada Classes-View Diferenças entre Rotina-View e Classe-View Criando uma Classe-View Instanciando uma Classe-View Funções Agregadas Inserindo Expressões Abertura e Exclusão Rotinas Armazenadas Criando uma Rotina Armazenada Valores de Retorno Nulos Resposta da Rotina Rotinas de Importação e Exportação de Texto (Rotinas-TXT) Associando Números, Datas e Valores Booleanos Arquivos com Cabeçalho e Rodapé C A P Í T U L O 3 - Sistema de Segurança Nível de Usuários Classes de Segurança Nível de Grupo de Usuários C A P Í T U L O 4 - Auditoria de Dados Utilizando as Classes de Auditoria Recuperando um Ponto de Restauração Excluindo um Ponto de Restauração Ligando e Desligando a Auditoria no Banco de Dados C A P Í T U L O 5 - Manutenção do Projeto Mantendo o Projeto Atualizado Adicionando e Removendo uma Tabela ao Projeto Atualizando as Classes de uma Tabela Atualizando as Classes de Várias Tabelas Sincronização do Projeto Resetando uma Classe Reconstruindo todo o Projeto BackUp O Class Browser O Data Browser

6 C A P Í T U L O 6 - Explorando o Data Access Layer (DAL) Estrutura A Classe Cryptografia A Classe Dados O Namespace SQLStructure C A P Í T U L O 7 - Documentação do Projeto Tipos de Documento Lista de Tabelas Lista de Views Dicionário de Dados Detalhes de Foreing-keys Relacionamentos Índices e Constraints Estrutura de Classes Domínio de Campos Métodos e Funções Rotinas-View Classes-View Rotinas-TXT Rotinas Armazenadas (mapeamento de stored procedures)

7 Surpreenda-se! Imagine uma ferramenta que vai muito além do ORM (Mapeamento de Objetos Relacionais). Uma ferramenta que permite a você construir todo um framework de acesso a dados personalizado, com instruções em português, de forma interativa, sem a necessidade de nenhum tipo de codificação, e ao final gerar uma biblioteca de classes especializadas para as mais diversas tarefas envolvendo dados. Esta ferramenta existe e chama-se Entity+

8 C A P Í T U L O 1 Apresentação O que é o Entity+ Representa uma nova categoria de software, pois é o único no que faz, combinando os recursos de ORM (Object Relational Mapping) a uma série de recursos para as mais diversas tarefas, o que permite a construção de um framework completo e personalizado para manipulação de dados em um banco SQL Server, de forma totalmente interativa. Por esse motivo é também uma ferramenta de produtividade no desenvolvimento de aplicações Windows/Web com o Visual Studio, podendo otimizar o tempo de trabalho com a construção de rotinas de manipulação a dados em até 80%, pois irá escrever todas as classes e rotinas para essa finalidade, de acordo com a estrutura de seu banco de dados e as necessidades do desenvolvedor, disponibilizando estes recursos na forma de uma biblioteca de classes (dll.net) e de um DAL (Data Access Layer), que serão referenciados em seu projeto no Visual Studio. Com o Entity+, você adiciona funcionalidades e comportamentos aos seus objetos de acesso a dados, de forma totalmente interativa, concentrando dentro de cada classe de tabela todas as rotinas relativas a ela, e disfruta desses recursos dentro de seu projeto no Visual Studio, direcionando seu esforço e atenção para às regras de negócio de sua aplicação. Além disso, você terá gerada toda a documentação relativa ao seu banco de dados (dicionário de dados, lista de tabelas/views, índices, constraints, relacionamentos, etc.) e a estrutura das classes, funções e métodos criados em seu projeto Entity+, além de um IDE rico em informações e recursos que lhe permitem fazer a navegação entre os registros das tabelas relacionadas, apenas com um click do mouse. 6

9 1.2 - Como Funciona Ao criar um novo projeto Entity+, o usuário fornece os dados para a conexão no banco de dados desejado e, a partir daí, o aplicativo irá fazer a leitura e análise de todas as tabelas, views, campos e relacionamentos deste banco, identificando dependências, chaves, índices, constraints, etc. Após esta análise, estas informações serão organizadas de forma a permitir que o usuário desenvolvedor as visualize e possa definir novas características e regras adicionais a esses objetos, tais como auto incremento, auto incremento condicional, validações, domínio de valores, campos calculados, encadeamento de objetos relacionais, consultas personalizadas, mapeamento de stored procedures em rotinas.net, implementação de classes de segurança e de auditoria, entre outras. Imediatamente após a criação do projeto Entity+, o usuário já pode compilá-lo, gerando as duas dlls, mencionadas acima, que irão conter todas as classes, métodos e funções necessárias à manipulação de dados do banco SQL processado. Para cada tabela do banco de dados será gerada uma classe e uma coleção desta classe. Os objetos instanciados a partir da classe representam um registro da tabela. Já os objetos instanciados a partir da coleção, representam um conjunto de registros recuperados desta tabela com base em um determinado critério de consulta. Será feito o mapeamento de objetos, onde cada campo da tabela estará disponível na classe na forma de propriedade. Assim, considerando uma tabela chamada Clientes, teríamos: clstbclientes - Classe que representa a tabela Clientes; coltbclientes - Coleção da classe clstbclientes, que representa um conjunto de registros da tabela Clientes. Nas duas classes acima existirão métodos e funções de consulta, gravação e exclusão, entre outras, além dos eventos específicos de cada classe, que serão discutidas em detalhes mais a frente Entity+ x Programação Convencional São inúmeras as vantagens da utilização do framework gerado pelo Entity+ com relação à forma de programação convencional. Dentre elas, destacamos: 1ª - Tempo de desenvolvimento de rotinas de acesso a dados Uma vez que todas as consultas que você irá precisar no seu projeto VS são criadas interativamente no Entity+, praticamente sem necessidade de codificação, e imediatamente disponíveis a partir das classes, você irá gastar até 80% menos tempo preocupando-se com esses problemas. Através do encadeamento de objetos, onde as classes de dados estão interligadas com base nos relacionamentos das tabelas, todas as informações dessa cadeia estão disponíveis automaticamente em um único objeto de tabela instanciado. Assim podemos, por exemplo, a partir da classe da tabela Vendas (clstbvendas) ter acesso a todos os dados da tabela Clientes (clstbclientes) e, a partir desse mesmo link, ter acesso aos dados da tabela ItemsVenda (clstbitemsvenda) e à tabela Produtos (clstbprodutos), visualizando 7

10 os dados dos produtos vendidos na operação em questão, e assim por diante enquanto houver relacionamentos. Todo o gerenciamento de conexões e transações é feito pelo DAL (Data Access Layer), assim, não há necessidade de desenvolver lógicas para abertura e fechamento de conexões (o que pode levar a um excesso de conexões abertas, comprometendo a estabilidade do sistema). Também é feito um controle muito mais eficiente de operações transacionadas. 2ª - Otimização do acesso ao banco de dados Todas as operações de acesso a dados são feitas de forma a minimizar o consumo de recursos do banco de dados, estabelecendo a conexão com o BD por um período mínimo enquanto os dados são lidos/salvos. A filosofia é: abrir - ler/gravar - fechar. 3ª - Padronização do código Como qualquer operação de acesso a dados é realizada através das classes geradas pelo Entity+, a codificação feita por uma equipe de desenvolvedores ficará mais homogênea, pois a utilização destas classes impõe padrões específicos de cada uma. 4ª - Elegância e clareza da codificação Nunca mais você terá que digitar as horríveis ADDHOC queries dentro de seus projetos no VS. Tudo que você precisa está contido nas classes do seu framework personalizado, permitindo, verdadeiramente, a utilização de programação orientada ao objeto. Esqueça a manipulação de connections, datasets, datareaders e outros objetos de acesso a dados tradicionais. Você tem seu próprio framework, muito mais fácil, familiar, seguro e intuitivo. 5ª - Separação da Camada de Acesso a Dados da Camada da Aplicação A utilização de um framework personalizado permite separar o código da sua aplicação do código de acesso a dados, mantendo o foco concentrado na regra de negócio. 8

11 6ª - Maior integridade dos dados Através de regras extras de validação de dados disponíveis no ambiente do Entity+, a consistência das informações alcançará um nível maior de controle. 7ª - Rotinas prontas para o transporte de dados Suas classes de tabelas disponibilizarão métodos para a importação e importação de dados na forma de objetos serializados (xml) e arquivos de texto. 8ª - Implementação automática do sistema de segurança Você pode habilitar a funcionalidade de gerenciamento de segurança de acesso a dados. O Entity+ criará tabelas e classes específicas para o controle de acesso à sua aplicação final, com recursos avançados de registros de log de acesso e total gerenciamento de permissões de grupos ou usuários, configurando desde a quantidade máxima de tentativas de logon até o tempo mínimo para novos logons de usuários bloqueados. O gerenciamento de usuários/grupos pode ser feito a partir do ambiente (IDE) do Entity+ e, também, a partir das classes de segurança, de dentro de sua aplicação final, utilizando-se as propriedades e métodos destas, assim como poder controlar o acesso (read, write, print e outros) à cada tabela ou módulo de seu sistema Windows/WEB. 9ª - Implementação automática do sistema de auditoria de dados A auditoria de dados consiste no gerenciamento e registro de operações de persistência (write, del) de todas ou algumas tabelas selecionadas pelo usuário desenvolvedor. Uma vez marcadas para a auditoria, estas tabelas serão monitoradas de forma que operações do tipo Update e/ou Delete sejam registradas em tabelas especiais com seu conteúdo compactado e encriptado, mantendo um histórico dessas operações, que servirão tanto para auditoria, quanto para a recuperação de dados alterados ou excluídos. Assim como no recurso de segurança, visto no item 8º acima, o acesso e recuperação dessas informações podem ser feitos, tanto a partir do ambiente do Entity+, quanto de dentro de sua aplicação final, através das classes geradas para essa finalidade. 10ª - Documentação do sistema As informações do seu banco de dados estarão dispostas de forma a facilitar a visualização das dependências entre as tabelas, suas chaves, índices, campos auto incremento, regras, consultas, etc. Também é gerado um relatório contendo o dicionário de dados, relação entre tabelas, descrição de todas as classes, métodos e funções, etc. 9

12 1.4 - Entity+ x Microsoft Entity Framework O Entity+ não faz referência ao Entity Framework da Microsoft, ele é uma tecnologia totalmente independente. A única similaridade é que ambos fazem o mapeamento de objetos relacionais (ORM). Todo projeto criado com o Entity+ é do tipo Database First, ou seja, você tem que ter sua estrutura de dados criada previamente fora do ambiente do Entity+. O Entity+ é muito mais que um ORM, ele é uma ferramenta de produtividade cuja finalidade é gerar um framework personalizado para uma determinada estrutura de dados. Ele faz isso de forma direta e intuitiva, promovendo uma curva de aprendizagem muito menor que a do Entity Framework da Microsoft, permitindo ao usuário adicionar uma miríade de recursos adicionais, agregando ao produto final poder, rapidez e flexibilidade A Quem se Destina? Desenvolvedores de aplicações.net (Windows ou Web) para banco de dados SQL Server, escritas em Visual Basic ou C# Requisitos Básicos Microsoft Visual Studio 2008 ou superior; Net Framework 3.0 ou superior (Client Profile não suportada); Banco de dados SQL Server 2005 ou superior. * Projetos que utilizam Cliente Profil, não reconhecerão o framework gerado. Será necessário selecionar outra versão do framework nas propriedades do projeto no Visual Studio Criando um Projeto Entity Requisitos do Banco de Dados Para que o Entity+ possa analisar e processar as tabelas de um banco de dados SQL Server, elas têm que possuir chave primária (simples ou composta) e estarem devidamente relacionadas. Tabelas sem chave primária serão ignoradas e tabelas sem relacionamentos não terão propriedades que permitam o encadeamento de objetos. Com isso você perde uma série de facilidades. Nomes de campos com espaços serão convertidos em propriedades sem esses espaços. Ex: [Nome Cliente] será transformado na propriedade cnomecliente. 10

13 Campos de auto incremento (identity) terão essa funcionalidade suplantada pelo auto incremento do Entity+, apesar que, caso você inclua manualmente um registro em uma tabela que possua este tipo de campo, o SQL Server ainda considerará o seu próprio auto incremento. Campos com o nome de ID que sejam chaves primárias, serão transformados automaticamente em auto incremento. Essa é uma transformação lógica, que ocorre somente dentro do ambiente do Entity+, não havendo alteração no banco de dados. Quando for criar uma tabela nova e pretender utilizar um campo como auto incremento, dê ele o nome de ID e o defina como chave primária. Senão faça isso posteriormente Chaves Compostas x Chaves Simples O Entity+ suporta tanto tabelas com chave simples quanto com chave composta. Essa implementação fica a seu critério, contudo é importante considerar o seguinte: Caso você use chaves simples, leve sempre em consideração a criação de constraints do tipo unique para identificar os campos que, além da chave primária (geralmente sequencial) tornam um registro único. Isso não é uma exigência do Entity+, mas é uma boa prática de modelagem de dados, além de permitir que a ferramenta construa rotinas de consulta que levam em consideração tanto a chave primária, quanto as uniques. Colocando a Mão na Massa Existem diversas formas de iniciar um novo projeto Entity+, uma delas é a tela de apresentação que é exibida logo que você inicia o sistema. Você pode iniciar um projeto por ela, além de abrir projetos existentes. 11

14 Ao iniciar a aplicação, selecione a opção de menu Arquivo/Novo. A tela ao lado aparecerá: Digite o nome ou IP do servidor de dados ou abra a combo Servidor e selecione <Procurar mais...> para listar os servidores SQL disponíveis. Forneça o login e a senha para logar no servidor (use credenciais de administrador - sa). Click no botão Conectar. Serão listados todos os bancos de dados disponíveis neste servidor. Selecione o banco de dados na lista e click em OK. Feito isso, o Entity+ irá analisar o banco de dados selecionado e carregar seus objetos para serem manipulados. Tabelas que não possuírem chave primária definida serão marcadas com um X vermelho e não estarão disponíveis. Tela Principal do Projeto A tela acima exibe o projeto totalmente criado e carregado. À esquerda nós temos todas as tabelas do banco de dados. Ao se selecionar uma tabela, seus campos serão exibidos na lista superior à direita. Esta lista exibe todas as informações do campo: 12

15 - Nome - Tipo - Tamanho - Requerido (SIM quando não permite nulo e NÃO quando o permite) - Unique: Se faz parte de uma constraint ou índice único - Validar: Indica se o campo será validado pelo método Salvar de um objeto de tabela (ver Regras de Validação, mais à frente) - Tabela PK: Tabela de origem de um campo foreing-key - Campo PK: Campo de origem da foreing-key - Valor Default: Valor default do campo definido no SQL - Comentário: Comentário adicional à descrição vinda do SQL - Descrição: Descrição vinda do SQL Simbologia dos Campos Algumas características dos campos são representadas através de símbolos. São eles: - Chave primária da tabela - Chave primária de auto incremento (Entity+) - Chave primária de auto incremento (SQL Server) - Constraint Unique - Constraint Unique de auto incremento - Índice Unique - Campo Foreign-Key 13

16 Visualização do Código Gerado Imediatamente após a criação do projeto, o Entity+ já está pronto para gerar o código com as classes que irão manipular o seu banco de dados e compila-lo em duas dlls. Para visualizar o código fonte que será compilado, basta selecionar a aba Código. Esta aba está dividida em outras duas (Código.NET e Stored Procedures). Na primeira, você verá o código (escrito em VB), contendo toda a definição das classes para a tabela selecionada na lista à esquerda. Na segunda você irá visualizar as stored procedures que serão compiladas no banco de dados para a manipulação dos dados da tabela atualmente selecionada. Código gerado em Visual Basic Para visualizar todas as classes, propriedades, métodos e funções, basta localizar o item desejado na combo. 14

17 Código das Stored Procedures Este recurso é somente para visualização. Os códigos não podem ser alterados diretamente de dentro do IDE do Entity+, mas se você quiser personalizar o código fonte VB, eles estarão disponíveis na forma de um projeto Class Library do Visual Studio, assim como as stored procedures estarão disponíveis em arquivos, após a publicação do seu projeto Entity+. Quando você publica o seu projeto Entity+, são criadas stored procedures no seu banco de dados assim como um projeto do Visual Studio que é compilado em seguida, dando origem às dlls Salvando o Seu Projeto Entity+ Até aqui você tem o seu projeto criado em memória. Então devemos salvá-lo, da mesma forma que salvaríamos um projeto no Visual Studio. Para salvar o seu projeto, basta ir ao menu principal e selecionar Arquivo/Salvar ou clicar no botão salvar. Selecione a pasta onde você irá salvar o seu projeto, dentro dela será criada uma outra com o mesmo nome do projeto. Seu projeto possui dois tipos básicos de arquivos: o projeto (.eprj - Entity+ Project) e as definições de tabelas (.etb - Entity+ Table) Publicação do Projeto O processo de publicação consiste em gerar fisicamente a codificação VB e SQL, compilar o código SQL na forma de stored procedures no banco de dados e compilar o código VB na forma de bibliotecas de classe (dll). Para publicar o seu projeto vá para Projeto/Publicar ou pressione CTRL + B. Nesse momento o sistema irá verificar se o projeto está totalmente atualizado em relação ao banco de dados e, caso haja divergência, irá perguntar a você se deseja sincronizá-los. É recomendado que você confirme esta sincronização. 15

18 Passos: 1º - Forneça o nome do projeto, que vem preenchido, por padrão, com o nome do banco de dados acrescido da palavra LIB. referenciar as dlls geradas. Obs: Evite colocar neste campo o mesmo nome do banco de dados, pois as chances de o seu projeto do Visual Studio ter o mesmo nome dele são muito grandes. Isso levaria a um conflito de namespaces quando você referenciasse as dlls geradas. 2º - Selecione a versão do VS que você deseja que o projeto seja escrito. A escolha da versão não implicará em nada no produto final (dlls), apenas no formado que o código será gerado para ser compilado. A linguagem que o projeto VS será gerado é o Visual Basic, independente da linguagem utilizada em seu projeto no VS. 3º - Selecione a versão do Framework de forma que ela seja igual ou inferior ao framework do seu projeto do Visual Studio que irá Aviso Importante!!! Por padrão, um projeto do Visual Studio usa a versão Client Profile do framework. Elas são totalmente incompatíveis com as dlls geradas pelo Entity+. Independente do número da versão selecionada, nunca selecione as Client Profile. 16

19 4 º - O formato padrão de data é o brasileiro - dd/mm/yyyy. 5º - Incluir string de conexão encriptada Selecione esta opção, caso você deseje incluir a string de conexão encriptada dentro da dll principal, dessa forma não será necessário passa-la de dentro do seu projeto no VS. 6º - Biblioteca de Classes Indica o local onde será gerado o projeto class library no formato do VS. 7º - Compilar projeto Deve estar marcado para que o projeto Class Library seja compilado e geradas as dlls. Caso não esteja, apenas o projeto Class Library será criado. 8º - Gerar Stored Procedures Salva as stored procedures na pasta indicada, caso você queira fazer alguma alteração posterior. 9º - Compilar stored procedures Compila as stored procedures no banco de dados. Caso essa opção não seja marcada, poderá haver problemas na chamada das mesmas pelos métodos de acesso a dados das classes geradas. Recomenda-se sempre seu uso. Ao clicar em OK, o Entity+ irá: 1º - Verificar a existência das tabelas no banco de dados; 2º - Verificar se há divergências entre as tabelas e o projeto; 3º - Construir o projeto Class Library do Visual Studio; 4º - Excluir as stored procedures anteriores do Entity+; 5º - Compilar as stored procedures no banco de dados; 6º - Compilar o projeto criado no 2º passo, gerando as dlls. Ao concluir estas etapas será exibida a pasta onde as dlls foram geradas. Considerando um projeto chamado de MySoftLIB, lá você encontrará os seguintes arquivos: - MySoftLIB.dll (contém as classes de acesso a dados); - MySoftLIBCore.dll (Data Acces Layer); - MySoftLIB.pbd (utilizado pelo debuger); - MySoftLIB.xml (utilizado pelo debuger); - E AGORA O QUE FAZER.TXT (Instruções para uso das dlls). 17

20 Principais Classes, Propriedades, Métodos, Funções e Eventos das Classes Entity+ Para cada tabela de seu banco de dados, o Entity+ cria duas classes: Classes de Registro Uma classe de registro representa uma linha de informação da tabela, onde encontram-se as propriedades que representam os campos. Objetos instanciados a partir delas, armazenam informações de 1 (um) registro específico desta tabela. Uma tabela chamada Cliente gera uma classe de registro chamada clstbcliente. Uma campo desta tabela chamado Nome gera uma propriedade chamada cnome. A este tipo de propriedade, chamamos Propriedade-Campo. Como Instanciá-la Fazendo import: VB Imports MySoftLIB.EntityPlus... 'Instancia a classe gerando um objeto sem dados, mas contendo todos os campos da tabela. Dim _objcliente As New clstbcliente 'Instancia a classe gerando um objeto que contém os dados de um cliente cujo campo chave primária '(simples) tenha o valor 25 Dim _objcliente As New clstbcliente(25, strstringconexao) C# using MySoftLIB.EntityPlus; //Instancia a classe gerando um objeto sem dados, mas contendo todos os campos da tabela. clstbcliente _objcliente = new clstbcliente(); //Instancia a classe gerando um objeto que contém os dados de um cliente cujo campo chave primária (simples) tenha o valor 25. clstbcliente _objcliente = new clstbcliente(25, strstringconexao); Sem import: VB Dim _objcliente As New MySoftLIB.EntityPlus.clsTbCliente C# MySoftLIB.EntityPlus.clsTbCliente _objcliente = new MySoftLIB.EntityPlus.clsTbCliente; Veremos os métodos de construção da classe de registro mais a frente em detalhes Principais Propriedades, Métodos e Funções Como falado anteriormente, todos os campos da tabela gerarão uma propriedade de campo, contudo, existem propriedades-campo especiais chamadas de Propriedades de Navegação. 18

21 Propriedades-Campo Foreign-Key São propriedades readonly, que se referem a campos foreign-key, e estabelecem relacionamento entre as tabelas. Consideremos o cenário abaixo: Observe a tabela tnotafiscalitem. Ela se relaciona com tnotafiscal (através do campo tnotafiscal_id) e com tproduto (através do campo tproduto_codigo). A classe clstbtnotafiscalitem terá, entre outras, as seguintes propriedades: - ctnotafiscal_id: Representa campo NotaFiscal_ID. - ctproduto_codigo: Representa o campo tproduto_codigo. - TbtNotaFiscal: Proprieade readonly do tipo clstbtnotafiscal que permite o encadeamento entre as classes clstbtnotafiscal (classe pai) e clstbtnotafiscalitem (classe filha). - TbtProduto: Propriedade do tipo clstbtproduto que permite o encadeamento entre as classes clstbtproduto (classe pai) e clstbtnotafiscalitem (classe filha). Observe que é adicionado o prefixo Tb ao nome da tabela para formar o nome desta propriedade. Para cada campo foreign-key da tabela, teremos duas propriedades na sua classe de registro: uma que armazena o valor do campo e outra que se refere à classe de uma tabela primary-key, e que expõe propriedades e métodos desta última. Enquanto as propriedades ctnotafiscal_id e ctproduto_codigo referem-se diretamente aos seus respectivos campos, TbtNotaFiscal e TbttProduto representam as tabelas primary-key tnotafiscal e tproduto, e são read-only. O exemplo abaixo mostra a utilidade dessas propriedades especiais: VB 'Instancia consultando pela chave-primária (ID = 100) Dim _objnfitem As New clstbttnotafiscalitem(100, _strstringconexao) 'Verifica se houve erro de acesso aos dados (sempre usar após consultas e gravações/exclusões) If _objnfitem.erro Then Messagebox.Show(_objNFItem.Mensagem) Exit Sub End If 19

22 If objnfitem.encontrado Then 'Caso tenha localizado txtcodproduto.text = objnfitem.ctproduto_codigo 'Lê um campo (propriedade) da 'própria tabela instanciada 'Através da propriedade de navegação, traz o conteúdo do campo Descricao da tabela 'primary-key tproduto. txtnomeproduto.text = objnfitem.tbttproduto.cdescricao 'Através da propriedade de navegação, traz o conteúdo do campo Nome da tabela 'primary-key tgrupo txtgrupo.text = objnfitem.tbttproduto.tbtgrupo.nome '(encadeamento tnotafiscalitem -> tproduto -> tgrupo) End If C# //Instancia consultando pela chave-primária (ID = 100) clstbttnotafiscalitem _objnfitem = new clstbttnotafiscalitem(100, _strstringconexao); //Verifica se houve erro de acesso aos dados (sempre usar após consultas e gravações/exclusões) if (_objnfitem.erro) { Messagebox.Show(_objNFItem.Mensagem); return; if (objnfitem.encontrado) //Caso tenha localizado { txtcodproduto.text = objnfitem.ctproduto_codigo; //Lê um campo (propriedade) da //própria tabela instanciada //Através da propriedade de encadeamento, traz o conteúdo do campo Descricao da tabela //primary-//key tproduto txtnomeproduto.text = objnfitem.tbttproduto.cdescricao; //Através da propriedade de encadeamento, traz o conteúdo do campo Nome da tabela //primary-//key //tgrupo txtgrupo.text = objnfitem.tbttproduto.tbtgrupo.nome; //(encadeamento tnotafiscalitem -> tproduto -> tgrupo) É feita a consulta através do método de construção New, passando-se o valor a ser localizado no campo chave-primária e a string de conexão do banco. Depois se verifica, através da propriedade Encontrado, se o registro foi achado. São passados para as TextBoxes informações contidas em três tabelas diferentes, através da chamada de apenas 1 método e utilizando-se as propriedades TbttProduto e TbtGrupo. Sempre que for executar um método de acesso a dados em um objeto Entity+, faça a verificação se a propriedade Erro deste objeto retornou verdadeiro. Caso isso ocorra, você pode usar a propriedade Mensagem para informar o que ocorreu. Estes erros estão geralmente associados a falhas no banco de dados, rede ou na conexão. O servidor pode estar fora, por exemplo, e, como o Entity+ não dispara exceções para estes erros, você os trata através dessas propriedades. 20

23 que: Para alcançar o mesmo resultado utilizando-se uma consulta ADD HOC convencional teríamos 1º - Relacionar as três tabelas com Inner Join em uma string; 2º - Abrir uma conexão com o banco de dados; 3º - instanciar um objeto DataReader; 4º - Fechar a conexão. Ao executar o método New() que instancia a classe consultando os dados da tabela, somente as informações de tnotafiscalitem são consultadas. Apenas quando as informações das demais tabelas (pais) são solicitadas, é que a classe as consulta, não permitindo, dessa forma, uma sobrecarga dos objetos relacionados. Chamamos isso de Consulta por demanda (ou lazy load no Microsoft Entity) Propriedades-Campo Primary-Key O relacionamento se dá entre tabelas primary-key e tabelas foreign-key, ou tabela-pai -> tabela-filha. Vimos no tópico anterior que podemos acessar informações contidas nas tabelas pai (primarykey) através das propriedades-campo foreign-key de uma tabela instanciada. Agora vamos ver esse mesmo encadeamento de objetos no sentido oposto (pai -> filha). Em uma classe criada a partir de uma tabela primary-key, teremos propriedades especiais para relacionarmos essa tabela com suas tabelas-filhas. Chamamos essas propriedades de Propriedades-Campo Primary-Key. Encadeamentos deste tipo têm de ser estabelecidos no ambiente (IDE) do Entity+, através do botão Encadeamento das classes, onde aparecerão os relacionamentos da tabela selecionada, para que você os habilite (ver item 2.4 do capítulo 2 - Encadeamento das Classes de Registro). No caso do diagrama mostrado no exemplo anterior, considere a tabela tnotafiscal. Ela se relaciona com a tabela tnotafiscalitem na forma de um para vários, assim cada registro de tnotafiscal terá vários registros relacionados em tnotafiscalitem. A classe clstbtnotafiscal terá uma propriedade chamada TftNotaFiscalItem. Ela é do tipo coltbtnotafiscalitem, que é uma coleção de clstbtnotafiscalitem, ou seja, um conjunto de registros da tabela tnotafiscalitem. Observe que é adicionado o prefixo Tf ao nome da tabela para formar o nome desta propriedade. Exemplos: VB 'Instancia a classe consultando a NF 22 Dim _objnotafiscal As New clstbtnotafiscal(22, _strstringconexao) 21

24 If _objnotafiscal.encontrado Then 'Repassa valores da tabela instanciada para as text-boxes txtdataemissao.text = _objnotafiscal.cdataemissao txtcpfcliente.text = _objnotafiscal.ctcliente_cpfcnpj 'Lista todos os itens da tnotafiscal através da propriedade TftNotaFiscalItem For i As Int16 = 0 To _objnotafiscal.tftnotafiscalitem.count - 1 Dim _lvwitem As New ListViewItem 'Adiciona o numero do item, que vem da tabela tnotafiscalitem através da 'propriedade tabela-filha (Tf) TftNotaFiscalItem _lvwitem = lvwitensnf.items.add(_objnotafiscal.tftnotafiscalitem(i).cnroitem) 'Pega a descrição do produto, que vem da tabela tproduto _lvwitem.subitems.add(_objnotafiscal.tftnotafiscalitem(i).tbtproduto.cdescricao) _lvwitem.subitems.add((_objnotafiscal.tftnotafiscalitem(i).cquantidade) _lvwitem.subitems.add((_objnotafiscal.tftnotafiscalitem(i).cvalorunitario) Next i End If C# //Instancia a classe consultando a NF 22 clstbtnotafiscal _objnotafiscal = new clstbtnotafiscal(22, _strstringconexao); if (_objnotafiscal.encontrado) { //Repassa valores da tabela instanciada para as text-boxes txtdataemissao.text = _objnotafiscal.cdataemissao; txtcpfcliente.text = _objnotafiscal.ctcliente_cpfcnpj; //Lista todos os itens da tnotafiscal através da propriedade TftNotaFiscalItem for (Int16 i = 0; (i <= _objnotafiscal.tftnotafiscalitem.count - 1); i++) { ListViewItem _lvwitem = new ListViewItem(); //Adiciona o numero do item, que vem da tabela tnotafiscalitem através da //propriedade tabela-filha (Tf) TftNotaFiscalItem _lvwitem = lvwitensnf.items.add(_objnotafiscal.tftnotafiscalitem[i].cnroitem); //Pega a descrição do produto, que vem da tabela tproduto _lvwitem.subitems.add(_objnotafiscal.tftnotafiscalitem[i].tbtproduto.cdescricao); _lvwitem.subitems.add(_objnotafiscal.tftnotafiscalitem[i].cquantidade); _lvwitem.subitems.add(_objnotafiscal.tftnotafiscalitem[i].cvalorunitario); Caso você tenha duas tabelas com relacionamento um para um, basta passar o índice zero para a propriedade-campo foreing-key da tabela PK. Exemplo: Dim _ObjCliente As New clstbcliente(txtcpf.text, strconexao) If ObjCliente.TfReferencia.Count > 0 Then txtrefcomercial.text = ObjCliente.TfReferencia(0).RefComercial txtrefbancaria.text = ObjCliente.TfReferencia(0).RefBancaria txtrefpessoal.text = ObjCliente.TfReferencia(0).RefPessoal End If Através das propriedades de navegação, pode-se ir de uma ponta à outra de uma estrutura de objetos relacionados. 22

25 Lembre-se sempre que as propriedades que iniciarem por Tb vão realizar a navegação no sentido TabelaFK -> TabelaPK (filha -> pai) e as que iniciarem por Tf vão fazê-lo no sentido TabelaPK -> TabelaFK (pai -> filha) Métodos de Consulta Vimos nos exemplos anteriores que podemos instanciar um registro de uma tabela de forma que uma consulta seja realizada com base na chave-primária desta ou com base em suas constraints uniques, e que isso é feito pelo método construtor New. A quantidade de parâmetros destes métodos construtores irá variar de acordo com a quantidade e tipo dos campos chave-primária e constraint unique, mas terá obrigatoriamente o parâmetro tipolock (com exceção do método construtor sem parâmetros New(). TipoLock Parâmetro opcional que informa como registros bloqueados (locked) serão considerados durante a consulta. São eles: Padrao (default), NOLOCK, READPAST. No item Salvando Sua Rotina-View, item do capítulo 2, veja em detalhes como esse parâmetro afeta a forma que os registros são recuperados em uma consulta e os problemas que podem ocorrer. Todos os exemplos utilizavam tabelas de chave simples. Assim para instanciarmos um registro da tabela tnotafiscal, utilizamos a seguinte sintaxe: VB: Dim _objtnf As New clstbtnotafiscal(<id da nota>, <String de Conexão>) C#: clstbtnotafiscal _objtnf = new clstbtnotafiscal(<id da nota>, <String de Conexão>); Caso tivéssemos a seguinte tabela: Tabela Produto Nome Tipo Descrição Fornecedor_CNPJ Char(14) FK da tabela Fornecedor Codigo int Código do produto Nome Varchar(50) Nome do produto Temos acima a definição da tabela Produto, cuja chave-primária (composta) é formada pelos campos Fornecedor_CNPJ e Codigo. O Entity+ iria criar um método de construção para ela com a seguinte sintaxe: Public Sub New(ByVal pfornecedor_cnpj As String, ByVal pcodigo As Int32, Optional _ ByVal strconn AsString = "") Veja que, como a chave é composta, ele considera os dois campos como parâmetros do método de construção New(). Assim a instância da classe clstbtproduto seria: 23

26 VB: Dim _objproduto As New clstbproduto(" ", 200, _strstringconexao) C#: clstbproduto _objproduto = New clstbproduto(" ", 200, _strstringconexao); unique: Vamos considerar agora outra estrutura de tabela: chave simples e definição de constraints Tabela Produto Nome Tipo Descrição ID Int Chave primaria auto incremento Fornecedor_CNPJ Char(14) FK da tabela Fornecedor (constraint unique) Codigo int Código do produto (constraint unique) Nome Varchar(50) Nome do produto A tabela acima possui uma chave-primária simples e dois campos constraints unique. A chaveprimária, neste caso, tem apenas a função de estabelecer relacionamentos com outras tabelas. Já as constraints vão fazer a integridade de dados, não permitindo ter dois produtos com o mesmo código para um mesmo fornecedor. Neste cenário o Entity+ irá criar dois métodos construtores diferentes via overload de métodos. 1º - Com base na chave primária: Public Sub New(ByVal pid As Int32, Optional ByVal strconn As String = "") 2º -Com base nas uniques Public Sub New(ByVal pfornecedor_cnpj As String, ByVal pcodigo As Int32, _ Optional ByVal strconn As String = "") Os dois métodos sempre se baseiam na busca de valores únicos da tabela. Dessa forma, você poderá instanciar esta classe passando o ID ou o CNPJ do fornecedor e o código do produto no método New(). Certifique-se que, ao passar valores para os parâmetros de qualquer método de consulta, eles sejam exatamente do mesmo tipo do respectivo parâmetro, caso contrário o Visual Studio irá acusar erro no uso do método ou a classe pode fazer confusão entre os overloads. Para evitar isto, utilize sempre que necessário a função Parse dos respectivos tipos. Exemplo: Dim _ObjNF As New clstbtnotafiscal(int32.parse(mskcodigo.text), strconexao) Propriedades, Funções e Métodos Pertinentes Propriedade Encontrado (Boolean, Default = False) Após uma consulta, esta propriedade indica se o registro foi encontrado. É equivalente à propriedade HasRows de um SqlDataReader. 24

27 Propriedade Erro (Boolean, Default = False) Indica se ocorreu algum erro após qualquer operação executada por métodos ou funções de uma classe Entity+ (métodos de consulta, gravação, exclusão, etc). Propriedade Mensagem (String) Retorna uma mensagem informativa sobre o resultado de uma operação executada por métodos ou funções de uma classe Entity+ (métodos de consulta, gravação, exclusão, etc). Propriedade ConsultaEmCascata (Boolean, Default = True) Habilita ou desabilita o encadeamento de objetos. Defina como False se você não quiser consultar informações de outras tabelas filhas a partir de uma tabela pai instanciada. Método CarregarFilhas Quando uma classe de uma tabela pai (primary-key) é instanciada para um objeto definido no escopo de uma classe ou de projeto, de forma a aumentar sua visibilidade e tempo de vida, e são consultadas informações de suas tabelas filhas (foreing-key), essas informações, uma vez carregadas no cache, podem estar desatualizadas com o banco de dados. Para forçar a atualização desses dados, basta chamar o método CarregarFilhas. Este método em si, não consulta os dados, mas avisa à classe que, se esses forem solicitados, os mesmos devem ser pesquisados novamente (refresh). Função Salvar Toda classe de registro possui a função Salvar. Ela é responsável em gravar as informações na forma de um registro na tabela que originou a sua classe. Esta função tem a capacidade de determinar se a operação de salvamento será um INSERT ou um UPDADE com base na sua chave-primária ou constraints unique. Para cada classe de Registro de Tabela, o Entity+ irá criar duas funções Salvar : Public Overridable Function Salvar(Optional ByVal strconn As String = "") As List(Of clscampo) Public Overridable Function Salvar(ByRef _objdados As <NomeProjeto>Core.Dados, Optional ByVal strconn As String = "", Optional ByVal Finalizar As Boolean = True, Optional SalvarFilhas As Boolean = False) As List(Of clscampo) A primeira função recebe opcionalmente a string de conexão, caso a mesma não tenha sido fornecida no método construtor da classe (New), e salva os dados contidos nas propriedades-campo. Ela retorna uma lista de campos que tiveram seus conteúdos invalidados. No item Validação de Campos, item 2.3 do capítulo 2, veja como definir as regras de validação para cada campo de uma tabela! 25

28 Exemplo da 1ª função (não transacionada): VB Dim _objcliente As New clstbcliente 'Atribui valores às propriedades-campo objcliente.ccpf = txtcpf.text objcliente.nome = txtnome.text objcliente.datanasc = mskdatanasc.text 'Tenta salvar os dados na tabela objcliente.salvar(_strstringconexao) 'Verifica se ocorreu algum erro If objcliente.erro Then 'Exibe a mensagem de erro retornada pela propriedade Mensagem Messagebox.Show(objCliente.Mensagem, "Erro", MessageBoxButtons.OK, _ MessageBoxIcon.Error Else 'Exibe a mensagem de sucesso indicando se foi uma inclusão ou atualização Messagebox.Show(objCliente.Mensagem, "Sucesso", MessageBoxButtons.OK, _ MessageBoxIcon.Information) End If C# clstbcliente _objcliente = new clstbcliente(); //Atribui valores às propriedades-campo objcliente.ccpf = txtcpf.text; objcliente.nome = txtnome.text; objcliente.datanasc = mskdatanasc.text; //Tenta salvar os dados na tabela objcliente.salvar(_strstringconexao); //erifica se ocorreu algum erro if (objcliente.erro) { //Exibe a mensagem de erro retornada pela propriedade Mensagem Messagebox.Show(objCliente.Mensagem, "Erro", MessageBoxButtons.OK, MessageBoxIcon.Error); else{ //Exibe a mensagem de sucesso indicando se foi uma inclusão ou atualização Messagebox.Show(objCliente.Mensagem, "Sucesso", MessageBoxButtons.OK, MessageBoxIcon.Information); A propriedade Erro, retorna True caso ocorra algum erro na tentativa de acesso ao banco de dados. Estes erros podem ser desde erro de integridade de dados até falhas de acesso à rede. A propriedade Mensagem diz exatamente o que ocorreu. Caso não tenha sido fornecido valores para os campos obrigatórios ou se esses valores não estiverem de acordo com as regras de validação definidas no ambiente do Entity+ (ver Validação de Campos), a propriedade erro indicará o erro, e a função Salvar() retornará uma lista com os campos invalidados. Esta lista é um list of clscampo, como vimos da declaração da função salvar. Se você não quiser recuperar essa lista através do retorno da função, pode recuperá-la através da propriedade CamposErro (string) que irá conter a mesma lista de campos, só que separada por vírgula. 26

29 Principais Propriedades da Classe clscampo Nome Nome Descrição Mensagem Exemplos: VB Função Retorna o nome do campo que foi invalidado. Retorna a descrição do campo que foi invalidado. Retorna a mensagem informando qual regra foi violada. Imports MySoftLIB 'Contem a classe clscampo Imports MySoftLIB.EntityPlus 'Contem as classes de registro e coleções de registros... 'Utilizando o retorno da função Dim _objcampos As List (Of clscampo) = objcliente.salvar(_strstringconexao) If _objcliente.erro Then For i As Int16 = 0 To _objcampos.count - 1 Messagebox.Show("Campo " & _objcampos(i).nome & " (" & objcampos(i).mensagem & ")") Next i End If 'Utilizando a propriedade CamposErros _objcliente.salvar(_strstringconexao) If _objcliente.erro Then Messagebox.Show("Os campos " & _objcliente.camposerros & _ " não foram preenchidos ou são inválidos.") End If C# using MySoftLIB; //Contem a classe clscampo using MySoftLIB.EntityPlus; //Contem as classes de registro e coleções de registros... //Utilizando o retorno da função List<clsCampo> _objcampos = objcliente.salvar(_strstringconexao); if (_objcliente.erro) { for (Int16 i = 0; (I <= _objcampos.count - 1); i++) { Messagebox.Show("Campo " + _objcampos[i].nome + " (" + _objcampos[i].mensagem + ")"); //Utilizando a propriedade CamposErros _objcliente.salvar(_strstringconexao); if (_objcliente.erro) { Messagebox.Show("Os campos " + _objcliente.camposerros + " não foram preenchidos ou são inválidos."); 27

30 Se por qualquer motivo você queira desativar a validação de dados feita dentro da função Salvar, basta utilizar a propriedade ValidarDados, do tipo boolean, fazendo-a igual a false, antes de chamar a função Salvar(). Exemplo: _objcliente.validardados = False O segundo overload da função Salvar(), deve ser utilizado em operações que envolvam mais de uma salva na tabela ou em tabelas diferentes, que exijam esse nível de integridade. Ou seja, operações transacionadas. Definição: Public Overridable Function Salvar(ByRef _objdados As <MeuBancoCore>.Dados, _ Optional ByVal strconn As String = "", _ Optional ByVal Finalizar As Boolean = True, _ Optional SalvarFilhas As Boolean = False) As List(Of clscampo) Parâmetros da Função Nome Obrigatória Função objdados SIM É um objeto do tipo Dados, que se encontra na dll data access layer, que faz a comunicação com o banco de dados. Este objeto gerenciará a transação executada pela função Salvar(). strconn NÃO String de conexão com o BD. Deve ser fornecida caso a classe não tenha sido instanciada com ela anteriormente e a string de conexão não foi incluída na publicação das DLLs. Finalizar NÃO Indica se, após salvar os dados, a função deverá dar um CommitTrans automático. SalvarFilhas NÃO Imagine a seguinte estrutura: Em um processo de salvamento em lote (pai e filhas), indica se as informações das filhas serão salvas. Parâmetro apenas disponíveis para as classes relativas a tabelas chaveprimária relacionadas. Neste cenário iremos salvar uma nota fiscal de venda, que é composta de vários itens (produtos), salvando os dados na tabela tnotafiscal e depois na tabela tnotafiscalitem. Caso haja algum problema em alguma etapa deste processo, toda a operação deverá ser desfeita (RollBack). 28

31 Os dados das duas tabelas serão salvos em duas etapas distintas (não em lote), mas compartilhando o mesmo objeto de dados, que gerencia a conexão e as transações. Exemplos: VB 'Salvando a nota fiscal Dim _objnf As New clstbtnotafiscal Dim _objdados As New Dados(_strStringConexao) _objnf.ctempresa_codigo = txtcodigo.text _objnf.ctcliente_cpfcnpj = txtcpfcnpj.text _objnf.ctfuncionario_codigovenda = cmbvendedor.selectedvalue... _objnf.salvar(_objdados,, False, False) If _objnf.erro Then 'Em caso de erro, dá RollBack automático MessageBox.Show(_objNF.Mensagem, "Erro", MessageBoxButtons.OK, _ MessageBoxIcon.Error) Exit Sub End If 'Salvando os itens que estão listados em um GridView For i As Int16 = 0 To grditens.rows.count - 1 Dim _objnfitem As New clstbtnotafiscalitem _objnfitem.ctproduto_codigo = grditens.rows(i).cells(2).value _objnfitem.cquantidade = Double.Parse(grdItens.Rows(i).Cells(9).Value) _objnfitem.cvalorunitario = Double.Parse(grdItens.Rows(i).Cells(8).Value)... 'Salva cada item mantendo a transação em andamento, indicado pelo 3º parâmetro '(Finalizar = False) _objnfitem.salvar(_objdados,, False, False) If _ objnfitem.erro Then 'Em caso de erro, dá RollBack automático MessageBox.Show(_objNF.Mensagem, "Erro", MessageBoxButtons.OK, _ MessageBoxIcon.Error) Exit Sub End If Next i 'Se chegou até aqui, não houve erros, então dá o commit If _objdados.emtransacao Then _Dados.CommitTrans End If C# //Salvando a nota fiscal clstbtnotafiscal _objnf = new clstbtnotafiscal(); Dados _objdados = new Dados(_strStringConexao); _objnf.ctempresa_codigo = txtcodigo.text; _objnf.ctcliente_cpfcnpj = txtcpfcnpj.text; _objnf.ctfuncionario_codigovenda = cmbvendedor.selectedvalue;... _objnf.salvar(_objdados, "", false, false); if (_objnf.erro) { //Em caso de erro, dá RollBack automático MessageBox.Show(_objNF.Mensagem, "Erro", MessageBoxButtons.OK, MessageBoxIcon.Error); return; //Salvando os itens que estão listados em um GridView 29

32 for (Int16 i = 0; (i <= grditens.rows.count - 1); i++) { clstbtnotafiscalitem _objnfitem = new clstbtnotafiscalitem(); _objnfitem.ctproduto_codigo = grditens.rows[i].cells[2].value; _objnfitem.cquantidade = Double.Parse(grdItens.Rows[i].Cells[9].Value); _objnfitem.cvalorunitario = Double.Parse(grdItens.Rows[i].Cells[8].Value);... //Salva cada item mantendo a transação em andamento, indicado pelo 3º parâmetro //(Finalizar = False) _objnfitem.salvar(_objdados, "", false, false); if (_objnfitem.erro) { //Em caso de erro, dá RollBack automático MessageBox.Show(_objNF.Mensagem, "Erro", MessageBoxButtons.OK, MessageBoxIcon.Error); return; //Se chegou até aqui, não houve erros, então dá o commit if (_objdados.emtransacao) { _Dados.CommitTrans(); No código acima não existe a necessidade de se preocupar com o RollBack, em caso de ocorrer algum erro. Ele é disparado internamente pela função Salvar. Observe a propriedade EmTransacao do objeto _objdados. Ela indica se existe uma transação em andamento. Como a string de conexão foi fornecida no método construtor do objeto _objdados, não foi necessário fornecê-la nas demais etapas, pois o objeto _objdados foi passado como argumento na função Salvar. Caso o parâmetro Finalizar (o penúltimo da função Salvar, em negrito e sublinhado) fosse True, não seria necessário finalizar a transação com o método CommitTrans, pois a própria função o faria. _objnfitem.salvar(_objdados,, True, False) 'CommitTrans automático Salvamento em Lote O exemplo anterior realiza a operação em duas etapas. Veremos agora como fazer a mesma operação em uma única etapa (salvamento em lote). Considere que a tabela tnotafiscalitem é filha de tnotafiscal e que, devido a isso, a classe clstbtnotafiscal possui uma propriedade do tipo coltbtnotafiscalitem, que é uma coleção de registros da tabela tnotafiscalitem (ver item Propriedades-Campo Primary-Key). Então teremos a propriedade TftNotaFiscalItem na classe TbtNotaFiscal e, sendo ela uma collection, poderemos utilizar o método ADD, para adicionarmos itens a nossa nota fiscal e depois salvá-lo única etapa. 30

33 Exemplos: VB Dim _objnf As New clstbtnotafiscal Dim _Dados As New Dados(_strStringConexao) _objnf.ctempresa_codigo = g_objconfiguracao.empresa.ccodigo _objnf.ctcliente_cpfcnpj = txtcpfcnpj.text _objnf.ctfuncionario_codigovenda = cmbvendedor.selectedvalue... 'Adicionando os itens, que estão listados em um GridView, ao objeto _objnf For i As Int16 = 0 To grditens.rows.count - 1 Dim _objnfitem As New clstbtnotafiscalitem _objnfitem.ctproduto_codigo = grditens.rows(i).cells(2).value _objnfitem.cquantidade = Double.Parse(grdItens.Rows(i).Cells(9).Value) _objnfitem.cvalorunitario = Double.Parse(grdItens.Rows(i).Cells(8).Value)... _objnf.tftnotafiscalitem.add(_objnfitem) Next i _objnf.salvar(_dados,, True, True) If _ objnf.erro Then 'Em caso de erro, dá RollBack automático MessageBox.Show(_objNF.Mensagem, "Erro", MessageBoxButtons.OK, _ MessageBoxIcon.Error) Else MessageBox.Show(_objNF.Mensagem, "Salvo Com Sucesso", MessageBoxButtons.OK, _ MessageBoxIcon.Information) End If C# clstbtnotafiscal _objnf = new clstbtnotafiscal(); Dados _Dados = new Dados(_strStringConexao); _objnf.ctempresa_codigo = g_objconfiguracao.empresa.ccodigo; _objnf.ctcliente_cpfcnpj = txtcpfcnpj.text; _objnf.ctfuncionario_codigovenda = cmbvendedor.selectedvalue;... //Adicionando os itens, que estão listados em um GridView, ao objeto _objnf for (Int16 i = 0; (i <= grditens.rows.count - 1); i++) { clstbtnotafiscalitem _objnfitem = new clstbtnotafiscalitem(); _objnfitem.ctproduto_codigo = grditens.rows[i].cells[2].value; _objnfitem.cquantidade = double.parse(grditens.rows[i].cells[9].value); _objnfitem.cvalorunitario = double.parse(grditens.rows[i].cells[8].value);... _objnf.tftnotafiscalitem.add(_objnfitem); _objnf.salvar(ref _Dados, "", true, true); if (_objnf.erro) { //Em caso de erro, dá RollBack automático MessageBox.Show(_objNF.Mensagem, "Erro", MessageBoxButtons.OK, MessageBoxIcon.Error); else { MessageBox.Show(_objNF.Mensagem, "Salvo Com Sucesso", MessageBoxButtons.OK, MessageBoxIcon.Information); 31

34 Neste exemplo, toda a gerência da transação foi feita de forma transparente, sem a intervenção do programador. O simples fato de ter passado o 3º parâmetro (Finalizar = True), fez com que a função executasse o CommitTrans automático. O 4º parâmetro (SalvarFilhas = True) indica para a função que todos os dados dos itens da nota fiscal deverão ser salvos também. Da mesma forma que no exemplo anterior, se houver algum problema na hora de salvar nenhum dos registros da tabela será salvo, devido ao rollback automático. Em uma tabela cuja chave primária seja um campo de auto incremento, deve-se atribuir ZERO a ele, para inserir um novo registro. Dessa forma, o Entity+ não encontrará um registro correspondente e assumirá que se trata de uma inclusão, adicionando um novo registro com o valor desse campo incrementado automaticamente. Caso você passe um outro valor para esse campo, o Entity+ tentará localizar o registro correspondente e aplicar a atualização (Update). Caso não o encontre, assume que é uma inclusão, realizando o auto incremento Propriedades, Funções e Métodos Pertinentes Propriedade CamposErros (String) Retorna uma string contendo o nome dos campos que foram invalidados após a execução das funções Salvar() e ValidarCampos que retornaram erro. Função ValidarCampos (Retorna List (of clscampo)) Faz a validação dos dados de um objeto antes de chamar a função Salvar. Esta função já é utilizada internamente pela função Salvar. Só a utilize se você quiser validar os dados antes de chamar a função Salvar. Método Excluir Executa a exclusão de um registro da tabela instanciada. Este método possui 4 overloads: 1º - Public Overridable Sub Excluir() Exclui um registro após instanciar (consultar) o objeto. Exemplos: VB Dim _objcliente As New clstbcliente(txtcnpj.text, _strstringconexao) If objcliente.encontrado Then objcliente.excluir() If objcliente.erro Then MessageBox.Show("Não foi possível excluir (" & objcliente.mensagem & _ ")") Else MessageBox.Show("Registro excluído com sucesso") 32

35 End If End If C# clstbcliente _objcliente = new clstbcliente(txtcnpj.text, _strstringconexao); if (objcliente.encontrado) { objcliente.excluir(); if (objcliente.erro) { MessageBox.Show("Não foi possível excluir (" + objcliente.mensagem + ")"); else { MessageBox.Show("Registro excluído com sucesso"); 2º - Public Overridable Sub Excluir(<CHAVE-PRIMÁRIA>, Optional ByVal strconn _ As String = "") Exclui um registro informando diretamente os valores de sua chave-primária. Exemplos: VB Dim _objcliente As New clstbcliente objcliente.excluir(txtcnpj.text, _strstringconexao) If objcliente.erro Then MessageBox.Show("Não foi possível excluir (" & objcliente.mensagem & _ ")") Else MessaeBox.Show("Registro excluído com sucesso") End If C# clstbcliente _objcliente = new clstbcliente(); objcliente.excluir(txtcnpj.text, _strstringconexao); if (objcliente.erro) { MessageBox.Show("Não foi possível excluir (" + objcliente.mensagem + ")"); else { MessaeBox.Show("Registro excluído com sucesso"); 3º - Public Overridable Sub Excluir(ByRef _objdados As <MeuBancoCore>.Dados, _ Optional ByVal strconn As String =, _ Optional ByVal Finalizar AsBoolean = False) Exclui um registro após instanciar (consultar) o objeto em uma operação transacionada. 33

36 Exemplos: VB Dim _objdados As New Dados '(da classe <MeuBancoCORE.dll>)...outras operações em outras tabelas 'Consulta a tabela Dim _objcliente As New clstbcliente(txtcnpj.text, _strstringconexao) If objcliente.encontrado Then 'Exclui o registro encontrado objcliente.excluir(_objdados, _strconexao, True) If objcliente.erro Then MessageBox.Show("Não foi possível excluir (" & objcliente.mensagem & ")") Else MessageBox.Show("Registro excluído com sucesso") End If End If C# Dados _objdados = new Dados(); //(da classe <MeuBancoCORE.dll>)...outras operações em outras tabelas //Consulta a tabela clstbcliente _objcliente = new clstbcliente(txtcnpj.text, _strstringconexao); if (objcliente.encontrado) { //Exclui o registro encontrado objcliente.excluir(ref _objdados, _strconexao, true); if (objcliente.erro) { MessageBox.Show("Não foi possível excluir (" + objcliente.mensagem + ")"); else { MessageBox.Show("Registro excluído com sucesso"); No exemplo acima supomos o import/using da DAL <MeuBancoCORE.dll> para podermos instanciar a classe Dados. Evidentemente que o código acima omite as outras operações que teriam iniciado a transação. Por exemplo, a salva ou exclusão em outra tabela e, considerando-se isso, caso houvesse algum problema na exclusão deste registro, toda operação seria cancelada por um rollback implícito no método Excluir(). 4º - Public Overridable Sub Excluir(<CHAVE-PRIMÁRIA>, ByRef _objdados As <MeuBancoCORE>.Dados, _ Optional ByVal strconn As String = "", Optional _ ByVal Finalizar As Boolean = False) Exclui um registro informando diretamente os valores de sua chave-primária em uma operação transacionada. Exemplo: VB Dim _objdados As New Dados '(da biblioteca <MeuBancoCORE.dll>)...outras operações em outras tabelas Dim _objcliente As New clstbcliente 34

37 objcliente.excluir(txtcnpj.text, objdados, _strstringconexao, True) If objcliente.erro Then MessageBox.Show("Não foi possível excluir (" & objcliente.mensagem & _ ")") Else MessageBox.Show("Registro excluído com sucesso") End If C# Dados _objdados = new Dados(); //(da biblioteca <MeuBancoCORE.dll>)...outras operações em outras tabelas clstbcliente _objcliente = new clstbcliente(); objcliente.excluir(txtcnpj.text, ref objdados, _strstringconexao, true); if (objcliente.erro) { MessageBox.Show( Não foi possível excluir (" + objcliente.mensagem + ")"); else { MessageBox.Show("Registro excluído com sucesso"); Caso você tente excluir um registro que possui dependências foreing-key em outras tabelas, o objeto retornará Objeto.Erro = True e a propriedade Mensagem retornará a descrição do erro disparado pelo mecanismo do SQL Server. Para evitar que isso ocorra, você pode utilizar Count de qualquer propriedade-campo primary-key (aquelas que iniciam com Tf (tabela filha)) do objeto. Exemplo: Dim _ObjCliente As New clstbcliente(txtcpf.text, strconexao) If ObjCliente.TfVendas.Count > 0 Then MessageBox("Impossível excluir registro, pois existem vendas p/ este cliente. ") End If A técnica acima é eficiente considerando-se que não haja exclusão em cascata definida nos relacionamentos da tabela em questão, do contrário, deve-se utilizar a propriedade Relacionamentos, para verificar se existem exclusões em cascata. Propriedade Relacionamentos (Collection) É uma propriedade de classe de registro (clstb) do tipo colrelacionamentos que disponibiliza todas as informações relativas aos relacionamentos do tipo pai -> filha ( um para um ou um para vários ) da tabela que deu origem à classe de registro clstb<tabela> em questão. A classe colrelacionamentos se encontra no namespace SQLStructure do (DAL) Data Access Layer gerado pelo Entity+. Então, caso tivéssemos publicado um projeto para um banco de dados chamado MySoft, encontraríamos a classe colrelacionamentos da seguinte forma: MySoftCore.SQLStructure.colRelacionamentos 35

38 colrelacionamentos, por sua vez, é uma coleção de clsrelacionamentos, que se encontra no mesmo namespace Propriedades da Classe clsrelacionamentos Propriedade Tabela (String) Propriedade que informa o nome da tabela foreing-key do relacionamento. No caso da tabela tnotafiscal de nossos exemplos anteriores, uma das tabelas encontradas via a propriedade Relacionamentos da classe clstbtnotafiscal seria a tabela tnotafiscalitem. Exemplos: VB Dim _objnotafiscal As New clstbtnotafiscal(100, strstringconexao) Console.WriteLine("Imprimindo relacionamentos da tabela tnotafiscal") For i As Int16 = 0 To _objnotafiscal.relacionamentos.count - 1 Console.WriteLine(_objNotaFiscal.Relacionamentos(i).Tabela) Next C# clstbtnotafiscal _objnotafiscal = clstbtnotafiscal(100, strstringconexao); Console.WriteLine("Imprimindo relacionamentos da tabela tnotafiscal"); for (Int16 i = 0; (i <= _objnotafiscal.relacionamentos.count - 1); i++) { Console.WriteLine(_objNotaFiscal.Relacionamentos[i].Tabela); Propriedade NomeTabelaPK (String) Retorna o nome da tabela primary-key da relação. Propriedade DelecaoCascata (Boolean) Propriedade que indica se determinado relacionamento é em cascata. Exemplos: VB Dim _objnotafiscal As New clstbtnotafiscal(100, strstringconexao) Console.WriteLine("Imprimindo relacionamentos da tabela tnotafiscal") For i As Int16 = 0 To _objnotafiscal.relacionamentos.count - 1 If _objnotafiscal.relacionamentos(i).delecaocascata Then Console.WriteLine("Tabela " & _objnotafiscal.relacionamentos(i).tabela & _ " possui exclusão em cascata") Else Console.WriteLine("Tabela " & _objnotafiscal.relacionamentos(i).tabela & _ " não possui exclusão em cascata") End If Next 36

39 C# clstbtnotafiscal _objnotafiscal = new clstbtnotafiscal(100, strstringconexao); Console.WriteLine("Imprimindo relacionamentos da tabela tnotafiscal"); for (Int16 i = 0; (i <= _objnotafiscal.relacionamentos.count - 1); i++) { if (_objnotafiscal.relacionamentos[i].delecaocascata) { Console.WriteLine ("Tabela " + _objnotafiscal.relacionamentos[i].tabela + " possui exclusão em cascata"); else { Console.WriteLine("Tabela " + _objnotafiscal.relacionamentos(i).tabela + " não possui exclusão em cascata"); Propriedade CamposRelacao (Collection) Propriedade do tipo colcamposrelação que disponibiliza todos os campos que fazem parte de determinada relação. A classe colcamposrelação se encontra no namespace SQLStructure do (DAL) Data Access Layer gerado pelo Entity+. Então, caso tivéssemos publicado um projeto para um banco de dados chamado MySoft, encontraríamos a classe colcamposrelação da seguinte forma: MySoftCore.SQLStructure.colCamposRelacao colcamposrelação, por sua vez, é uma coleção de clscamposrelação, que se encontra no mesmo namespace Propriedades da Classe clscamposrelacao Propriedade CampoPK (String) Nome do campo primary-key da relação. Propriedade CampoFK (String) Nome do campo foreing-key da relação. Exemplos: VB Dim _objnotafiscal As New clstbtnotafiscal(100, strstringconexao) Console.WriteLine("Imprimindo relacionamentos da tabela tnotafiscal") For i As Int16 = 0 To _objnotafiscal.relacionamentos.count - 1 Console.WriteLine("Tabela " & _objnotafiscal.relacionamentos(i).tabela) Console.WriteLine("Campos da relação: " & _objnotafiscal.relacionamentos(i).tabela & vbcrlf) For x As Int16 = 0 To _objnotafiscal.relacionamentos(i).camposrelacao.count - 1 Console.WriteLine(_objNotaFiscal.Relacionamentos(i).CamposRelacao(x).CampoPK & -> & objnotafiscal.relacionamentos(i).camposrelacao(x).campofk) Next x Next i 37

40 C# clstbtnotafiscal _objnotafiscal = new clstbtnotafiscal(100, strstringconexao); Console.WriteLine("Imprimindo relacionamentos da tabela tnotafiscal"); for (Int16 i = 0; (i <= _objnotafiscal.relacionamentos.count - 1); i++) { Console.WriteLine("Tabela " + _objnotafiscal.relacionamentos[i].tabela); Console.WriteLine("Campos da relação: " + _objnotafiscal.relacionamentos[i].tabela); for (Int16 x = 0; (_objnotafiscal.relacionamentos[i].camposrelacao.count - 1); i++) Console.WriteLine(_objNotaFiscal.Relacionamentos[i].CamposRelacao[x].CampoPK & -> + _objnotafiscal.relacionamentos[i].camposrelacao[x].campofk); Propriedade NomeFK (String) Retorna o nome do relacionamento. Propriedade Novo (Boolean) Retorna verdadeiro quando um objeto do tipo classe de registro (clstb<tabela>) ainda não foi salvo no banco de dados. Propriedades StringConexao (String) Retorna/Atribui a string de conexão com o banco de dados. Exemplos: VB Dim _strconn As String = "Server = '(local)';database='particular';uid='sa';pwd='123456'" Dim _objcliente As New clstbtcliente(txtcpfcnpj.text, _strconn) Console.WriteLine(objCliente.StringConexao) C# String _strconn = "Server = '(local)';database='particular';uid='sa';pwd='123456'"; clstbtcliente _objcliente = new clstbtcliente(txtcpfcnpj.text, _strconn); Console.WriteLine(_objCliente.StringConexao); Propriedades NomeTabela (String/Read only) Retorna o nome da tabela relativa à classe. Função Clone (Retorna Object) Cria um clone do objeto instanciado. Use essa função caso queira criar dois objetos idênticos que não tenham referência entre si. Definição: Public Function Clone() As Object Implements System.ICloneable.Clone Exemplos: VB Dim _objcliente As New clstbcliente(20, _strstringconexao) Dim _objcliente2 As clstbcliente = _objcliente.clone 38

41 C# clstbcliente _objcliente = new clstbcliente(20, _strstringconexao); clstbcliente _objcliente2 = _objcliente.clone(); Método LerSqlDataReader Permite criar um objeto do tipo classe de registro de tabela a partir de um SqlDataReader gerado a partir da mesma tabela de origem. Todos os campos da tabela devem constar na consulta que gerou o SqlDataReader. Definição: Public Sub LerSqlDataReader(ByRef dr As SqlDataReader, Optional Fechardr As Boolean = True) Parâmetros: dr - SqlDataReader gerado Fechardr - Indica se o SqlDataReader será fechado após a operação. Exemplo: VB Dim _objdados As New Dados(_strStringConexao) Dim _strsql As String = "Select * From Cliente" Dim _dr As SqlDataReader = _objdados.consultardados(_strsql) If _objdados.erro Then MessageBox.Show(_objDados.Mensagem) Else Dim _objcliente As New clstbcliente _objcliente.lersqldatareader(_dr, True) End If C# Dados _objdados = new Dados(_strStringConexao); String _strsql = "Select * From Cliente"; SqlDataReader _dr = _objdados.consultardados(_strsql); if (_objdados.erro) { MessageBox.Show(_objDados.Mensagem); else { clstbcliente _objcliente = new clstbcliente() _objcliente.lersqldatareader(_dr, true); Métodos Winforms Existem alguns métodos específicos para aplicações Winform que servem para automatizar algumas operações. Alguns destes utilizam a propriedade TAG dos controles de um formulário, de forma a identificar quais desses irão ser processados. A TAG dever conter o nome da propriedade- campo de uma classe de registro de tabela. Os controles que são suportados por estes métodos são: TextBox, MaskedTextBox, Combobox, Label, CheckBox, RadioButton e NumericUpDown. 39

42 Método WINIniciarControles Este método inicializa (limpa) os controles contidos em um formulário. Definição: Public Sub WINIniciarControles(ByRef Container As Object) Parâmetro: Container - Indica qual container contem os controles a serem processados. Container é qualquer objeto que agrupe outros objetos. Exemplos: VB Dim _objcliente As New clstbcliente 'Inicia (limpa) todos os controles contidos em Form1 clstbcliente.wininiciarcontroles(form1) 'Inicia (limpa) todos os controles contidos em GroupBox1 clstbcliente.wininiciarcontroles(groupbox1) C# clstbcliente _objcliente = new clstbcliente(); //Inicia (limpa) todos os controles contidos em Form1 clstbcliente.wininiciarcontroles(form1); //Inicia (limpa) todos os controles contidos em GroupBox1 clstbcliente.wininiciarcontroles(groupbox1); Efeitos: TextBox, Label e MaskedTextBox: Atribui "" à propriedade Text. ComboBox: Desfaz qualquer item selecionado (.SelectedValue = -1) CheckBox e RadioButton: Desmarca o controle (.Checked = False) NumericUpDown: Seta o controle para seu valor mínimo (Controle.Value = Controle.Minimum) Método WINLerControles Lê os valores dos controles e as repassa para as suas respectivas propriedades-campo. Muito útil quando você quer salvar dados de um form em uma tabela sem ter que pegar os valores dos controles um por um (tipo obj.ccampo = Text1.Text). Definição: Public Overridable Sub WINLerControles(ByRef Container As Object) Parâmetro: Container - Indica qual container contem os controles a serem processados. Exemplo: Imagine os seguintes controles: Controle Tipo Tag Tipo Campo txtnome TextBox cnome Varchar lblid Label cid Int chkcasado CheckBox ccasado Bit cmbcategoria ComboBox ccodcategoria Int 40

43 VB Dim _objcliente As New clstbcliente objcliente.winlercontroles(form1) 'Salva os dados contidos nos controles do form, na tabela Cliente. objcliente.salvar(_strstringconexao) C# clstbcliente _objcliente = new clstbcliente(); objcliente.winlercontroles(form1); //Salva os dados contidos nos controles do form, na tabela Cliente. objcliente.salvar(_strstringconexao); Método WINEscreverControles Faz o caminho inverso do método anterior, repassaando os valores das propriedades-campo do objeto para seus respectivas controles. Definição: Public Sub WINEscreverControles(ByRef Container As Object) Parâmetro: Container - Indica qual container contem os controles a serem processados. Exemplos: VB Dim _objcliente As New clstbcliente(txtcnpj.text, _strstringconexao) If objcliente.encontrado Then 'Repassa para os controles do form, os valores das respectivas propriedades- 'campo objcliente.winescrevercontroles(form1) End If C# clstbcliente _objcliente = new clstbcliente(txtcnpj.text, _strstringconexao); if (objcliente.encontrado) { //Repassa para os controles do form, os valores das respectivas propriedades- //campo objcliente.winescrevercontroles(form1); Eventos das Classes de Registro Alguns métodos e funções disparam eventos, que podem ser manipulados dentro de seu projeto no Visual Studio. Evento AntesSalvar É disparado pela função Salvar() momentos antes da operação ser concluída. Programe este evento para realizar tarefas anteriores a efetivação da função e, dependendo da sua regra de negócio, poder cancelar a operação de salvamento. Definição: Public Event AntesSalvar(ByVal sender As Object, ByRef cancelar As Boolean) Parâmetros: 41

44 - sender: Objeto que disparou o evento - cancelar: Cancela a operação de salvamento Exemplos: VB Private WithEvents objcliente As New clstbtcliente Private Sub objcliente_antessalvar(sender As Object, ByRef cancelar As Boolean) _ Handles objcliente.antessalvar txtaviso.text = "iniciando salvamento" If blncondicao Then 'Se a condição for verdadeira, cancela o salvamento cancelar = True End If End Sub C# private void objcliente_antessalvar(object sender, ref Boolean cancelar) { txtaviso.text = "iniciando salvamento"; if (blncondicao) { //Se a condição for verdadeira, cancela o salvamento cancelar = true; Evento DepoisSalvar É disparado pela função Salvar após a operação de salvamento ser concluída. Definição: Public Event DepoisSalvar(ByVal sender As Object) Parâmetros: - sender: Objeto que disparou o evento Exemplos: VB Private WithEvents objcliente As New clstbtcliente Private Sub objcliente_depoissalvar(sender As Object) Handles objcliente.depoissalvar txtaviso.text = " salvamento finalizado" End Sub C# private void objcliente_depoissalvar(object sender) { txtaviso.text = " salvamento finalizado"; Evento ErroSalvar É disparado pela função Salvar() após a operação de salvamento falhar, retornando um erro. Definição: Public Event ErroSalvar(ByVal sender As Object, ByRef mensagem As String) Parâmetros: - sender: Objeto que disparou o evento - mensagem: String contendo a mensagem de erro 42

45 Exemplo: VB Private WithEvents objcliente As New clstbtcliente Private Sub objcliente_errosalvar(sender As Object, ByRef mensagem As String) Handles _ objcliente.errosalvar MessageBox.Show(mensagem, "Erro ao Salvar (" & mensagem & ")") End Sub C# private void objcliente_errosalvar(object sender, ref String mensagem) { MessageBox.Show(mensagem, "Erro ao Salvar (" + mensagem + ")"); Evento AoSalvarFilhas É disparado pela função Salvar() em uma operação transacionada onde o parâmetro SalvarFilhas for definido como True. Ele monitora cada registro filho salvo. Definição: Public Event AoSalvarFilhas(ByVal sender As Object, ByVal e As AoSalvarFilhasEventArgs) Parâmetros: - sender: Objeto que disparou o evento - e: Objeto contendo opções do evento Classe AoSalvarFilhasEventArgs É a classe que disponibiliza propriedades para o argumento e do evento. Propriedades: - TabelaAtual (String) Retorna o nome da tabela sendo salva no momento (tabela principal mais dependeências). - QtdRegistros (Int32) Retorna a quantidade total de registros (elementos das tabelas foreing-key relacionadas) que serão salvos. - RegistroAtual Retorna a quantidade de registros atualmente salvos. Exemplos: VB Private WithEvents objvenda As New clstbvendas Private Sub objvenda_aosalvarfilhas(sender As Object, e As AoSalvarFilhasEventArgs) _ Handles objvenda.aosalvarfilhas LabelProgresso.Text = "Salvando tabela " & e.tabelaatual & registro " & _ e.registroatual & " de " & e.qtdregistros & "..." Me.Refresh End Sub 43

46 C# private void objvenda_aosalvarfilhas(object sender, AoSalvarFilhasEventArgs e) { LabelProgresso.Text = "Salvando tabela " + e.tabelaatual + " registro " + e.registroatual + " de " + e.qtdregistros + "..." this.refresh(); Os exemplos acima monitoram o salvamento dos dados das tabelas-filhas da tabela Venda, informando em um Label qual tabela está sendo salva no momento, o registro atual e a quantidade total de registros. Vamos imaginar qua a tabela Vendas esteja relacionada com a tabela ItensVenda (um para muitos). Ao executar a função Salvar(), que faria a persistência da tabela Vendas juntamente com os dados dos itens desta, iriamos exibir o progresso de toda a operação. Assim teríamos na label algo como: Salvando tabela ItensVenda registro 2 de Evento AntesExcluir É disparado pela função Excluir(), momentos antes da operação ser concluída. Programe este evento para realizar tarefas anteriores a efetivação da função e, dependendo da sua regra de negócio, poder cancelar a operação de exclusão. Definição: Public Event AntesExcluir(ByVal sender As Object, ByRef cancelar As Boolean) Parâmetros: - sender: Objeto que disparou o evento - cancelar: Cancela a operação de exclusão Exemplos: VB Private WithEvents objcliente As New clstbtcliente Private Sub objcliente_antesexcluir(sender As Object, ByRef cancelar As Boolean) _ Handles objcliente.antesexcluir Dim _blncancelar As Boolean = Messagebox.Show("Deseja excluir? ", "Atenção", _ MessageBoxButtons.YesNo, _ MessageBoxButtons.Question) = DialogResult.Yes cancelar = _blncancelar End Sub C# private void objcliente_antesexcluir(object sender, ref Boolean cancelar) { Boolean _blncancelar = Messagebox.Show("Deseja excluir? ", "Atenção", MessageBoxButtons.YesNo, MessageBoxButtons.Question) = DialogResult.Yes; cancelar = _blncancelar; Evento DepoisExcluir É disparado pela função Excluir() após a operação de exclusão ser concluída. Definição: 44

47 Public Event DepoisExcluir(ByVal sender As Object) Parâmetros: - sender: Objeto que disparou o evento Exemplos: VB Private WithEvents objcliente As New clstbtcliente Private Sub objcliente_depoisexcluir(sender As Object) Handles objcliente.depoisexcluir Messagebox.Show("Registro excluído com sucesso") End Sub C# private void objcliente_depoisexcluir(object sender) { Messagebox.Show("Registro excluído com sucesso"); Evento ErroExcluir É disparado pela função Excluir() após a operação de exclusão falhar, retornando um erro. Definição: Public Event ErroExcluir(ByVal sender As Object, ByRef mensagem As String) Parâmetros: - sender: Objeto que disparou o evento - mensagem: String contendo a mensagem de erro Exemplos: VB Private WithEvents objcliente As New clstbtcliente Private Sub objcliente_erroexcluir(sender As Object, ByRef mensagem As String) Handles _ objcliente.erroexcluir MessageBox.Show(mensagem, "Erro ao Salvar (" & mensagem & ")") End Sub C# private void objcliente_erroexcluir(object sender, ref String mensagem) { objcliente.erroexcluir MessageBox.Show(mensagem, "Erro ao Salvar (" + mensagem + ")"); Outras Propriedades InfoCampo (do tipo colinfocampo) Retorna metadados relativos aos campos da tabela. Declaração: Public Property InfoCampo As colinfocampo Onde colinfocampo é uma coleção de clsinfocampos. Estrutura da Classe clsinfocampos: 45

48 Public Class clsinfocampo Public Property Nome As String Public Property AutoIncremento As Boolean Public Property ValorDefault As String Public Property Descricao As String Public Property TipoSQL As String Public Property Tamanho As Int64 Public Property TipoNET As String Public Property TemDominio As Boolean Public Property Requerido As Boolean Public Property Dominio As Object Public Property ChavePrimaria As Boolean Public Property Unique As Boolean Public Property Indexado As Boolean Public Property TabelaPK As clsinfotabelapk Public Sub New() End Class Propriedades, Métodos e Funções Nome Tipo Descrição Nome String Retorna o nome do campo AutoIncremento Boolean Indica se um campo é auto incremento ValorDefault String Retorna o valor default do campo, se ele ele possuir Descricao String Retorna a descrição do campo TipoSQL String Retorna o tipo SQL do campo Tamanho Int64 Retorna o tamanho do campo no SQL TipoNet String Retorna o tipo.net do campo TemDomínio Boolean Indica se um campo tem domínio definido Requerido Boolean Indica se o campo é requerido ChavePrimaria Boolean Indica se o campo faz parte da chave-primária Unique Boolean Indica se um campo faz barte de uma chave ou constraint única Indexado Boolean Indica se o campo faz parte de um índice TabelaPK clsinfotabelapk Retorna o nome da tabela primary-key e o campo de origem, se for uma foreing-key New() Método Construtor Instancia a classe Estrutura da Coleção colinfocampos: Public Class colinfocampo Default Public ReadOnly Property item(byval I As Integer) As clsinfocampo Default Public ReadOnly Property item(byval Nome As String) As clsinfocampo Public Sub Add(ByVal obj As clsinfocampo) End Class Propriedades, Métodos e Funções: Nome Tipo Descrição item(i) clsinfocampo Retorna um item da coleção pelo seu índice Item(Nome) clsinfocampo Retorna um item da coleção pelo nome do campo Add() Método Adiciona um item à coleção 46

49 Exemplos: VB Dim _strconexao As String = "Server = '(local)';database='sglpdesk';uid='sa';pwd='123456'" Dim _objnotafiscal As New clstbtnotafiscalsaida(13, _strconexao) 'Lista algumas propriedades dos campos pelo índice da coleção For i As Int16 = 0 To _objnotafiscal.infocampo.count - 1 Console.WriteLine("Campo: " & _objnotafiscal.infocampo(i).nome) Console.WriteLine("Tipo SQL: " & _objnotafiscal.infocampo(i).tiposql) Console.WriteLine("Tamanho: " & _objnotafiscal.infocampo(i).tamanho) Console.WriteLine("Valor Default: '" & _objnotafiscal.infocampo(i).valordefault & "'") Console.WriteLine(" ") Next 'Lista os dados da tabela primary-key do campo foreing-key, informando-se o nome do campo Console.WriteLine("TabelaPK: " & objnotafiscal.infocampo("ttipocliente_id").tabelapk.nometabela) Console.WriteLine("CampoPK: " & _objnotafiscal.infocampo("ttipocliente_id").tabelapk.nomecampo) C# String _strconexao = "Server = '(local)';database='sglpdesk';uid='sa';pwd='710912'"; clstbtnotafiscalsaida _objnotafiscal = new clstbtnotafiscalsaida(13, _strconexao); //Lista algumas propriedades dos campos pelo índice da coleção for (Int16 i = 0; (i <=_objnotafiscal.infocampo.count - 1); i++) { Console.WriteLine("Campo: " + _objnotafiscal.infocampo[i].nome); Console.WriteLine("Tipo SQL: " + _objnotafiscal.infocampo[i].tiposql); Console.WriteLine("Tamanho: " + _objnotafiscal.infocampo[i].tamanho); Console.WriteLine("Valor Default: '" + _objnotafiscal.infocampo[i].valordefault + "'"); Console.WriteLine(" "); //Lista os dados da tabela primary-key do campo foreing-key, informando-se o nome do campo Console.WriteLine("TabelaPK: " + objnotafiscal.infocampo["ttipocliente_id"].tabelapk.nometabela); Console.WriteLine("CampoPK: " + _objnotafiscal.infocampo["ttipocliente_id"].tabelapk.nomecampo); Coleções de Registros Representa um conjunto de registros de uma tabela, que são consultados através de diversos métodos. Como vimos anteriormente, uma tabela gera duas classes básicas: uma classe de registro e uma coleção desta classe. Para uma tabela chamada Cliente, teremos: - clstbcliente - coltbcliente: Coleção de clstbcliente Como Instanciá-la Existem pelo menos duas maneiras de se instanciar uma coleção de registros: simplesmente inicializando uma variável ou inicializando-a e consultando dados de sua tabela de origem. VB Imports MySoftLIB.EntityPlus Dim _objclientes As New coltbcliente() 'Instancia a classe gerando um objeto sem dados, mas contendo todos os campos da tabela. Dim _objclientes As New coltbcliente(nothing, "Nome", "TipoPessoa = 'Fisica'",, _,strstringconexao) 'Instancia a classe gerando um objeto que contem um conjunto de registros da tabela Cliente, 'cujo campo TipoPessoa = "Fisica", ordenado pelo campo Nome. 47

50 C# coltbcliente _objclientes = new coltbcliente(); //Instancia a classe gerando um objeto sem dados, mas contendo todos os campos da tabela. coltbcliente _objclientes = new coltbcliente(null, "Nome", "TipoPessoa = 'Fisica'", false, 0, strstringconexao); //Instancia a classe gerando um objeto que contem um conjunto de registros da tabela Cliente, //cujo campo TipoPessoa = 'Fisica', ordenado pelo campo Nome. Como esta classe é uma coleção, você irá acessar os dados através de um índice. Exemplos: VB Dim _objclientes As New coltbcliente(nothing, "Nome", _ "TipoPessoa = 'Fisica'",,,strStringConexao) 'Lista os clientes em um grid For i As Int16 = 0 To _objclientes.count - 1 GridDados.Rows.Add("") GridDados.Rows(i).Cells(0).Value = _objclientes(i).nome GridDados.Rows(i).Cells(1).Value = _objclientes(i).sexo Next i 'Exclui o registro contido na 3ª posição da collection. _objclientes(2).excluir C# coltbcliente _objclientes = new coltbcliente(null, "Nome", "TipoPessoa = 'Fisica'", false, 0,strStringConexao); //Lista os clientes em um grid for (Int16 i = 0; (I <= _objclientes.count - 1); i++) { GridDados.Rows.Add(""); GridDados.Rows[i].Cells[0].Value = _objclientes[i].nome; GridDados.Rows[i].Cells[1].Value = _objclientes[i].sexo; //Exclui o registro contido na 3ª posição da collection. _objclientes[2].excluir(); Como este tipo de classe é Strongly Typed, você pode definir o objeto instanciado, como DataSource de qualquer controle que possua esta propriedade, fazendo um databind. Exemplos: VB Dim cmbfornecedor As New ComboBox cmbfornecedor.displaymember = "cnome" cmbfornecedor.valuemember = "ccnpj" Dim _objfornecedor As New coltbfornecedor(nothing, "Nome",,,, strstringconexao) If Not _objfornecedor.erro Then cmbfornecedor.datasource = _objfornecedor End If 48

51 C# ComboBox cmbfornecedor = new ComboBox(); cmbfornecedor.displaymember = "cnome"; cmbfornecedor.valuemember = "ccnpj"; coltbfornecedor _objfornecedor = new coltbfornecedor(null, "Nome", "", false, 0, strstringconexao); if (!_objfornecedor.erro) { cmbfornecedor.datasource = _objfornecedor; Principais Propriedades, Métodos e Funções Assim como nas classes de registro, uma coleção de registro possui seus próprios métodos, funções e propriedades. Método New() É o método construtor da classe que, como no caso das classes de registro, instanciam um objeto consultando informações na tabela de origem. Ele é considerado um método de consulta geral, pois permite consultar registros de uma tabela com base em critérios de pesquisa que você utilizaria na clausula Where em uma instrução Select do SQL, assim como os campos de Order By. Ao executar este método, são passados alguns parâmetros que definirão quais registros serão recuperados, sua ordem e quantidade máxima. Definição: Public Sub New(ByVal obj<tabela> As clstb<tabela>, Optional ByVal Ordem As String = "", _ Optional ByVal Condicao As String = "", Optional ByVal ignorarzeros As _ Boolean = False, Optional ByVal MaxRegistros As Int32 = 0, Optional ByVal _ strconn As String = "") Parâmetros: 1º - Obj<Tabela> Objeto do tipo clstb<tabela> que, se passado como parâmetro, indica ao método utilizar os valores contidos nas propriedades-campos deste objeto como parâmetro de consulta dos registros. Exemplos: VB Dim _objcliente As New clstbcliente _objcliente.ctipopessoa = "Fisica" _objcliente.especial = True Dim _objclientes As New coltbcliente(_objcliente, "Nome, DataCadastro",, True, _ 50, strstringconexao) If _objclientes.erro Then MessageBox.Show(_objClientes.Mensagem) End If 49

52 C# clstbcliente _objcliente = new clstbcliente(); _objcliente.ctipopessoa = "Fisica"; _objcliente.especial = true; coltbcliente _objclientes = new coltbcliente(_objcliente, "Nome, DataCadastro", "", true, 50, strstringconexao); if (_objclientes.erro) { MessageBox.Show(_objClientes.Mensagem); O código acima consulta os registros da tabela Cliente com base nos valores das propriedadescampo fornecidas no objeto da classe clstbcliente, ou seja, todos os clientes especiais pessoa física. 2º - Ordem String que indica os campos de order by da consulta. No exemplo acima, a consulta é ordenada pelos campos Nome e DataCadastro. Caso você queira uma ordenação descendente, basta passar a palavra Desc depois dos nomes de cada campo (a default é Asc ). 3º - Condicao String que indica quais registros serão recuperados, semelhante aos parâmetros da cláusula Where de uma instrução SQL. Forneça este parâmetro quando não passar o primeiro. Exemplos: VB Dim _objclientes As New coltbcliente(nothing, "Nome, DataCadastro", _ "TipoPessoa = 'Fisica' and Especial = 1", True, _ 50, strstringconexao) C# coltbcliente _objclientes = new coltbcliente(null, "Nome, DataCadastro", "TipoPessoa = 'Fisica' and Especial = 1", true, 50, strstringconexao); Observe que foi fornecido Nothing/null no primeiro parâmetro, pois a condição Where foi fornecida diretamente na chamada do método. 4º - IgnorarZeros Quando passado o primeiro argumento do método (clstb<tabela>), indica se valores de propriedades-campo numéricas iguais a ZERO, não serão consideradas na construção da consulta. Exemplos: Imagine a tabela Cliente abaixo: Campo Tipo Valor Default Nome Varchar(50) Especial Bit 0 LimCredito Money 0 50

53 VB Dim _objcliente As New clstbcliente _objcliente.especial = True Dim _objclientes As New coltbcliente(_objcliente, "Nome, DataCadastro",, True, _ 50, strstringconexao) C# clstbcliente _objcliente = new clstbcliente(); _objcliente.especial = true; coltbcliente _objclientes = new coltbcliente(_objcliente, "Nome, DataCadastro", "", true, 50, strstringconexao); No código acima, a coleção é instanciada com base nas propriedades-campo do objeto _objcliente, ou seja, consultar todos os clientes especiais. Contudo temos o campo LimCredito (Money com valor default igual a ZERO). Isto indicaria ao método New() utilizar esta propriedade como argumento da consulta, pois, mesmo ela não tendo sido informada explicitamente, assume o seu valor default do banco de dados. Assim, seriam listados apenas os registros onde o limite de crédito do cliente fosse igual a ZERO. Para evitar isso, passa-se True no valor deste parâmetro, como feito no exemplo acima. 5º - MaxRegistros Informa a quantidade máxima de registros que deverão ser retornados. Utilize este parâmetro para evitar retornar uma lista de registros muito extensa, que pode demorar muito a executar. Caso informe ZERO, ou não informe, todos os registros serão retornados. No exemplo acima foi passado o valor 50. 6º - strstringconexao Informa a string de conexão com o banco de dados, caso o projeto Entity+ não tenha sido gerado com a opção Salvar senha encriptada selecionada. Este método é bastante flexível e pode consultar os registros de uma tabela por qualquer combinação de seus campos. Sua única limitação é que as condições da consulta estão limitadas aos campos da tabela. Caso deseje consultar dados de uma tabela baseados em campos de outras tabelas que estiverem relacionadas a ela, você deverá criar consultas especiais, que veremos mais a frente neste manual. Propriedade Count (Integer) Após uma consulta, esta propriedade indica se foram recuperados alguns registros (Count > 0). Utilize esta propriedade junto com a instrução For/Next para percorrer registros de uma coleção. Exemplo: Dim _ObjClientes As New coltbcliente(nothing,,,, strconexao) For i As Int16 = 0 To _objclientes.count - 1 MessageBox.Show("Nome: " & _objclientes(i).cnome) Next 51

54 Propriedade Erro (Boolean, Default = False) Indica se ocorreu algum erro após qualquer operação executada por métodos ou funções de uma classe Entity+ (métodos de consulta, gravação, exclusão, etc). Propriedade Mensagem (String) Retorna uma mensagem informativa sobre o resultado de uma operação executada por métodos ou funções de uma classe Entity+ (métodos de consulta, gravação, exclusão, etc.). Propriedade UltimoSQL Retorna a última string SQL gerada pela classe após a última chamada de um método de consulta. Propriedade ConsultaEmCascata (Boolean, Default = True) Habilita ou desabilita o encadeamento de objetos. Defina como False se você não quiser consultar informações de outras tabelas filhas a partir de uma tabela pai instanciada. Método Salvar() Salva um conjunto de registros recuperados em uma consulta de uma só vez. Caso algum problema ocorra durante este processo, um RollBack automático é disparado e a operação é desfeita. Definição: Public Sub Salvar(ByRef _objdados As <MeuProjeto>Core.Dados, Optional ByVal strconn As String = _ "", Optional ByVal Finalizar As Boolean = True) Parâmetros do Método Nome Obrigatória Função _objdados SIM É um objeto do tipo Dados, que se encontra da dll data access layer, que faz a comunicação com o banco de dados. Este parâmetro gerenciará a transação executada pela função Salvar(). strconn NÃO String de conexão com o BD. Deve ser fornecida caso a classe não tenha sido instanciada com ela anteriormente. Finalizar NÃO Indica se após salvar os dados, a função deverá dar um CommitTrans automático. Exemplos: VB Dim _objclientes As New coltbcliente(nothing, "Nome, DataCadastro", _ "TipoPessoa = 'Fisica' and Especial = 1", True, 50, strstringconexao) For i As Int16 = 0 To objclientes.count - 1 objclientes(i).cespecial = False Next i objclientes.salvar(nothing, _strstringconexao, True) 52

55 If objclientes.erro Then MessageBox.Show(objClientes.Mensagem) Else MessageBox.Show("Dados atualizados com sucesso") End If C# coltbcliente _objclientes = new coltbcliente(null, "Nome, DataCadastro", "TipoPessoa = 'Fisica' and Especial = 1", true, 50, strstringconexao); For (Int16 i = 0); (i <= objclientes.count - 1); i++) { objclientes(i).cespecial = false; objclientes.salvar(null, _strstringconexao, true); if objclientes.erro { MessageBox.Show(objClientes.Mensagem); else { MessageBox.Show("Dados atualizados com sucesso"); Os exemplos acima selecionam todos os clientes pessoa física especiais e retira o status de especial de todos os registros recuperados, salvando-os em seguida. Apesar de ter passado Nothing/null no primeiro parâmetro, toda a operação de salvamento é transacionada. Se um registro falhar, nenhum deles será salvo. Como o parâmetro Finalizar foi passado como True, é feito um committrans ao final e, caso ocorra algum erro, um roll back automatico é disparado. Método Excluir() Exclui todos os registros recuperados por um método de consulta. Caso ocorra algum erro, um Roll Back automático é disparado. Este método possui dois overloads: 1º - Public Sub Excluir() Exclui todos os registros recuperados na coleção. Exemplos: VB Dim _objclientes As New coltbcliente(nothing, "Nome, DataCadastro", _ "TipoPessoa = 'Fisica' and Especial = 1", True, 50, _ strstringconexao) _objclientes.excluir() If objclientes.erro Then MessageBox.Show(objClientes.Mensagem) End If 53

56 C# coltbcliente _objclientes = new coltbcliente(null, "Nome, DataCadastro", "TipoPessoa = 'Fisica' and Especial = 1", true, 50, strstringconexao); _objclientes.excluir(); if (objclientes.erro) { MessageBox.Show(objClientes.Mensagem); 2º - Public Sub Excluir(ByRef _objdados As EntityPlusCore.Dados, Optional ByVal _ strconn As String = "",Optional ByVal Finalizar As Boolean = True) Exclui todos os registros recuperados por um método de consulta em uma operação que envolva transação. Exemplos: VB Imports MySoftLIB.Entity 'Acesso às classes Entity+ Imports MySoftLIB Core 'Acesso às classes do DAL, onde se encontra a classe Dados... Dim _objdados As New Dados(_strStringConexao) Dim _objclientes As New coltbcliente(nothing,, "Inativo = 1",,, _ strstringconexao) 'Exclui todos os registros recuperados objclientes.excluir(_objdados, _strstringconexao, False) If objclientes.erro Then MessageBox.Show(objClientes.Mensagem) Exit Sub End If 'Após a exclusão, registra na tabela de log Dim _objlog As New clstblog _objlog.coperacao = "Exclusao de registros" _objlog.cusuario = strusuario _objlog.salvar(_objdados,, True, True) If _objlog.erro Then MessageBox.Show("Operação falhou (" & _ objlog.mensagem & ")") End If C# using MySoftLIB.EntityPlus //Acesso às classes Entity+ using MySoftLIBCore //Acesso às classes do DAL, onde se encontra a classe Dados... Dados _objdados = new Dados(_strStringConexao); coltbcliente _objclientes = new coltbcliente(null, "", "Inativo = 1", false, 0, strstringconexao); //Exclui todos os registros recuperados objclientes.excluir(_objdados, _strstringconexao, false); if (objclientes.erro) { MessageBox.Show(objClientes.Mensagem); Return; 54

57 //Após a exclusão, registra na tabela de log clstblog _objlog = new clstblog(); _objlog.coperacao = "Exclusao de registros"; _objlog.cusuario = strusuario; _objlog.salvar(_objdados, "", true, true); if (_objlog.erro) { MessageBox.Show("Operação falhou (" + _objlog.mensagem + ")"); O exemplo acima mostra duas operações de persistência de banco de dados. A primeira exclui todos os clientes inativos e, caso essa operação tenha êxito, registra na tabela de log o resumo da operação. Se em qualquer das etapas ocorrer erro, é dado um Roll Back automático e toda a operação é desfeita. Propriedade TotalInserts (Int32) Retorna a quantidade de inserts na tabela realizada na operação de salvamento. Propriedade TotalUpdates (Int32) Retorna a quantidade de updates na tabela realizada na operação de salvamento Método ADD() Adiciona um item à coleção. Exemplos: VB Dim _objclientes As New coltbcliente Dim _objcliente As New clstbcliente _objcliente.nome = txtnome.text _objcliente.datanasc = txtdatanasc.text _objclientes.add(_objcliente) C# coltbcliente _objclientes = new coltbcliente(); clstbcliente _objcliente = new clstbcliente(); _objcliente.nome = txtnome.text; _objcliente.datanasc = txtdatanasc.text; _objclientes.add(_objcliente); Método ExportarXML Salva um conjunto de registros recuperados pela coleção em um arquivo XML. Definição: Public Sub ExportarXML(ByVal arquivo As String) Parâmetro - Arquivo: Caminho mais nome do arquivo XML a ser salvo. 55

58 Exemplos: VB Dim _objclientes As New coltbcliente(nothing,, "Inativo = 1",,,_strStringConexao) _objclientes.exportarxml("c:\temp\clientes.xml") If objclientes.erro Then MessageBox.Show(_objClientes.Mensagem) End If C# coltbcliente _objclientes = new coltbcliente(null, "", "Inativo = 1", false, 0,_strStringConexao); _objclientes.exportarxml("c:\temp\clientes.xml"); if (objclientes.erro) { MessageBox.Show(_objClientes.Mensagem); Método ImportarXML() Recupera um conjunto de registros salvos em um arquivo XML gerado pelo método ExportarXML(). Definição: Public Sub ImportarXML(ByVal arquivo As String) Parâmetro - Arquivo: Caminho mais nome do arquivo XML a ser salvo. Exemplos: VB Dim _objclientes As New coltbcliente _objclientes.importarxml("c:\temp\clientes.xml") If objclientes.erro Then MessageBox.Show(_objClientes.Mensagem) End If C# coltbcliente _objclientes = new coltbcliente(); _objclientes.importarxml("c:\temp\clientes.xml"); if (objclientes.erro) { MessageBox.Show(_objClientes.Mensagem); Estes dois métodos são uma excelente opção para o desenvolvedor implementar rotinas de exportação e importação de dados. 56

59 Função Clone (Retorna Object) Cria um clone do objeto instanciado. Use essa função caso queira criar dois objetos idênticos que não tenham referência entre si. Definição: Public Function Clone() As Object Implements System.ICloneable.Clone Exemplos: VB Dim _objclientes As New coltbcliente(nothing,,,,, _strstringconexao) Dim _objclientes2 As coltbcliente = _objclientes.clone C# coltbcliente _objclientes = new coltbcliente(null, "", "", false, 0, _strstringconexao); coltbcliente _objclientes2 = _objclientes.clone(); Eventos das Coleções de Registro São os mesmos das classes de registro, com exceção do AoSalvarFilhas Propriedades, Métodos e Funções Windows Aplication Assim como nas Classes de Registro, as Coleções de Registros possuem recursos exclusivos para aplicações Windows Forms. Propriedade WINPesquisaPopUp (clswinpesquisapopup) Retorna um objeto do tipo clswinpesquisapopup, que disponibiliza propriedades e funções para a exibição de uma tela PopUp de consulta aos dados de uma tabela, permitindo retornar valores para o módulo chamador. Esta propriedade automatiza o processo de consulta aos dados de uma tabela PK, que fornece dados para uma segunda tabela FK, permitindo realizar consultas por qualquer campo da tabela e retornando o valor desejado ao módulo chamador. Imagine uma tela de cadastro de funcionários de um sistema de folha de pagamento, onde você deve informar os dados bancários de cada funcionário. Você deverá selecionar qual o código do banco para, depois fornecer agencia e conta. Em casos como esse você pode optar por uma Pesquisa PopUp, como a mostrada abaixo: 57

60 Este tipo de recurso está disponível a em qualquer objeto instanciado a partir de qualquer Coleção de Registro através da propriedade WINPesquisaPopUp. Exemplos: VB 'consulta os dados ta tabela tbanco, ordenada por nome Dim objbancos As New coltbtbanco(nothing, "Nome",,,, _strstringconexao) 'Exibe a janela popup de pesquisa objbancos.winpesquisapopup.show("pesquisar Bancos") C# //consulta os dados ta tabela tbanco, ordenada por nome coltbtbanco objbancos = new coltbtbanco(null, "Nome", "", false, 0, _strstringconexao); //Exibe a janela popup de pesquisa objbancos.winpesquisapopup.show("pesquisar Bancos"); É possível localizar um registro a partir de qualquer campo listado no grid, bastando clicar na coluna desejada e digitar o valor a ser encontrado na textbox de busca. Os valores são verificados em qualquer parte do campo e, caso encontrado, o mesmo fica visível e marcado em azul. Se o valor digitado não estiver listado no grid de consulta, é feita uma nova pesquisa no banco de dados e o grid é atualizado. Se esta última consulta não retornar dados, o grid fica vazio e o texto a ser localizado fica em vermelho Propriedades, Métodos e Funções da Classe clswinpesquisapopup Sendo a propriedade WINPesquisaPopUp do tipo clswinpesquisapopup, as seguintes propriedades, métodos e funções estão disponíveis a partir dele. Propriedade Erro (Boolean, ReadOnly) Retorna True quando algum erro ocorre durante a execução da consulta. Exemplo: If objbancos.winpesquisapopup.erro Then... End If Propriedade Mensagem (String, Readonly) Retorna a mensagem de erro. Exemplo: If objbancos.winpesquisapopup.erro Then MessageBox.Show(objBancos.WinPesquisaPopUp.Mensagem) End If Propriedade Campos (colwincampospesquisapopup) Representa a coleção de campos que irão ser listados na consulta. Caso não seja fornecido nenhum campo, a consulta irá retornar todos os campos da tabela, exibindo nas colunas os nomes. 58

61 Como se trata de uma coleção você dispõe de todas as propriedades, métodos e funções deste tipo de objeto, tais como Count, Add, etc... Cada item desta coleção representa um objeto do tipo clswincampospesquisapopup. Sintaxe do método Add(): Objeto.WinPesquisaPopUp.Campos.Add(objclsWinCamposPesquisaPopUp) Objetos do tipo clswincampospesquisapopup possuem as seguintes propriedades: 1º - Campo (String) Nome do campo a ser exibido 2º - Titulo (String) Titulo a ser exibido na coluna do grid. 3º - Formato (String) Formatação para os campos exibidos no grid. Utiliza o mesmo padrão da função Format do VB. 4º - Retornar (Boolean) Indica se o valor deste campo deverá ser retornado para o módulo chamador. 5º - ValorRetornado (String) Retorna o valor do campo devolvido pela consulta. Função Show() Exibe a janela de pesquisa e retorna True, em caso do usuário ter selecionado um registro. A seleção do registro ocorre com um duplo click na linha desejada ou selecionando-se a linha e clicando no botão OK. Sintaxe: Show([Titulo da Janela], [Largura da Janela], [Altura da Janela]) Todos os parâmetros são opcionais. Se for omitido o título, o valor padrão é Pesquisar Se forem omitidas as dimensões da janela, o padrão é largura = 452, altura = 350) Ajuste as dimensões de acordo com suas necessidades. Exemplos: VB 1 Imports MySoftLIB.EntityPlus 2 Imports MySoftLIB... 'Consulta a tabela 3 Dim objbancos As New coltbtbanco(nothing, "Nome",,,, _strstringconexao) If objbancos.erro Then MessageBox.Show(objBancos.Mensagem) Exit Sub End If 'Adiciona os campos que irão aparecer no grid 'True indica que este campo será retornado. 59

62 4 Dim objcampo As New clswincampospesquisapopup("codigo", "Código", "", _ tpalinhamento.esquerda, _ tpexibir.campo, "", True) 5 objbancos.winpesquisapopup.campos.add(objcampo) 'True indica que este campo será retornado. 6 objcampo = New clswincampospesquisapopup("nome", "", "", tpalinhamento.esquerda, _ tpexibir.campo, "", True) 7 objbancos.winpesquisapopup.campos.add(objcampo) 8 objcampo = New clswincampospesquisapopup("datainclusao", "Data de Inclusão", _ "dd/mm/yyyy") 9 objbancos.winpesquisapopup.campos.add(objcampo) 10 If objbancos.winpesquisapopup.show("pesquisar Bancos") Then 'Retorna o código do banco para uma MaskedTextBox 11 mskcodbanco.text = objbancos.winpesquisapopup.campos(0).valorretornado 'Retorna o nome do banco para um TextBox 12 lblnomebanco.text = objbancos.winpesquisapopup.campos(1).valorretornado 13 End If C# 1 using MySoftLIB.EntityPlus 2 using MySoftLIB... //Consulta a tabela 3 coltbtbanco objbancos = new coltbtbanco(null, "Nome", "", false, 0, _strstringconexao); if (objbancos.erro) { MessageBox.Show(objBancos.Mensagem); Return; //Adiciona os campos que irão aparecer no grid //True indica que este campo será retornado. 4 clswincampospesquisapopup objcampo = new clswincampospesquisapopup("codigo", "Código", "", tpalinhamento.esquerda, tpexibir.campo, "", true); 5 objbancos.winpesquisapopup.campos.add(objcampo); //True indica que este campo será retornado. 6 objcampo = new clswincampospesquisapopup("nome", "", "",tpalinhamento.esquerda, tpexibir.campo, "", true); 7 objbancos.winpesquisapopup.campos.add(objcampo); 8 objcampo = new clswincampospesquisapopup("datainclusao", "Data de Inclusão", "dd/mm/yyyy"); 9 objbancos.winpesquisapopup.campos.add(objcampo); 10 if (objbancos.winpesquisapopup.show("pesquisar Bancos")) { //Retorna o código do banco para uma MaskedTextBox 11 mskcodbanco.text = objbancos.winpesquisapopup.campos[0].valorretornado; //Retorna o nome do banco para um TextBox 12 lblnomebanco.text = objbancos.winpesquisapopup.campos[1].valorretornado; 13 Considerações: - Na linha 1 é feito o import da classe EntityPlus (MySoft representa o nome do projeto. Forneça o nome de sua DLL). Todas as Classes de Registro e Coleções de Registro estão disponíveis a partir dela. - Na linha 2 é feito o import das classes Root da dll, inclusive clswincampospesquisapopup. 60

63 - Na linha 4 é instanciado um objeto do tipo clswincampospesquisapopup, que recebe os parâmetros Campo, Titulo, Formato e Retornar. Este último indica que este campo será retornado após a seleção do registro. - Na linha 6 são passados apenas o nome do campo (que servirá também de título da coluna) e o parâmetro Retornar = True, para retornar o valor do campo após a seleção do registro. - Na linha 8 é passado o parâmetro formato dd/mm/yyyy para que todos os dados desta coluna (3ª) tenham esta formatação. - Na linha 10 é chamada a função Show(), que retornará True se o usuário selecionar um registro. - Na linha 11 é retornado o valor correspondente ao campo Código, que se encontra na posição 0 (zero) da coleção Campos. - Na linha 12 é retornado o valor correspondente ao campo Nome, que se encontra na posição 1 (zero) da coleção Campos. Caso a tabela a ser exibida contenha mais de 100 registros, é aconselhável fornecer o parâmetro MaxRegistros do método New/Consultar, igual ou inferior a 100. Qualquer registro não localizado entre os 100 selecionados inicialmente, serão consultados e listados no popup de consulta conforme valor digitado no campo localizar. Exemplo: Dim objbancos As coltbtbanco(nothing, "Nome",,, 100, _strstringconexao) Trazendo Dados de outras Tabelas Caso você queira exibir na janela de popup, dados de outra tabela que esteja relacionada com a tabela em questão, através de uma foreing-key, você deverá passar os parâmetros Exibir e CampoExibição da função Show(). Vejamos as seguintes tabelas: A tabela tcliente está relacionada com ttipocliente através da foreing-key ttipocliente_id. 61

64 Exemplos: VB Dim _strconexao As String = "Server = '(local)';database='sglpdesk';uid='sa';pwd='123456'" Dim _objclientes As New coltbtcliente(nothing, "Nome",,, 100, _strconexao) Dim _objcampo As New clswincampospesquisapopup("cpfcnpj", "CPF/CNPJ",,,,, True) _objclientes.winpesquisapopup.campos.add(_objcampo) _objcampo = New clswincampospesquisapopup("nome", "Nome/Rezão Social") _objclientes.winpesquisapopup.campos.add(_objcampo) _objcampo = New clswincampospesquisapopup("ttipocliente_id", "Tipo") _objclientes.winpesquisapopup.campos.add(_objcampo) _objclientes.winpesquisapopup.show("clientes") C# String _strconexao = "Server = '(local)';database='sglpdesk';uid='sa';pwd='123456'"; coltbtcliente _objclientes = new coltbtcliente(null, "Nome","",false, 100, _strconexao); clswincampospesquisapopup _objcampo = new clswincampospesquisapopup("cpfcnpj", "CPF/CNPJ", "", tpalinhamento.esquerda, tpexibir.campo,"", true); _objclientes.winpesquisapopup.campos.add(_objcampo); _objcampo = new clswincampospesquisapopup("nome", "Nome/Rezão Social"); _objclientes.winpesquisapopup.campos.add(_objcampo); _objcampo = new clswincampospesquisapopup("ttipocliente_id", "Tipo") ; _objclientes.winpesquisapopup.campos.add(_objcampo); _objclientes.winpesquisapopup.show("clientes"); O resultado do código acima é a exibição da seguinte tela: Observe que o conteúdo da foreingkey ttipocliente_id é listado com valores 1 ou 2, que não informam muita coisa. O correto aqui é trazer o significado desta coluna na sua tabela de origem. Alterando o código para trazer os dados da tabela-pk: 62

65 VB _objcampo = New clswincampospesquisapopup("ttipocliente_id", "Tipo",,, tpexibir.tabelapk, _ "Descricao") 'O quinto parâmetro passado acima indica que o conteúdo a ser exibido vem da tabela-pk do 'relacionamento, e o sexto parâmetro indica qual campo da tabela-pk será exibido, neste caso o 'campo Descrição _objclientes.winpesquisapopup.campos.add(_objcampo) _objclientes.winpesquisapopup.show("clientes") C# _objcampo = new clswincampospesquisapopup("ttipocliente_id", "Tipo", "", tpalinhamento.esquerda, tpexibir.tabelapk,"descricao") ; //O quinto parâmetro passado acima indica que o conteúdo a ser exibido vem da tabela-pk do //relacionamento, e o sexto parâmetro indica qual campo da tabela-pk será exibido, neste caso o //campo Descrição _objclientes.winpesquisapopup.campos.add(_objcampo); _objclientes.winpesquisapopup.show("clientes"); Veja no detalhe a mudança (1 = CONSUMIDOR e 2 = REVENDA) 63

66 C A P Í T U L O 2 Customizando o Seu FrameWork Vimos até agora todos os recursos disponíveis por padrão pelo Entity+, recursos estes que não dependem da interferência do usuário. Agora vamos mostrar como utilizar o IDE para customizar e aperfeiçoar o seu framework Comentários e Descrições de Campos No Microsoft SQL Server Management Studio, você pode fornecer uma descrição ao campo de uma tabela, de forma a identificar o conteúdo esperado para ele. No ambiente do Entity+ temos, além desta descrição, um campo de comentário para o mesmo. As descrições serão trazidas para dentro do projeto Entity+, e serão utilizadas, também, na função ValidarCampos() de uma classe de registro gerada, de forma a identificar qual campo violou sua regra de validação. Imagine a seguinte tabela: Campo Tipo Descrição ID int Nome Varchar(50) Nome completo do cliente Idade smallint EstadoCivil Char(1) Foi definida uma descrição para o campo Nome. Quando esta tabela for adicionada ao projeto Entity+, esta descrição será importada, tanto como descrição, quanto como comentário. Para o Entity+, somente o comentário tem função informativa. Ela será exibida, juntamente com as demais informações, na tela principal de seu IDE e na documentação de seu projeto. Assim teremos: Observe que a descrição e o comentário são os mesmos. Agora iremos alterar o comentário. Para isso devemos clicar no botão e descrições, ou selecionar a mesma opção pelo menu Editar. Comentários 64

67 Então fizemos as alterações, deixando o campo comentário mais completo e o campo Descrição mais sucinto. Observe agora o exemplo do item 10.6, capítulo 1: VB 'tenta salvar e retorna a lista de campos invalidados Dim _objcampos As List (Of clscampo) = objcliente.salvar(_strstringconexao) If _objcliente.erro Then For i As Int16 = 0 To _objcampos.count - 1 Messagebox.Show("Campo " & _objcampos(i).descricao & " (" & objcampos(i).mensagem & ")") Next i End If C# //tenta salvar e retorna a lista de campos invalidados List<clsCampo> _objcampos = objcliente.salvar(_strstringconexao); if (_objcliente.erro) { for (Int16 i = 0; (I <= _objcampos.count - 1); i++) { Messagebox.Show("Campo " + _objcampos[i].descricao + " (" + _objcampos[i].mensagem + ")"); Caso o campo nome tivesse sua regra de validação violada, ao invés da mensagem exibir o nome do campo Nome, ela irá exibir Nome do cliente Definição de Auto incremento Vimos no início deste manual, que podemos definir alguns campos de uma tabela como auto incremento, e que ele é gerenciado pela DAL de seu framework. 65

68 Para definir campos de auto incremento deve-se selecionar a tabela (na lista de tabelas) e clicar no botão Auto incremento, na tela principal de seu projeto, ou selecionar no menu Editar/Definir Auto incremento. Na parte superior da tela você verá todos os campos numéricos inteiros, candidatos ao auto incremento. Ao selecionar um campo, você verá a instrução que o Entity+ irá incluir nas stored procedures de inclusão. Na lista Campos de Condição você poderá definir condições de auto incremento. Na tela acima temos o campo ID definido como auto incremento. Isto significa que a cada registro incluído este campo será incrementado (+1). Como o mesmo é chave-primária, não teria sentido em selecionar um campo de condição de auto incremento, pois a regra de integridade seria disparada. Mas existem casos em que condições de auto incremento são necessárias. Imagine a tabela abaixo: Tabela Atendimento PK Campo Tipo Numero int Ano smallint Descricao Varchar(50) Esta tabela registra dados de atendimentos de assistência técnica de uma empresa. Cada atendimento é composto por dois números: um número sequencial e o ano do atendimento. Assim teríamos o atendimento , , , , e Ou seja, o auto incremento 66

69 depende do ano do atendimento. Neste caso, o campo Ano será a condição de auto incremento do campo Numero. Para definir esta condição, basta selecionar este campo na lista Campos de Condição. Caso a sua condição de auto incremento seja mais complexa do que a ferramenta possa oferecer interativamente, você pode codificá-la direto no campo Codificação, utilizando SQL ANSI. Sempre dê preferência ao auto incremento do Entity+. Mesmo que o campo seja auto incremento definido no SQL Server, faça o auto incremento no ambiente do Entity+ também Validação de Campos No SQL Server, você define se um campo é obrigatório ou não, através da propriedade Permitir Nulos. Também define, via integridade referencial, que um campo foreing-key só poderá conter valores contidos em sua tabela primary-key. No ambiente do Entity+ você pode definir validações extras, que funcionarão como constraints controladas pela DAL do seu framework. Para determinar se um campo será validado antes de ser salvo na tabela, basta selecionar a checkbox ao lado do seu nome. Ao se executar o método Salvar() de um objeto Entity+, ele fará as validações dessas regras e, só depois, salvará os dados no BD, do contrário retorna Erro, e a lista de campos não conformes, como vimos no item 10.6 do capítulo 1. 67

70 Na tela acima, os campos ID, Descrição, Indicador, preço e Tipo estão indicados para validação. Sendo o campo ID chave-primária não incrementável, ele é obrigatoriamente um campo marcado para validação, não podendo ser modificado. O campo Descrição, que é do tipo varchar (texto), seu operador de validação é > 0. Como é um campo de texto isto significa que o tamanho de seu conteúdo seja maior que ZERO, ou seja, ele deve ter conteúdo. Em se tratando de campos numéricos, os operadores de validação exigem que o conteúdo do campo seja avaliado numericamente. O campo Indicador, por exemplo, exige que o valor a ser armazenado ali, seja maior que ZERO. Todos os campos que não permitem nulos (requeridos) são marcados para validação pelo Entity+, a não ser que tenham valor default definido, como é o caso dos campos Quantidade e Preço, que tem valor default ZERO. Mesmo assim você pode foçar as suas validações. Até mesmo campos marcados como não requeridos no SQL Server, podem ter seus conteúdos marcados para validação no IDE do Entity+, conforme a regra que você definir. Para definirmos a condição de validação de um campo, basta selecioná-lo e clicar no botão Validação. Vejamos o campo Preço. Vamos definir que nenhum registro desta tabela poderá ter preços inferiores a 2,00. 68

71 Um campo numérico pode ser validado dentro de um intervalo de valores. Por exemplo, o preço tem que ser entre R$ 2,00 e R$ 10,00. Neste caso teríamos: Caso você não selecione para validação um campo requerido que não possua valor default definido, a função Salvar() não irá dar o devido tratamento a ele. Neste caso o mesmo não consta na lista de campos retornados pela propriedade CamposErros e pelo retorno na função Salvar(). Como consequência, será retornada uma mensagem de erro de integridade do SQL Validação de Datas É possível definir regras de validação para campos do tipo data. Sua regra default é > 0, ou seja, é obrigatório fornecê-la, mas podemos definir regras mais sofisticadas, como, por exemplo, uma data tem ser superior à 23/02/2000 por algum motivo, ou tem que estar num intervalo de datas válidas. Para editar uma regra de validação, você tem que marcar o campo desejado para validação, selecionando a checkbox ao lado de seu nome. Nesse momento é aplicada a regra padrão > 0 ou >= 0, dependendo do tipo de campo. Temos agora que clicar no botão opção pelo menu Editar. Validações, o selecionar a mesma Vamos imaginar um escritório de advocacia que precisa de um sistema para controle de processos, e que nenhum processo cadastrado pode ser anterior a 01/01/2000. Então teríamos: Aplicando esta regra, impediríamos que processos antes desta data fossem cadastrados no sistema. 69

72 Agora vamos imaginar uma data de nascimento. Nunca esta data pode ser maior que a data atual. Então teríamos: A data 00/00/0000 faz com que a comparação seja feita em relação à data do sistema do servidor de dados SQL (GetDate()). Imagine agora um consultório médico, onde a data de retorno do paciênte não pode ser antes de 10 dias da data atual e nem depois de 30 dias desta mesma data. Ao se fornecer a data 00/00/0000, aparecerá um botão para a edição de uma regra complementar. Você poderá incrementar ou decrementar a data do sistema para definir a sua regra. Caso você queira retornar à regra padrão do campo, basta fornecer o comparador > e a data em branco / / Domínio de Campos Outro tipo de validação de dados é a validação por domínio. Nele, um campo só poderá conter valores que fazem parte do domínio de valores. Então, um domínio nada mais é que uma lista de valores válidos. O SQL Server já faz isso através da integridade referencial, onde um campo foreing-key de uma tabela só aceitará valores contidos em um campo primary-key de outra tabela, mas em alguns casos é desnecessário criar esta relação. Por exemplo, o campo EstadoCivil da tabela Cliente só poderá aceitar 70

73 os seguintes valores imutáveis (Solteiro, Casado, Viúvo, Divorciado). Para estes casos o Entity+ utiliza os domínios. Para definir um domínio para um campo, basta selecioná-lo para validação e clicar no botão Domínio ou selecionar a mesma opção no menu Editar. Nesta tela podem-se informar os valores que serão aceitos no campo e a descrição de cada valor. Quando você define um domínio para um campo, o Entity+ irá escrever duas classes para ele (uma classe de domínio e uma coleção desta classe). No caso do campo EstadoCivil, teríamos: - Classe clsdm_exemplo_estadocivil Onde Exemplo é o nome da tabela e EstadoCivil o nome do campo. Propriedades: - Valor: Retorna o valor definido no domínio - Descrição: Retorna a descrição do valor de domínio - Classe coldm_exemplo_ EstadoCivil Esta classe é uma coleção da classe clsdm_exemplo_estadocivil e contém todos os itens definidos para o domínio. O Entity+ cria estas duas classes para que você possa utilizar os valores de domínio, contidos na coleção. Vamos imaginar a tela de cadastro para esta tabela. Geralmente os valores para o campo EstadoCivil viriam listados em uma ComboBox, e você entraria com esses valores manualmente, mas como temos a coleção coldm_exemplo_estadocivil, vamos utilizá-la para preencher a combo. 71

74 Exemplos: VB Dim cmbtipo As New ComboBox cmbtipo.displaymember = "Descricao" cmbtipo.valuemember = "Valor" Dim _objec As New clstbexemplo.coldm_exemplo_estadocivil cmbtipo.datasource = _objec C# ComboBox cmbtipo = new ComboBox(); cmbtipo.displaymember = "Descricao"; cmbtipo.valuemember = "Valor"; clstbexemplo.coldm_exemplo_estadocivil _objec = new clstbexemplo.coldm_exemplo_estadocivil(); cmbtipo.datasource = _objec; Observe que a classe coldm_exemplo_estadocivil foi instanciada a partir da classe de registro da tabela Exemplo, clstbexemplo. Existem dois overloads para o método de construção de uma coleção de domínio (coldm): - Sem parâmetros Public Sub New() - Com parâmetro de seleção de elemento Public Sub New(valor As String) Este segundo overload retorna uma coleção contendo somente um elemento com base no valor fornecido. Sendo assim, caso quiséssemos recuperar apenas o elemento Solteiro da lista, teríamos: Dim _objec As New clstbexemplo.coldm_exemplo_estadocivil("s") Quando você define um domínio para um campo, a propriedade referente a ele na classe de registro passa a ser do tipo da classe que foi criada para o domínio. No exemplo acima, tempos o campo EstadoCivil, que inicialmente dava origem à propriedade cestadocivil (string), da classe clstbexemplo. Com a definição do domínio para este campo, a propriedade cestadocivil passou a ser do tipo clsdm_exemplo_estadocivil. Isto muda a forma que você vai se referir à esta propriedade: - Antes do domínio Dim _objexemplo As New clstbexemplo(1, strstringconexao) txtcodec.text = _objexemplo.cestadocivil txtdescec.text = "Solteiro" _objexemplo.cestadocivil = "S" _objexemplo.salvar() - Depois do domínio Dim _objexemplo As New clstbexemplo(1, strstringconexao) txtcodec.text = _objexemplo.cestadocivil.valor 72

75 txtdescec.text = _objexemplo.cestadocivil.descricao _objexemplo.cestadocivil.valor = S _objexemplo.salvar() Messagebox.Show(_objExemplo.cEstadoCivil.Descricao) Mostra Solteiro no popup Observe que, após a adição do domínio, a propriedade cestadocivil não é mais referenciada diretamente, pois ela passou a ser um object que possui duas propriedades: Valor e Descrição. Quando estiver definindo os campos de uma tabela no ambiente do Sql Server, você pode fornecer um domínio diretamente lá, através da propriedade Descrição de um campo, fornecendo uma lista de valores separados por ;. Exemplo: S-Solteiro;C-Casado;V-Viúvo;D-Divorciado. Ao ler a estrutura dessa tabela o Entity+ irá lhe perguntar se deseja definir um domínio para o campo Encadeamento das Classes de Registro Vimos no início deste manual que as Classes de Registro podem ser encadeadas baseadas nos relacionamentos entre suas tabelas de origem, e que, através deste encadeamento, podemos acessar as informações de qualquer tabela a partir de um único objeto instanciado. Existem dois tipos de encadeamento. O primeiro é feito automaticamente pelo Entity+, onde qualquer campo foreing-key já gera um encadeamento via propriedade Tb<Tabela> (ver exemplo 1). O outro tipo ocorre entre tabelas pai e tabelas filhas (Um para um/vários) (ver exemplo 2). Este último deve ser estabelecido manualmente, pois, uma vez feito, serão codificadas classes e rotinas para dar suporte a ele. Não valeria a pena, por exemplo, fazer o encadeamento entre as tabelas Produto -< ItemNotaFiscal (um para vários), pois não seria útil consultar todos os itens de notas fiscais para um determinado produto, por que, além de retornar uma lista gigantesca, não teria uso prático. Então fica a seu critério fazê-lo de acordo com a suas necessidades. Exemplo1: VB 'Consulta um registro da tabela tnotafiscalitem pala sua chave-primária Dim _objnotafiscalitem As New clstbtnotafiscalitem(10, strstringconexao) If _objnotafiscalitem.encontrado Then 'Lê a descrição do produto da tabela tproduto via propriedade de encadeamento TbtProduto txtproduto.text = _objnotafiscalitem.tbtproduto.cdescricao End If Exemplo2: 'Consulta um registro da tabela tnotafiscal pala sua chave-primária 'Relacionamento tnotafiscal -< tnotafiscalitem >- tproduto Dim _objtnotafiscal As New clstbtnotafiscal(100, strstringconexao) 'Exibe o preco de custo de todos os itens da nota via propriedade (Tabela-Filha) TfNotaFiscalItem 73

76 For i As Int16 = 0 To _objtnotafiscal. TftNotaFiscalItem.Count - 1 MessageBox.Show(_objtNotaFiscal.TftNotaFiscalItem(i).TbtProduto.cPrecoCusto) 'duplo 'encademanto Next i Como o primeiro tipo de encadeamento se baseia na chave-primária da tabela PK relacionada (Produto.Codigo), o código abaixo daria erro: Dim _objitemnotafiscal As New clstbtitemnotafiscal(200, strstringconexao) _objitemnotafiscal.cproduto_codigo = Nothing txtpreco.text = _objitemnotafiscal.tbtproduto.cprecocusto O código acima dispararia o erro Object not set to an instance of an object, pois o campo foreing-key cproduto_codigo foi atribuido o valor Nothing, impedindo que encadeamento encontre o registro relacionado. Como estabelecer o encadeamento? Editar. Basta clicar no botão Encadeamentos da classe ou através da mesma opção no menu São listadas todas as tabelas que estejam relacionadas com a tabela atual. Basta selecionar as tabelas-filhas, cujas classes serão encadeadas. 74

77 O campo Selecione o método de construção mostra o método que irá permitir este encadeamento. Este método pertence à classe de registro da tabela foreing-key. Na tela acima, o método NewtEmpresa() da classe coltbtfuncionario gerencia este encadeamento. Métodos com essa finalidade são criados automaticamente pelo Entity+. Eles utilizam a chave-primária da tabela atual (PK) como parâmetro de consulta. Você não deve se preocupar com estes métodos, contudo poderá utilizá-los em seu código para instanciar uma coleção de uma determinada tabela. Por exemplo, você pode consultar todos os funcionários de uma empresa cujo campo Codigo, chave-primária da tabela tempresa seja igual a 30. Dim _objtfuncionario As New coltbtfuncionario _objtfuncionario.newtempresa(30, strstringconexao) ' Gera uma coleção contendo totos os funcionários da empresa Código = 30 Após estabelecermos este encadeamento, teremos disponível a propriedade TftFuncionario do tipo coltbtfuncionario. É através dela que navegaremos para os registros tabela tfuncionario relacionada. Então teremos: VB Dim _objtempresa As New clstbtempresa(30, strstringconexao) If _objtempresa.encontrado Then Console.WriteLine("Funcionários da empresa " & _objtempresa.crazaosocial) For i As int32 = 0 To _objtempresa.tftfuncionario.count - 1 Console.WriteLine(_objtEmpresa.TftFuncionario(i).cNome) Next End If C# clstbtempresa _objtempresa = new clstbtempresa(30, strstringconexao) if (_objtempresa.encontrado) { Console.WriteLine("Funcionários da empresa " + _objtempresa.crazaosocial); for (int32 = 0; (i <= _objtempresa.tftfuncionario.count - 1); i++) { Console.WriteLine(_objtEmpresa.TftFuncionario[i].cNome) 75

78 2.5 - Propriedades Totalizadoras São propriedades pertencentes às classes de registro que totalizam valores de campos contidos em registros de tabelas-filhas. Imagine as tabelas tnotafiscal e tnotafiscalitem. Na tabela tnotafiscalitem temos os campos Quantidade e ValorUnitario. Seria interessante eu saber qual o valor total da nota sem a necessidade de ter um campo Total na tabela tnotafiscal, pois esta informação está disponível através dos campos Quantidade e ValorUnitario, dos registros relacionados da tabela tnotafiscalitem. Para facilitar isto, o Entity+ permite a você, criar propriedades totalizadoras na classe da tabela tnotafiscal. Este recurso está disponível a partir do botão Propriedades totalizadoras ou na mesma opção do menu Editar. Para definir uma propriedade totalizadora, você deverá estabelecer o encadeamento das tabelas envolvidas, como vimos no tópico anterior. Selecione a tabela e os campos que serão totalizados. 76

79 Ao selecionar os campos de totalização, o Entity+ adiciona uma propriedade para cada campo da seleção na classe de registro da tabela atual. Então, neste caso, teríamos na classe clstbtnotafiscal as seguintes propriedades totalizadoras: - Public ReadOnly Property cttnotafiscalitem_quantidade As Int32 - Public ReadOnly Property cttnotafiscalitem_valorvarejo As Double Exemplos: VB Dim _objnotafiscal As New clstbtnotafiscal(10, strstringconexao) If _objnotafiscal.encontrado Then txttotalnotafiscal.text = objnotafiscal.cttnotafiscalitem_quantidade * _objnotafiscal.cttnotafiscalitem_valorvarejo End If C# clstbtnotafiscal _objnotafiscal = new clstbtnotafiscal(10, strstringconexao); if (_objnotafiscal.encontrado) { txttotalnotafiscal.text = _objnotafiscal.cttnotafiscalitem_quantidade * _objnotafiscal.cttnotafiscalitem_valorvarejo; Consultas Personalizadas Vimos que as classes de registro possuem métodos construtores New(), que localizam um registro de uma tabela com base na sua chave-primária ou constraints, e que as coleções de registro localizam um conjunto de registros, também, através de seus métodos construtores New(), informando determinados parâmetros de consulta. Contudo, você pode criar métodos de consulta próprios. Existem três formas de definir estas consultas: Métodos de Consulta de Coleção São métodos que serão criados a partir da classe de coleção de uma tabela para localizar um conjunto de registros de acordo com determinado critério de busca. Estes métodos estão limitados a utilizar como parâmetros, campos da tabela de origem. 77

80 Você define os seus métodos através da interface acima, que consta na tela principal de seu projeto no Entity+. Aqui você nomeia o método e seleciona os campos da tabela e os operadores de comparação. Observe que já existem alguns métodos definidos para algumas tabelas do projeto. Estes métodos são criados automaticamente pelo Entity+ para tabelas que possuem foreing-keys. Eles têm a função de estabelecer o encadeamento entre as tabelas, como vimos anteriormente. Estes métodos automáticos não podem ser alterados ou excluídos pelo usuário, mas podem (como mencionado anteriormente) serem utilizados para instanciar uma coleção de uma tabela com base nas suas chaves estrangeiras. Para incluirmos um novo método, basta clicar no botão Adicionar e digitar o nome. Depois selecione os campos que servirão como parâmetros do método e, consequentemente, como critérios de pesquisa. Os operadores de comparação são: =, >, <, >=, <=, <>, Like valor%, Like %valor e Between. Exemplo: Vamos criar um método que consulta a tabela tcliente pelo campo Nome, de forma que possa ser utilizada em um módulo de consulta, localizando os clientes à medida que seu nome é digitado. Observe que selecionamos o campo Nome e atribuímos o operador Like valor% para que a busca seja feita considerando-se qualquer parte do campo a partir do seu início. É importante fornecer a descrição do método para que a mesma seja exibida no ambiente do Visual Studio pelo recurso de intellisense ao se digitar o nome do método. 78

81 Para que os dados da coleção venham ordenados pelo campo Nome, definiremos este campo como order by, clicando no botão Order By. Selecione o campo na lista e a ordem. Você pode selecionar vários campos de order by. Exemplos: VB Private Sub txtnome_textchanged(sender As System.Object, e As System.EventArgs) Handles txtnome.textchanged 'Lista os clientes cujo nome iniciam pelo texto contido em txtnome.text Dim _objclientes As New coltbtcliente _objclientes.pesquisanome(txtnome.text, strstringconexao) grditens.datasource = _objclientes End Sub C# private void textbox1_textchanged(object sender, EventArgs e) { 'Lista os clientes cujo nome iniciam pelo texto contido em txtnome.text coltbtcliente _objclientes = new coltbtcliente(); _objclientes.pesquisanome(txtnome.text, strstringconexao); grditens.datasource = _objclientes; Overloads dos Métodos de Consulta de Coleção Você pode ter vários métodos definidos com o mesmo nome, desde que as suas assinaturas sejam diferentes. Você observa as assinaturas de um método através dos tipos de seus parâmetros. Os métodos PesquisaNome() abaixo, possuem a mesma assinatura (String), apesar de terem operadores diferentes. Quando isso ocorrer você não poderá ter nomes iguais. 79

82 Observe que houve uma falha de overload, pois os métodos têm o mesmo nome e a mesma assinatura, portanto este último é inválido. Operador Between Caso você defina Between como operador de um campo que servirá de critério de consulta para um método, serão criados dois parâmetros para este campo. Observe que agora a assinatura do método foi validada. Agora temos os dois oveloads do método PesquisaNome(): Public Sub PesquisaNome(pNome As String, Optional ByVal strconn As String = "") Public Sub PesquisaNome(pNome As String, pdatainclusao1 As Date, pdatainclusao2 As Date, _ Optional ByVal strconn As String = "") Observe que segundo overload do método recebe duas datas como parâmetros, por conta da condição Between para o campo DataInclusao. Exemplo: Dim _objclientes As New coltbtcliente _objclientes.pesquisanome(txtnome.text, mskdatainicial.text, mskdatafinal.text, strstringconexao) 80

83 2.7 - Rotinas-View Na maioria dos casos, o método de construção New() de uma coleção de registros é suficiente para retornar os registros desejados de uma tabela, contudo existem determinadas situações em que você precisa consultar os dados, com base em campos de outras tabelas relacionadas. Em uma programação convencional, você faria isso escrevendo uma cansativa AD HOC query, contendo um Inner Join entre as tabelas relacionadas e gerando um DataReader, por exemplo. Com o Entity+ você pode criar rotinas personalizadas, para a coleção da classe da tabela que você deseja consultar, parecida com a que criamos no tópico anterior, mas com muito mais recursos. Chamamos estas rotinas de Rotinas-view. Estas rotinas são criadas dentro do escopo da Classe de Registro (collection) de uma tabela e estão disponíveis a partir destas. Para criar uma nova rotina-view, basta clicar no botão através do menu Editar. Rotinas-view ou na mesma opção Através desta interface você irá montar a sua consulta com base em critérios diversos vindos da tabela principal e de seus relacionamentos encadeados. Este tipo de consulta somente recuperará registros da tabela selecionada, vista acima com sua barra de título em marrom, na forma de um objeto do tipo coleção de registro (coltb). No exemplo acima temos uma consulta que irá recuperar os registros da tabela tnotafiscalsaida com base no campo Código da tabela tproduto relacionada. Ao clicarmos na aba SQL, veremos a string SQL gerada para ela. 81

84 Critérios de Consulta Existem dois tipos de critérios de consulta: os parâmetros e as condições. gerado. Os parâmetros irão receber valores repassados através do método de consulta que irá ser As condições serão determinadas internamente e são fixas. No exemplo acima, tempos um critério do tipo Parâmetro. Tanto os parâmetros quanto as condições possuem um comparador. Estes irão determinar o tipo de comparação no critério de consulta. A coluna valor define a variável que irá receber o parâmetro internamente no método de consulta que será gerado. 82

85 Na condição definida acima foi estabelecido que as notas fiscais a serem recuperadas devem ser aquelas que, além de se referirem a um determinado grupo de produtos (passado via parâmetro), devem ser de produtos inativos. A Consulta SQL gerada ficaria da seguinte forma: SELECT tnotafiscalsaida.* FROM tnfsaidaitem, tnotafiscalsaida, tproduto WHERE tnotafiscalsaida.id = tnfsaidaitem.tnotafiscalsaida_id And tproduto.codigo = tnfsaidaitem.tproduto_codigo AND tproduto.tgrupo_codigo and tproduto.inativo = 1 A receberá o valor via párâmetro do método a ser criado. Já a condição exige que sejam apenas produtos inativos (inativo = 1 (true)). Observe a coluna Operador. Ela define a lógica boleana na montagem da consulta, podendo ser AND ou OR. regras: O código SQL gerado pode ser alterado manualmente, contanto que não viole as seguintes - Todos os campos da tabela principal devem ser retornados. - Os nomes de variáveis de parâmetro não podem ser modificados. Caso alguma dessas regras seja violada, o Entity+ se recusará a salvar a rotina-view. O Comparador Between No caso de um parâmetro, este comparador irá causar a criação de dois parâmetros na rotina a ser criada. Assim teríamos: E o SQL: SELECT tnotafiscalsaida.* FROM tnfsaidaitem, tnotafiscalsaida, tproduto WHERE tnotafiscalsaida.id = tnfsaidaitem.tnotafiscalsaida_id And tproduto.codigo = tnfsaidaitem.tproduto_codigo AND 83

86 tnotafiscalsaida.datasaida Testando a consulta Após definir os critérios da consulta, podemos testá-la. Para isso basta clicar no botão Executar consulta ou selecionar a mesma opção no menu Editar. Forneça os valores dos parâmetros e click em OK. A tela abaixo surgirá trazendo os registros recuperados. 84

87 Salvando Sua Rotina View Após ter criado e testado sua rotina-view, é hora de salvá-la no seu projeto. Uma vez salva, ela estará vinculada à tabela principal da consulta e, ao se publicar o projeto, irá dar origem a uma rotina disponível a partir da coleção de registro da tabela (uma coltb). Para salvar sua rotina-view, basta clicar no botão Salvar. Você deverá fornecer o nome da rotina e, opcionalmente, sua descrição, que irá aparecer no recurso interlicense do Visual Studio e na documentação do projeto. Ele dará origem à função abaixo: Public Function ProdutoDataSaida(tNotaFiscalSaida_DataSaida1 As Date, _ tnotafiscalsaida_datasaida2 As Date, Optional ByVal _ strordem As String = "", Optional ByVal strcondicao _ As String = "", Optional ByVal strconn As String = "", _ Optional ByVal TipoLock As entipolock = entipolock.padrao) _ As ColTbtNotaFiscalSaida Parâmetros da Função Gerada Nome tnotafiscalsaida_datasaida1 tnotafiscalsaida_datasaida2 strordem strcondicao strconn TipoLock Descrição Data inicial DataFinal Parâmetro opcional que informa a lista de campos para a ordenação dos dados recuperados (order by). Parâmetro opcional que pode fornecer critérios adicionais de consulta, obedecendo o padrão SQL ANSI. String de conexão (opcional) Parâmetro opcional que informa como registros bloqueados (locked) serão considerados durante a consulta. São eles: Padrao (default), NOLOCK, READPAST. 85

88 TipoLock Nome Padrão NOLOCK READPAST Descrição Registros bloqueados não serão recuperados pela consulta. Também conhecido como READUNCOMMITTED. Lê todos os registros, inclusive os não commitados. Permite a leitura de todos os registros com exceção dos não commitados. Caso exista uma ou mais operações de persistência em uma tabela envolvendo uma transação que ainda não foi concluída, os registros desta estarão bloqueados (locked) e, caso você tente ler registros desta mesma tabela neste momento, sua aplicação irá travar. Para evitar isto, use o parâmetro entipolock.readpast nos métodos e funções de consulta que suportam este parâmetro. Fazendo isto você poderá recuperar todos os registros desta tabela, com exceção dos não commitados. Assim, considerando a rotina-view do exemplo acima, teríamos: VB Dim _objdados As New Dados(_strStringConexao) 'Instancia classe Dados, vinda da DAL. Dim _objclstbnf As New clstbtnotafiscalsaida(100, strstringconexao) objclstbnf.excluir(_objdados,, False) 'Exclui o registro recuperado na consulta acima, em uma 'operação transacionada não finalizada (último parâmetro 'Finalizar = False. Dim _objcoltbnf As New coltbtnotafiscalsaida 'Consulta dados da tabela através da função (rotina-view) ProdutoDataSaida _objnf.produtodatasaida(date.parse(mskdata1.text), Date.Parse(mskData2.Text), "DataSaida",, _ strstringconexao) 'A linha acima causaria o travamento da aplicação, uma vez que existe uma operação transacionada 'não finalizada na mesma tabela. If _objdados.emtransacao Then _objdados.committrans 'Finaliza a transação End If C# Dados _objdados = new Dados(_strStringConexao); //Instancia classe Dados, vinda da DAL. clstbtnotafiscalsaida _objclstbnf = new clstbtnotafiscalsaida(100, strstringconexao); objclstbnf.excluir(ref _objdados, "", false) //Exclui o registro recuperado na consulta acima em //uma operação transacionada não finalizada (último //parâmetro Finalizar = False. coltbtnotafiscalsaida _objcoltbnf = new coltbtnotafiscalsaida(); //Consulta dados da tabela através da função (rotina-view) ProdutoDataSaida _objnf.produtodatasaida(datetime.parse(mskdata1.text), DateTime.Parse(mskData2.Text), "DataSaida", "", strstringconexao); //A linha acima causaria o travamento da aplicação, uma vez que existe uma operação transacionada //não finalizada na mesma tabela. if _objdados.emtransacao { _objdados.committrans(); //Finaliza a transação 86

89 Para evitar esse problema, passaremos o parâmetro TipoLock = entipolock.readpast: _objnf.produtodatasaida(date.parse(mskdata1.text), Date.Parse(mskData2.Text), "DataSaida",, _ strstringconexao, entipolock.readpast) Passando uma condição adicional: VB... Dim _strcond As String = TipoNF = 2 Definindo uma condição extra _objnf.produtodatasaida(date.parse(mskdata1.text), Date.Parse(mskData2.Text), "DataSaida", _ strcond, strstringconexao) C#... string _strcond = String = "TipoNF = 2"; Definindo uma condição extra _objnf.produtodatasaida(date.parse(mskdata1.text), Date.Parse(mskData2.Text), "DataSaida", strcond, strstringconexao); Classes-View Vimos no tópico anterior que as rotinas-view podem carregar dados de uma tabela em um objeto do tipo classe de registro (clstb) com base em critérios de campos de outras tabelas relacionadas. Isso restringe a consulta aos campos da tabela em questão (principal). Porém, existe outra forma de consultarmos registros de várias tabelas relacionadas, recuperando informações de quaisquer campos destas tabelas. Fazemos isso através das classes-view. Uma classe-view irá mapear os campos de uma consulta na forma de propriedades e disponibilizará um método de consulta onde passaremos parâmetros, da mesma forma que fizemos com as classes-view, contudo, ao invés de criarmos uma função disponível dentro de uma coleção de registros, criaremos uma classe e sua respectiva coleção da classe. 87

90 Diferenças entre Rotina-View e Classe-View Uma rotina-view gera uma função dentro da coleção de registro de uma tabela, que pode ser disparada de qualquer objeto instanciado a partir desta classe, recuperando os registros e alimentando, assim, esta coleção. Uma classe-view, por sua vez, irá produzir uma clsvw (classe-view) contendo o mapeamento dos campos da consulta na forma de propriedades, e uma coleção desta classe colvw (coleção-view). Dentro desta ultima estará disponível o método construtor New(), onde você irá passar os parâmetros necessários. Para executar uma consulta de uma classe-view, você deverá instanciar um objeto desta classe passando os parâmetros necessários no método construtor. Ex: Dim _objclassview As New coltb<tabela>.colvw<nome>(<parâmetros>) Criando uma Classe-View Assim como na criação das rotinas-view, utilizaremos um designer para definirmos nossas classes-view. Este designer é quase idêntico ao anterior, contendo apenas algumas diferenças. Editar. Para chamar o designer, basta clicar no botão Classes-View ou na mesma opção no menu 88

91 Da mesma forma que no designer das rotinas-view, aqui existirá uma tabela principal (em marrom), contudo poderemos selecionar qualquer campo de qualquer tabela para serem mapeados, na forma de propriedades, na classe-view resultante. Estes mesmos campos podem servir, também, como critério de consulta, que serão transformados em parâmetros do método construtor New(). A tabela principal apenas indicará em que coleção de registro (coltb) estarão disponíveis as classes e coleções-view. Ao selecionar um campo, clicando na checkbox ao lado de seu nome, o mesmo é adicionado à lista na forma de campo, mas que podem ser alterados para um parâmetro ou condição mais tarde. Os conceitos de parâmetros e condições são os mesmos das rotinas-view. A coluna Select desta lista indicará se o campo fará parte do select do SQL gerado e, dessa forma, mapeado na forma de propriedade. Caso um campo tenha sido selecionado e adicionado à lista, mas a checkbox Select seja desmarcada, este campo não terá função alguma. Ou você utiliza-o como parâmetro ou como condição. Na coluna Alias você poderá atribuir um novo nome ao campo adicionado, dessa forma a propriedade gerada para ele terá este nome. Por exemplo, se adicionei o campo tnfsaidaitem_qtdestoque e alterei o seu Alias para QuantidadeEstoque, na classe-view resultate este campo será mapeado como QuantidadeEstoque. 89

92 itens: Na tela do designer da página anterior, definimos uma classe-view que nos trará os seguintes Campos: Nome tnotafiscalsaida.tempresa_codigo tnfsaidaitem.nroitem tproduto.codigo tproduto.descricao tnotafiscalsaida.datasaida Alias tnotafiscalsaida_tempresa_codigo tnfsaidaitem.nroitem CodProduto NomeProduto tnotafiscalsaida.datasaida Os campos acima farão parte da cláusula select da consulta SQL e serão mapeados como propriedades. Parâmetros e condições: Nome Tipo Comparador Valor tproduto.tgrupo_codigo Parâmetro tnotafiscalsaida.datasaida Parâmetro tproduto.inativo Condição = 0 (false) Os Campos e condições acima serão incluídos na cláusula where da consulta SQL e serão transformados em parâmetros do método construtor da coleção. Consulta SQL gerada: SELECT tnotafiscalsaida.tempresa_codigo AS tnotafiscalsaida_tempresa_codigo, tnfsaidaitem.nroitem AS tnfsaidaitem_nroitem, tproduto.codigo AS CodProduto, tproduto.descricao AS NomeProduto, tnotafiscalsaida.datasaida AS tnotafiscalsaida_datasaida FROM tnfsaidaitem, tnotafiscalsaida, tproduto WHERE tnotafiscalsaida.id = tnfsaidaitem.tnotafiscalsaida_id And tproduto.codigo = tnfsaidaitem.tproduto_codigo And tproduto.tgrupo_codigo And tnotafiscalsaida.datasaida And tproduto.inativo = 0 90

93 Após a publicação do projeto serão geradas as seguintes classes (resumo): Classe-View (campos mapeados) Public Class clsvwprodutodatasaida Public Property tnfsaidaitem_nroitem As Int16 Public Property CodProduto As Int32 Public Property NomeProduto As String Public Property tnotafiscalsaida_tempresa_codigo As Int32 Public Property tnotafiscalsaida_datasaida As Date Public Function Clone() As Object Implements System.ICloneable.Clone End Class Coleção-View (List(of clsvwprodutodatasaida)) Public Class colvwprodutodatasaida Inherits CollectionBase Implements ICloneable Public Property StringConexao As String Public ReadOnly Property Mensagem As String Public ReadOnly Property Erro As Boolean Public Sub Add(ByVal obj As clsvwprodutodatasaida) Public Sub New(tProduto_tGrupo_Codigo As Int32, tnotafiscalsaida_datasaida1 As Date, tnotafiscalsaida_datasaida2 As Date, Optional OrderBy As String = "", Optional ByVal strconn As String = "") End Class As propriedades StringConexao, Mensagem e Erro tem a mesma função de suas homônimas das coleções de registros (coltb), contudo não possuem suas outras propriedades e métodos. Este tipo de objeto não possui métodos de persistência Instanciando uma Classe-View Exemplos: VB Dim _objcwnotafisacal As New coltbtnotafiscalsaida.colvwprodutodatasaida(10, _ Date.Parse("01/01/2000"), Date.Parse("12/12/2014"),, strstringconexao) C# coltbtnotafiscalsaida.colvwprodutodatasaida _objcwnotafisacal = new coltbtnotafiscalsaida.colvwprodutodatasaida(10, DateTime.Parse("01/01/2000"), DateTime.Parse("12/12/2014"), "", strstringconexao); As classes-view são uma boa opção para a listagem de registros em uma lista ou relatório. Apesar de podermos utilizar as coleções de registros (coltb) para esta finalidade, através da navegação de seus encadeamentos, criar uma classe-view produz um objeto menos complexo e menos caro, que pode ser utilizado em operações de databound, pois todas as suas propriedades estão expostas na forma de tipos simples (strings, datas, números, etc.). 91

94 O parâmetro OrderBy Vimos que o método construtor New() possui o parâmetro opcional OrderBy. Ele deve obedecer às mesmas regras da cláusula Order by do SQL, devendo conter nomes dos campos separados por vírgula e podendo usar as instruções asc e desc. Exemplos: VB Dim _strorder As String = "tproduto.descricao" Dim _objcwnotafisacal As New coltbtnotafiscalsaida.colvwprodutodatasaida(10, _ Date.Parse("01/01/2000"), Date.Parse("12/12/2014"), strorder, _ strstringconexao) C# String _strorder = "tproduto.descricao"; coltbtnotafiscalsaida.colvwprodutodatasaida _objcwnotafisacal = new coltbtnotafiscalsaida.colvwprodutodatasaida(10, DateTime.Parse("01/01/2000"), DateTime.Parse("12/12/2014"), strorder, strstringconexao); Funções Agregadas No SQL server as funções agregadas tem por finalidade executar o cálculo de um conjunto de valores e retornar um único valor. Você pode usar alguma delas diretamente no designer das classes-view através da combobox disponível na coluna função. As funções disponíveis são SUM, AVG,COUNT, MIN e MAX. 92

95 Exemplo: Na classe-view acima, definimos uma consulta que recupera os dados de um cliente, trazendo seu CPF/CNPJ, nome, data da compra (DataSaida), a quantidade de itens comprados e o valor total. Executando essa consulta, teremos os seguintes registros: Passando os parâmetros da consulta: 93

96 Utilizando agora a função SUM nos campos Quantidade e ValorTotal: 94

97 Registros retornados: Observe o agrupamento dos valores e das quantidades Inserindo Expressões Você pode incluir em sua classe-view, resultados obtidos através de expressões matemáticas envolvendo campos, funções, números, etc. Vamos adaptar o exemplo anterior para incluir uma expressão que calcule o valor total de um item de nota fiscal baseado na expressão: ValorTotal = ((Quantidade * ValorUnitario) - Desconto). Para inserirmos uma expressão, basta clicar no botão Inserir Expressão. Na imagem acima vemos a uma expressão inserida na última linha, chamada Expressão01. Elas são nomeadas sequencialmente, mas podemos alterar o seu Alias, que neste caso é ValorTotal. Para editarmos esta expressão basta dar um duplo click no campo Valor da expressão. A tela abaixo aparecerá: 95

98 Formule a sua expressão e click no botão OK. Executando esta consulta, teremos: 96

99 A expressão ValorTotal, será mapeada, juntamente com os campos listados na instrução select, na forma de propriedade na classe clsvw<nome>, gerada na publicação do projeto Abertura e Exclusão Para abrir uma classe-view, basta clicar no botão abrir, e a seguinte tela aparecerá: Selecione a classe-view desejada e click em OK, ou dê um duplo click em seu nome. Caso queira excluir uma classeview, basta clicar no botão Excluir. Quando você exclui uma classe-view, o seu respectivo arquivo (.ecvw) também será excluído da pasta Consultas do projeto. 97

100 2.9 - Rotinas Armazenadas Rotina armazenada é o nome que o Entity+ dá ao mapeamento de uma stored procedure ou função na forma de classes, métodos e/ou funções.net. Ao se mapear uma stored procedure, o usuário indica se a mesma irá resultar em uma função ou método. Stored procedures que retornam valores, geralmente serão convertidas em funções, se o usuário assim quiser. Já aquelas que apenas executam uma tarefa, mas não retornam nenhum valor, só poderão ser mapeadas como métodos. Será criada uma classe e uma coleção desta classe, se a rotina armazenada for mapeada como função, do contrário apenas o método em si será criado. Da mesma forma que as rotinas-view e classes-view, as rotinas armazenadas estarão disponíveis a partir da coleção de registros (coltb), mas neste caso, serão do tipo Shared/Static, ou seja, suas classes não precisam ser instanciadas em objetos, mas apenas referenciadas Criando uma Rotina Armazenada Novamente, o Entity+ disponibiliza um designer para que você construa sua rotina de forma interativa. Basicamente você irá selecionar a stored procedure que você deseja mapear e dizer se a mesma será um método ou uma função. Para abrir o designer, basta clicar no botão opção no menu Editar. Rotinas Armazenadas, ou selecionar a mesma 98

101 Ao selecionar a stored procedure desejada na combo Stored Procedures, o sistema irá ler a mesma e fazer sua análise, recuperando seus parâmetros de entrada e os dados que ela, por ventura, retorne. Caso existam dados de retorno, você tem a opção de gerar tanto um método quanto uma função. Caso você selecione gerar uma função, você terá que informar se a mesma retornará uma ou mais linhas de informação. No caso acima, a stored procedure retorna um select ao final que poderá trazer várias linhas. Como optamos por gerar uma função, serão escritas uma classe e uma coleção desta classe para recuperar os dados de retorno. No caso acima teríamos: Classe com dados de retorno mapeados Public Class clssp_movimentacaoestoque Public Property tproduto_codigo As Int32 Public Property NomeProduto As String Public Property CodPirelli As String 99

102 Public Property Grupo As Int16 Public Property NomeGrupo As String Public Property SaldoAnterior As Double Public Property Entradas As Double Public Property Saidas As Double Public Property Transferencias As Double Public Property SaldoAtual As Double Public Property CustoMedio As Double Public Property tempresa_codigo As Int16 Public Property CodFiscal As Int32 Public Property Unidade As String End Class Coleção (List(of clssp_movimentacaoestoque)) Public Class colsp_movimentacaoestoque Inherits CollectionBase End Class Coleção de registros (coltb) Public Class coltbtnotafiscalsaida... 'Parâmetros da stored procedure mapeados como parâmetros da função Public Shared Function sp_movimentacaoestoque(byval DataInicial As Date, ByVal DataFinal As Date, ByVal Empresa As Int16, Optional ByVal pproduto As Int32 = 0, Optional ByVal GrupoInicial As Int32 = 1, Optional ByVal GrupoFinal As Int32 = 932, Optional ByVal SoProdMov As Boolean = True, Optional ByRef objdados As SGLPDESKLIBCore.Dados = Nothing, Optional ByVal strconn As String = "", Optional ByVal Finalizar As Boolean = True) As colsp_movimentacaoestoque... End Class A função acima executa a stored procedure sp_movimentacaoestoque, passando para ela os parâmetros recebidos, e devolvendo o seu retorno na forma de um objeto do tipo colsp_movimentacaoestoque. Observe que todos os parâmetros com valor default definido, foram criados como parâmetros opcionais na função (pproduto, GrupoInicial, GrupoFinal, SoProdMov). Como chamar a função VB Try Dim _strconexao As String = "Server = '(local)';database='sglpdesk';uid='sa';pwd='123456'" Dim _objresultado As coltbtnotafiscalsaida.colsp_movimentacaoestoque = _ coltbtnotafiscalsaida.sp_movimentacaoestoque(date.parse("01/01/2014"), _ Date.Parse("30/09/2014"), 19,,,,,, _strconexao) Console.WriteLine("Listando estoque...") For i As Int32 = 0 To _objresultado.count - 1 Console.WriteLine("Nome: " & _objresultado(i).nomeproduto) Console.WriteLine("Estoque: " & _objresultado(i).saldoatual) Next Catch ex As Exception MessageBox.Show(ex.Message) 100

103 End Try C# try { string _strconexao = "Server = '(local)';database='sglpdesk';uid='sa';pwd='123456'"; Dados _objdados = null; coltbtnotafiscalsaida.colsp_movimentacaoestoque _objresultado = coltbtnotafiscalsaida.sp_movimentacaoestoque(datetime.parse("01/01/2014"), DateTime.Parse("30/09/2014"), 19, 0, 1, 932, true, ref _objdados, strconexao); Console.WriteLine("Listando estoque..."); for (Int32 i = 0; (i <= (_objresultado.count - 1)); i++) { Console.WriteLine(("Nome: " + _objresultado[i].nomeproduto)); Console.WriteLine(("Estoque: " + _objresultado[i].saldoatual)); catch (Exception ex) { MessageBox.Show(ex.Message); Observações: Uma vez que o C# não aceita brechas na passagem dos parâmetros opcionais, repassamos para estes, seus valores default. Como a rotina gerada é do tipo shared/static, ela é executada sem a necessidade de instanciar um objeto, dessa forma qualquer erro deverá ter tratado com try/catch, pois não haverá as propriedades Erro e Mensagem, disponíveis nas outras classes vistas até agora. Toda execução de uma rotina armazenada é feita dentro de uma transação, mesmo que você passe Nothing/null para o parâmetro objdados. O último parâmetro (Finalizar) indica se a transação será concluída ao final da execução da stored procedure. Seu valor default é true. Caso você realize outras operações de persistência antes da execução da rotina armazenada e queira que todo esse conjunto de instruções seja transacionado, você instanciará um objeto do tipo Dados, passando-o como parâmetro para as suas operações de persistência. Evidente que, se uma stored procedure apenas recuperar dados de tabelas, não alterando seu conteúdo, esse tipo de recurso seria desnecessário. Exemplo: VB Try Dim _strconexao As String = "Server = '(local)';database='sglpdesk';uid='sa';pwd='123456'" 'Instancia o objeto Dados da DAL (Data Access Layer) para controlar as transações Dim _objdados As New Dados(_strConexao) 'Recupera todos os produtos inativos Dim _objprodutos As New coltbtproduto(nothing,, "Inativo = 1",,, _strconexao) 'Exclui os registros recuperados _objprodutos.excluir(_objdados,, False) 'Não foi necessário passar o parâmetro "strconn", pois a string de conexao ja foi passada 'para _objdados. 'Parâmetro Finalizar = False para não concluir a transação 101

104 If _objprodutos.erro Then 'Caso aconteça algum erro, o RollBack é automático MessageBox.Show(_objProdutos.Mensagem) Exit Sub End If 'Executa a rotina armazenada dentro da mesma transação e a conclui (Finalizar = True) Dim _objresultado As coltbtnotafiscalsaida.colsp_movimentacaoestoque = _ coltbtnotafiscalsaida.sp_movimentacaoestoque(date.parse("01/01/2014"), _ Date.Parse("30/09/2014"), 19,,,,, _objdados,, True) Catch ex As Exception MessageBox.Show(ex.Message) End Try C# try { String _strconexao = "Server = '(local)';database='sglpdesk';uid='sa';pwd='123456'"; //Instancia o objeto Dados da DAL (Data Access Layer) para controlar as transações Dados _objdados = new Dados(_strConexao); //Recupera todos os produtos inativos coltbtproduto _objprodutos = new coltbtproduto(null,"", "Inativo = 1", false, 0, _strconexao); //Exclui os registros recuperados _objprodutos.excluir(ref _objdados, "", false); //Não foi necessário passar o parâmetro "strconn", pois a string de conexao ja foi passada //para o _objdados. //Parâmetro Finalizar = False para não concluir a transação if (_objprodutos.erro) { //Caso aconteça algum erro, o RollBack é automático MessageBox.Show(_objProdutos.Mensagem); return; //Executa a rotina armazenada dentro da mesma transação e a conclui (Finalizar = True) coltbtnotafiscalsaida.colsp_movimentacaoestoque _objresultado = coltbtnotafiscalsaida.sp_movimentacaoestoque(datetime.parse("01/01/2014"), DateTime.Parse("30/09/2014"), 19, 0, 1, 932, true, ref _objdados, "", true); catch (Exception ex) { MessageBox.Show(ex.Message); 102

105 Valores de Retorno Nulos Quando você cria uma rotina armazenada do tipo Função (com retorno de valores), estes podem conter valores nulos que, se não tratados, podem disparar erros. Caso exista a possibilidade disto ocorrer, é altamente recomendável que você marque estes como Nullable. O campo de retorno Transferencias, ao lado está marcado como nullable, pois existe a possibilidade de ele ter valor nulo. Isto evita que erros ocorram Resposta da Rotina Caso sua stored procedure seja mapeada como um método, você ainda pode recuperar um valor retornado por ela, que chamamos de resposta da rotina. Este é um valor inteiro que pode ser retornado após a execução do método criado. Na stored procedure ele é retornado através do comando Return. Vejamos a stored procedure abaixo: Create Procedure money) As int Delete Teste Where Preco A stored procedure acima exclui os registros da tabela Teste para todos aqueles que tenham o preço maior que o valor passado como parâmetro, e retorna a quantidade de registros excluídos. Como esse valor é um inteiro, podemos recuperá-lo na forma de resposta da rotina. Método Criado: Public Shared Sub sp_exemplo(byval Valor As Double, Optional ByRef objdados As SGLPDESKLIBCore.Dados = Nothing, Optional ByVal strconn As String = "", Optional ByVal Finalizar As Boolean = True, Optional ByRef vlrretornosp As Int32 = 0) 103

106 Exemplos: VB Dim _intqtdexcluida As Int32 coltbtnotafiscalsaida.sp_exemplo(1000, Nothing, _strconexao,, _intqtdexcluida) Console.WriteLine("Registros excluídos: " & _intqtdexcluida) C# Int32 _intqtdexcluida = 0; coltbtnotafiscalsaida.sp_exemplo(1000, ref _objdados, _strconexao, true, ref _intqtdexcluida); Console.WriteLine("Registros excluídos: " + _intqtdexcluida); Rotinas de Importação e Exportação de Texto (Rotinas-TXT) O Entity+ permite a criação de rotinas especiais de transporte de dados no formato de texto delimitado. Para isso dispõe de um poderoso designer, onde você poderá definir a origem e o destino dos dados de uma coleção de registros de forma totalmente interativa e intuitiva. Imagine que um órgão do governo disponibilize um cadastro de pessoas jurídicas em formato CSV (comma separated value, ou arquivo separado por vírgula), e você precisa alimentar seu sistema a partir dele. Normalmente você iria criar uma rotina para ler este arquivo, identificar os elementos, extraí-los e salvá-los em uma ou mais tabelas. Além deste trabalho, você teria que verificar a sua integridade, validar seus dados de acordo com as regras de integridade de suas tabelas e, ao salvar, sua rotina teria que decidir entre inserts e updates. Ou seja, não é uma tarefa muito simples. Como os objetos Entity+ de manipulação de dados já executam todas as validações e gerenciam a persistência de dados, já temos 50% do problema resolvido, falta apenas habilitar métodos que importem/exportem estes dados a partir/para arquivos de texto delimitado. Para criarmos uma rotina-txt, basta selecionar a tabela que será proprietária da rotina, na lista de tabelas do módulo principal do IDE e clicar, no menu principal, Editar/Rotinas auxiliares/importação/exportação Texto. A primeira vez que criar uma rotina, você deverá localizar o arquivo que servirá de amostra para a definição de sua rotina-txt, ele será aberto e analisado, tendo seu delimitador e campos identificados, assim como verificada a existência de headers e footers. 104

107 Na tela do designer acima, temos carregada a amostra de um arquivo. Nele estão identificadas a extensão do arquivo, o caractere delimitador, a existência de headers/footers e as colunas, que deverão ser associadas aos campos da tabela em questão. A tabela proprietária da rotina é tfornecedor. Para fazer a associação de seus campos às colunas listadas no grid, basta clicar no header de cada coluna, onde está escrito Click. Uma tela aparecerá solicitando que você selecione qual campo da tabela será associado à coluna. 105

108 Clicando na primeira coluna teremos: Na combo Campo temos todos os campos da tabela. Selecionei CNPJ. Quando você seleciona um campo, o sistema faz algumas validações de compatibilidade entre o tipo do campo e o conteúdo da coluna, avisando, quando necessário, se será possível a associação. Ao confirmar a associação, o nome do campo aparecerá na coluna que você selecionou. Após fazermos as devidas associações, é necessário dar um nome e uma descrição à nossa rotina-txt, além de especificar quais tipos de rotinas serão geradas a partir dela. Na combo Criar rotinas, são listadas três opções: Importação, Exportação e Importação/Exportação. Selecionando-se Importação, apenas uma rotina de importação de dados será criada. Selecionando-se Exportação apenas uma rotina de exportação de dados desta tabela será criada. Selecionando-se Importação/Exportação, ambas serão criadas. 106

109 Observe na imagem acima, que as colunas foram associadas a seus respectivos campos na tabela, e que foram atribuídos um nome, uma descrição e um tipo de rotina a ser gerada. Para confirmar estas informações, você deverá clicar no botão Aplicar. Quando você aplica as alterações, está apenas repassando-as para o projeto, elas ainda não estão salvas. Para salvá-las, você tem que salvar o projeto, pois, diferentemente das rotinas-view e das classes view, não são criados arquivos especiais para esse tipo de recurso, eles são salvos dentro do arquivo.etb relativo à sua tabela proprietária Associando Números, Datas e Valores Booleanos Ao associarmos as colunas de um arquivo aos campos de uma tabela, alguns tipos de dados podem necessitar de ajustes, dependendo de sua formatação no arquivo. Ao se associar um número a uma coluna, será verificado se aquele tipo de dado é numérico e, caso não seja, o usuário será alertado. Além disso, um número pode ou não vir formatado (com agrupamento de dígitos e vírgula decimal). Uma data pode vir formatada ou não, e a ordem do dia, ano, mês, hora, minuto e segundos, podem estar em qualquer sequência. Campos que armazenam valores boleanos (sim/não, 0/1, verdadeiro/falso) tem que fazer a interpretação de o que significa true, e o que significa false. 107

110 Campos Numéricos Campos numéricos sem formatação são validados automaticamente, mas, caso haja algum tipo de formatação, os caracteres que a compõe serão identificados. Na figura ao lado o conteúdo da coluna selecionada foi identificado como um número formatado, no momento que o associamos ao campo PrecoAtacado. Nela vemos em destaque o reconhecimento dos caracteres de agrupamento de dígito e símbolo decimal. Caso uma coluna tenha valores numéricos sem formatação, e você associá-lo a um campo reconhecido como double, você poderá informar quantas casas decimais serão consideradas. Exemplo: o número representa o valor R$ 1.256,50, considerando-se os dois últimos dígitos como centavos. Neste caso você informa a quantidade de casas decimais a considerar. Campos Data Datas formatadas obedecendo-se o formato definido nas Configurações Regionais do Windows serão aceitas automaticamente sem ajustes, caso contrário, teremos que considerar o seguinte: - Datas formatadas fora do padrão definido nas Configurações Regionais do Windows Imagine uma coluna do arquivo contendo a data 12/30/2013, no formato MM/dd/yyyy. Ao se associar esta coluna a um campo date da tabela, o mesmo será invalidado, e a combo Formatação será habilitada para você informar o formato correto. Nela já vêm alguns formatos definidos, mas caso você não encontre um adequado, pode digitá-lo diretamente. Como o formato adequado não está na lista, informei diretamente na combo. 108

111 Campos Boolean No SQL, campos booleanos (bit) aceitam apenas 0 (zero) e 1 (um), mas seu arquivo pode ter outros caracteres ou palavras que representam estes valores. Neste caso você terá que fazer a tradução, informando que valor representa zero (false) e que valor representa 1 (true). Vamos considerar que no arquivo, V significa verdadeiro e F significa falso: Ao selecionar um campo boolean para a coluna, foi habilitado o grupo Valores Boolean, onde você informará os valores válidos para true e false. Quando você define este tipo de rotina no seu projeto, será criado um método para cada operação (importação/exportação). Como nomeamos nossa rotina do exemplo como FornecedorGov, será criado um método chamado ExportarFornecedorGov na classe coltbtfornecedor. Se tivéssemos escolhido a opção Importação/Exportação, seria gerada, também, o método ImportarFornecedorGov. Declaração: Public Sub ExportarFornecedorGOV(ByVal Arquivo As String) Exemplos: VB 'instancia o objeto de dados passando a string de conexão Dim _objdados As New Dados("Server = '(local)';database='sglpdesk';uid='sa';pwd='123456'") 'Instancia um objeto da coleção de registro da tabela tfornecedores Dim _objfornecedores As New coltbtfornecedor 'Lê os dados do arquivo, alimentando a coleção _objfornecedores.importarfornecedorgov("c:\temp\fornecedores.csv") 'Se deu erro, exibe a mensagem e sai If _objfornecedores.erro Then MessageBox.Show("Erro ao importar arquivo (" & _objfornecedores.mensagem & ")") Exit Sub End If 'Se conseguiu importar, salva os dados na tabela _objfornecedores.salvar(_objdados) 109

112 If _objfornecedores.erro Then MessageBox.Show("Erro ao salvar (" & _objfornecedores.mensagem & ")") End If C# //instancia o objeto de dados passando a string de conexão Dados _objdados = new Dados("Server = '(local)';database='sglpdesk';uid='sa';pwd='123456'"); //Instancia um objeto da coleção de registro da tabela tfornecedores coltbtfornecedor _objfornecedores = new coltbtfornecedor(); //Lê os dados do arquivo, alimentando a coleção _objfornecedores.importarfornecedorgov("c:/temp/fornecedores.csv"); //Se deu erro, exibe a mensagem e sai if (_objfornecedores.erro) { MessageBox.Show("Erro ao importar arquivo (" + _objfornecedores.mensagem + ")"); return; //Se conseguiu importar, salva os dados na tabela _objfornecedores.salvar(ref _objdados); if (_objfornecedores.erro) { MessageBox.Show("Erro ao salvar (" + _objfornecedores.mensagem + ")"); Arquivos com Cabeçalho e Rodapé Alguns arquivos possuem informações de cabeçalho e rodapé, que geralmente trazem dados adicionais que podem ser recuperados ou ignorados por nossa rotina. Quando você carrega o arquivo de amostra para a análise, o designer verifica a existência de cabeçalhos e rodapés, fazendo a comparação da primeira e da última linha com o resto do arquivo e, caso haja diferenças na quantidade de colunas, adiciona estes dois elementos. Vamos considerar o seguinte arquivo: ;Administrador;PCADM ;3;1;5864;1; ;1475;SERQUIMICA IND COM IMP EXP PROD QUIMICA;;RUA ARCANGELO MAGRO;1; ;3;1;2877;1; ;178;CURINGA DOS PNEUS LTDA;;AV.ARAGUAIA;1; ;3;1;5018;1; ;791;GHELLER E BRUM LTDA;;AVE GIL MARTINS;1; ;3;1;5880;1; ;1487;GHELLER & BRUM LTDA;;QD 08 LT 32 R VCI 06 FI;1; ;3;1;5343;1; ;1061;TAPAJOS DIST DE VEICULOS LTDA;;101 SUL AV NS1 07;1;0 11 Em destaque, temos o cabeçalho e o rodapé. No cabeçalho temos a data/hora da geração do arquivo, no formato ddmmyyyhhmmss, o nome do operador do sistema e o nome do computador onde o arquivo foi gerado. No rodapé, temos a quantidade de registros do arquivo. 110

113 Fazendo a sua importação, teremos: No detalhe, observe que o cabeçalho e o rodapé foram adicionados automaticamente. Se eles não lhe interessarem, basta desativá-los nas checkboxes Possui header e Possui footer. Caso você queira recuperar esses valores, terá que associá-los a propriedades especialmente criadas para isso, uma vez que eles não podem ser associados aos campos da tabela. O processo é parecido com a associação aos campos, bastando selecionar a coluna, clicando em seu header, onde tem a palavra Click. Você define um nome para a propriedade e seleciona seu tipo. Dependendo do tipo selecionado, você terá que fornecer informações adicionais, como no exemplo ao lado, onde foi exigida uma formatação válida para a data. Implicações da criação do cabeçalho e rodapé Quando um cabeçalho e/ou rodapé são adicionados à rotina, são criadas propriedades e classes adicionais dentro da coleção de registro da tabela proprietária da rotina-txt. Caso sua rotina possua cabeçalho, será adicionada a propriedade <NomeRotina>Header à coleção de registro (coltb). Esta propriedade será do tipo cls<nomerotina>header. 111

114 Exemplo: Public Property FornecedorGovHFHeader As clsfornecedorgovhfheader Também será adicionada a classe que tipifica esta propriedade. Ela estará disponível a partir da coleção de registro da tabela proprietária da rotina-txt, e irá expor as propriedades que recuperam os dados do cabeçalho. Considerando que atribuímos os nomes DataGeração, Operador e Computador às três colunas do cabeçalho do exemplo anterior. Teríamos: Public Class clsfornecedorgovhfheader Public Property DataGeracao As Date Public Property Operador As String Public Property Computador As String End Class Da mesma forma, se tivéssemos um rodapé, e nomeássemos a coluna como QtdReg, seriam criadas a seguinte propriedade e classe: Public Property FornecedorGovHFFooter As clsfornecedorgovhffooter Public Class clsfornecedorgovhffooter Public Property QtdReg As Int32 End Class Onde FornecedorGovHF é o nome da rotina-txt. Exemplos: VB Dim _objdados As New Dados("Server = '(local)';database='sglpdesk';uid='sa';pwd='123456'") Dim _objfornecedores As New coltbtfornecedor _objfornecedores.importarfornecedorgovhf("c:\temp\fornecedores.csv") If _objfornecedores.erro Then MessageBox.Show("Erro ao importar arquivo (" & _objfornecedores.mensagem & ")") Exit Sub End If txtdatageracao.text = _objfornecedores.fornecedorgovhfheader.datageracao txtoperador.text = _objfornecedores.fornecedorgovhfheader.operador txtcomputador.text = _objfornecedores.fornecedorgovhfheader.computador txtqtdreg.text = _objfornecedores.fornecedorgovhffooter.qtdreg C# Dados _objdados = new Dados("Server = '(local)';database='sglpdesk';uid='sa';pwd='123456'"); coltbtfornecedor _objfornecedores = new coltbtfornecedor(); _objfornecedores.importarfornecedorgov("c:/temp/fornecedores.csv"); if (_objfornecedores.erro) { MessageBox.Show("Erro ao importar arquivo (" + _objfornecedores.mensagem + ")"); return; txtdatageracao.text = _objfornecedores.fornecedorgovhfheader.datageracao; 112

115 txtoperador.text = _objfornecedores.fornecedorgovhfheader.operador; txtcomputador.text = _objfornecedores.fornecedorgovhfheader.computador; txtqtdreg.text = _objfornecedores.fornecedorgovhffooter.qtdreg; 113

116 C A P Í T U L O 3 Sistema de Segurança Todo sistema de informação necessita de um controle de acesso de usuários a seus recursos, garantido ou negando direitos a uma pessoa ou grupo de pessoas. Esta tarefa exige que o programador desenvolva tabelas, classes e rotinas específicas para esta finalidade, o que demanda de muito trabalho e tempo. Com o recurso de segurança do Entity+, você irá criar, de forma interativa, todas as classes necessárias para o controle de acesso dos usuários ao seu sistema final, feito no Visual Studio. Ele também irá escrever no seu banco de dados as tabelas para o cadastro de usuários e/ou grupos e seus respectivos direitos. Para habilitar os recursos de segurança em seu projeto Entity+, basta clicar no botão Configurar Segurança. Existem dois níveis de segurança: Nível de Usuários Selecionando esta opção, todo o controle de acesso será feito atribuindo-se direitos específicos à cada usuário em relação à uma determinada tabela. São três os direitos básicos (Leitura, Gravação e Exclusão), mas podem ser incluídos direitos adicionais. 114

117 Além de atribuir direitos, você também poderá controlar a quantidade máxima de tentativas de login, assim como o tempo mínimo necessário para novas tentativas, após o bloqueio da senha. Também é possível definir uma chave de criptografia para as senhas que serão armazenadas no banco de dados. Considerando-se a tela acima, e selecionando o nível de segurança de usuários, serão criadas as seguintes tabelas: - EntityUser: Armazenda os dados dos usuários. Estrutura: - EntityRight: Armazena os direitos dos usuários. Estrutura: - EntityLogInFail: Armazena as tentativas inválidas de login. Estrutura: 115

118 Relacionamentos: Após configurar o sistema de segurança, você já pode administrar os usuários de dentro do ambiente do Entity+, através do botão Gerenciar usuários, ou através do menu Dados/Segurança/Gerenciar usuários. Existe um status especial para o usuário Master, onde você pode utilizá-lo para validar um tipo de acesso privilegiado. Uma vez que habilitamos os recursos de segurança em nosso projeto, e isto adicionou tabelas especiais de segurança, serão criadas classes e coleções para estas tabelas da mesma forma que é feito com as demais tabelas do projeto. Através destas classes e coleções de tabelas, você poderá instanciar um usuário ou uma coleção destes, incluir e excluir através dos métodos e funções já discutidos aqui. Então teremos: 116

119 Exemplos: VB Try Dim _strconexao As String = "Server = '(local)';database='sglpdesk';uid='sa';pwd='123456'" Dim _objusuario As New clstbentityuser("elton", _strconexao) If Not _objusuario.encontrado Then MessageBox.Show("Usuário inexistente") Exit Sub End If If Not _objusuario.acessobloqueado Then 'Propriedade especial exclusiva desta classe. MessageBox.Show("Usuário temporariamente bloqueado") Exit Sub End If Catch ex As Exception MessageBox.Show(ex.Message) End Try C# try { String _strconexao = "Server = '(local)';database='sglpdesk';uid='sa';pwd='123456'"; clstbentityuser _objusuario = new clstbentityuser("elton", _strconexao); if (!_objusuario.encontrado) { MessageBox.Show("Usuário inexistente"); return; if (_objusuario.acessobloqueado) { MessageBox.Show("O suário " + _objusuario.cnome + " encontra-se temporariamente bloqueado"); return; catch (Exception ex) { MessageBox.Show(ex.Message); Um objeto do tipo clstbentityuser terá uma propriedade especial chamada AcessoBloqueado (boolean/readonly) que indica se o usuário encontra-se bloqueado Classes de Segurança Vimos que o Entity+ adicionou tabelas especias de segurança e, por consequência, temos suas respectivas classes e coleções de registro, contudo, são escritas classes específicas de segurança disponíveis a partir do namespace Seguranca da biblioteca <Projeto>.DLL Estrutura das classes de segurança Namespace Seguranca Public Class clsdireitos Public Property Leitura As Boolean 117

120 Public Property Gravacao As Boolean Public Property Exclusao As Boolean Public Property Impressao As Boolean End Class 'Cada tabela do banco de dados é controlada por uma propriedade na classe abaixo Public Class clsdireitostabela Public Property <NomeTabela1> As clsdireitos Public Property <NomeTabela2> As clsdireitos Public Property <NomeTabelan> As clsdireitos Public Property Erro As Boolean Public Property Mensagem As String 'Método construtor que recupera os direitos do usuário em cada tabela Public Sub New(Login As String, StringConexao As String) End Class 'Classe principal que agrupa todas as demais Public Class clslogin Public Property Direitos As clsdireitostabela Public Property Usuario As EntityPlus.clsTbEntityUser Public ReadOnly Property Erro As Boolean Public ReadOnly Property Mensagem As String Public Sub New() Public Sub New(Login As String, Senha As String, StringConexao As String) Public Function Logar(Login As String, Senha As String, StringConexao As String) As _ Boolean End Class End Namespace A classe clslogin disponibiliza todas as propriedades métodos e funções necessárias para gerenciar o acesso dos usuários aos módulos/tabelas do sistema. Exemplos: VB Imports SGLPDESKLIB.EntityPlus Imports SGLPDESKLIB.Seguranca 'Namespace contendo as classes de segurança... Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load Dim _strconexao As String = "Server = '(local)';database='sglpdesk';uid='sa';pwd='123456'" Dim _objlogin As New clslogin("elton", "1234", _strconexao) If _objlogin.erro Then 'Se usuário ou senha inválidos ou usuário bloqueado, dispara o erro 'Erros de acesso ao banco também dispararão esta propriedade MessageBox.Show("Erro ao logar (" & _objlogin.mensagem & ")") Exit Sub End If MessageBox.Show("Seja bem vindo Sr(a) " & _objlogin.usuario.cnome) 'Lista os direitos em cada tabela através de seu encadeamento TfEntityRight Console.WriteLine("Direitos do usuário:") For i As Int16 = 0 To _objlogin.usuario.tfentityright.count - 1 Dim _strdireitos As String = "Nenhum" 118

121 If _objlogin.usuario.tfentityright(i).cleitura Then _strdireitos = "L" End If If _objlogin.usuario.tfentityright(i).cgravacao Then _strdireitos += "G" End If If _objlogin.usuario.tfentityright(i).cexclusao Then _strdireitos += "E" End If If _objlogin.usuario.tfentityright(i).cimpressao Then _strdireitos += "I" End If Console.WriteLine(_objLogin.Usuario.TfEntityRight(i).cTabela & "(" & _strdireitos & ")") Next 'Testando se tem direitos em uma tabela específica If _objlogin.direitos.tnotafiscalsaida.leitura Then MessageBox.Show("Você não tem acesso de leitura nesta tabela") End If End Sub C# using SGLPDESKLIB.EntityPlus; using SGLPDESKLIB.Seguranca; 'Namespace contendo as classes de segurança... String _strconexao = "Server = '(local)';database='sglpdesk';uid='sa';pwd='123456'"; clslogin _objlogin = new clslogin("elton", "1234", _strconexao); if (_objlogin.erro) //Se usuário ou senha inválidos ou usuário bloqueado, dispara o erro { //Erros de acesso ao banco também dispararão esta propriedade MessageBox.Show("Erro ao logar (" + _objlogin.mensagem + ")"); return; MessageBox.Show("Seja bem vindo Sr(a) " + _objlogin.usuario.cnome); //Lista os direitos em cada tabela através de seu encadeamento TfEntityRight Console.WriteLine("Direitos do usuário:"); for (Int16 i = 0; (i <= (_objlogin.usuario.tfentityright.count - 1)); i++) { String _strdireitos = "Nenhum"; if (_objlogin.usuario.tfentityright[i].cleitura) { _strdireitos = "L"; if (_objlogin.usuario.tfentityright[i].cgravacao) { _strdireitos += "G"; if (_objlogin.usuario.tfentityright[i].cexclusao) { _strdireitos += "E"; if (_objlogin.usuario.tfentityright[i].cimpressao) { _strdireitos += "I"; Console.WriteLine(_objLogin.Usuario.TfEntityRight[i].cTabela + "(" + _strdireitos + ")"); 119

122 //Testando se tem direitos em uma tabela específica if (_objlogin.direitos.tnotafiscalsaida.leitura) { MessageBox.Show("Você não tem acesso de leitura nesta tabela"); Resultado da rotina: Nos exemplos acima, utilizamos o método construtor New() para fazermos o login, recuperando os dados do usuário e seus direitos, através das propriedades Usuario e Direitos respectivamente. Também usamos a propriedade TfEntityRight (encadeamento entre as tabelas EntityUser e EntityRight), para navegarmos através dos direitos do usuário. Já para testarmos se o usuário logado tinha direito de leitura na tabela tnotafiscalsaida, utilizamos a propriedade Direitos (_objlogin.direitos.tnotafiscalsaida.leitura). Utilize este tipo de rotina nas suas telas de logon, de preferência utilizando uma variável visível para todo o sistema, para que, uma vez feito o logon, qualquer outro módulo do sistema possa testar os direitos do usuário antes de permitir seu acesso a determinados recursos. Observação: O método Logar(), permite fazer o logon do usuário após o objeto já ter sido instanciado passando-se exatamente os mesmos parâmetros do método New(). Exemplo VB Dim _objlogin As New clslogin _objlogin.logar("elton", "1234", _strconexao) C# clslogin _objlogin = new clslogin(); _objlogin.logar("elton", "1234", _strconexao); Nível de Grupo de Usuários Selecionando esta opção, todo o controle de acesso será feito atribuindo-se direitos específicos a cada grupo, e estes serão herdados por seus usuários. 120

123 As seguintes tabelas serão adicionadas neste nível de segurança: Além das tabelas anteriores, foi acrescentada a tabela EntityUserGroup. Estrutura das tabelas EntityUser: EntityUserGroup: EntityRight: EntityLogInFail: A mesma que no tópico anterior. Relacionamentos das tabelas: 121

124 Após configurar o sistema de segurança, você já pode administrar os usuários de dentro do ambiente do Entity+, através do botão Gerenciar grupos de usuários, ou através do menu Banco de Dados/Segurança/Gerenciar grupos. Neste nível de segurança você atribui os direitos diretamente aos grupos. Sendo assim, a tela de gerenciamento de usuários vai mudar um pouco. 122

125 Ao selecionar o grupo ao qual o usuário irá pertencer, seus direitos irão ser listados, contudo não será possível alterá-los diretamente nesta tela. Esta modificação tem que ser definida no grupo. Agora teremos que adaptar o exemplo da página 94, teremos: VB Dim _strconexao As String = "Server = '(local)';database='sglpdesk';uid='sa';pwd='123456'" Dim _objlogin As New clslogin("elton", "1234", _strconexao) If _objlogin.erro Then MessageBox.Show("Erro ao logar (" & _objlogin.mensagem & ")") Exit End If MessageBox.Show("Seja bem vindo Sr(a) " & _objlogin.usuario.cnome) Console.WriteLine("Direitos do usuário:") For i As Int16 = 0 To _objlogin.usuario.tbentityusergroup.tfentityright.count - 1 Dim _strdireitos As String = "Nenhum" If _objlogin.usuario.tbentityusergroup.tfentityright(i).cleitura Then _strdireitos = "L" End If If _objlogin.usuario.tbentityusergroup.tfentityright(i).cgravacao Then _strdireitos += "G" End If If _objlogin.usuario.tbentityusergroup.tfentityright(i).cexclusao Then _strdireitos += "E" End If 123

126 If _objlogin.usuario.tbentityusergroup.tfentityright(i).cimpressao Then _strdireitos += "I" End If Console.WriteLine(_objLogin.Usuario.TbEntityUserGroup.TfEntityRight(i).cTabela & "(" & _strdireitos & ")") Nex 'Aqui não houve mudanças If _objlogin.direitos.tnotafiscalsaida.leitura Then MessageBox.Show("Você não tem acesso de leitura nesta tabela") End If C# String _strconexao = "Server = '(local)';database='sglpdesk';uid='sa';pwd='123456'"; clslogin _objlogin = new clslogin("elton", "1234", _strconexao); if (_objlogin.erro) //Se usuário ou senha inválidos ou usuário bloqueado, dispara o erro { //Erros de acesso ao banco também dispararão esta propriedade MessageBox.Show("Erro ao logar (" + _objlogin.mensagem + ")"); return; MessageBox.Show("Seja bem vindo Sr(a) " + _objlogin.usuario.cnome); //Lista os direitos em cada tabela através de seu encadeamento TfEntityRight Console.WriteLine("Direitos do usuário:"); for (Int16 i = 0; (i <= (_objlogin.usuario.tbentityusergroup.tfentityright.count - 1)); i++) { String _strdireitos = "Nenhum"; if (_objlogin.usuario.tbentityusergroup.tfentityright[i].cleitura) { _strdireitos = "L"; if (_objlogin.usuario.tbentityusergroup.tfentityright[i].cgravacao) { _strdireitos += "G"; if (_objlogin.usuario.tbentityusergroup.tfentityright[i].cexclusao) { _strdireitos += "E"; if (_objlogin.usuario.tbentityusergroup.tfentityright[i].cimpressao) { _strdireitos += "I"; Console.WriteLine(_objLogin.Usuario.TbEntityUserGroup.TfEntityRight[i].cTabela + "(" + _strdireitos + ")"); //Testando se tem direitos em uma tabela específica if (_objlogin.direitos.tnotafiscalsaida.leitura) { MessageBox.Show("Você não tem acesso de leitura nesta tabela"); Observe o destaque em laranja. Os direitos tem que ser listados agora pelo encadeamento feito com a tabela EntityUserGroup. No mais, tudo fica igual, continuamos verificando o direito de acesso de um login pela sua propriedade Direitos.<NomeTabela>.<NomeDireito>. 124

127 Utilize classes e coleções de registros Entity+ criados para as tabelas de segurança, para desenvolver as rotinas de manutenção de usuários, grupos e direitos dentro do seu sistema final no Visual Studio. Desfrute das facilidades de navegação via encadeamento de classes (Tb e Tf). Abaixo mostraremos como desenvolver uma rotina básica de cadastro de usuário para os dois níveis de segurança. Estes exemplos têm apenas função didática, por isso os valores dos campos estão sendo passados diretamente ao objeto e não através de um controle (textbox, combobox, etc.). Nivel de Usuário VB Imports SGLPDESKLIB.EntityPlus Imports SGLPDESKLIB.Seguranca Dim _strconexao As String = "Server = '(local)';database='sglpdesk';uid='sa';pwd='123456'" Dim _objusuario As New clstbentityuser _objusuario.clogin = "elton" _objusuario.cnome = "Elton Castro Sousa" _objusuario.csenha = "1234" _objusuario.salvar(_strconexao) If _objusuario.erro Then MessageBox.Show("Erro ao salvar usuário (" & _objusuario.mensagem & ")") Else MessageBox.Show("Usuário salvo com sucesso") End If C# String _strconexao = "Server = '(local)';database='sglpdesk';uid='sa';pwd='123456'"; clstbentityuser _objusuario= new clstbentityuser(); _objusuario.clogin = "elton"; _objusuario.cnome = "Elton Castro Sousa"; _objusuario.csenha = "1234"; _objusuario.salvar(_strconexao); if (_objusuario.erro) { MessageBox.Show("Erro ao salvar usuário (" + _objusuario.mensagem + ")"); else { MessageBox.Show("Usuário salvo com sucesso"); Este exemplo instancia um novo usuário, atribui valores a seus campos e os salva no banco de dados. Como a chave desta tabela é o campo Login, se o usuário elton já existisse no banco de dados, seria feito apenas um update destas informações. Outro ponto importante a salientar, é que, se você selecionou a opção Criptografar senhas na configuração do seu sistema de segurança, a senha fornecida no exemplo acima será encriptada automaticamente no banco de dados e, quando recuperada, será desencriptada da mesma forma. 125

128 Exemplos: VB Dim _objusuario As New clstbentityuser("elton", _strconexao) 'Localiza o usuário elton 'Exibe a senha atual If _objusuario.encontrado Then MessageBox.Show("A senha atual é " & _objusuario.csenha) 'Exibe a senha desemcriptada End If 'Altera a senha e faz o update _objusuario.csenha = "outrasenha" _objusuario.salvar(_strconexao) C# clstbentityuser _objusuario = new clstbentityuser("elton", _strconexao); //Localiza o usuário elton //Exibe a senha atual if (_objusuario.encontrado) { MessageBox.Show("A senha atual é " + _objusuario.csenha); //Exibe a senha desemcriptada //Altera a senha e faz o update _objusuario.csenha = "outrasenha"; _objusuario.salvar(_strconexao); Nível de Grupo de Usuários A única diferença é que teremos que passar agora o ID do grupo. Exemplo: _objusuario.centityusergroup_id = cmbgrupo.selectedvalue Se você definiu o nível de segurança para usuários, cadastrou usuários e definiu direitos, e depois mudou para o nível de grupo, todos os usuários que você cadastrou anteriormente serão excluídos. Isso vale para o inverso também. 126

129 C A P Í T U L O 4 Auditoria de Dados Consiste basicamente em manter registradas as ações de usuários (inserts, updates e deletes), de forma a identificar quem fez o que e quando em determinada tabela, assim como poder restaurar registros alterados ou excluídos. Uma vez habilitada a auditoria, o Entity+ irá disponibilizar classes, métodos e funções específicos para a manipulação dessas informações, assim como adaptar as classes e coleções de registro para que, além de fazer o registro do log quando um método ou função de persistência for chamado, disponibilizem propriedades adicionais de auditoria. Para habilitarmos e configurarmos a auditoria, basta clicar no botão no menu Banco de dados/auditoria. Auditoria, ou selecionar Você pode selecionar quais tabelas serão auditadas e quais ações serão registradas. Por padrão todas as exclusões (deletes) são monitoradas, já as alterações (updates) têm que ser selecionado tabela por tabela, informado o máximo de logs por registro. Quando um registro é excluído de uma tabela monitorada pela auditoria, uma cópia deste registro é feita em uma tabela especial chamada EntityAudit, assim como as alterações. 127

130 Estrutura da tabela EntityAudit Campo ID TabelaOrigem IDOrigem DataOperacao Usuário Dados Seguranca Função chave-primária de autoincremento. Origem dos dados Valores das chaves-primárias do registro excluído/alterado. Data de ocorrência do evento. Usuário do sistema que executou a ação. Dados originais do registro Dados de segurança criptografados (usuário, IP, winuser, computador) Implicações nas Classes e Coleções de Registro 1ª) - Inclusão do parâmetro AuditoriaUsuario (string) nas funções Salvar(). Nas classes de registros (clstb) temos dois overloads da função Salvar(). Antes da auditoria: Public Overridable Function Salvar(Optional ByVal strconn As String = "") _ As List(Of clscampo) Public Overridable Function Salvar(ByRef objdados As <NomeProjeto>Core.Dados, _ Optional ByVal strconn As String = "", _ Optional ByVal Finalizar As Boolean = True, _ Optional SalvarFilhas As Boolean = False) _ As List(Of clscampo) Depois da auditoria: Public Overridable Function Salvar(AuditoriaUsuario As String, _ Optional ByVal strconn As String = "") _ As List(Of clscampo) Public Overridable Function Salvar(ByRef objdados As <NomeProjeto>Core.Dados, _ AuditoriaUsuario As String, Optional ByVal _ strconn As String = "", Optional ByVal Finalizar As _ Boolean = True, Optional SalvarFilhas As Boolean = False) As List(Of clscampo) Nas coleções de registros (coltb) temos: 128

131 Antes da auditoria: Public Sub Salvar(ByRef objdados As SGLPDESKLIBCore.Dados, _ Optional ByVal strconn As String = "", Optional ByVal Finalizar As _ Boolean = True, Optional SalvarFilhas As Boolean = False) Depois da auditoria Public Sub Salvar(ByRef objdados As <NomeProjeto>Core.Dados, AuditoriaUsuario As String, _ Optional ByVal strconn As String = "", Optional ByVal Finalizar As _ Boolean = True, Optional SalvarFilhas As Boolean = False) 2ª) - Inclusão do parâmetro AuditoriaUsuario (string) nos métodos Excluir(). Nas classes de registros (clstb) temos quatro overloads do método Excluir(). Antes da auditoria: Public Overridable Sub Excluir() Public Overridable Sub Excluir(ByVal pid As Int32, Optional ByVal strconn As String = "") Public Overridable Sub Excluir(ByVal pid As Int32, ByRef objdados As _ <NomeProjeto>Core.Dados, Optional ByVal strconn As _ String = "", Optional ByVal Finalizar As Boolean = False) Public Overridable Sub Excluir(ByRef objdados As <NomeProjeto>Core.Dados, _ Optional ByVal strconn As String = "", _ Optional ByVal Finalizar As Boolean = False) Depois da auditoria: Public Overridable Sub Excluir(AuditoriaUsuario As String) Public Overridable Sub Excluir(ByVal plogin As String, AuditoriaUsuario As String, _ Optional ByVal strconn As String = "") Public Overridable Sub Excluir(ByVal plogin As String, ByRef objdados As _ <NomeProjeto>Core.Dados, AuditoriaUsuario As String, _ Optional ByVal strconn As String = "", Optional ByVal _ Finalizar As Boolean = False) Public Overridable Sub Excluir(ByRef objdados As <NomeProjeto>Core.Dados, _ AuditoriaUsuario As String, Optional ByVal strconn As _ String = "", Optional ByVal Finalizar As Boolean = False) Nas coleções de registros (coltb) temos dois overloads do método Excluir(): Antes da auditoria: Public Sub Excluir() Public Sub Excluir(ByRef _objdados As <NomeProjeto>Core.Dados, Optional ByVal strconn _ As String = "", Optional ByVal Finalizar As Boolean = True) Depois da auditoria: Public Sub Excluir(AuditoriaUsuario As String) Public Sub Excluir(ByRef _objdados As <NomeProjeto>Core.Dados, AuditoriaUsuario As _ String, Optional ByVal strconn As String = "", _ Optional ByVal Finalizar As Boolean = True) 129

132 Exemplos: Observação: Os dois overloadas do método ExcluirDireto(), não registram operações no log de auditoria. VB Public Class frmlogin... Imports SGLPDESKLIB.EntityPlus Imports SGLPDESKLIB.Seguranca... Private Sub Logar() 'Fazendo o login pelo sistema de segurança gobjlogin = new clslogin(txtlogin.text, txtsenha.text, _strconexao)'assumindo a declaração 'da var gobjlogin como pública If gobjlogin.erro Then MessageBox.Show("Erro ao logar (" & gobjlogin.mensagem & ")") Exit Sub End If End Sub End Class Public Class frmcadusuarios... Imports SGLPDESKLIB.EntityPlus Imports SGLPDESKLIB.Seguranca... Private Sub SalvarUsuario()... Dim _objusuario As New clstbentityuser _objusuario.clogin = txtlogin.text _objusuario.cnome = txtnome.text _objusuario.csenha = txtsenha.text _objusuario.salvar(gobjlogin.clogin, _strconexao) 'passando para a função Salvar() o 'usuário que executou a ação... End Sub End Class C# public partial class frmlogin : Form {... using SGLPDESKLIB.EntityPlus; using SGLPDESKLIB.Seguranca;... Private void Logar() { //Fazendo o login pelo sistema de segurança clslogin gobjlogin = new clslogin(txtlogin.text, txtsenha.text, _strconexao); //Assumindo a declaração da var gobjlogin como pública if (gobjlogin.erro) { MessageBox.Show("Erro ao logar (" + gobjlogin.mensagem + ")"); return 130

133 public partial class frmcadusuarios : Form {... using SGLPDESKLIB.EntityPlus; using SGLPDESKLIB.Seguranca;... Private void SalvarUsuario() {... clstbentityuser _objusuario = new clstbentityuser(); _objusuario.clogin = txtlogin.text; _objusuario.cnome = txtnome.text; _objusuario.csenha = txtsenha.text; _objusuario.salvar(gobjlogin.clogin, _strconexao);//passando para a função Salvar() o //usuário que executou a ação... Imagine um sistema cujo acesso é feito através de uma tela de login, onde você informa usuário e senha e, uma vez validadas, esta informações ficam disponíveis através de uma variável do tipo clslogin, que contém dados do usuário e seus direitos. É isso que o exemplo acima faz. Ele supõe a existência de uma variável gobjlogin de escopo global. Todas as tabelas monitoradas pela auditoria terão seus métodos de persistência exigindo o parâmetro AuditoriaUsuario e, através deste, registra as ações feitas pelo usuário logado. Utilizamos a variável de login passando sua propriedade clogin. No frmcadusuarios (cadastro de usuários) temos o método SalvarUsuario(), que salva os dados dos usuários na tabela de segurança EntityUser (monitorada pela auditoria). Ao executarmos a função Salvar() do objeto _objusuario, esta irá também alimentar a tabela de auditoria EntityAudit, registrando quem incluiu/atualizou, o horário, tipo de atualização (U=update; D=delete; R=recover) e os dados de recuperação do registro afetado, entre outros. Vejamos o resultado dessa operação na tabela EntityAudit, abrindo os dados desta tabela no ambiente do Entity+. Para isso, basta selecionar a referida tabela na lista de tabelas na tela principal do sistema, clicar com o botão direito do mouse e selecionar Tabela/Selecionar 1000 Linhas Superiores. Os registros são listados abaixo: 131

134 Mesmo considerando que foi feito um insert no exemplo, a auditoria faz o registro dessa operação (Operação = U update) para que, caso este registro seja alterado mais tarde, possamos restaurálo a seu estado original. No exemplo anterior, salvamos o usuário, mas não passamos um valor para o campo Master, pois ele não é um campo obrigatório e tem valor default definido (zero - boolean: false) e, portanto, assumiu esse valor. Vamos agora alterar o campo Master para true, adicionando a linha abaixo ao exemplo anterior:... Dim _objusuario As New clstbentityuser(txtlogin.text, strconexao) 'Localiza oregistro... _objusuario.cmaster = True 'Altera o campo _Objusuario.Salvar(gobjLogin.cLogin, _strconexao)... Se por algum motivo você não queira que a ação seja auditada, basta passar # no parâmetro AuditoriaUsuário. Sempre habilite a auditoria antes que você comece a escrever seu sistema no Visual Studio, pois caso faça isso depois que suas rotinas estiverem escritas, você terá que alterar todas as chamadas dos métodos e funções de persistência das tabelas auditadas e, caso não o faça, todas elas apresentarão erro de execução. Por exemplo, imagine a função Salvar(), que antes da auditoria pedia somente o parâmetro strconn, mas que depois de implementada irá pedir AuditoriaUsuario e strconn. Situações do tipo descrito acima iriam resultar no erro string de conexão não fornecida Podemos restaurar um registro que foi alterado, através do databrowser visto na imagem acima, neste caso teremos que selecionar e abrir a tabela tentityuser, localizar e selecionar o registro em questão (que agora está como Master=True), dar um click com o botão direito do mouse e selecionar Auditoria/Exibir histórico do registro. 132

135 Então teremos: Observe o histórico registro listado acima, em ordem decrescente (do mais recente ao mais antigo). Neste caso o registro do insert é o último da lista. À direita temos o detalhe do ponto de restauração contendo, além dos dados anteriores do registro, informações de segurança. Vamos agora restaurar o registro para seu estado anterior, clicando no botão Restaurar. Feito isso, o usuário Elton, voltou a ter o campo Master igual à false. Quando você restaura um ponto de restauração, ele é excluído do histórico e é criado outro, do tipo R (Restauração). 133

136 Caso queira eliminar um ponto de restauração, basta selecioná-lo e clicar no botão Excluir Ponto de Restauração. Se um registro for excluído de uma tabela auditada, também é possível restaurá-lo. Para isso, basta selecionar a tabela de origem do registro na tela principal do programa, clicar com o botão direito e selecionar a opção Tabela/Auditoria/Exibir Registros Excluídos. Exemplos: VB Dim _objusuario As New clstbentityuser("elton", _strconexao) If _objusuario.encontrado Then _objusuario.excluir(gobjlogin.clogin) If _objusuario.erro Then MessageBox.Show(_objusuario.Mensagem) Else MessageBox.Show("usuário excluído") End If End If C# clstbentityuser _objusuario = new clstbentityuser("elton", _strconexao); if (_objusuario.encontrado) { _objusuario.excluir(gobjlogin.clogin); if (_objusuario.erro) { MessageBox.Show(_objusuario.Mensagem); else { MessageBox.Show("usuário excluído"); O exemplo acima localiza o usuário Elton e, caso o encontre, exclui o registro e, como essa é uma tabela auditada, registra essa operação no log de auditoria. Registro da exclusão no log de auditoria: 134

137 Observe o campo Operação, em destaque, ele exibe D de delete. Recuperando o registro excluído: Para recuperar o registro excluído, basta selecioná-lo e clicar em Restaurar. 135

138 Vimos neste tópico que, quando habilitamos a auditoria para uma tabela, alguns métodos de persistência das classes e coleções de registros, terão o parâmetro UsuarioAuditoria adicionado, contudo, em alguns casos, mesmo que determinada tabela não esteja marcada na auditoria, alguns métodos de persistência irão exigir este parâmetro. Caso você tenha uma tabela que não esteja marcada para auditoria, mas que possua um relacionamento com outra tabela monitorada, o referido parâmetro será exigido em alguns métodos de persistência da tabela pai. Imagine o seguinte relacionamento (tnotafiscal -< tnotafiscalitem), onde tnotafiscal não está auditada, mas sua tabela filha sim. Neste caso, o segundo overload da função Salvar() da classe de registro (clstb) e o método Salvar() da coleção de registro (coltb) irão exigir o referido parâmetro. Isto se faz necessário nas operações de salvamento em lote, onde um registro é salvo juntamente com as suas dependências (Notas fiscas salvas juntamente com seus itens, por exemplo). Agora, se você excluir um registro que possua dependências em outra tabela e deseja manter o log de exclusão desta última, você deverá chamar o método Excluir() da coleção de registros dependentes. Exemplo: Dim _objdados As New Dados(_strConexao) 'Instancia o objeto para gerenciar a transação Dim _objnf As New clstbtnotafiscal(100, _strconexao) 'Consulta a nota fiscal 'Exclui todos os itens da nota fiscal _objnf.tftnotafiscalitem.excluir(_objdados, _objlogin.usuario,, False) 'Caso não consiga excluir os itens, faz o rollback automático e sai If _objnf.tftnotafiscalitem.erro MessageBox.Show(_objNF.TftNotaFiscalItem.Mensagem) Exit Sub End If _objnf.excluir(_objdados,, True) 'Exclui a NF e conclui a transação Utilizando as Classes de Auditoria Até agora vimos como recuperar os registros alterados ou excluídos utilizando o IDE do Entity+, porém o mais importante é entender como fazer isso programaticamente de dentro de sua aplicação, utilizando as classes, propriedades, métodos e funções especiais de auditoria. Vimos no item 1.1 deste capítulo as alterações nas chamadas de alguns métodos e funções por conta da auditoria, além deles o Entity+ adiciona propriedades e funções especiais de auditoria. Implicações nas Classes de Registro (clstb) Vejamos como fica o esqueleto de uma classe de registro após a implantação da auditoria. Public Class clstb<nometabela>... Public ReadOnly Property LogAuditoria As collogauditoria<nometabela> Public Class clslogauditoria<nometabela> Inherits clstb<nometabela> 'Herda a classe de registro para disponibilizar seus valores 'originais... Public Property DataOperacao As Date 136

139 Public Property Usuario As String Public Property Operacao As String Public Property IPOrigem As String Public Property WinUser As String Public Property Computador As String Public Sub Restaurar(AuditoriaUsuario As String, Optional strconn As String = "") Public Function LogTexto() As String... End Class Public Class collogauditoria<nometabela>... Public ReadOnly Property Erro As Boolean Public ReadOnly Property Mensagem As String Default Public ReadOnly Property item(byval I As Integer) As clslogauditoria<nometabela> Default Public Property item(byval Data As Date) As clslogauditoria<nometabela> Public Sub Add(ByVal obj As clslogauditoria<nometabela>) Public Function LogTexto() As String Public Sub New(IDOrigem As String, StringConexao As String) Public Sub New(DataInicio As Date, DataFim As Date, StringConexao As String, Optional _ ByVal MaxRegistros As Int32 = 0, Optional Operacao As _ clsauditoria.enoperacao = clsauditoria.enoperacao.todas) Public Function Clone() As Object Implements System.ICloneable.Clone... End Class... End Class 1º) - Inclusão da propriedade LogAuditoria Propriedade do tipo collogauditoria<nometabela>), que disponibiliza todas as informações de log relativas ao registro instanciado, desde sua inclusão até suas alterações. A classe collogauditoria<nometabela> estará disponível dentro da classe de registro (clstb<nometabela>) da tabela auditada, ela é uma coleção da classe clslogauditoria<nometabela> Principais propriedades, métodos e funções de collogauditoria<nometabela>: Nome Tipo Descrição Erro Propriedade Boolean Indica se houve erro ao instanciar classe. Mensagem Propriedade String Retorna a descrição do erro. item Propriedade clslogauditoria<nometabela> Propriedade default que retorna os dados de um ponto de restauração. Add() Método Adiciona um item à coleção. LogTexto() Função String Retorna todo o log de auditoria referente ao registro instanciado na forma de string. New() Método Método construtor. Clone() Função Boolean Retorna um clone do objeto instanciado. Detalhes: Propriedade item() - Dois overloads Default Public ReadOnly Property item(byval I As Int32) As clslogauditoria<nometabela> 137

140 índice. Onde I é o índice da coleção. Pode-se então localizar um elemento na coleção pelo seu Default Public Property item(byval ID As Int64) As clslogauditoria<nometabela> Onde ID é o valor do campo ID da tabela EntityAudit. Pode-se então localizar um elemento na coleção por seu identificador único. Método Add() Public Sub Add(ByVal obj As clslogauditoria<nometabela>) Método New() - Dois overloads Public Sub New(IDOrigem As String, StringConexao As String) Onde IDOrigem é o conteúdo do campo IDOrigem da tabela EntityAudit. Public Sub New(DataInicio As Date, DataFim As Date, StringConexao As String, _ Optional ByVal MaxRegistros As Int32 = 0, Optional Operacao As _ clsauditoria.enoperacao = clsauditoria.enoperacao.todas) Seleciona os pontos de restauração do registro instanciado, mas dentro de um intervalo de datas e, opcionalmente informando a quantidade máxima de registros retornados e que tipo de operação será recuperado. Tipos de operação: clsauditoria.enoperacao.todas clsauditoria.enoperacao.deletes clsauditoria.enoperacao.updates clsauditoria.enoperacao.restoreupd clsauditoria.enoperacao.restoredelete LogTexto() Public Function LogTexto() As String Principais propriedades, métodos e funções de clslogauditoriar<nometabela>: Nome Tipo Descrição EntityAudit_ID Propriedade Int64 Chave da tabela EntityAudit, que identifica unicamente um ponto de restauração. DataOperacao Propriedade Date Data da operação. Erro Propriedade Boolean Herdada de clstb<tabela>. Indica se houve erro ao ser executado um método ou função Mensagem Propriedade String Herda de de clstb<tabela>. Retorna a descrição do erro. Usuario Propriedade String Usuário do sistema que executou a operação (AuditoriaUsuario). Operacao Propriedade String U=Update; D=Delete; R=Recover Upd; B=Recover Delete. IPOrigem Propriedade Endereço IP do computador que executou a operação. Propriedade String WinUser Propriedade String Usuário do Windows que executou a operação. Computador Propriedade String Nome do computador que executou a operação. Restaurar() Método Restaura o ponto de restauração. LogTexto() Função String Retorna os dados do ponto de restauração na forma de string. New() Método construtor Instancia um objeto da classe. Excluir() Método Exclui um ponto de restauração. 138

141 Detalhes: Método New() - Dois overloads Public Sub New() Instancia sem consultar um ponto de restauração Public Sub New(ByVal ID As Int64, ByVal strconn As String) Instancia consultando um ponto de restauração pelo seu ID. Método Restaurar() Public Sub Restaurar(AuditoriaUsuario As String, Optional strconn As String = "") Onde AuditoriaUsuário informa o usuário que esta realizando a restauração. Método Excluir() Public Sub Excluir() Vamos agora explorar as funcionalidades da propriedade LogAuditoria de uma classe de registro (clstb). Exemplos: VB Dim _strconexao As String = "Server = '(local)';database='sglpdesk';uid='sa';pwd='123456'" Dim _objusuario As New clstbentityuser("elton", _strconexao) If _objusuario.encontrado Then If _objusuario.logauditoria.count > 0 Then 'Se existir algum log de auditoria para o registro 'atual MessageBox.Show(_objusuario.LogAuditoria.LogTexto()) 'exibe o log na forma de texto 'Listando os pontos de restauração For i As Int16 = 0 To _objusuario.logauditoria.count - 1 Console.WriteLine("Data: " & _objusuario.logauditoria(i).dataoperacao) Console.WriteLine("Usuário: " & _objusuario.logauditoria(i).usuario) Console.WriteLine("Operação: " & _objusuario.logauditoria(i).operacao) Console.WriteLine("IP Origem: " & _objusuario.logauditoria(i).iporigem) Console.WriteLine("WinUser: " & _objusuario.logauditoria(i).winuser) Console.WriteLine("Computador: " & _objusuario.logauditoria(i).computador) Console.WriteLine("Dados originais ") Console.WriteLine("Login: " & _objusuario.logauditoria(i).clogin) Console.WriteLine("Nome: " & _objusuario.logauditoria(i).cnome) Console.WriteLine("Master: " & _objusuario.logauditoria(i).cmaster) Console.WriteLine("") Next End If End If C# String _strconexao = "Server = '(local)';database='sglpdesk';uid='sa';pwd='123456'"; clstbentityuser _objusuario = new clstbentityuser("elton", _strconexao); if (_objusuario.encontrado) { if (_objusuario.logauditoria.count > 0) //Se existir algum log de auditoria para o registro { //atual MessageBox.Show(_objusuario.LogAuditoria.LogTexto()); //exibe o log na forma de texto //Listando os pontos de restauração 139

142 for (Int16 i = 0; (_objusuario.logauditoria.count - 1); i++) { Console.WriteLine("Data: " + _objusuario.logauditoria[i].dataoperacao); Console.WriteLine("Usuário: " + _objusuario.logauditoria[i].usuario); Console.WriteLine("Operação: " + _objusuario.logauditoria[i].operacao); Console.WriteLine("IP Origem: " & _objusuario.logauditoria(i).iporigem); Console.WriteLine("WinUser: " & _objusuario.logauditoria(i).winuser); Console.WriteLine("Computador: " & _objusuario.logauditoria(i).computador); Console.WriteLine("Dados originais "); Console.WriteLine("Login: " + _objusuario.logauditoria[i].clogin); Console.WriteLine("Nome: " + _objusuario.logauditoria[i].cnome); Console.WriteLine("Master: " + _objusuario.logauditoria[i].cmaster); Console.WriteLine(""); O exemplo acima instancia um registro da tabela EntityUser e mostra num popup os pontos de restauração dele, depois faz a listagem detalhada destes mesmos pontos, exibindo inicialmente os dados de log e, em seguida, seus valores originais. Como a classe clslogauditoriaentityuser herda a sua classe pai clstbentityuser, ela disponibiliza todas a propriedades desta para exibir os dados originais (ver propriedades em rosa). Resultados: Recuperando um Ponto de Restauração Através do método Restaurar(), podemos voltar um registro para um estado anterior, armazenado no log de auditoria. Exemplos: VB Dim _strconexao As String = "Server = '(local)';database='sglpdesk';uid='sa';pwd='123456'" Dim _objusuario As New clstbentityuser("elton", _strconexao) 140

143 If _objusuario.encontrado Then If _objusuario.logauditoria.count > 1 Then 'Se existir pelo menos um insert e um update 'Restaura o 2o ponto de restauração fornecendo o usuário executou esta ação _objusuario.logauditoria(1).restaurar("usuário logado", _strconexao) If _objusuario.logauditoria(1).erro Then MessageBox.Show(_objusuario.LogAuditoria(1).Mensagem) Else MessageBox.Show("Registro restaurado com sucesso") End If End If End If C# String _strconexao = "Server = '(local)';database='sglpdesk';uid='sa';pwd='123456'" clstbentityuser _objusuario = new clstbentityuser("elton", _strconexao); if (_objusuario.encontrado) if (_objusuario.logauditoria.count > 1) Then //Se existir pelo menos um insert e um update { //Restaura o 2 o ponto de restauração fornecendo o usuário executou esta ação _objusuario.logauditoria[1].restaurar("usuário logado", _strconexao); if (_objusuario.logauditoria[1].erro) { MessageBox.Show(_objusuario.LogAuditoria(1).Mensagem); else { MessageBox.Show("Registro restaurado com sucesso"); Veja no destaque o registro da restauração no Entity+. Foi restaurado um ponto de restauração de atualização: Vejamos agora como restaurar um ponto de restauração de uma operação de exclusão. Temos que ter em mente que, neste caso, não teremos mais o registro original em sua tabela de origem, mas somente seu ponto de restauração (do tipo D ) na tabela EntityAudit, que teremos que encontrar antes de restaurar. Para isso teremos que instanciar a coleção de auditoria da tabela em questão. Veja o exemplo abaixo: VB Dim _strconexao As String = "Server = '(local)';database='sglpdesk';uid='sa';pwd='123456'" 'Consulta os 10 ultimos registros excluídos da tabela EntityUser Dim _objusuarios As New collogauditoriaentityuser("01/03/2015", "17/03/ :59:59", strconexao, 10, _ lsauditoria.enoperacao.deletes) 141

144 If _objusuarios.erro Then MessageBox.Show("Erro ao recuperar dados de auditoria (" & _objusuarios.mensagem & ")") Exit Sub End If If _objusuarios.count = 0 Then MessageBox.Show("Não existem pontos de retauração de exclusão para o período fornecido") Exit Sub End If 'Restaura o primeiro ponto de restauração pelo indice _objusuarios(int16.parse(0)).restaurar("administrador") 'utiliza a propriedade Item, que está 'implícita por ser default 'Restaura o ponto de restauração pelo seu ID, na lista _objusuarios(int64.parse(520)).restaurar("administrador") 'utiliza a propriedade Item, passando 'agora o ID do ponto de restauração If _objusuarios.erro Then MessageBox.Show(_objUsuarios.Mensagem) Else MessageBox.Show("Registro recuperado com sucesso") End If C# String _strconexao = "Server = '(local)';database='sglpdesk';uid='sa';pwd='123456'"; //Consulta os 10 ultimos registros excluídos da tabela EntityUser collogauditoriaentityuser _objusuarios = new collogauditoriaentityuser("01/03/2015", "17/03/ :59:59", _strconexao, 10, clsauditoria.enoperacao.deletes); if (_objusuarios.erro) { MessageBox.Show("Erro ao recuperar dados de auditoria (" + _objusuarios.mensagem + ")"); return; if (_objusuarios.count = 0) { MessageBox.Show("Não existem pontos de retauração de exclusão para o período fornecido"); return; //Restaura o primeiro ponto de restauração _objusuarios[int32.parse("0")].restaurar("administrador"); //utiliza a propriedade Item, que //está implícita por ser default //Restaura o ponto de restauração pelo seu ID, na lista _objusuarios[int64.parse("520")].restaurar("administrador"); //utiliza a propriedade Item, //passando agora o ID do ponto de //restauração if (_objusuarios.erro) { MessageBox.Show(_objUsuarios.Mensagem); else { MessageBox.Show("Registro recuperado com sucesso"); Observe que, como a propriedade default Item, aceita tanto um índice (Int16), quanto o ID (Int64), é necessário explicitar o tipo de dado passado, utilizando a função Parse(). 142

145 Também podemos restaurar um ponto de restauração instanciando um ponto específico pelo seu ID. Lembre-se que a chave primária da tabela EntityAudit é o campo sequencial ID. O método New() de uma classe clslogauditoria<nometabela> recebe este parâmetro para achar um ponto de restauração específico e único Exemplos: VB Dim _strconexao As String = "Server = '(local)';database='sglpdesk';uid='sa';pwd='123456'" Dim _objaudit As New clslogauditorianotafiscal(41, _strconexao) If _objaudit.erro Then MessageBox.Show(_objAudit.Mensagem) Exit Sub End If If Not _objaudit.encontrado Then MessageBox.Show("Ponto de restauração não encontrado") Else _objaudit.restaurar("usuário logado") End If C# String _strconexao = "Server = '(local)';database='sglpdesk';uid='sa';pwd='123456'"; clslogauditorianotafiscal _objaudit = new clslogauditorianotafiscal(41, _strconexao); if (_objaudit.erro) { MessageBox.Show(_objAudit.Mensagem); return; if (!_objaudit.encontrado) { MessageBox.Show("Ponto de restauração não encontrado"); else { _objaudit.restaurar("teste"); Excluindo um Ponto de Restauração Você pode desenvolver, dentro de seu sistema final no Visual Studio, um módulo para manutenção dos pontos de restauração, onde basicamente seriam consultados os registros da tabela EntityAudit, utilizando-se as classes e coleções de auditoria que vimos até agora. Vejamos algumas adaptações do exemplo anterior: VB Dim _objaudit As New clslogauditorianotafiscal(41, _strconexao) If _objaudit.erro Then MessageBox.Show(_objAudit.Mensagem) Exit Sub End If If _objaudit.encontrado Then objaudit.excluir() Else MessageBox.Show("Ponto de restauração não encontrado ) End If 143

146 C# clslogauditorianotafiscal _objaudit = new clslogauditorianotafiscal(41, _strconexao); if (_objaudit.erro) { MessageBox.Show(_objAudit.Mensagem); return; if (_objaudit.encontrado) { _objaudit.excluir(); else { MessageBox.Show("Ponto de restauração não encontrado ); No exemplo abaixo veremos como excluir os pontos de restauração de exclusão de uma tabela, gerados dentro de um período: VB Dim _strconexao As String = "Server = '(local)';database='sglpdesk';uid='sa';pwd='123456'" 'Consulta os 10 ultimos registros excluídos da tabela EntityUser Dim _objaudit As New collogauditorianotafiscal("01/03/2015", "17/03/ :59:59", strconexao, 10, clsauditoria.enoperacao.deletes) If objaudit.erro Then MessageBox.Show("Erro ao recuperar dados de auditoria (" & objaudit.mensagem & ")") Exit Sub End If For i As Int16 = 0 To _objaudit.count - 1 _objaudit(i).excluir() 'chama o método de exclusão If _objaudit.erro Then MessageBox.Show("Erro ao excluir (" & _objaudit.mensagem & ")") Exit Sub End If Next C# String _strconexao = "Server = '(local)';database='sglpdesk';uid='sa';pwd='123456'"; //Consulta os 10 ultimos registros excluídos da tabela EntityUser collogauditorianotafiscal _objaudit = new collogauditorianotafiscal("01/03/2015", "17/03/ :59:59", _strconexao, 10, clsauditoria.enoperacao.deletes); if (objaudit.erro) { MessageBox.Show("Erro ao recuperar dados de auditoria (" + objaudit.mensagem + ")"); return; for (Int16 i = 0; (i <= _objaudit.count - 1); ++i) { _objaudit[i].excluir(); //chama o método de exclusão if (_objaudit.erro) { MessageBox.Show("Erro ao excluir (" + _objaudit.mensagem + ")"); return; 144

147 4.4 - Ligando e Desligando a Auditoria no Banco de Dados Vimos que quando habilitamos a auditoria para determinadas tabelas, estas têm algumas de suas rotinas de persistência adaptadas para este propósito e que, caso não quisermos logar determinadas operações nestas tabelas, passamos o coringa #, no parâmetro AuditoriaUsuario, mas isto é feito na programação do seu sistema final no Visual Studio e, caso haja alguma mudança, teríamos que fazer as devidas alterações, recompilar nossa aplicação e disponibilizá-la em produção. Para evitar este transtorno, podemos gerenciar as tabelas auditadas diretamente no nosso banco de dados, ligando e desligando o recurso de auditoria de algumas delas. Isto é feito habilitando-se a opção Criar controle de auditoria no banco de dados, disponível na tela de auditoria de dados do Entity+, vista no início deste tópico. Habilitando-se esta opção, o Entity+ irá adicionar a tabela EntityAuditControl ao banco de dados para que possamos gerenciar a auditoria de cada tabela monitorada. Vejamos então como ficaria o conteúdo desta tabela se habilitássemos este recurso no projeto do nosso exemplo ao lado. Listagem da tabela EntityAuditControl: Observe que todas as tabelas auditadas constam na listagem e todas estão marcadas para auditar deletes e updates. Para desabilitarmos os logs de updates da tabela tnotafiscalsaida, por exemplo, bastaria alterar o conteúdo do campo AuditaUpdate para False. A partir daí, toda e qualquer inclusão ou alteração de registros nesta tabela não seriam registrados no log de auditoria. 145

148 C A P Í T U L O 5 Manutenção do Projeto Neste capítulo veremos como executar tarefas de manutenção do nosso projeto Entity+, adicionando, excluindo ou alterando recursos a ele Mantendo o Projeto Atualizado Após criarmos nosso projeto Entity+, é quase certo que teremos que alterar várias vezes a estrutura de nossas tabelas, índices, relacionamentos, etc. ao longo do desenvolvimento de nossa aplicação. Estas alterações têm que ser atualizadas em nosso projeto, do contrário, erros de compilação ou lógica poderão afetar nosso produto final, que são as dlls geradas. Existem alguns níveis de atualização que podemos executar Adicionando e Removendo uma Tabela ao Projeto Este é o nível mais básico de atualização que podemos fazer, ele consiste em simplesmente adicionar uma ou mais tabelas ao nosso projeto Entity+, ou remover uma existente. Somente tabelas com chaves-primárias definidas poderão ser adicionadas. Para adicionar: Através do menu Projeto/Adicionar Tabela ao Projeto ou do botão Adicionar Tabela. Observe que as tabelas que não possuem chave-primária são impedidas de serem adicionadas. Elas estão marcadas com um X em vermelho. Uma vez selecionadas as tabelas, basta clicar em OK. As mesmas serão analisadas e adicionadas ao projeto. Veja ao lado a tabela recém-adicionada, destacada em verde. Isto indica que a mesma foi adicionada mais ainda não está salva. Você terá que salvar o projeto para que a mesma seja gravada como um arquivo.etb (Entity table). 146

149 Para remover: Através do menu Projeto/Excluir Tabela do Projeto ou do botão Excluir Tabela. Uma tabela só poderá ser removida se não tiver dependências de relacionamento. Por exemplo, a tabela tnotafiscal está relacionada com tnotafiscalitem (tnotafiscal -< tnotafiscalitem), neste caso tnotafiscal não poderá ser excluída, pois tnotafiscalitem depende dela. Para excluí-la, teremos que eliminar tnotafiscalitem primeiro. Após a exclusão você deverá salvar o projeto, do contrário ficarão as Referências-Fantasma dentro do arquivo de projeto.eprj (Entity Project) Atualizando as Classes de uma Tabela Este tipo de atualização consiste em verificar a estrutura de uma tabela no banco de dados e compará-la à sua estrutura dentro do projeto Entity+ e, caso haja diferenças, o projeto é atualizado. São verificados os campos, índices, constraints, chaves e relacionamentos. Para executarmos este tipo de atualização, basta selecionar a tabela na lista, com um click do mouse e escolher no menu principal Projeto/Atualizar Classe clstb<nometabela> ou clicar no botão Atualizar classe. O sistema irá pedir confirmação. Após clicar no botão Sim, será verificado se a data de alteração da tabela no banco de dados é diferente da data de alteração no projeto e, caso sejam, a verificação será executada. das datas. Se selecionarmos a checkbox forçar atualização, a verificação será feita independentemente A imagem a esquerda mostra uma atualização forçada, onde não houve diferenças. A da direita mostra as diferenças encontradas e as atualizações feitas no projeto. 147

150 Atualizando as Classes de Várias Tabelas Faz o mesmo tipo de verificação/atualização que a do item anterior, contudo afeta todas as tabelas do projeto. Para executar este tipo de atualização, selecione no menu Projeto/Atualizar classes das tabelas selecionadas, ou click no botão com o mesmo nome Sincronização do Projeto É o tipo de atualização mais completa. Enquanto que a atualização de classes de várias tabelas, vista no item acima, compara cada tabela do projeto com as do banco de dados, a sincronização faz o inverso, ela lê cada tabela do banco de dados e, caso exista no projeto, faz a comparação e as devidas atualizações no projeto. Caso não exista no projeto, a mesma é adicionada. Para executar este tipo de atualização, selecione no menu Projeto/Sincronizar Projeto com o Banco de Dados, ou click no botão Sincronizar projeto Resetando uma Classe Através deste processo, a estrutura de uma tabela existente no projeto é totalmente reconstruída, e todos seus recursos agregados perdidos. Um recurso agregado é qualquer funcionalidade adicionada à tabela dentro do projeto (auto incremento, campos totalizados, consultas, regras de validação, rotinas, encadeamentos, etc.). Só execute esta operação se tiver certeza que está disposto a perder estes eventuais recursos. botão Para executar esta operação, selecione Projeto/Resetar Classe clstb<nometabela>, ou click no Resetar Classe. Caso a tabela tenha algum recurso agregado, a seguinte tela aparecerá: 148

151 Reconstruindo todo o Projeto Este processo consiste na total reconstrução de seu projeto, com base no estado atual de seu banco de dados, e a consequente perda de todos os recursos agregados. Para executar esta operação, selecione Projeto/Reconstruir Projeto BackUp O Entity+ dispõe do recurso de backup, onde todas as alterações feitas no projeto são salvas em arquivos especiais.bak para posterior recuperação. Toda vez que você salva o seu projeto, uma cópia dele é feita na pasta Backup em um único arquivo com o nome no formato yyyymmddhhmmss. Por default, todo projeto tem este recurso habilitado e configurado para manter os últimos 100 (cem) backups mais atuais. Para alterar esta configuração, basta ir ao menu Projeto/configurações e selecione a aba Geral. Aqui você pode configurar a quantidade máxima de backups. Informe zero para desabilitar os backups. Para restaurar um backup, basta clicar no botão Recuperar Backups. Eles estarão listados em ordem decrescente, do mais recente ao mais antigo. Selecione a data desejada e click em Restaurar. 149

152 Os arquivos destacados em verde são os que foram alterados no salvamento do projeto. Após clicar em Restaurar, surgirá a tela com o log da restauração, onde você pode, opcionalmente, informar outra pasta de destino O Class Browser Permite visualizar a estrutura das classes que serão geradas na publicação do projeto. Para visualizá-lo selecione Projeto/Class Browser. 150

153 5.4 - O Data Browser Recurso que permite a visualização dos dados das tabelas e a navegação entre seus relacionamentos de forma inteligente e interativa. Imagine no ambiente do SQL Server, fazer um select na tabela de notas fiscais e se deparar com o campo ttipocliente_id, cujo conteúdo de um dos registros é 2. Este campo é uma foreing-key vinda da tabela ttipocliente, e você terá que abrir outra consulta para listar o conteúdo dela e saber o que o valor 2 significa. Ou então você quer consultar os itens de uma nota fiscal, que estão na tabela tnotafiscalitem. Outra vez terá que abrir uma consulta e passar os dados de chave na cláusula where para localizá-los. Com o Data Browser do Entity+, você fará isso apenas com clicks do mouse, sem a necessidade de digitar nenhuma linha de instrução SQL. Imagine a estrutura: Vou selecionar a tabela tnotafisalsaida com o botão direito do mouse se clicar em Tabela/Selecionar 1000 linhas superiores. Observe no detalhe, que ao passar o mouse sobre o conteúdo do campo ttipocliente_id, apareceu um tooltip com o seu significado. Caso não surgisse a tooltip, bastava dar dois clicks no conteúdo da célula, para exibir o menu Listar registros relacionados da tabela-pk, e clicar no nome da tabela para listar os seus dados em outro data browser. 151

154 Vamos agora ver quais itens pertencem a uma determinada nota fiscal listada no data browser. Para isso basta selecionar o registro com o botão direito do mouse. Todas as tabelas dependentes de tnotafiscalsaida são listadas no menu. Selecionamos tnotafiscalsaidaitem. Itens da nota fiscal da tela anterior. Esta navegação pode ser feita nos dois sentidos do relacionamento, até onde eles existam. Poderíamos agora ver quais os dados do produto de código 1403, dando dois cliques nessa célula, e assim por diante. Outro recurso muito útil de navegação está disponível no painel principal do sistema, onde você visualiza a estrutura de uma tabela (campos, tipos, etc.). Nele você pode navegar diretamente para os dados de uma tabela primary-key. No exemplo abaixo temos a estrutura da tabela tnotafiscalsaida, nele podemos observar, destacado em verde, vários campos foreing-key, entre eles o campo ttipoemissaonf_id, que vem da tabela ttipoemissaonf. Em caso de dúvida com relação aos valores válidos para este campo, podemos navegar diretamente para os registros desta tabela. 152

155 153

156 C A P Í T U L O 6 Explorando o Data Access Layer (DAL) Vimos logo no início deste manual que o produto final gerado pelo Entity+ é composto por duas DLLs, sendo uma delas o DAL, responsável pela comunicação das classes de entidades, criadas em nosso projeto, e o banco e dados. A DLL principal solicita serviços a esta outra, que por sua vez os executa e responde à solicitação. Nós também podemos desfrutar dos serviços oferecidos pelo DAL, bastando para isso referenciá-la em nosso projeto. Este capítulo aborda suas principais classes métodos e funções, que você poderá usar diretamente, sem intermediários, fazendo comunicação direta com o banco de dados. Este é um recurso especialmente interessante quando você for desenvolver aplicações que fogem ao escopo das classes e coleções de registro. O próprio Entity+ os utiliza para analisar as estruturas dos objetos de um banco de dados Estrutura É basicamente formada por três classes principais e um namespace A Classe Cryptografia Disponibiliza métodos de criptografia e compressão de dados. Método Encrypt (shared/static) Encripta uma string com base em uma chave de criptografia. Declaração: Public Shared Function Encrypt(Texto As String, Chave As String) As String Exemplo: VB Imports <NomeProjeto>Core 'DAL... Dim _strencrip As String = Cryptografia.Encrypt("Entity+", "minhachave") C# using <NomeProjeto>Core; //DAL... String _strencrip = Cryptografia.Encrypt("Entity+", "minhachave"); 154

157 Método Decrypt (shared/static) Decripta uma string com base em uma chave de criptografia. Declaração: Public Shared Function Decrypt(TextoEncriptado As String, Chave As String) As String Exemplo: VB Imports <NomeProjeto>Core 'DAL... Dim _strdecrip As String = Cryptografia.Decrypt(_strEncrip, "minhachave") C# using <NomeProjeto>Core; //DAL... String _strdecrip = Cryptografia.Decrypt(_strEncrip, "minhachave"); Método HashMD5 (shared/static) Gera o hash MD5 de uma string. Declaração: Public Shared Function HashMD5(Texto As String) As String Exemplo: VB Imports <NomeProjeto>Core 'DAL... Dim _strhash As String = Cryptografia.HashMD5("Entity+") C# using <NomeProjeto>Core; //DAL... String _strhash = Cryptografia.HashMD5("Entity+"); Método Zip (shared/static) Compacta uma string. Declaração: Public Shared Function Zip(Texto As String) As String Exemplo: VB Imports <NomeProjeto>Core 'DAL... Dim _strzip As String = Cryptografia.Zip("Entity+") C# using <NomeProjeto>Core; //DAL

158 String _strzip = Cryptografia.Zip("Entity+"); Método UnZip (shared/static) Descompacta uma string. Declaração: Public Shared Function UnZip(Textocompactado As String) As String Exemplo: VB Imports <NomeProjeto>Core 'DAL... Dim _strunzip As String = Cryptografia.UnZip(_strZip) C# using <NomeProjeto>Core; //DAL... String _strunzip = Cryptografia.UnZip(_strZip); A Classe Dados Esta é a classe mais importante do DAL, responsável pela comunicação com o banco de dados. Estrutura: Public Class Dados Public Property CommandTimeout As Int16 Public Readonly Property EmTransacao As Boolean Public Readonly Property StringConexao As String Public Property Transacao As SqlTransaction Public ReadOnly Property CodigoRetornado As Int32 Public ReadOnly Property Chave As String Public ReadOnly Property Erro() As Boolean Public ReadOnly Property Mensagem() As String Public ReadOnly Property Servidor() As String Public Sub New() Public Sub New(ByVal stringconexao As String, Optional ByVal AbrirConexao As Boolean = False) Public Sub BeginTrans() Public Sub CommitTrans() Public Sub RollBackTrans() Public Sub ExecutarSql(ByVal SqlString As String, Optional ByVal Finalizar As Boolean = False) Public Sub ExecutarSqlNonQuery(ByVal SqlString As String, Optional Transacionada As _ Boolean = False, Optional ByVal Finalizar As Boolean = False) Public Function ConsultarDados(ByVal strsqlstring As String, Optional ByVal tipo As _ System.Data.CommandBehavior = CommandBehavior.CloseConnection) _ As SqlDataReader Public Function DataSistema() As Date Public Sub Dispose() Public Function fretornaschema(byval tbldestino As String) As DataTable Public Shared Function BancosdeDados(ByVal servidor As String, ByVal senha As String) _ As String() 156

159 Public Class SqlServer Public Sub New() Public Property Servidor() As String Public Property Instancia() As String Public Property IsClustered() As Boolean Public Property Local() As Boolean End Class Public Class campo Public Property Checked As Boolean Public Property Descricao() As String Public Property Argumento() As Boolean Public Property tamanho() As Int64 Public Property PermiteNull() As Boolean Public Property nome() As String Public Property tiposql() As String Public Property tipovb() As String Public Property PK() As Boolean Public Property Unique As Boolean Public Sub New() End Class Public Class colcampos Inherits CollectionBase Default Public ReadOnly Property item(byval I As Integer) As campo Default Public ReadOnly Property item(byval nome As String) As campo Public Sub New() Public Sub Remove(ByVal obj As campo) Public Sub Add(ByVal obj As campo) End Class End Class Principais Propriedades, Métodos e Funções: Nome Tipo Descrição CommandtimeOut Propriedade Int16 Retorna/define o tempo máximo de resposta do BD em milissegundos. EmTransacao Propriedade Boolean Indica se alguma transação está em andamento. StringConexao Propriedade String Retorna/define a string de conexão com o banco de dados. Transacao Propriedade Define/retorna um objeto de transação. SqlTransaction Erro Propriedade Boolean Indica se alguma operação de acesso a dados ocasionou algum erro. Mensagem Propriedade String Retorna uma mensagem após a execução de algum método ou função. Servidor Propriedade String Retorna/Define o nome do servidor. New() Método Construtor Instancia a classe opcionalmente estabelecendo uma conexão com o BD. BeginTrans() Método Inicia uma transação no banco de dados. CommitTrans() Método Finaliza uma transação no banco de dados. RollBackTrans() Método Desfaz uma transação. ExecutarSql() Método Executa uma instrução SQL. ConsultarDados() Função SqlDataReader Executa uma consulta SQL, retornando seus registros na forma de um DataReader. DataSistema() Função Date Retorna a data do sistema do servidor de dados. 157

160 Dispose() Método Finaliza o objeto instanciado e fecha a suas conexões. fretornaesquema() Função DataTable Retorna as informações da estrutura de uma tabela na forma de um DataTable. BancosdeDados() Função Shared de Array de Strings Retorna um array contendo todos os nomes dos bancos de dados contidos em um servidor O Namespace SQLStructure Possui classes, métodos e funções voltados para a estrutura do Sql Server, dando ao programador, acesso a uma série de informações dos diversos objetos de um banco de dados. Estrutura: Namespace SQLStructure Public Class clstabela Public Sub New() Public Sub New(ByVal tabnome As String, strconexao As String) Public ReadOnly Property Erro As Boolean Public ReadOnly Property Mensagem As String Public ReadOnly Property StringConexao As String Public Property Relacionamentos As colrelacionamentos Public ReadOnly Property ChaveSimples As Boolean Public Property Nome As String Public ReadOnly Property DataCriacao As Date Public ReadOnly Property DataAlteracao As Date Public ReadOnly Property TotalRegistros As Int64 Public Property Descricao As String Public Property Tipo As String Public Property Schema As String Public Property Campos As colcampos Public ReadOnly Property ChavesPrimarias As colcampos Public Property TabelasFK As coltabela Public Function fglerpropextendida(byval nometabela As String, _ ByVal propriedade As String) As String Public Function findicestabela() As colchavesuniques Public Function fexistconstraintunique() As Boolean Public Function QtdPK() As Int16 Public Function ExistPK() As Boolean End Class Public Class colcampos Inherits CollectionBase Public Sub New() Public Sub New(ByVal nometabela As String, strstringconexao As String) Default Public ReadOnly Property item(byval I As Integer) As clscampo Default Public ReadOnly Property item(byval nome As String) As clscampo Public Sub Remove(ByVal obj As clscampo) Public Sub Remove(ByVal nomecampo As String) Public Sub Add(ByVal obj As clscampo) Public Function RetornaCampos(ByVal nometabela As String, _ strstringconexao As String) As colcampos End Class 158

161 Public Class coltabela Inherits CollectionBase Public Enum enautoincremento Sim = 1 Nao = 2 NaoPratodos = 3 End Enum Public Sub New() Public Sub New(strConexao As String) Public Sub Remove(ByVal obj As clstabela) Default Public Property item(byval I As Integer) As clstabela Default Public Property item(byval nome As String) As clstabela Public Sub Add(ByVal obj As clstabela) Public Function LerTabelasBD(ByVal strstringconexao As String) As coltabela End Class Public Class clsrelacionamentos Public Sub New() Public Property Tabela As String Public ReadOnly Property CamposRelacao As colcamposrelacao Public Property NomeTabelaPK As String Public Property DelecaoCascata As Boolean Public Property StringConexao As String End Class Public Class colrelacionamentos Inherits CollectionBase Public Sub New() Public Sub New(objTabelaPK As clstabela, strconexao As String) Public ReadOnly Property Erro As Boolean Public ReadOnly Property Mensagem As String Default Public ReadOnly Property item(byval I As Integer) As clsrelacionamentos Default Public ReadOnly Property item(byval NomeTabela As String) As clsrelacionamentos Public Sub Add(ByVal obj As clsrelacionamentos) End Class Public Class clscamposrelacao Public Property NomeFK As String Public Property CampoPK As String Public Property CampoFK As String End Class Public Class colcamposrelacao Inherits CollectionBase Default Public ReadOnly Property item(byval I As Integer) As clscamposrelacao Default Public ReadOnly Property item(byval NomeCampo As String) As clscamposrelacao Public Sub Add(ByVal obj As clscamposrelacao) End Class Public Class colforeingkeys Default Public ReadOnly Property item(byval I As Integer) As clsforeingkeys Default Public ReadOnly Property item(byval nome As String) As clsforeingkeys Public Sub New() Public Shared Function fqtdrelactabela(tabela As String, FKs As colforeingkeys) As Int16 Public Sub Remove(ByVal obj As clsforeingkeys) Public Sub Add(ByVal obj As clsforeingkeys) End Class 159

162 Public Class clsforeingkeys Public Property TabelaPK As String Public Property NomeFK As String Public Property Campos As colcampos End Class Public Class clscampo Public Property NomeChave As String Public Property Indexado As Boolean Public Property Identity As Boolean Public Property ValorDefault() As String Public Property NomeTabela As String Public Property Descricao() As String Public Property FkTabInfo As fkinfo Public Property FkTabInfos As colfkinfo Public Property Tamanho() As Int64 Public Property PermiteNull() As Boolean Public Property Nome() As String Public Property TipoSql() As String Public Property TipoVB() As String Public Property PK() As Boolean Public Property Unique As Boolean Public Sub New() Public Function Clone() As Object Implements System.ICloneable.Clone End Class Public Class colfkinfo Inherits CollectionBase Default Public ReadOnly Property item(byval I As Integer) As fkinfo Default Public ReadOnly Property item(byval Tabela As String) As fkinfo Public Sub Remove(ByVal obj As fkinfo) Public Sub Add(ByVal obj As fkinfo) Public Sub New() End Class Public Class fkinfo Public Tabela As String Public Descricao As String Public Campo As String End Class Public Class clstabelafk Public Property Nome As String Public Property Campos As colcampos Public Sub New() End Class Public Class coltabelafk Inherits CollectionBase Default Public Property item(byval I As Integer) As clstabelafk Default Public Property item(byval nome As String) As clstabelafk Public Sub New() Public Sub Remove(ByVal obj As clstabelafk) End Class Public Class colchavesuniques Inherits CollectionBase Default Public ReadOnly Property item(byval I As Integer) As clschavesuniques Default Public ReadOnly Property item(byval nome As String) As clschavesuniques Public Sub New() Public Sub Remove(ByVal obj As clschavesuniques) Public Sub Add(ByVal obj As clschavesuniques) End Class 160

163 Public Class colcamposunique Inherits CollectionBase Default Public ReadOnly Property item(byval I As Integer) As clscamposunique Default Public ReadOnly Property item(byval nome As String) As clscamposunique Public Sub New() Public Sub Remove(ByVal obj As clscamposunique) Public Sub Add(ByVal obj As clscamposunique) End Class Public Class clscamposunique Public Property Tamanho As Int32 Public Property PermiteNull As Boolean Public Property TipoVB As String Public Property TipoSQL As String Public Property Nome As String End Class Public Class clschavesuniques Public Property Tipo As String Public Property NomeChave As String Public Property Campos As colcamposunique Public Sub New() End Class End Namespace 161

164 C A P Í T U L O 7 Documentação do Projeto O Entity+ gera toda a documentação do seu projeto, desde o dicionário de dados até as estruturas das classes e coleções de registros, de forma detalhada. Este tipo de recurso é muito útil para manter uma equipe de desenvolvimento atualizada com relação ao projeto de sistema como um todo. Além de permitir uma visão ampla do banco de dados e seus diversos objetos, disponibiliza toda a estrutura das classes, métodos e funções criadas. Para gerar a documentação, basta clicar no botão Documentação do projeto. Você deve selecionar quais documentos serão gerados e para quais tabelas, então será criado um arquivo HTML na pasta Documentação de seu projeto Tipos de Documento Lista de Tabelas Contém a relação de todas as tabelas selecionadas, suas descrições e status de auditoria. 162

165 Lista de Views Contém a relação de todas as views selecionadas e suas descrições Dicionário de Dados Gera o dicionário de dados contendo, opcionalmente, os detalhes das foreing-keys, relacionamentos, índices e constraints Detalhes de Foreing-keys Lista os campos foreing-key de uma tabela, contendo seu nome, tabela e campo de origem. 163

166 Relacionamentos Lista todos os relacionamentos (PK -> FK) da tabela Índices e Constraints Lista os índices e constraints únicas de uma tabela Estrutura de Classes Lista todas as informações relativas às classes geradas em seu projeto Domínio de Campos Lista os domínios definidos para os campos de uma tabela. 164

Procedimentos para Reinstalação do Sisloc

Procedimentos para Reinstalação do Sisloc Procedimentos para Reinstalação do Sisloc Sumário: 1. Informações Gerais... 3 2. Criação de backups importantes... 3 3. Reinstalação do Sisloc... 4 Passo a passo... 4 4. Instalação da base de dados Sisloc...

Leia mais

Manual Captura S_Line

Manual Captura S_Line Sumário 1. Introdução... 2 2. Configuração Inicial... 2 2.1. Requisitos... 2 2.2. Downloads... 2 2.3. Instalação/Abrir... 3 3. Sistema... 4 3.1. Abrir Usuário... 4 3.2. Nova Senha... 4 3.3. Propriedades

Leia mais

ArpPrintServer. Sistema de Gerenciamento de Impressão By Netsource www.netsource.com.br Rev: 02

ArpPrintServer. Sistema de Gerenciamento de Impressão By Netsource www.netsource.com.br Rev: 02 ArpPrintServer Sistema de Gerenciamento de Impressão By Netsource www.netsource.com.br Rev: 02 1 Sumário INTRODUÇÃO... 3 CARACTERÍSTICAS PRINCIPAIS DO SISTEMA... 3 REQUISITOS DE SISTEMA... 4 INSTALAÇÃO

Leia mais

Noções de. Microsoft SQL Server. Microsoft SQL Server

Noções de. Microsoft SQL Server. Microsoft SQL Server Noções de 1 Considerações Iniciais Basicamente existem dois tipos de usuários do SQL Server: Implementadores Administradores 2 1 Implementadores Utilizam o SQL Server para criar e alterar base de dados

Leia mais

INSTALAÇÃO DO SISTEMA CONTROLGÁS

INSTALAÇÃO DO SISTEMA CONTROLGÁS INSTALAÇÃO DO SISTEMA CONTROLGÁS 1) Clique duas vezes no arquivo ControlGasSetup.exe. Será exibida a tela de boas vindas do instalador: 2) Clique em avançar e aparecerá a tela a seguir: Manual de Instalação

Leia mais

CRIANDO BANCOS DE DADOS NO SQL SERVER 2008 R2 COM O SQL SERVER MANAGEMENT STUDIO

CRIANDO BANCOS DE DADOS NO SQL SERVER 2008 R2 COM O SQL SERVER MANAGEMENT STUDIO CRIANDO BANCOS DE DADOS NO SQL SERVER 2008 R2 COM O SQL SERVER MANAGEMENT STUDIO Antes de criarmos um novo Banco de Dados quero fazer um pequeno parênteses sobre segurança. Você deve ter notado que sempre

Leia mais

Manual de Utilização

Manual de Utilização Manual de Utilização Versão 1.0 18/01/2013 Sempre consulte por atualizações deste manual em nossa página. O Cotação Web está em constante desenvolvimento, podendo ter novas funcionalidades adicionadas

Leia mais

MANUAL COTAÇAO WEB MANUAL MANUAL AVANÇO INFORMÁTICA AVANÇO INFORMÁTICA. [Digite seu endereço] [Digite seu telefone] [Digite seu endereço de email]

MANUAL COTAÇAO WEB MANUAL MANUAL AVANÇO INFORMÁTICA AVANÇO INFORMÁTICA. [Digite seu endereço] [Digite seu telefone] [Digite seu endereço de email] MANUAL COTAÇAO WEB [Digite seu endereço] [Digite seu telefone] [Digite seu endereço de email] MANUAL MANUAL AVANÇO INFORMÁTICA AVANÇO INFORMÁTICA Material Desenvolvido para a Célula Materiais Autor: Equipe

Leia mais

Despachante Express - Software para o despachante documentalista veicular DESPACHANTE EXPRESS MANUAL DO USUÁRIO VERSÃO 1.1

Despachante Express - Software para o despachante documentalista veicular DESPACHANTE EXPRESS MANUAL DO USUÁRIO VERSÃO 1.1 DESPACHANTE EXPRESS MANUAL DO USUÁRIO VERSÃO 1.1 1 Sumário 1 - Instalação Normal do Despachante Express... 3 2 - Instalação do Despachante Express em Rede... 5 3 - Registrando o Despachante Express...

Leia mais

GUIA INTEGRA SERVICES E STATUS MONITOR

GUIA INTEGRA SERVICES E STATUS MONITOR GUIA INTEGRA SERVICES E STATUS MONITOR 1 - Integra Services Atenção: o Integra Services está disponível a partir da versão 2.0 do software Urano Integra. O Integra Services é um aplicativo que faz parte

Leia mais

Manual do Visualizador NF e KEY BEST

Manual do Visualizador NF e KEY BEST Manual do Visualizador NF e KEY BEST Versão 1.0 Maio/2011 INDICE SOBRE O VISUALIZADOR...................................................... 02 RISCOS POSSÍVEIS PARA O EMITENTE DA NOTA FISCAL ELETRÔNICA.................

Leia mais

Manual do sistema SMARsa Web

Manual do sistema SMARsa Web Manual do sistema SMARsa Web Módulo Gestão de atividades RS/OS Requisição de serviço/ordem de serviço 1 Sumário INTRODUÇÃO...3 OBJETIVO...3 Bem-vindo ao sistema SMARsa WEB: Módulo gestão de atividades...4

Leia mais

02 - Usando o SiteMaster - Informações importantes

02 - Usando o SiteMaster - Informações importantes 01 - Apresentação do SiteMaster - News Edition O SiteMaster foi desenvolvido para ser um sistema simples de gerenciamento de notícias, instalado em seu próprio computador e com configuração simplificada,

Leia mais

Instalando software MÉDICO Online no servidor

Instalando software MÉDICO Online no servidor Instalando software MÉDICO Online no servidor A máquina denominada Servidora é a que armazenará o banco de dados do software (arquivo responsável pelas informações inseridas), compartilhando com as demais

Leia mais

Caso já seja usuário do SCAW siga as instruções a partir da página X.

Caso já seja usuário do SCAW siga as instruções a partir da página X. Caso já seja usuário do SCAW siga as instruções a partir da página X. Para iniciar o sistema dê um duplo clique no ícone, que se encontra na área de trabalho. 1 Login do sistema. Esta é a tela de login

Leia mais

Objetivo. Este documento tem como objetivo demonstrar o conceito, o processo de instalação e o funcionamento do SITEF (Tef dedicado).

Objetivo. Este documento tem como objetivo demonstrar o conceito, o processo de instalação e o funcionamento do SITEF (Tef dedicado). Sitef - Instalação Objetivo Este documento tem como objetivo demonstrar o conceito, o processo de instalação e o funcionamento do SITEF (Tef dedicado). O que é Sitef? O SiTef (ou tef dedicado) é um conjunto

Leia mais

Procedimentos para Instalação do Sisloc

Procedimentos para Instalação do Sisloc Procedimentos para Instalação do Sisloc Sumário: 1. Informações Gerais... 3 2. Instalação do Sisloc... 3 Passo a passo... 3 3. Instalação da base de dados Sisloc... 16 Passo a passo... 16 4. Instalação

Leia mais

MANUAL DE INSTALAÇÃO DO ODONTO TECHNOLOGY

MANUAL DE INSTALAÇÃO DO ODONTO TECHNOLOGY MANUAL DE INSTALAÇÃO DO ODONTO TECHNOLOGY 1 Índice I - Prefácio...3 II - Instalação do tipo servidor...4 III Obter o nome do computador servidor...17 IV Instalação do tipo cliente...19 V Como inserir a

Leia mais

SUMÁRIO Acesso ao sistema... 2 Atendente... 3

SUMÁRIO Acesso ao sistema... 2 Atendente... 3 SUMÁRIO Acesso ao sistema... 2 1. Login no sistema... 2 Atendente... 3 1. Abrindo uma nova Solicitação... 3 1. Consultando Solicitações... 5 2. Fazendo uma Consulta Avançada... 6 3. Alterando dados da

Leia mais

SISTEMAS OPERACIONAIS LIVRES. Professor Carlos Muniz

SISTEMAS OPERACIONAIS LIVRES. Professor Carlos Muniz SISTEMAS OPERACIONAIS LIVRES Agendar uma tarefa Você deve estar com logon de administrador para executar essas etapas. Se não tiver efetuado logon como administrador, você só poderá alterar as configurações

Leia mais

Manual do Sistema "Vida Controle de Contatos" Editorial Brazil Informatica

Manual do Sistema Vida Controle de Contatos Editorial Brazil Informatica Manual do Sistema "Vida Controle de Contatos" Editorial Brazil Informatica I Vida Controle de Contatos Conteúdo Part I Introdução 2 1 Vida Controle... de Contatos Pessoais 2 Part II Configuração 2 1 Configuração...

Leia mais

FERRAMENTAS DE COLABORAÇÃO CORPORATIVA

FERRAMENTAS DE COLABORAÇÃO CORPORATIVA FERRAMENTAS DE COLABORAÇÃO CORPORATIVA Compartilhamento de Arquivos no Google Drive Sumário (Clique sobre a opção desejada para ir direto à página correspondente) Utilização do Google Grupos Introdução...

Leia mais

Manual Integra S_Line

Manual Integra S_Line 1 Introdução O é uma ferramenta que permite a transmissão Eletrônica de Resultado de Exames, possibilitando aos Prestadores de Serviços (Rede Credenciada), integrarem seus sistemas com os das Operadoras

Leia mais

AP_ Conta Aplicativo para digitação e envio de contas médicas no padrão TISS

AP_ Conta Aplicativo para digitação e envio de contas médicas no padrão TISS AP_ Conta Aplicativo para digitação e envio de contas médicas no padrão TISS Manual de Instalação Tempro Software StavTISS Sumário 1. INTRODUÇÃO... 2 2. REQUISITOS DO SISTEMA... 3 3. INSTALAÇÃO... 4 4.

Leia mais

Vamos criar uma nova Página chamada Serviços. Clique em Adicionar Nova.

Vamos criar uma nova Página chamada Serviços. Clique em Adicionar Nova. 3.5 Páginas: Ao clicar em Páginas, são exibidas todas as páginas criadas para o Blog. No nosso exemplo já existirá uma página com o Título Página de Exemplo, criada quando o WorPress foi instalado. Ao

Leia mais

Fluxo de trabalho do Capture Pro Software: Indexação de OCR e separação de documentos de código de correção

Fluxo de trabalho do Capture Pro Software: Indexação de OCR e separação de documentos de código de correção Este procedimento corresponde ao fluxo de trabalho de Indexação de OCR com separação de código de correção no programa de treinamento do Capture Pro Software. As etapas do procedimento encontram-se na

Leia mais

Sumário: Fluxo Operacional... 3 Contatos... 4. Agenda Online... 10. Reservas de Salas... 26. Tarefas... 42

Sumário: Fluxo Operacional... 3 Contatos... 4. Agenda Online... 10. Reservas de Salas... 26. Tarefas... 42 Sumário: Fluxo Operacional... 3 Contatos... 4 Passo a passo para visualização de contatos... 5 Passo a passo para filtragem da lista de contatos... 6 Como ordenar a lista de contatos... 7 Como gerar uma

Leia mais

Omega Tecnologia Manual Omega Hosting

Omega Tecnologia Manual Omega Hosting Omega Tecnologia Manual Omega Hosting 1 2 Índice Sobre o Omega Hosting... 3 1 Primeiro Acesso... 4 2 Tela Inicial...5 2.1 Área de menu... 5 2.2 Área de navegação... 7 3 Itens do painel de Controle... 8

Leia mais

O Komunik é uma ferramenta de comunicação interna que permite a interação completa entre todos os setores de uma empresa.

O Komunik é uma ferramenta de comunicação interna que permite a interação completa entre todos os setores de uma empresa. ORG 13.8 KOMUNIK O QUE É Manual Estoque - Versão 4.55.001-2ª Edição - 2012 O Komunik é uma ferramenta de comunicação interna que permite a interação completa entre todos os setores de uma empresa. PRA

Leia mais

Manual de configuração do sistema

Manual de configuração do sistema Manual de configuração do sistema (v.1.5.x Beta) Rua México, 119 Sala 2004 Centro Rio de Janeiro, RJ www.doctors-solution.com.br www.simdoctor.com.br contato@simdoctor.com.br Sumário 1. Fazendo seu primeiro

Leia mais

Manual de Utilização COPAMAIL. Zimbra Versão 8.0.2

Manual de Utilização COPAMAIL. Zimbra Versão 8.0.2 Manual de Utilização COPAMAIL Zimbra Versão 8.0.2 Sumário ACESSANDO O EMAIL... 1 ESCREVENDO MENSAGENS E ANEXANDO ARQUIVOS... 1 ADICIONANDO CONTATOS... 4 ADICIONANDO GRUPOS DE CONTATOS... 6 ADICIONANDO

Leia mais

Está apto a utilizar o sistema, o usuário que tenha conhecimentos básicos de informática e navegação na internet.

Está apto a utilizar o sistema, o usuário que tenha conhecimentos básicos de informática e navegação na internet. 1. Descrição Geral Este manual descreve as operações disponíveis no módulo VTWEB Client, cuja finalidade é gerenciar cadastros de funcionários, realização de pedidos e controle financeiro dos pedidos.

Leia mais

MANUAL EXPORTAÇÃO IMPORTAÇÃO

MANUAL EXPORTAÇÃO IMPORTAÇÃO MANUAL EXPORTAÇÃO IMPORTAÇÃO Diretoria de Vigilância Epidemiológica/SES/SC 2006 1 Módulo 04 - Exportação e Importação de Dados Manual do SINASC Módulo Exportador Importador Introdução O Sistema SINASC

Leia mais

1. Escritório Virtual... 5. 1.1. Atualização do sistema...5. 1.2. Instalação e ativação do sistema de Conexão...5

1. Escritório Virtual... 5. 1.1. Atualização do sistema...5. 1.2. Instalação e ativação do sistema de Conexão...5 1 2 Índice 1. Escritório Virtual... 5 1.1. Atualização do sistema...5 1.2. Instalação e ativação do sistema de Conexão...5 1.3. Cadastro do Escritório...5 1.4. Logo Marca do Escritório...6...6 1.5. Cadastro

Leia mais

MANUAL DE UTILIZAÇÃO

MANUAL DE UTILIZAÇÃO MANUAL DE UTILIZAÇÃO Módulo de operação Ativo Bem vindo à Vorage CRM! Nas próximas paginas apresentaremos o funcionamento da plataforma e ensinaremos como iniciar uma operação básica através do nosso sistema,

Leia mais

SSE 3.0 Guia Rápido Parametrizando o SISTEMA DE SECRETARIA Nesta Edição Configurando a Conexão com o Banco de Dados

SSE 3.0 Guia Rápido Parametrizando o SISTEMA DE SECRETARIA Nesta Edição Configurando a Conexão com o Banco de Dados SSE 3.0 Guia Rápido Parametrizando o SISTEMA DE SECRETARIA Nesta Edição 1 Configurando a Conexão com o Banco de Dados 2 Primeiro Acesso ao Sistema Manutenção de Usuários 3 Parametrizando o Sistema Configura

Leia mais

Microsoft Office Outlook Web Access ABYARAIMOVEIS.COM.BR

Microsoft Office Outlook Web Access ABYARAIMOVEIS.COM.BR Microsoft Office Outlook Web Access ABYARAIMOVEIS.COM.BR 1 Índice: 01- Acesso ao WEBMAIL 02- Enviar uma mensagem 03- Anexar um arquivo em uma mensagem 04- Ler/Abrir uma mensagem 05- Responder uma mensagem

Leia mais

INTRODUÇÃO 2 ACESSO AO SIGTECWEB 3 TEMPO DE CONEXÃO 5 NAVEGAÇÃO 7 BARRA DE AÇÕES 7 COMPORTAMENTO DOS BOTÕES 7 FILTROS PARA PESQUISA 8

INTRODUÇÃO 2 ACESSO AO SIGTECWEB 3 TEMPO DE CONEXÃO 5 NAVEGAÇÃO 7 BARRA DE AÇÕES 7 COMPORTAMENTO DOS BOTÕES 7 FILTROS PARA PESQUISA 8 ÍNDICE INTRODUÇÃO 2 ACESSO AO SIGTECWEB 3 TEMPO DE CONEXÃO 5 NAVEGAÇÃO 7 BARRA DE AÇÕES 7 COMPORTAMENTO DOS BOTÕES 7 FILTROS PARA PESQUISA 8 ACESSO ÀS FERRAMENTAS 9 FUNÇÕES 12 MENSAGENS 14 CAMPOS OBRIGATÓRIOS

Leia mais

Manual do AP_Conta. Manual do AP_Conta. Aplicativo para digitação e envio de contas médicas no padrão TISS

Manual do AP_Conta. Manual do AP_Conta. Aplicativo para digitação e envio de contas médicas no padrão TISS 2014 Manual do AP_Conta Aplicativo para digitação e envio de contas médicas no padrão TISS 0 Sumário 1. Sobre esse manual... 3 2. Habilitando e Configurando o AP_Conta... 4 3. Habilitação e Licenciamento...

Leia mais

Manual Administrador - Mídia System

Manual Administrador - Mídia System Manual Administrador - Mídia System Logo após cadastrarmos sua Empresa em nosso sistema, será enviado um e-mail confirmando as informações de acesso do Administrador do sistema. Obs: Caso não tenha recebido

Leia mais

Revisão: Introdução. - Integração com o AutoManager; 1 Atualização de versão do banco de dados PostgreSQL

Revisão: Introdução. - Integração com o AutoManager; 1 Atualização de versão do banco de dados PostgreSQL Urano Indústria de Balanças e Equipamentos Eletrônicos Ltda. Rua Irmão Pedro 709 Vila Rosa Canoas RS Fone: (51) 3462.8700 Fax: (51) 3477.4441 Características do Software Urano Integra 2.2 Data: 12/05/2014

Leia mais

Sistema de Instalação e Criação da Estrutura do Banco de Dados MANUAL DO INSTALADOR. Julho/2007. Ministério da saúde

Sistema de Instalação e Criação da Estrutura do Banco de Dados MANUAL DO INSTALADOR. Julho/2007. Ministério da saúde Sistema de Instalação e Criação da Estrutura do Banco de Dados MANUAL DO INSTALADOR Julho/2007 Ministério da saúde SUMÁRIO Módulo 1. Instalação... 4 Introdução... 4 Configurações de equipamentos para instalação

Leia mais

MANUAL DO ANIMAIL 1.0.0.1142 Terti Software

MANUAL DO ANIMAIL 1.0.0.1142 Terti Software O Animail é um software para criar campanhas de envio de email (email Marketing). Você pode criar diversas campanhas para públicos diferenciados. Tela Principal do sistema Para melhor apresentar o sistema,

Leia mais

Lição 1 - Criação de campos calculados em consultas

Lição 1 - Criação de campos calculados em consultas 1 de 5 21-08-2011 22:15 Lição 1 - Criação de campos calculados em consultas Adição de Colunas com Valores Calculados: Vamos, inicialmente, relembrar, rapidamente alguns conceitos básicos sobre Consultas

Leia mais

Vamos criar uma nova Página chamada Serviços. Clique em Adicionar Nova.

Vamos criar uma nova Página chamada Serviços. Clique em Adicionar Nova. 3.5 Páginas: Ao clicar em Páginas, são exibidas todas as páginas criadas para o Blog. No nosso exemplo já existirá uma página com o Título Página de Exemplo, criada quando o WorPress foi instalado. Ao

Leia mais

Cenários do CEL. Acessar ao sistema

Cenários do CEL. Acessar ao sistema Cenários do CEL Acessar ao sistema Permitir que o usuário acesse ao Sistema de Léxicos e Cenários nas seguintes condições: logando-se, quando já estiver cadastrado; ou incluindo usuário independente, quando

Leia mais

Procedimentos para Instalação do SISLOC

Procedimentos para Instalação do SISLOC Procedimentos para Instalação do SISLOC Sumário 1. Informações Gerais...3 2. Instalação do SISLOC...3 Passo a passo...3 3. Instalação da Base de Dados SISLOC... 11 Passo a passo... 11 4. Instalação de

Leia mais

BEM-VINDO AO dhl PROVIEW

BEM-VINDO AO dhl PROVIEW BEM-VINDO AO dhl PROVIEW Guia de Usuário O DHL PROVIEW COLOCA VOCÊ NO CONTROLE DE SEUS ENVIOS. PROVIEW O DHL ProView é uma ferramenta de rastreamento on-line que permite o gerenciamento dos envios, a programação

Leia mais

Programação Orientada a Objetos com PHP & MySQL Sistema Gerenciador de Banco de Dados: Introdução e configuração de bases de dados com Postgre e MySQL

Programação Orientada a Objetos com PHP & MySQL Sistema Gerenciador de Banco de Dados: Introdução e configuração de bases de dados com Postgre e MySQL Programação Orientada a Objetos com PHP & MySQL Sistema Gerenciador de Banco de Dados: Introdução e configuração de bases de dados com Postgre e MySQL Prof. MSc. Hugo Souza Iniciando nossas aulas sobre

Leia mais

www.neteye.com.br NetEye Guia de Instalação

www.neteye.com.br NetEye Guia de Instalação www.neteye.com.br NetEye Guia de Instalação Índice 1. Introdução... 3 2. Funcionamento básico dos componentes do NetEye...... 3 3. Requisitos mínimos para a instalação dos componentes do NetEye... 4 4.

Leia mais

Figura 1: tela inicial do BlueControl COMO COLOCAR A SALA DE INFORMÁTICA EM FUNCIONAMENTO?

Figura 1: tela inicial do BlueControl COMO COLOCAR A SALA DE INFORMÁTICA EM FUNCIONAMENTO? Índice BlueControl... 3 1 - Efetuando o logon no Windows... 4 2 - Efetuando o login no BlueControl... 5 3 - A grade de horários... 9 3.1 - Trabalhando com o calendário... 9 3.2 - Cancelando uma atividade

Leia mais

Manual. ID REP Config Versão 1.0

Manual. ID REP Config Versão 1.0 Manual ID REP Config Versão 1.0 Sumário 1. Introdução... 3 2. Pré-Requisitos... 3 3. Instalação do ID REP Config... 4 4. Visão Geral do Programa... 8 4.1. Tela Principal... 8 4.2. Tela de Pesquisa... 12

Leia mais

Manual do Google agenda. criação e compartilhamento de agendas

Manual do Google agenda. criação e compartilhamento de agendas Manual do Google agenda criação e compartilhamento de agendas 1 O que é o Google Agenda? Google Agenda é um serviço de agenda on line gratuito do Google, onde você pode anotar compromissos e tarefas, organizando

Leia mais

FERRAMENTAS DE COLABORAÇÃO CORPORATIVA

FERRAMENTAS DE COLABORAÇÃO CORPORATIVA FERRAMENTAS DE COLABORAÇÃO CORPORATIVA Manual de Utilização Google Grupos Sumário (Clique sobre a opção desejada para ir direto à página correspondente) Utilização do Google Grupos Introdução... 3 Página

Leia mais

Operações de Caixa. Versão 2.0. Manual destinado à implantadores, técnicos do suporte e usuários finais

Operações de Caixa. Versão 2.0. Manual destinado à implantadores, técnicos do suporte e usuários finais Operações de Caixa Versão 2.0 Manual destinado à implantadores, técnicos do suporte e usuários finais Sumário Introdução... 3 Suprimento... 3 Sangria... 4 Abertura de Caixa... 6 Fechamento de Caixa...

Leia mais

Instalação: permite baixar o pacote de instalação do agente de coleta do sistema.

Instalação: permite baixar o pacote de instalação do agente de coleta do sistema. O que é o projeto O PROINFODATA - programa de coleta de dados do projeto ProInfo/MEC de inclusão digital nas escolas públicas brasileiras tem como objetivo acompanhar o estado de funcionamento dos laboratórios

Leia mais

Principais Novidades Abril/2013 a Junho/2013

Principais Novidades Abril/2013 a Junho/2013 Principais Novidades Abril/2013 a Junho/2013 Sumário 1. Ambiente Group Shopping... 3 2. Alteração na Tela de Contratos e Controle de Edições... 7 3. Propagação de Contratos... 10 4. Configuração de Impressora

Leia mais

Manual de Atualização Versão 3.6.4.

Manual de Atualização Versão 3.6.4. Manual de Atualização Versão 3.6.4. Sumário 1. AVISO... 1 2. INTRODUÇÃO... 2 3. PREPARAÇÃO PARA ATUALIZAÇÃO... 3 4. ATUALIZANDO GVCOLLEGE E BASE DE DADOS... 7 5. HABILITANDO NOVAS VERSÕES DO SISTEMA....

Leia mais

CONSTRUÇÃO DE BLOG COM O BLOGGER

CONSTRUÇÃO DE BLOG COM O BLOGGER CONSTRUÇÃO DE BLOG COM O BLOGGER Blog é uma abreviação de weblog, qualquer registro frequênte de informações pode ser considerado um blog (últimas notícias de um jornal online por exemplo). A maioria das

Leia mais

Manual SAGe Versão 1.2 (a partir da versão 12.08.01)

Manual SAGe Versão 1.2 (a partir da versão 12.08.01) Manual SAGe Versão 1.2 (a partir da versão 12.08.01) Submissão de Relatórios Científicos Sumário Introdução... 2 Elaboração do Relatório Científico... 3 Submissão do Relatório Científico... 14 Operação

Leia mais

2 de maio de 2014. Remote Scan

2 de maio de 2014. Remote Scan 2 de maio de 2014 Remote Scan 2014 Electronics For Imaging. As informações nesta publicação estão cobertas pelos termos dos Avisos de caráter legal deste produto. Conteúdo 3 Conteúdo...5 Acesso ao...5

Leia mais

Obs: É necessário utilizar um computador com sistema operacional Windows 7.

Obs: É necessário utilizar um computador com sistema operacional Windows 7. Instalando os Pré-Requisitos Os arquivos dos 'Pré-Requisitos' estão localizados na pasta Pré-Requisitos do CD HyTracks que você recebeu. Os arquivos também podem ser encontrados no servidor. (www.hytracks.com.br/pre-requisitos.zip).

Leia mais

PAINEL GERENCIADOR DE E-MAILS

PAINEL GERENCIADOR DE E-MAILS Este manual foi criado com o objetivo de facilitar o gerenciamento de suas contas de e-mail. Com ele, o administrador poderá criar e excluir e-mails, alterar senha, configurar redirecionamento de contas,

Leia mais

CONFIGURAÇÃO MINIMA EXIGIDA:

CONFIGURAÇÃO MINIMA EXIGIDA: Este tutorial parte do princípio que seu usuário já possua conhecimentos básicos sobre hardware, sistema operacional Windows XP ou superior, firewall, protocolo de rede TCP/IP e instalação de software.

Leia mais

Escritório Virtual Administrativo

Escritório Virtual Administrativo 1 Treinamento Módulos Escritório Virtual Administrativo Sistema Office Instruções para configuração e utilização do módulo Escritório Virtual e módulo Administrativo do sistema Office 2 3 1. Escritório

Leia mais

www.nddigital.com.br Manual de Administração DPS Printer 2.1 NDDigital S/A - Software

www.nddigital.com.br Manual de Administração DPS Printer 2.1 NDDigital S/A - Software www.nddigital.com.br Manual de Administração DPS Printer 2.1 NDDigital S/A - Software 2 Introdução Este manual foi elaborado para administradores, para entendimento do funcionamento do produto e administração

Leia mais

MÓDULO 5 Movimentações

MÓDULO 5 Movimentações MÓDULO 5 Movimentações Bem-vindo(a) ao quinto módulo do curso. Agora que você já conhece as entradas no HÓRUS, aprenderá como são feitas as movimentações. As movimentações do HÓRUS são: Requisição ao Almoxarifado:

Leia mais

Síntese das discussões do fórum Livro-APF: Julho/2010

Síntese das discussões do fórum Livro-APF: Julho/2010 Síntese das discussões do fórum Livro-APF: Julho/2010 Assunto: Estimativa de Aumento de Produtividade Data: 01/07/2010 Link: http://br.groups.yahoo.com/group/livro-apf/message/2577 Dúvida: Existe alguma

Leia mais

GERENCIADOR DE CONTEÚDO

GERENCIADOR DE CONTEÚDO 1/1313 MANUAL DO USUÁRIO GERENCIADOR DE CONTEÚDO CRISTAL 2/13 ÍNDICE 1. OBJETIVO......3 2. OPERAÇÃO DOS MÓDULOS......3 2.1 GERENCIADOR DE CONTEÚDO......3 2.2 ADMINISTRAÇÃO......4 Perfil de Acesso:... 4

Leia mais

Como funciona? SUMÁRIO

Como funciona? SUMÁRIO SUMÁRIO 1. Introdução... 2 2. Benefícios e Vantagens... 2 3. Como utilizar?... 2 3.1. Criar Chave / Senha de Usuário... 2 3.2. Recursos da Barra Superior... 2 3.2.1. Opções... 3 3.2.1.1. Mover Para...

Leia mais

Programação Orientada a Objetos com PHP & MySQL Cookies e Sessões. Prof. MSc. Hugo Souza

Programação Orientada a Objetos com PHP & MySQL Cookies e Sessões. Prof. MSc. Hugo Souza Programação Orientada a Objetos com PHP & MySQL Cookies e Sessões Prof. MSc. Hugo Souza Se você precisar manter informações sobre seus usuários enquanto eles navegam pelo seu site, ou até quando eles saem

Leia mais

Fox Gerenciador de Sistemas

Fox Gerenciador de Sistemas Fox Gerenciador de Sistemas Índice 1. FOX GERENCIADOR DE SISTEMAS... 4 2. ACESSO AO SISTEMA... 5 3. TELA PRINCIPAL... 6 4. MENU SISTEMAS... 7 5. MENU SERVIÇOS... 8 5.1. Ativação Fox... 8 5.2. Atualização

Leia mais

Índice. Para encerrar um atendimento (suporte)... 17. Conversa... 17. Adicionar Pessoa (na mesma conversa)... 20

Índice. Para encerrar um atendimento (suporte)... 17. Conversa... 17. Adicionar Pessoa (na mesma conversa)... 20 Guia de utilização Índice Introdução... 3 O que é o sistema BlueTalk... 3 Quem vai utilizar?... 3 A utilização do BlueTalk pelo estagiário do Programa Acessa Escola... 5 A arquitetura do sistema BlueTalk...

Leia mais

MANUAL DE UTILIZAÇÃO MASTER VENDAS

MANUAL DE UTILIZAÇÃO MASTER VENDAS MANUAL DE UTILIZAÇÃO MASTER VENDAS 1. CONCEITO Master Vendas não é somente um sistema, e sim, um novo conceito de gestão para sua empresa. Foi desenvolvido por profissionais de informática juntamente com

Leia mais

CONTRA CONTROLE DE ACESSOS E MODULARIZADOR DE SISTEMAS

CONTRA CONTROLE DE ACESSOS E MODULARIZADOR DE SISTEMAS MINISTÉRIO DO DESENVOLVIMENTO AGRÁRIO SUBSECRETARIA DE PLANEJAMENTO, ORÇAMENTO E ADMINISTRAÇÃO COORDENAÇÃO-GERAL DE MODERNIZAÇÃO E INFORMÁTICA CONTRA CONTROLE DE ACESSOS E MODULARIZADOR DE SISTEMAS MANUAL

Leia mais

Guia de boas práticas para realização de Backup

Guia de boas práticas para realização de Backup Objetivo Quando o assunto é backup de dados, uma proposição de atividades e procedimentos como sendo a melhor prática pode ser bastante controversa. O que permanece verdadeiro, porém, é que seguir algumas

Leia mais

Manual Comunica S_Line

Manual Comunica S_Line 1 Introdução O permite a comunicação de Arquivos padrão texto entre diferentes pontos, com segurança (dados criptografados e com autenticação) e rastreabilidade, isto é, um CLIENTE pode receber e enviar

Leia mais

Sumário. Tutorial: Editor de Exercícios Online para o professor

Sumário. Tutorial: Editor de Exercícios Online para o professor 1 Sumário Inserir Exercícios... 4 Minhas Avaliações... 5 Cadastrar perguntas... 7 Inserindo imagens... 10 Inserindo arquivos... 13 Inserindo vídeos... 15 Gerenciador de fórmulas e equações matemáticas...

Leia mais

Banco de Dados Microsoft Access: Criar tabelas. Vitor Valerio de Souza Campos

Banco de Dados Microsoft Access: Criar tabelas. Vitor Valerio de Souza Campos Banco de Dados Microsoft Access: Criar tabelas Vitor Valerio de Souza Campos Objetivos do curso 1. Criar uma tabela no modo de exibição Folha de Dados. 2. Definir tipos de dados para os campos na tabela.

Leia mais

SISTEMA DE PRODUTOS E SERVIÇOS CERTIFICADOS. MÓDULO DO CERTIFICADOR MANUAL DE OPERAÇÃO Versão 2.4.6

SISTEMA DE PRODUTOS E SERVIÇOS CERTIFICADOS. MÓDULO DO CERTIFICADOR MANUAL DE OPERAÇÃO Versão 2.4.6 SISTEMA DE PRODUTOS E SERVIÇOS CERTIFICADOS Versão 2.4.6 Sumário Fluxograma básico do processo de envio de remessa... 5 Criar novo certificado... 6 Aprovar certificado... 16 Preparar e enviar remessa...

Leia mais

OCOMON PRIMEIROS PASSOS

OCOMON PRIMEIROS PASSOS OCOMON PRIMEIROS PASSOS O OCOMON ainda não possui um arquivo de Help para atender a todas questões relacionadas ao sistema. Esse arquivo serve apenas para dar as principais instruções para que você tenha

Leia mais

CRIANDO TEMPLATES E LEGENDAS

CRIANDO TEMPLATES E LEGENDAS CRIANDO TEMPLATES E LEGENDAS Este tutorial tem como objetivo instruir passo à passo como criar templates de peças, utilizar os novos recursos de cadastro de propriedade de peças e criação de legenda. 1-

Leia mais

Portaria Express 3.0

Portaria Express 3.0 Portaria Express 3.0 A portaria do seu condomínio mais segura e eficiente. Com a preocupação cada vez mais necessária de segurança nos condomínio e empresas, investe-se muito em segurança. Câmeras, cercas,

Leia mais

Google Drive. Passos. Configurando o Google Drive

Google Drive. Passos. Configurando o Google Drive Google Drive um sistema de armazenagem de arquivos ligado à sua conta Google e acessível via Internet, desta forma você pode acessar seus arquivos a partir de qualquer dispositivo que tenha acesso à Internet.

Leia mais

1- Requisitos mínimos. 2- Instalando o Acesso Full. 3- Iniciando o Acesso Full pela primeira vez

1- Requisitos mínimos. 2- Instalando o Acesso Full. 3- Iniciando o Acesso Full pela primeira vez Manual Conteúdo 1- Requisitos mínimos... 2 2- Instalando o Acesso Full... 2 3- Iniciando o Acesso Full pela primeira vez... 2 4- Conhecendo a barra de navegação padrão do Acesso Full... 3 5- Cadastrando

Leia mais

O programa Mysql acompanha o pacote de instalação padrão e será instalado juntamente com a execução do instalador.

O programa Mysql acompanha o pacote de instalação padrão e será instalado juntamente com a execução do instalador. INTRODUÇÃO O Programa pode ser instalado em qualquer equipamento que utilize o sistema operacional Windows 95 ou superior, e seu banco de dados foi desenvolvido em MySQL, sendo necessário sua pré-instalação

Leia mais

Aula 01 - Formatações prontas e condicionais. Aula 01 - Formatações prontas e condicionais. Sumário. Formatar como Tabela

Aula 01 - Formatações prontas e condicionais. Aula 01 - Formatações prontas e condicionais. Sumário. Formatar como Tabela Aula 01 - Formatações prontas e Sumário Formatar como Tabela Formatar como Tabela (cont.) Alterando as formatações aplicadas e adicionando novos itens Removendo a formatação de tabela aplicada Formatação

Leia mais

Serviço Público Federal Universidade Federal do Pará - UFPA Centro de Tecnologia da Informação e Comunicação - CTIC S I E

Serviço Público Federal Universidade Federal do Pará - UFPA Centro de Tecnologia da Informação e Comunicação - CTIC S I E Serviço Público Federal Universidade Federal do Pará - UFPA Centro de Tecnologia da Informação e Comunicação - CTIC S I E SISTEMA DE INFORMAÇÕES PARA O ENSINO (*) Módulo: Produção Institucional Guia de

Leia mais

SISTEMAS OPERACIONAIS LIVRES. Professor Carlos Muniz

SISTEMAS OPERACIONAIS LIVRES. Professor Carlos Muniz SISTEMAS OPERACIONAIS LIVRES Professor Carlos Muniz Atualizar um driver de hardware que não está funcionando adequadamente Caso tenha um dispositivo de hardware que não esteja funcionando corretamente

Leia mais

V.1.0 SIAPAS. Sistema Integrado de Administração ao Plano de Assistência à Saúde. Contas Médicas

V.1.0 SIAPAS. Sistema Integrado de Administração ao Plano de Assistência à Saúde. Contas Médicas 2014 V.1.0 SIAPAS Sistema Integrado de Administração ao Plano de Assistência à Saúde Contas Médicas SIAPAS Sistema Integrado de Administração ao Plano de Assistência à Saúde Módulos CONTAS MÉDICAS Capa

Leia mais

Cadastramento de Computadores. Manual do Usuário

Cadastramento de Computadores. Manual do Usuário Cadastramento de Computadores Manual do Usuário Setembro 2008 ÍNDICE 1. APRESENTAÇÃO 1.1 Conhecendo a solução...03 Segurança pela identificação da máquina...03 2. ADERINDO À SOLUÇÃO e CADASTRANDO COMPUTADORES

Leia mais

Agendamento para Importação de Notas Fiscais

Agendamento para Importação de Notas Fiscais LIBERAÇÃO DE ATUALIZAÇÃO CORDILHEIRA VERSÃO 2 (Orientamos aos clientes que utilizam banco de dados SQL, para efetuarem a atualização preferencialmente após o encerramento das atividades do dia, acessando

Leia mais

Iniciação à Informática

Iniciação à Informática Meu computador e Windows Explorer Justificativa Toda informação ou dado trabalhado no computador, quando armazenado em uma unidade de disco, transforma-se em um arquivo. Saber manipular os arquivos através

Leia mais

Oficina de Inclusão Tecnológica Windows Live Skydrive

Oficina de Inclusão Tecnológica Windows Live Skydrive 1 Windows Live Skydrive Fonte imagem: blogaomobile.org Ementa: O windows Live Skydrive apresenta a possibilidade da computação em nuvem, que permite ao usuário armazenar arquivos online, de forma a não

Leia mais

Gerenciamento de Arquivos e Pastas. Professor: Jeferson Machado Cordini jmcordini@hotmail.com

Gerenciamento de Arquivos e Pastas. Professor: Jeferson Machado Cordini jmcordini@hotmail.com Gerenciamento de Arquivos e Pastas Professor: Jeferson Machado Cordini jmcordini@hotmail.com Arquivo Todo e qualquer software ou informação gravada em nosso computador será guardada em uma unidade de disco,

Leia mais

3. No painel da direita, dê um clique com o botão direito do mouse em qualquer espaço livre (área em branco).

3. No painel da direita, dê um clique com o botão direito do mouse em qualquer espaço livre (área em branco). Permissões de compartilhamento e NTFS - Parte 2 Criando e compartilhando uma pasta - Prática Autor: Júlio Battisti - Site: www.juliobattisti.com.br Neste tópico vamos criar e compartilhar uma pasta chamada

Leia mais

Criando Banco de Dados, Tabelas e Campos através do HeidiSQL. Prof. Vitor H. Migoto de Gouvêa Colégio IDESA 2011

Criando Banco de Dados, Tabelas e Campos através do HeidiSQL. Prof. Vitor H. Migoto de Gouvêa Colégio IDESA 2011 Criando Banco de Dados, Tabelas e Campos através do HeidiSQL Prof. Vitor H. Migoto de Gouvêa Colégio IDESA 2011 Edição 2 Pedreiros da Informação Criando Banco de Dados, Tabelas e Campos através do HeidiSQL

Leia mais

Configurando o IIS no Server 2003

Configurando o IIS no Server 2003 2003 Ser ver Enterprise Objetivo Ao término, você será capaz de: 1. Instalar e configurar um site usando o IIS 6.0 Configurando o IIS no Server 2003 Instalando e configurando o IIS 6.0 O IIS 6 é o aplicativo

Leia mais