EDITORIAL Editorial THE CLUB Av. Celso Ferreira da Silva, 190 Jd. Europa - Avaré - SP - CEP 18.707-150 Informações: (0xx14) 3732-3689 Suporte: (0xx14) 3733-1588 - Fax: (0xx14) 3732-0987 Internet http://www.theclub.com.br Cadastro: [email protected] Suporte: [email protected] Informações: [email protected] Dúvidas Correspondência ou fax com dúvidas devem ser enviados ao - THE CLUB, indicando "Suporte". Opinião Se você quer dar a sua opinião sobre o clube em geral, mande a sua correspondência para a seção "Tire sua dúvida". Reprodução A utilização, reprodução, apropriação, armazenamento em banco de dados, sob qualquer forma ou meio, de textos, fotos e outras criações intelectuais em cada publicação da Revista “The Club” são terminantemente proibidos sem autorização escrita dos titulares dos direitos autorais. Olá amigos, Vocês estão recebendo mais uma edição da revista The Club Megazine, recheada de informações importantes para manter-lhes sempre atualizados. Começamos com mais um artigo do nosso amigo Marcelo Nogueira, onde ele apresenta o ITIL (Information Technology Infrastructure Library), que é o modelo de referência para gerenciamento de processos de TI mais aceito no mundo. Atendendo várias solicitações, nossos amigos Victory Fernandes e Augusto Frederico prepararam um excelente artigo sobre Impressão de Código de Barras utilizando impressoras ZEBRA, não deixe de conferir. Se você necessita desenvolver para a plataforma Microsoft .NET sem gastar nenhum centavo, não deixe de conferir o artigo “Um estranho no ninho” onde nosso amigo Emerson Facunte apresenta a ferramenta: Microsoft Visual C# 2005 Express, uma excelente IDE totalmente gratuita! Falando em .NET, não podemos deixar de lado o poderoso Delphi 2005 onde nosso consultor Claudinei Rodrigues apresenta algumas dicas sobre impressão em aplicações WinForms. Já que o assunto é relatório, nosso consultor Alessandro Ferreira demonstra em seu artigo como construir um relatório CrossTab (referência cruzada) utilizando o Rave Reports, gerador presente a partir do Delphi 7. E fechando esta edição, trazemos a última parte da série sobre ASP.NET onde abordamos os arquivos Global.asax/pas e o web.config, não deixe de conferir a importância destes arquivos. Boa leitura à todos e até a próxima. Copyright© The Club® 2005 Impressão e acabamento: Celso Jefferson Paganelli GRAFILAR Presidente The Club Tel.: (0xx14) 3841-2587 - Fax: (0xx14) 3841-3346 Rua Cel. Amando Simôes, 779 - Cep 18.650-000 São Manuel - SP Tiragem: 5.000 exemplares Diretor - Presidente Celso Jefferson M. Paganelli Diretor Técnico Mauro Sant’Anna Colaboradores Emerson Facunte, Marcelo Nogueira Victory Fernandes e Augusto Frederico Delphi é marca registrada da Borland International, as demais marcas citadas são registradas pelos seus respectivos proprietários. Editorial ..................................................................................................... 03 Perguntas & Respostas ........................................................................... 04 Gestão de infraestrutura de tecnologia da informação com ITL .......... 05 Impressão de Código de Barras Uma abordagem prática ZEBRA ZPL2 .................................................... 09 Um estranho no ninho Ferramenta gratuita invade o mundo dos Delphianos .......................... 13 Imprimindo no Delphi 2005 ...................................................................... 16 Construindo um relatório CrossTab no Rave Reports .......................... 20 ASP.NET: Parte III ....................................................................................... 26 Dicas & Truques ....................................................................................... 30 MeGAZINE 3 Perguntas & Respostas Perguntas & Respostas Pergunta: Gostaria de verificar se uma pasta existe no Windows via Clipper, isso é possível? mesma máquina, basta instalar o Firebird 1.5, NÃO gerar a cópia da GDS32.DLL (para não sobrepor a versão do Interbase já instalado) e depois mudar a PORTA de comunicação do Firebird. Resposta: Isso poderá ser feito utilizando a função Directory, conforme demonstra o exemplo a seguir: Para alterar a porta de comunicação do Firebird, abra o arquivo Firebird.conf (via um editor de textos qualquer) e localize a seguinte linha: cPath = “C:\WINDOWS\” aDir := Directory( cPath + “*.*” ) lIsDir := Valtype( aDir ) == “A” .And. !Empty( aDir ) if lIsDir ? “Existe” else ? “Não existe!” end if Dúvida enviada por Bkr Informática Ltda, Chiapetta/RS. Pergunta: É possível desabilitar a barra de tarefas do Windows? Se possível, envie-nos um exemplo. Resposta: Isso é possível efetuando uma pesquisa pelo handle da janela referente a barra de tarefas e depois desabilita a janela via API EnableWindow, veja a seguir: var H: hwnd; begin H := FindWindow(‘Shell_traywnd’, nil); EnableWindow(H, FALSE); // disable it end; # —————————————— # TCP Protocol Settings # # # The TCP Service name/Port number to be used for client database # connections. # # It is only necessary to change one of the entries, not both. The # order of precendence is the ‘RemoteServiceName’ (if an entry is # found in the ‘services.’ file) then the ‘RemoteServicePort’. # # Type: string, integer # #RemoteServiceName = gds_db #RemoteServicePort = 3050 Tire o comentário (#) antes de RemoteServicePort e altere o valor para 3051, por exemplo. Em seu componente SQLConnection, no parâmetro VENDORLIB, altere para: FbClient.dll Dúvida enviada por Almir R. Borges, Araçatuba/SP. E a partir disso, você não irá se referir mais a GDS32.DLL e sim a FBCLIENT.DLL, ou seja, ao invés de compartilhar na pasta a GDS32.DLL, deverá disponibilizar a FBCLIENT.DLL. Pergunta: Como faço para rodar o Firebird 1.5 e o Dessa forma terá o Interbase e o Firebird rodando s/ problemas. Interbase em um mesmo servidor? Resposta: Para rodar o Interbase e o Firebird 1.5 na 4 Dúvida enviada por Júlio Cezar de Jesus Rodrigues, Curitiba/PR. MeGAZINE Delphi Gestão Gestão de de infraestrutura infraestrutura de de tecnologia tecnologia da da informação informação com com ITIL ITIL Por Marcelo Nogueira Resumo - O ITIL (Information Technology Infrastructure Library) é o modelo de referência para gerenciamento de processos de TI mais aceito mundialmente. A metodologia foi criada pela secretaria de comércio (Office of Government Commerce, OGC) do governo Inglês, a partir de pesquisas realizadas por Consultores, Especialistas e Doutores, para desenvolver as melhores práticas para a gestão da área de TI nas empresas privadas e públicas. Atualmente se tornou a norma BS-15000, sendo esta um anexo da ISO 9000/2000. O foco deste modelo é descrever os processos necessários para gerenciar a infra-estrutura de TI eficientemente e eficazmente de modo a garantir os níveis de serviço acordados com os clientes internos e externos. Palavras-chave: ITIl, . · Alinha a estratégia de TI com as do negócio. · Mais capacidade e agilidade para novos modelos de negócios ou ajustes nos modelos atuais; · Explicita a relação entre aumento nos custos de TI e aumento no valor da informação; · Mantém os riscos do negócio sob controle; · Explicita a importância da TI na continuidade dos negócios; · Mede e melhora continuamente a performance de TI. BS 15000 A governança permite controlar, medir, auditar, a execução e a qualidade dos serviços e: [2] A especificação para Gestão dos Serviços e Processos de Tecnologia da Informação (TI ) – BS 15000 , foi preparado pelo Comitê Técnico BDD/3 do Instituto de Padronização Britânico (BSI). [3] O comitê técnico BDD/3, composto pela British Computer Society (BCS), Central Computer and Telecommunications (CCTA), IT Service Management Forum (itSMF), National Audit (NAO) e alguns colaboradores ,foi responsável pela emissão da especificação em 15 de Novembro de 2000. [3] O modelo especificado é aplicável na gestão dos serviços e processos de TI, além desta aplicação ela pode ser utilizada para: · As organizações buscarem propostas para outsource dos serviços; · Organizações que requerem um acesso consistente para todos os provedores de serviços em uma cadeia de fornecimento (supply chain); · Benchmark da gestão dos serviços de TI dos provedores existentes; · Viabiliza o acompanhamento de contratos internos e externos da organização. · Define condições para o exercício eficaz da gestão com base em conceitos consolidados de qualidade. · Base formal para certificação. O relacionamento entre os diferentes processos de gestão, planejamento do serviço e os processos de gestão considerados nesta norma são mostrados na ilustração a seguir: [3] Introdução - Governança de TI Governança de tecnologia da Informação é uma estrutura de relacionamentos e processos para dirigir e controlar a organização no atingimento dos objetivos desta organização, adicionando valor, ao mesmo tempo em que equilibra os riscos em relação ao retorno da TI e seus processos. [2] São estruturas e processos visando a garantir que a TI suporte e maximize os objetivos e estratégias da organização. [2] MeGAZINE 5 Delphi PLANEJAMENTO DO SERVIÇO E GESTÃO DOS PROCESSOS Gerenciamento da segurança Gerenciamento das habilidades Gerenciamento do nível do serviço Relatório do serviço Eficácia e Continuidade do serviço Administração financeira CONTROLE DE PROCESSOS Gerenciamento das configurações PROCESSOS DE LIBERAÇÃO Gerenciamento das modificações Gerenciamento das versões PROCESSOS DE RELACIONAMENTO Gerenciamento dos Incidentes Gerenciamento do Relacionamento dos negócios Gerenciamento dos problemas Gerenciamento dos fornecedores PROCESSOS DE DECISÃO AUTOMAÇÃO no documento DISC PD 005, como, por exemplo, temos “métrica”, que está definido como o elemento mensurável da função ou processo do serviço. A partir do item 4 ao item 9 temos a descrição do modelo de gestão, para a Gestão dos Serviços e Processos de Tecnologia da Informação (TI ). No item 4 da norma foram detalhados os limites da gestão de serviços. Estes limites devem ser definidos de acordo com as características de cada organização, sua localização, seus ativos e a tecnologia empregada.Dentro destes limites estão Figura 1 - Processo de gestão e planejamento do serviço. definidos: [3] Os relacionamentos entre os diferentes processos de gestão e planejamento dos serviços foram mostrados acima, agora é interessante conhecermos como a versão 2000 desta norma está organizada. A seguir será mostrado como está organizada a norma: · O direcionamento e os recursos necessários para implementação da gestão dos serviços de TI; · As competências necessárias para os profissionais que executam atividades nesta área; · Como deve ser evidenciada a melhoria continua da qualidade dos serviços; · Como devem ser executadas as auditorias; · Como deve ser demonstrada a conformidade dos objetivos da gestão dos serviços. Tabela 1 - Conteúdo da norma bs 15000 ITEM DESCRIÇÃO 1 ESCOPO 2 REFERENCIAS NORMATIVAS 3 DEFINIÇÕES 4 PRINCIPIO GERAL 5 GESTÃO E PROJETO DO SERVIÇO 6 PROCESSOS DE RELACIONAMENTO 7 PROCESSOS DE DECISÃO 8 CONTROLE DE PROCESSO 9 GERENCIAMENTO DAS VERSÕES No item número 5 (que é dedicado a gestão e o planejamento do serviço) está definido o nível de gestão do serviço.Isto pode ser traduzido: · Como é usada eficazmente a gestão para a tradução e a integração dos requisitos solicitados; · Como a organização assegura a continuidade dos serviços; · Como a organização produz informações para a tomada de decisões; · Como é controlado e calculado o custo para provisão e recuperação dos serviços; · A competência da gestão da organização. ANEXO A (INFORMATIVO) OUTRAS FONTES DE INFORMAÇÕES BIBLIOGRAFIA O escopo, que compreende o item número 1 desta norma, foi mostrado no inicio deste artigo. O item a seguir indica que a BS 15000 está referenciando itens do documento DISC PD 005 (Code of Practice for IT Service Management). O item número 3 algumas definições que não estão definidas 6 No item 5 , destaca-se a utilização do SLA ( Service Level Agreement ), como ferramenta para obtenção do entendimento entre o provedor do serviço e um cliente que documenta e define o nível do serviço desejado. No item 6 , dedicado ao Processo de Relacionamento estão detalhados os processos para gerar e manter um bom relacionamento entre o provedor de serviço e o cliente. Este relacionamento é baseado no entendimento do cliente e o MeGAZINE Delphi direcionamento de seu negócio.O relacionamento descrito é traduzido: · Na gestão do relacionamento dos negócios; · Na gestão dos fornecedores. Um outro item, que é o de número 7, trata dos processos de resolução. Neste processo estão descritas as formas de redução da degradação, pelo gerenciamento do ciclo de vida completo dos incidentes, além da identificação e gerenciamento das causas fundamentais da minimização dos incidentes. No penúltimo item desta norma está definido o Controle dos processos. Este item objetiva: [3] · Registrar e controlar os componentes dos serviços ou infraestrutura e proteção da integridade dos sistemas de informações e meio físico. · Assegurar que as mudanças requeridas nos negócios, infraestrutura ou serviço são avaliadas, aprovadas e implementadas de uma forma controlada. · O planejamento da implementação de novos serviços ou modificação de serviços e demonstração dos resultados alcançados. No último item desta norma está definido como planejar e receber uma versão para garantir que qualquer modificação dos itens de configuração sejam corretos, rastreáveis, protegidos e autorizados. O Que é ITIL™ O ITIL™ (Information Technology Infrastructure Library) é o modelo de referência para gerenciamento de processos de TI mais aceito mundialmente. A metodologia foi criada pela secretaria de comércio (Office of Government Commerce, OGC) do governo Inglês, a partir de pesquisas realizadas por Consultores, Especialistas e Doutores, para desenvolver as melhores práticas para a gestão da área de TI nas empresas privadas e públicas. Atualmente se tornou a norma BS-15000, sendo esta um anexo da ISO 9000/2000. O foco deste modelo é descrever os processos necessários para gerenciar a infra-estrutura de TI eficientemente e eficazmente de modo a garantir os níveis de serviço acordados com os clientes internos e externos. [1] Entre os processos que fazem parte do modelo de referência, podemos citar: · Planejamento de serviços; MeGAZINE · · · · · · · · · · · Gerenciamento de incidentes; Problemas; Mudanças; Configuração; Operações; Segurança; Capacidade; Disponibilidade; Custos; Entrada em produção; Testes. As empresas que o adotaram estão preocupadas em gerar valor do TI para os negócios da empresa e provar este valor de maneira adequada, através de processos corretos. [1] As normas ITIL™ estão documentadas em aproximadamente 40 livros, onde os principais processos e as recomendações das melhores práticas de TI estão descritas. O ITIL™ é composto por módulos. Os mais importantes são o “IT Service Support” e o “IT Service Delivery”. Características do ITIL™ · As principais características do ITIL™ são: · Modelo de referência para processos de TI não proprietário; · Adequado para todas as áreas de atividade; · Independente de tecnologia e fornecedor; · Um padrão de fato; · Baseado nas melhores práticas; · Um modelo de referência para a implementação de processos de TI; · Padronização de terminologias; · Interdependência de processos; · Diretivas básicas para implementação; · Diretivas básicas para funções e responsabilidades dentro de cada processo; · Checklist testado e aprovado; · O que fazer e o que não fazer. Porque ITIL™? O ITIL™ conduz a uma forma de trabalho orientada a processos objetivando oferecer um serviço de alta qualidade e garantia para os clientes da área de TI. As vantagens de trabalhar orientado a processos são listadas abaixo: [1] · Faz com que as melhorias de qualidade possam ser medidas; · Torna os processos de gerenciamento dos serviços de TI mensuráveis; · Fornece uma forma consistente de trabalho; · Fornece uma terminologia padronizada; 7 Delphi · Deve estar concluído em 2005; · Centralização do help-desk: aumento de chamados de 20.000 para 60.000; · Tempo de atendimento reduzido em 20%; · Volume de reclamações reduzido em 80%; · 94% dos atendimentos completados em menos de 20 segundos; Conclusão A governança de TI tem sido largamente difundida e implementada nas organizações. No entanto para o seu sucesso, depende diretamente da adoção em conjunta com metodologias e padrões de qualidade. No caso do ITIL, o adicionamento da cultura de qualidade nos processos ficou demonstrada nesse artigo, devido ao enriquecimento que a norma BS 15000 contém. Figura 2 - Estrutura ITIL · Aperfeiçoa os processos de comunicação; · Aumenta a satisfação do cliente ajustando corretamente sua expectativa; · Auxilia na obtenção da certificação ISO 9000. Casos de Sucesso 1 - Procter & Gamble [2] · Adotou ITIL em 1997; · Economizou US$ 500 milhões em 4 anos: · 6 a 8% em corte de custos operacionais · 15 a 20% em redução de staff de tecnologia 2 - Governo de Ontario, Canadá [2] · Adotou ITIL para melhorar o serviço de 25.000 usuários em 1.000 locais; · Criou um service desk que melhorou a resposta e reduziu os custos com chamados em 40%; 3 - ABN Amro [2] · Iniciou ITIL em 2001 – Data Center e implantação de equipamentos do banco/agências; 8 Referências Bibliográficas [1] ITIL, ITIL Definições, Consist, acessado em 26/08/ 2004 http://www.consist.com.br/brasil/consistitsm/itil.htm [2] BRODBECK, Henrique J., Governança de TI, acessado em 30/07/2004 http://www.inf.ufrgs.br/~brodbeck/ [3]Sasaki, Luís Hiromitsu , Conhecendo a norma de Gestão de Serviços TI (BS 15000). Acesso 04/06/03 http:// www.alternet.com.br/canal/administracao/bs15000.doc [4]Ghigonetto, Mauricio, ITIL, acesso em 07/08/2004. http://www.emm.usp.br/g_fr_tutor.html Sobre o autor Marcelo Nogueira é Mestre em Engenharia de Produção com ênfase em Gestão da Informação, bacharel em Análise de Sistemas, Professor Universitário, Instrutor e Desenvolvedor Delphi desde 1995, Membro fundador do DUG-BR. e-mail: [email protected] MeGAZINE Delphi Impressão Impressão de de Código Código de de Barras Barras Uma Uma abordagem abordagem prática prática ZEBRA ZEBRA ZPL2 ZPL2 por Victory Fernandes e Augusto Frederico Na Internet estão disponíveis diversos componentes para geração e impressão de Código de Barras utilizando o Delphi e impressoras Laser ou Jato de Tinta. Ao trabalharmos com diferentes impressoras, tivemos alguns problemas quanto à resolução, configuração de impressoras, impressão nas margens das etiquetas, impressão de grandes quantidades de etiquetas e etc, o que comprometia a confiabilidade do sistema. Devido a estes e outros problemas, consideramos que a maneira mais simples, prática e profissional de se imprimir códigos de barras, é utilizando impressoras específicas para impressão de etiquetas e códigos de barras. Neste artigo fazemos uma abordagem prática para as impressoras Zebra, que utilizam linguagem de script ZPL2, após este estudo, o leitor estará familiarizado com o conceito geral, e pronto para utilizar qualquer impressora do gênero. Acessando a impressora COPY “MEU_ARQUIVO.TXT” LPT1 ou COPY “MEU_ARQUIVO.TXT” COM1 Onde “MEU_ARQUIVO.TXT” é um arquivo de texto comum contendo o script em ZPL2 que se deseja executar e deve ser enviado para a porta paralela (LPT1) ou serial (COM) Este tipo de abordagem de comunicação facilita, e muito, a implementação, uma vez que a nossa única preocupação será conhecer os comandos, utilizando os métodos padrões do Delphi para o envio das strings. Conhecendo a Linguagem Os comandos em ZPL2 obedecem a uma sintaxe geral do tipo: ·A ·p1,p2,p3 ·[p1,p2,p3] Comandos Parâmetros Parâmetros opcionais Caso deseje, o usuário da impressora pode utilizar softwares prontos disponíveis para download que acompanham a impressora ou são vendidos separadamente. Este não é o tipo de abordagem que desejamos aos nossos clientes. O ideal é que sejamos capazes de oferecer a funcionalidade de impressão de código de barras por dentro dos nossos programas, utilizando uma interface com a qual o usuário já esteja familiarizado. Para isso, é necessário conhecer o formato de comunicação com a impressora. Apesar da impressora disponibilizar uma infinidade de comandos e opções, tais como contadores, criação e armazenamento de formulários em memória, velocidade de impressão dentre outros, vamos abordar alguns itens principais: · Configuração da Etiqueta · Impressão de Textos · Impressão de Códigos de Barras A impressora em questão não requer nenhum tipo de driver específico para funcionar, bastando que lhe seja passada uma seqüência de comandos ASCII pela porta a qual esta conectada. Sendo assim o acesso pode ser feito até mesmo pelo MS-DOS com um comando do tipo: Sempre que desejarmos imprimir uma determinada etiqueta devemos seguir um procedimento geral indicado pela impressora: · Inicialmente devemos indicar o início de formatação da etiqueta, Comando XA. · Enviamos à impressora os comandos relativos à MeGAZINE 9 Delphi Teste de Impressao, N, N, N, 15 15 configuração e montagem da nova etiqueta –Comandos Texto e Código de Barras. · Uma vez concluída a montagem da etiqueta, com o Comando PQ determina-se a quantidade de impressão. · O Comando XZ decretará o término da formatação. Veremos agora a análise de cada um dos comandos citados separadamente: Modo de Formatação O primeiro Comando passado à impressora será o Comando XA, que indicará o início no modo de formatação da etiqueta. Impressão de Textos Para impressão de textos formatados na etiqueta, utilizamos o Comando_Texto_ZPL2, que nada mais é do que a junção de vários comandos da impressora e cuja sintaxe é mostrada abaixo: Onde, p1 margem esquerda em pontos (8 pontos/mm). default: 0 0- 9999 p2 margem superior em pontos(8 pontos/mm). default:0 0-9999 p3 inverter cores Ao enviarmos este parâmetro, a impressora inverte as cores pretas em brancas e vice-versa . p4 tipo fonte A..Z 1..9 p5 orientação p6 p7 p8 Valor Descrição N Sem rotação R Rotação de 90º I Rotação de 180º B Rotação de 270º A Listagem 01 mostra o retorno do script ZPL2 após a chamada feita acima: ^FO20,70 ^AN,N,15,15 ^FDTeste de Impressao ^FS Listagem 01 - Formatação do texto Impressão de Código de Barras Para impressão de códigos de barras nos mais diversos formatos, utilizamos o Comando Código_Barras_ZPL2, uma junção de vários comandos da impressora e cuja sintaxe é mostrada abaixo: Bp1,p2, p3,p4, p5,p6 Onde, p1 margem esquerda em pontos (8 pontos/mm). default: o 0- 9999 p2 margem superior em pontos(8 pontos/mm). default:0 0-9999 p3 tipo código 1, 2, 3, 4, 7, 8, 9, A, B, C, D, E, F, I, J, K, L, M, P, Q, S, U, X, Y, Z. p4 Orientação Tabela 01 Valores de Rotação altura fonte em pontos (8 pontos/mm) default: 15 10- 1500 pontos largura fonte em pontos(8 pontos/mm) default: 12 10-1500 pontos Texto (informação a ser impressa) //Texto //Inverter Cores //Orientação //Tipo fonte //Altura Fonte //Largura Fonte Valor Descrição N Sem rotação R Rotação de 90º I Rotação de 180º B Rotação de 270º Tabela 02 Valores de Rotação p5 inverter cores Ao enviarmos esse parâmetro a impressora inverte as cores pretas em brancas e vice-versa. p6 Código (valor do código de barras). Chamamos a função texto da seguinte forma: Texto_ZPL2(20, //Margem Esquerda 70, //Margem Superior 10 Chamamos a função Código_Barras_ZPL2 da seguinte forma: Codigo_Barras_ZPL2(20, //Margem Esquerda 70, //Margem Superior MeGAZINE Delphi 1 123, N, N); //Tipo fonte //Código //Inverter Cores //Orientação A Listagem 02 mostra o retorno do script ZPL2 após a chamada feita acima: ^FO20,70 ^B1N ^FD123 ^FS Listagem 02 - Formatação do Código de Barras Comandos Finais da Etiqueta Após passarmos todos dados para a etiqueta, determinamos a quantidade de etiqueta a ser impressa através do Comando PQ, com sintaxe: PQ p1 p1 determina a quantidade de cópias, 1 até 99.999.999. O comando XZ determina o termino da formatação. O Programa Exemplo Veja na Figura 01 a tela do aplicativo demonstrativo criado: Figura 01 - Tela principal do exemplo de utilização de Impressora de Código de Barras Este programa exemplifica a impressão de códigos de barras. Nele podemos: · Configurar todos os parâmetros de formatação dos comandos XA, Texto, Código de Barras, PQ, XZ. · Adicionar e excluir produtos para impressão. · Visualizar a codificação em ZPL2 gerada para impressão das etiquetas. · Salvar um arquivo de script ZPL2 para impressão futura. · Abrir um arquivo de script ZPL2 para impressão. · Imprimir códigos de barras em qualquer impressora paralela compatível com ZPL2. Nele foram implementadas as chamadas às funções de impressão de texto e código de barras, descritas anteriomente, como mostrado: Function Comando_XA: String; Procedure Texto_ZPL2(p1,p2 p3,p4,p5,p6,p7,p8 :string) Procedure Codigo_Barras_ZPL2(p1, p2, p3, p4, p5, p6: string) Function Comando_PQ(q: String): String; Function Comando_XZ: String; O programa faz sucessivas chamadas a estas funções, de acordo com a quantidade de produtos contida no componente TListview e a quantidade de etiquetas por produto definida pelo usuário, para gerar o script em ZPL2 que é enviado para o componente TMemo. Uma vez o script em ZPL2 pronto, utilizamos uma função de escrita na porta da impressora para enviar os comandos contidos no componente TMemo para a impressora instalada na porta paralela, como mostrado: procedure DirectPrint(s: String String); var PTBlock : TPassThroughData; begin PTBlock.nLen := Length(s); StrPCopy(@PTBlock.Data, s); Escape(printer.handle, PASSTHROUGH, 0, @PTBlock, nil nil); end end; procedure TForm1.Button2Click(Sender: TObject); begin //impressao do codigo de barras if memo1.Lines.Count > 0 then begin Printer.BeginDoc; DirectPrint(memo1.Lines.Text); Printer.EndDoc; end end; end end; Delphi A ZPL2_Unit As chamadas dos comandos da impressora demonstradas durante o artigo foram feitas utilizando a ZPL2_Unit.pas, uma Unit desenvolvida em Delphi de acordo com o manual de referência da linguagem ZPL2 para geração de script utilizado nas impressoras de código de barras Zebra. As vantagens de utilizar a ZPL2_Unit incluem: · Completa abstração da camada de geração do script, sendo necessário apenas fazer chamadas às funções da Unit para os comandos desejados. · Velocidade na implementação da comunicação com a impressora. · Geração de etiquetas com texto e código de barras de forma muito simples. · Facilidade na geração de código ZPL2 Maiores informações sobre a ZPL2_Unit podem ser obtidas no site do produto em http://www.igara.com.br/ produto.php?cod_produto=46 Conclusão Agora que você está familiarizado com as principais opções das impressoras, fica muito mais fácil partir para implementações mais elaboradas, que utilizem outros recursos não abordados neste artigo, como opções de contadores, temporizadores, impressão de imagens e logomarcas, impressão de formulários etc... Maiores informações sobre impressoras de códigos de barras, bem como download de manuais podem ser encontradas no site do fabricante em http://www.zebra.com. Maiores informações sobre a ZPL2_Unit podem ser obtidas no site do produto em http://www.igara.com.br/ produto.php?cod_produto=46 Sobre o autor Victory Fernandes é desenvolvedor sócio da TKS Software - Soluções de Automação Comercial e Softwares Dedicados. Pode ser contactado em [email protected], ou através dos sites www.victory.hpg.com.br - www.enge.cjb.net – www.igara.com.br. Sobre o autor Augusto Frederico é estudante de Engenharia Mecatrônica e desenvolvedor da TKS Software Soluções de Automação e Softwares Dedicados. Pode ser contactado em [email protected] Delphi Um estranho no ninho Ferramenta Ferramenta gratuita gratuita invade invade oo mundo mundo dos dos Delphianos Delphianos por Emerson Facunte Salve, salve Delphianos! Peço licença a vocês para apresentar uma ferramenta de desenvolvimento C# totalmente gratuita: Microsoft Visual C# 2005 Express. Eu sei que alguns irão torcer o nariz e dizer: essa revista é dirigida aos desenvolvedores Delphi, certo? O Facunte sempre defendeu o Delphi com unhas e dentes, certo? E por que o Facunte quer apresentar uma ferramenta C#? O mercado está cada vez mais exigente, meus amigos! E agradeço a Borland por introduzir o suporte ao C# em sua IDE. Isso não é nenhuma surpresa, é um antigo sonho da Borland em oferecer linguagens e tecnologias diferentes em sua IDE. Em meus artigos anteriores mostrei como é fácil e prazeroso o aprendizado desta fantástica linguagem de desenvolvimento: C#. Agora mostrarei a facilidade de utilizar uma ferramenta de desenvolvimento gratuita muito semelhante ao Visual Studio da MS. É uma ferramenta totalmente gratuita para o uso pessoal e comercial, com bons recursos para o desenvolvimento de aplicações Console, Windows, além de bibliotecas de classe, controles entre outras. Na tela inicial (figura 1) temos uma central com Wizards, Tutoriais e sites da comunidade C#. Criando a aplicação Vamos criar nossa aplicação no modelo Windows Forms. Selecione as opções File/New/Project (Ctrl-Shift-N), e na janela seguinte (figura 2), selecione a opção Windows Application, informando TheClubBrowser como nome da aplicação. Repare que agora foi criado um formulário. Vamos inserir os objetos necessários para a nossa aplicação. Os objetos estão disponíveis na ToolBox (figura 3). Selecione a seção Windows Forms e insira os objetos que seguem: ComboBox Name cmbURL Coragem meus amigos, quebre esse paradigma, seja generalista! Button Name - btnGo Text - > O início Antes de iniciarmos, sugiro que vocês baixem a ferramenta MS Visual C# 2005 Express no site: http://lab.msdn.microsoft.com/express/ MeGAZINE WebBrowser wbrClient Anchor – Top, Bottom, Left, Right 13 Delphi Figura 1 – Tela inicial Figura 2 – Selecionando a opção Windows Application 14 Figura 3 – ToolBox MeGAZINE Delphi Neste ponto iremos codificar o objeto btnGo. Dê um duplo-clique no objeto btnGO (ou selecione o evento Click) e insira o código que segue: wbrCLient.Navigate(cmbURL.Text); A figura 4 ilustra a disposição dos objetos. Execute a aplicação (F5) e veja o resultado (ver figura 5). Sobre o autor Facunte é co-Owner Framework.Net Microsoft, evangelista de aplicações e-business, publicou 6 livros e mais de 80 artigos, ministrou palestra para cerca de 10.000 pessoas em todo o país (Borcon, TechWeek-SP-POA-RJ, .Net 2005 RoadShow), membro-fundador do DUG-BR, lider do grupo Go.Net, consultor sênior do grupo DevMedia e Arquiteto de Software do Grupo Saraiva. Nos tempos livres curte programação MSX, Cinema, Basquete e uma boa pista de dança! http://br.thespoke.net/MyBlog/borlandman/ MyBlog.aspx Figura 4 – Disposição dos objetos Figura 5 – Aplicação em execução MeGAZINE 15 Delphi Imprimindo Imprimindo no no Delphi Delphi 2005 2005 Por Claudinei Rodrigues – [email protected] A parte de impressão é uma das mais importantes tarefas de uma aplicação. Neste artigo eu vou abordar a impressão via programação no Delphi 2005 utilizando os recursos disponíveis no .NET Framework. Você verá que este tipo de trabalho é bem simples de ser feito, pois o .NET Framework traz uma classe que encapsula todas as funções de impressão mais complexas. Com esta classe você tem a possibilidade de permitir ao usuário que configure em qual impressora ele quer imprimir, configurar o tamanho da página, margens, quantidade de cópias, etc. Nós vamos começar com um exemplo bem simples que imprime apenas um string, depois baseado neste exemplo nós vamos implementar outros recursos. Agora nós vamos incluir quatro botões ao nosso WinForm. Vá até o Tool Palette na categoria Windows Forms. Clique no componente Button, como mostrado na figura 2, e arraste-o ao nosso WinForm. Figura 2: Tool Palette Criando um novo projeto. Agora chame o seu Delphi 2005. Clique em File | New | Windows Forms Application – Delphi for .NET, como mostrado na figura 1. Após incluir os botões você terá o WinForm semelhante ao mostrado na figura 3. Figura 3: WinForm com as opções de impressão Agora para podermos utilizar a classe de impressão, temos que declarar um namespace. Vá até o código fonte e declare o namespace System.Drawing.Printing, como mostrado na listagem 1; unit WinForm; interface Figura 1: Criando uma aplicação Windows Forms 16 uses MeGAZINE Delphi System.Drawing, System.Collections, System.ComponentModel, System.Windows.Forms, System.Data, System.Drawing.Printing ; Type Listagem 1: Declaração dos namespaces. É neste namespace que encontraremos a classe PrintDocument que é responsável em enviar informações para a impressora. Tudo o que você precisa para imprimir desde relatórios simples até os mais complexos. Entretanto nós veremos a utilização de outras classes que irão enriquecer o nosso exemplo. Para imprimirmos um texto ou um gráfico basta que chamemos o método Print da classe PrintDocument. Ao executar este método, um evento de impressão será disparado. É neste evento que iremos incluir o que precisamos que seja impresso. ImpDoc.Print; // Verifica se ocorreu algum erro except on E: System.Exception do begin // Caso ocorra algum erro, será // mostrada uma mensagem. MessageBox.Show(E.Message.ToString()); end; end; end; Listagem 2: Rotina de impressão direta. Conforme eu havia dito, ao você executar o método Print um evento de impressão seria disparado. No código acima eu estou atribuindo uma procedure que eu criei ao evento de impressão do PrintDocument, como você pode ver nesta linha que está incluída no código mostrado anteriormente. // Atribui o evento PrintPage a função ImpPag include(ImpDoc.PrintPage,ImpPag); Escrevendo o evento O nosso evento recebe um argumento do tipo System.Drawing.Printing.PrintPageEventArgs, contendo os dados relacionados ao evento de impressão. Um objeto que encontramos em PrintPageEventArgs é o objeto Graphics que é responsável pela impressão da página. Para enviar um texto nós vamos utilizar o método DrawString. Existem também outros métodos como FillRectangle, DrawEllipse, etc. Para que você possa entender melhor como tudo isto funciona, vamos montar uma rotina bem simples. Depois iremos adicionar os novos recursos. Bem, no começo desta matéria você adicionou quatro botões no WinForm. Vá até o evento Click do primeiro botão e inclua o código abaixo: procedure TWinForm.Button1_Click (sender: System.Object; e: System.EventArgs); var // Define uma variável do tipo PrintDocument ImpDoc : PrintDocument; begin try // Cria uma variável do tipo PrintDocument ImpDoc := PrintDocument.Create(); // Atribui o evento PrintPage a função ImpPag include(ImpDoc.PrintPage,ImpPag); // Executa a impressão MeGAZINE Agora veja a seguir como é a nossa procedure que irá fornecer os dados necessários a impressão. procedure TWinForm.ImpPag(sender: System.Object; e: PrintPageEventArgs); var texto : string string; MargemEsquerda, MargemTopo : integer; fonte : System.Drawing.Font; begin // Defini o texto a ser impresso texto := ‘Exemplo de impressão em Delphi .NET’; // Configura o tipo de fonte fonte := System.Drawing.Font. Create(‘Arial’, 20); // Defini a margem esquerda MargemEsquerda := e.MarginBounds.Left; // Defini a margem direita MargemTopo := e.MarginBounds.Top; // Imprime a linha e.Graphics.DrawString(texto, fonte, Brushes.Black, MargemEsquerda, MargemTopo); end; Listagem 3: Rotina de impressão. Como você pode ver, a rotina é muito simples. Agora basta 17 Delphi compilar. Está pronto o seu primeiro exemplo de impressão em .NET através do Delphi 2005. Usando o PrintDialog end; end; Listagem 3: Utilização do PrintDialog. Agora vamos adicionar mais recursos ao nosso programa. Vamos utilizar o PrintDialog para que possamos selecionar para qual impressora queremos mandar a nossa impressão, implementar a possibilidade de cancelar a impressão, selecionar o numero de cópias, quais páginas desejamos imprimir, etc. Para se utilizar o PrintDialog é muito simples, veja o código a seguir que está incluído no segundo botão do nosso exemplo. procedure TWinForm.Button2_Click(sender: System.Object; e: System.EventArgs); var // Define uma variável do tipo PrintDocument ImpDoc : PrintDocument; // Define uma variável do tipo PrintDialog dlg : PrintDialog; begin try //Cria uma variável do tipo PrintDocument ImpDoc := PrintDocument.Create(); // Cria uma variável do tipo PrintDialog dlg := PrintDialog.Create(); // Permite a seleção de páginas dlg.AllowSomePages := True; //Atribui o PrintDocumento ao PrintDialog dlg.Document := ImpDoc; //Atribui o evento PrintPage //a função ImpPag include(ImpDoc.PrintPage,ImpPag); // Chama o componente PrintDialog. // Se clicar no botão OK o relatório // será impresso, caso contrário // o relatório não será impresso. if (dlg.ShowDialog() = System.Windows. Forms.DialogResult.OK) then begin // Imprime o relatório ImpDoc.Print; end; // Verifica se ocorreu algum erro except on E: System.Exception do begin // Caso ocorra algum erro, será // mostrada uma mensagem. MessageBox.Show(E.Message.ToString()); end; 18 Configuração de página Agora nós vamos adicionar o recurso de configuração de página. Para isto nós vamos trabalhar com o PageSettings. Você pode incluir um botão em sua aplicação apenas para fazer a configuração da página, veja no código a seguir que está incluído no terceiro botão da nossa aplicação. procedure TWinForm.Button5_Click(sender: System.Object; e: System.EventArgs); begin //Cria uma variável do tipo PageSetupdialog psd := PageSetupDialog.Create(); // Cria uma variável do tipo PageSettings ConfPag := PageSettings.Create(); // Atribui as configurações de página // ao PageSetupDialog psd.PageSettings := ConfPag; // Permite alterar a orientação do papel psd.AllowOrientation := True; // Permite a alteração de margens psd.AllowMargins := True; // Chama a tela do PageSetupDialog psd.ShowDialog(); end; Listagem 4: Configurando páginas Preview do relatório Normalmente antes de se mandar imprimir um relatório, muitos usuários gostam de ver o relatório antes de enviá-lo para a impressora. Assim vamos montar o preview do relatório, algo muito simples. Veja no código abaixo onde utilizamos o PrintPreviewDialog que pode ser visto no quarto botão de nossa aplicação. procedure TWinForm.Button3_Click(sender: System.Object; e: System.EventArgs); var // Define uma variável do // tipo PrintDocument ImpDoc : PrintDocument; // Define uma variável do // tipo PrintPreviewDialog prvdlg : PrintPreviewDialog; begin MeGAZINE Delphi try //Cria uma variável do tipo PrintDocument ImpDoc := PrintDocument.Create(); // Atribui o evento PrintPage // a função ImpPag include(ImpDoc.PrintPage,ImpPag); // Cria uma variável do tipo // PrintPreviewDialog prvdlg := PrintPreviewDialog.Create(); // Atribui o relatório ao Preview prvdlg.Document := ImpDoc; // Texto da tela de preview prvdlg.Text := ‘THE CLUB - Exemplo de Preview’; // Texto da tela de preview maximizada prvdlg.WindowState := FormWindowState.Maximized; // Chama o componente PrintPreviewDialog prvdlg.ShowDialog(); // Verifica se ocorreu algum erro except on E: System.Exception do begin // Caso ocorra algum erro, será // mostrada uma mensagem. MessageBox.Show(E.Message.ToString()); end; end; end; Listagem 5: Montando o preview Conclusão Como você pôde ver nesta matéria eu tentei ser o mais simples possível, para que você possa entender como se pode fazer a impressão via programação no Delphi 2005 utilizando os recursos disponíveis no .NET Framework. É claro que você pode fazer muito mais, basta a partir destes exemplos utilizar a sua criatividade. Até o próximo mês, e um grande abraço a todos. Download do projeto em: http://www.theclub.com.br/revista/download/imp032005.zip Sobre o autor Claudinei Rodrigues, Consultor Técnico do The Club [email protected] Delphi Construindo Construindo um um relatório relatório CrossTab CrossTab no no Rave Rave Reports Reports por Alessandro Ferreira, [email protected] Como sabem, o Rave Reports é um poderoso gerador de relatórios que apesar de estar no mercado há um bom tempo, somente após sua distribuição junto ao Delphi 7 passou a ser mais utilizando entre os programadores Delphi. Este gerador possui muitos recursos interessantes, contudo, a falta de documentação a respeito do mesmo gera uma certa resistência em sua adoção. Diariamente atendemos dezenas de programadores com dúvidas sobre situações até simples que estavam habituados a implementar em outros geradores como o QuickReport por exemplo, porém esbarrando na falta de informação dentro do Rave Reports. Uma destas situações é a implementação do famoso relatório CrossTab ou seja, um relatório de referência cruzada onde os dados podem possuir uma coluna fixa, como por exemplo com o nome do cliente e ao lado, a totalização de suas compras mês a mês, estando cada mês representado em uma coluna. Pensando nestas situações, resolvi publicar este artigo abordando o Rave Reports e CrossTab, somando mais um artigo sobre este excelente gerador de relatórios em nossa The Club Megazine. Banco de dados Neste exemplo, iremos utilizar o Firebird 1.5.2 onde iremos criar duas tabelas, sendo uma contendo os dados dos clientes e outra contendo as compras efetuadas por estes clientes. Sugiro utilizar o IBExpert (www.ibexpert.com) que é uma ferramenta gratuita para manutenção em bancos Interbase/Firebird para criar o banco de dados e suas tabelas. (Poderá encontrar referência sobre o IBExpert em nossa revista de Dezembro/2004). Vamos criar as estrutura da tabela Clientes, veja o código na listagem 1. 20 CREATE TABLE ID NOME ENDERECO BAIRRO CIDADE UF CEP CNPJ_CPF RG_IE TELEFONE EMAIL ); CLIENTES ( INTEGER NOT NULL PRIMARY KEY, VARCHAR(70), VARCHAR(70), VARCHAR(30), VARCHAR(30), CHAR(2), CHAR(10), VARCHAR(18), VARCHAR(18), VARCHAR(18), VARCHAR(80) Listagem 1 – Tabela Clientes Agora vamos criar uma tabela chamada Vendas, a qual terá uma estrutura bem simples apenas para ilustrar nosso relatório, veja a listagem 2. CREATE TABLE VENDAS ( NF CHAR(6) NOT NULL PRIMARY KEY, DATA DATE NOT NULL, CLIENTE_ID INTEGER NOT NULL, VALOR_TOTAL NUMERIC(15,2) NOT NULL ); ALTER TABLE VENDAS ADD CONSTRAINT FK_VENDAS_CLIENTES FOREIGN KEY (CLIENTE_ID) REFERENCES CLIENTES (ID); Listagem 2 – Tabela Vendas Para podermos testar nosso relatório, vamos acionar alguns registros em ambas as tabelas… Para isso, poderá utilizar a aba MeGAZINE Delphi Figura 1 – Clientes Agora vamos adicionar alguns registros que irão representar as compras destes clientes, veja a figura 2. LoginPrompt para False, dê um duplo clique no componente e adicione uma conexão apontando para nosso banco de dados de exemplo, conforme sugere a figura 3. Figura 2 – Vendas Observação: CrossTab “no braço” Alguns geradores de relatório como, por exemplo, o Report Builder e o Crystal Reports possuem recursos específicos para implementação de relatórios que necessitam de dados agrupados, assim como este que iremos construir. Contudo, no caso do Rave Reports não temos este tipo de funcionalidade e com isso teremos que construí-lo “no braço” mesmo, contudo você verá que isso não será tão complicado assim. Primeiro, vamos criar um projeto no Delphi 7 ou Delphi 2005 se preferir onde iremos através da dbExpress acessar o banco de dados e gerar uma consulta SQL para agrupar os dados de acordo com nossas necessidades e depois utilizá-los via Rave Reports. Adicione um componente SQLConnection (dbExpress), altere sua propriedade Name para cnxCrossTab, a propriedade Adicione dados para todos os clientes alternando valores e datas. Se preferir, poderá baixar o projeto de exemplo apresentado neste artigo no qual já adicionamos dados nas tabelas para testes, veja o endereço no final deste artigo MeGAZINE Figura 3 – Conexão dbExpress. Prosseguindo, adicione um componente SQLDataSet, configure a propriedade SQLConnection para cnxCrossTab, Name para sdsCrossTab e na propriedade CommandText adicione a sentença SQL apresentada na listagem 3. Select CLI.NOME AS CLIENTE, EXTRACT(MONTH FROM VEN.DATA) AS MES, SUM(VEN.VALOR_TOTAL) AS TOTAL From VENDAS VEN Left Outer Join CLIENTES CLI on CLI.ID = VEN.CLIENTE_ID Where EXTRACT(YEAR FROM VEN.DATA) = :ANO Group By CLI.NOME, 21 Delphi EXTRACT(MONTH FROM VEN.DATA) Listagem 3 – Sentença SQL. Adicione um componente DataSetProvider, configure Name para dspCrossTab e DataSet para sdsCrossTab. Após isso, adicione um componente ClientDataSet, configure Name para cdsCrossTab, ProviderName para dspCrossTab e depois clique com o botão direito no mesmo e selecione a opção: ‘Fetch Params’. Para testes, se executar esta sentença SQL no IBExpert, terá o resultado apresentado na figura 4. Figura 5 - Seleção do objeto Page1. Figura 4 Select executado Esta segunda Band iremos utilizar componentes VLine e Rectangle (aba Drawing) e componentes Text para dar a aparência de uma tabela, parecido com o layout apresentado na figura 7. Observe que os dados ficam arranjados contendo mês/total linha a linha para cada cliente. Contudo, um relatório de referência cruzada consiste em arranjar os dados na estrutura apresentada na tabela 1. altere Name para RvCrossTab, adicione um componente RvDataSetConnection, altere Name para RvDsCrossTab e aponte a propriedade DataSet para cdsCrossTab. Após isso, dê um duplo clique no RvProject para acessarmos os Rave Design, no qual Cliente Jan vamos criar um novo relatório. Para isso, acesse o menu File | New, volte ao menu File e selecione agora Save As... e salve no projeto Rave junto com os demais arquivos do projeto qual estamos trabalhando, como o nome de RvCrossTab, feito isso, alterne ao projeto Delphi e ajuste a propriedade ProjectFile do RvCrossTab para RvCrossTab.Rav. Devido a estrutura deste relatório, vamos necessitar de mais espaço na transversal, por isso, selecione o objeto ‘Page1’ utilizando o treeview de objetos ao lado direito do Rave Design e ajuste a propriedade Orientation para poLandScape a qual indica o modo ‘paisagem’, veja a figura 5. Adicione agora um componente Region (aba Report) e ajusteo de forma a ocupar todo o Report1. Após isso, adicione dois componentes Band (aba Report) e configure a propriedade BandStyle conforme demonstra a figura 6, estas bandas serão utilizadas como cabeçalho de página e cabeçalho de coluna. Obs. Por questões de espaço, não temos como mostrar o layout completo, mas as colunas vão até Dezembro, sendo a última para apresentar o total, seguindo o mesmo layout que apresentamos anteriormente na tabela 1. Figura 7 – Layout do relatório Fev Mar Abr Mai Jun Jul Ago 180,00 420,00 280,00 500,00 420,00 180,00 100,00 320,00 180,00 100,00 Emerson... 1267,00 487,00 1850,00 1190,00 1190,00 530,00 650,00 540,00 221,00 311,00 Alessand... 420,00 Figura 6 – Cabeçalhos Total Set Out Nov Dez Total 500,00 3.600,00 123,00 1205,00 9.564,00 13.164,00 22 MeGAZINE Tabela 1 – Dados arranjados em cross-tab. Delphi Antes de adicionarmos um DataBand (na qual iremos apresentar os dados), vamos configurar a fonte de dados. Para isso, clique no botão ‘New Data Object’, selecione a opção ‘Direct Data View’ e estando com ‘RsDsCrossTab’ selecionado, clique em ‘Finish’ e com isso teremos um objeto DataView adicionado em nosso relatório. Selecione-o no treeview a direita e altere sua propriedade Name para dvCrossTab. Adicione agora uma DataBand (aba Report), ligue sua propriedade DataView ao dvCrossTab. Para que as bandas de cabeçalho funcionem corretamente, selecione-as (Band1 e Band2) e aponte a propriedade ControllerBand para DataBand1. Em nossa DataBand também iremos utilizar componentes VLine a fim de deixar o layout parecido com uma tabela, seguindo a estrutura que construímos no cabeçalho de coluna. Ainda em nossa DataBand, adicione 14 componentes DataText os quais iremos nomear como: dt_Nome, dt_01, dt_02, dt_03, dt_04, dt_05, dt_06, dt_07, dt_08, dt_09, dt_10, dt_11, dt_12 e dt_Total, os quais serão utilizados para apresentação dos dados na DataBand. Cada um destes DataText estará ligado a um parâmetro que iremos definir selecionando o objeto Page e depois acessando a propriedade Parameters na qual declare os seguintes valores, “um por linha”: pNome, p01, p02, p03, p04, p05, p06, p07, p08, p09, p10, p11, p12, pTotal. Na propriedade DataField do dt_Nome, informe: Param.pNome. Na propriedade DataField do dt_Total, informe: Param.pTotal e nos demais DataText “dt_??” informe o parâmetro correspondente, como exemplo para o dt_01 configure o DataField como: Param.p01 e assim sucessivamente. E finalmente vamos adicionar uma banda para totalização geral de nosso relatório, então, adicione mais um Band e ajuste a propriedade ControllerBand para DataBand1 e BandStyle conforme a figura 8. Figura 8 – Banda Sumário. Adicione componentes VLine e Rectangle (aba Drawing) para dar continuidade ao layout de nossa tabela. Para efetuar a totalização das colunas, adicione 13 CalcText1 os quais irão totalizar cada mês e na última coluna o total geral. Configure as propriedades: Controller para DataBand1, DisplayFormat para ##,##0.00, FontJustify para pjRight e DataField para cada parâmetro respectivamente, como exemplo Param.p01 referente janeiro e o último referente o total geral para Param.pTotal, com isso, nossa banda de totalização estará pronta. Aqui, finalizamos as implementações dentro do projeto Rave, restando agora a codificação dentro do Delphi, vamos lá... MeGAZINE Finalizando a codificação Adicione um componente Label e altere seu Caption para ‘Informe o Ano para gerar o relatório:’, um componente MaskEdit e configure Name para MEdit_Ano e um BitBtn configurando Name para btnVisualizar. Vamos agora implementar e declarar variáveis e métodos que serão utilizados em nosso projeto, veja a listagem 4. private { Private declarations } NomeDoCliente: String; TotalDoCliente: Extended; procedure ZeraValores; procedure AtualizaTotalDoCliente; procedure PreencheParametros; procedure MostraTotal; public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} { Atribui “zero” para os parâmetros, para que se um determinado mês não possuir movimentação, não mostre o valores anterior } procedure TForm1.ZeraValores; var i: Integer; begin for i := 1 to 12 do RvCrossTab.SetParam(‘p’+FormatFloat (‘00’, i),’0,00'); end; { Vai acumulando mês a mês para totalizar o cliente } procedure TForm1.AtualizaTotalDoCliente; begin TotalDoCliente := TotalDoCliente + cdsCrossTab.FieldByName(‘TOTAL’).AsFloat; end; { Atribui valores aos parâmetros que representam mês a mês } procedure TForm1.PreencheParametros; 23 Delphi begin if (NomeDoCliente <> cdsCrossTab.FieldByName(‘CLIENTE’).AsString) then RvCrossTab.SetParam(‘pNome’, cdsCrossTab.FieldByName(‘CLIENTE’).AsString); NomeDoCliente := cdsCrossTab.FieldByName(‘CLIENTE’).AsString; RvCrossTab.SetParam(‘p’+FormatFloat(‘00’, cdsCrossTab.FieldByName(‘MES’).AsInteger), FormatFloat(‘##,##0.00’, cdsCrossTab.FieldByName(‘TOTAL’).AsFloat)); end; { Mostra total do cliente } procedure TForm1.MostraTotal; begin RvCrossTab.SetParam(‘pTotal’, FormatFloat(‘##,##0.00’, TotalDoCliente)); TotalDoCliente := 0; end; Listagem 4 – Métodos auxiliares. Efetuei comentários no topo de cada método apresentado na listagem 4, contudo gostaria de falar um pouco mais sobre o método “PrencheParametros” o qual considero o mais importante... Este método será chamado nos eventos OnGetRow e OnNext do objeto RvDataSetConnection e é nele que verificamos o momento de imprimir o nome do cliente (ou seja, quando houver mudança de nome o mesmo deverá ser impresso) utilizando para controle a variável “NomeDoCliente” a qual recebe o campo CLIENTE. Após isso, atribuímos o valor ao parâmetro referente o mês atualmente posicionado. Apenas para lembrar, nomeamos os parâmetros como p01, p02 e assim sucessivamente representando os meses, dessa forma, ficou fácil atribuir o valor ao parâmetro, bastando concatenar “p” ao mês corrente advindo do ClientDataSet. Estando com os métodos declarados, vamos codificar o evento OnClick do botão btnVisualizar, acompanhe o código apresentado na listagem 5, o qual também está comentado. procedure TForm1.btnVisualizarClick(Sender: TObject); begin with cdsCrossTab do begin 24 Close; Params.ParamByName(‘ANO’). AsInteger := StrToInt(MEdit_Ano.Text); Open; { Variável que será usada para totalizar cliente por cliente } TotalDoCliente := 0; { Abre o Engine de Report } RvCrossTab.Open; { Zera parâmetros } ZeraValores; { Chama o Report } RvCrossTab.Execute; end; end; Listagem 5 – Evento OnClick do btnVisualizar. Para finalizarmos a codificação iremos acessar alguns eventos do objeto RvDsCrossTab (TRvDataSetConnection) o qual é responsável em ‘prover’ os dados ao nosso relatório, sendo neste componente possível interceptar registro a registro que será apresentado em nosso realtório... Iremos utilizar os seguintes eventos: OnGetRow: acionado no momento que o engine de relatório obtém os dados providos pelo TRvDataSetConnection; OnNext: acionado quando o engine de relatório avança para o próximo registro a fim de suprir o OnGetRow; OnFirst: acionado quando o engine de relatório inicia a solicitação de registros. Na listagem 6 a seguir apresentamos a codificação destes três eventos. { Evento acionado quando o Report busca os dados para impressão. Neste evento, verificamos se está no mesmo cliente e não permitimos a mudança de linha, forçando a impressão para a próxima coluna } procedure TForm1.RvDsCrossTabGetRow(Connection: TRvCustomConnection); begin if (NomeDoCliente = cdsCrossTab.FieldByName (‘CLIENTE’).AsString) then if cdsCrossTab.RecNo < cdsCrossTab.RecordCount then Connection.ExecNext else begin AtualizaTotalDoCliente; PreencheParametros; MostraTotal; MeGAZINE Delphi end else MostraTotal; end; procedure TForm1.RvDsCrossTabNext(Connection: TRvCustomConnection); begin { Evento acionado quando vai para o próximo registro } if TotalDoCliente = 0 then ZeraValores; PreencheParametros; AtualizaTotalDoCliente; Connection.DoNext; end; implícido fornecido pelo objeto RvDsCrossTab e, dessa forma não necessitamos implementar nenhum laço de controle while ou semelhante. Ao entrar no evento OnNext, fazemos a verificação da variável TotalDoCliente e caso ela esteja igual a zero sabemos que um novo cliente está sendo inicializado. Ainda neste evento, efetuamos o preenchimento dos parâmetros através do método ‘PreencheParametros’, atualizamos o total do cliente através do método ‘AtualizaTotalDoCliente’ e finalizando efetuamos a chamada do método ‘DoNext’ que tem a finalidade de manter o evento ativo durante o processamento. Estando tudo codificado, vamos testar nosso projeto de exemplo, bastando para isso teclar [F9] e clicar no botão ‘Visualizar’. Se tudo correu bem, você irá obter como resultado uma tela parecida com a figura 9 Considerações finais procedure TForm1.RvDsCrossTabFirst(Connection: TRvCustomConnection); begin { Evento acionado quando abre o primeiro registro } PreencheParametros; Connection.DoFirst; end; Demonstramos aqui uma abordagem bastante simples de como manipular o Rave Reports para implementação de um relatório de referencia cruzada, mostrando como é possível customizar o Rave de acordo com nossas necessidades. Esta abordagem abre um leque de opções para situações de relatórios não-triviais, pois fornece ao programador bastante flexibilidade no controle dos mesmos. Até a próxima, abraço e sucesso à todos. Listagem 6 – Eventos do RvDsCrossTab O projeto de exemplo referente este artigo está disponível para download em: http://www.theclub.com.br/revista/download/ ravecrosstab.zip. Download No evento OnGetRow efetuamos um controle a fim de apresentar apenas um cliente por linha e os demais registros correspondentes ao mesmo cliente deverão preencher as colunas da direita, conforme o layout anteriormente sugerido. Para isso, assumimos o controle de salto de registros fazendo a chamada do método ‘ExecNext’ do objeto ‘Connection’ que é fornecido como parâmetro do evento. Observe que estamos dentro de um looping Sobre o autor Alessandro Ferreira, Consultor Técnico do The Club [email protected] Figura 9 – Preview do relatório MeGAZINE 25 ASP.NET ASP.NET: Parte III por: [email protected] Global.asax/pas & Web.config maior poder e funcionalidade para suas aplicações ASP.NET. Comprar um carro é uma tarefa complicada. Ninguém quer se sentir como se tivesse feito um mal negócio, então você certamente vai olhar o carro de perto antes de tomar a decisão de comprá-lo. Talvez você investigue o carro pela internet, mas isso forneceria somente fotos e uma descrição. E por último, você vai querer ver o carro pessoalmente e sentar nele. Provavelmente vai querer fazer um test-drive! Nas últimas duas colunas não fizemos muito além de “dar uma olhada em algumas fotos da Web” de uma aplicação ASP.NET (veja a Parte I e a Parte II). Examinamos somente a superfície de uma aplicação ASP.NET muito simples no Delphi 8/ 2005. Vimos uma aplicação ASP.NET do ponto de vista do desenvolvedor — isto é, como o asp.net funciona por traz das cortinas. Neste capítulo, vamos dar uma olhada em duas coisas que de alguma forma estão “debaixo dos panos,” porém facilmente encontradas no Project Manager: o arquivo global.asax/pas e o arquivo web.config. O arquivo global.asax/pas contém o código para gerenciar o código e eventos da aplicação. Ele implementa um descendente de System.Web.HttpApplication. Esta classe é análoga ao TApplication do VCL; ela fornece a infra-estrutura para toda a sua aplicação ASP.NET, permitindo que você faça um gancho dos códigos dos eventos que ocorrem para todas as requisições que chegarem. O arquivo web.config contém informações de configuração de sua aplicação, como um arquivo *.ini para uma aplicação cliente comum. Ambas as entidades são partes importantes na aplicação ASP.NET, mas nunca são visíveis para os usuários. Neste artigo, vamos dar uma olhada de perto nestes arquivos, e mostrar como eles podem ser usados para adicionar 26 A Global Unit O módulo global consiste de dois arquivos, global.asax e global.pas. O principal propósito do modulo global é fornecer um container para o código a nível de aplicação e apontamento para os eventos. O run-time do ASP.NET compila automaticamente o arquivo global.asax quando a primeira requisição para a aplicação é feita, e executa o código do módulo toda vez que uma requisição chegue para a aplicação. Obs: Por padrão, o ASP.NET é configurado para nunca permitir que o usuário veja um arquivo que tenha a extensão *.asax. O aspnet_isapi.dll tem um apontamento definido para a extensão *.asax que impede que o usuário veja as páginas asax. O mesmo também ocorre para os arquivos *.config. A não ser que você altere as configurações do seu IIS, ou permita a listagem de diretório para seus diretórios virtuais, não há maneira dos usuários verem o conteúdo destes arquivos, então você não precisa se preocupar sobre colocá-los no diretório principal. A requisição deles via browser resulta no erro “This type of page is not served”. O arquivo global.asax, por padrão, contém apenas uma linha: <%@ Application Codebehind= ”Global.pas” Inherits=”Global.Global”%> O atributo Application simplesmente define a unit de código que fornecerá o code-behind para o objeto global de sua aplicação. O arquivo global.asax deve ficar no diretório principal de sua aplicação. Você pode, se desejar, adicionar um script baseado em apontamentos de eventos em seu arquivo global.asax, mas é muito mais fácil gerenciar este código no arquivo de code-behind global.pas. (O Delphi 8/2005 não suporta o uso do Delphi- MeGAZINE ASP.NET Language em páginas *.as?x.) Você também pode declarar as tags de objeto do lado do servidor neste arquivo e ainda é possível adicionar referências de include do lado servidor neste arquivo, e elas funcionarão como você espera de uma função de include direta. (Veja a documentação do MSDN para mais informações destas últimas duas características, pois foge do contexto deste artigo.) O arquivo global.pas é um arquivo de código Delphi que contém por padrão, uma declaração da classe TGlobal que como mencionamos, descende da System.Web.HttpApplication. A principal função desta classe no ponto de vista do desenvolvedor, é disponibilizar eventos que ocorrem durante o ciclo de vida de uma única requisição. A unit padrão inclui stubs para oito eventos a nível de aplicação. Novamente, a coisa mais importante a se observer é que o apontamento de eventos da classe TGlobal são eventos a nível de aplicação. Alguns eventos serão disparados para cada requisição individual, alguns dispararão para cada requisição feita pelo usuário, e alguns dispararão uma vez para cada instância do objeto da aplicação, mas eles são todos “eventos horizontais”, quer dizer, os códigos nos apontamentos de eventos se cruzarão através de todas as páginas, e nenhum dos códigos escritos neles Evento Application_Start Session_Start Application_BeginRequest Application_EndRequest Application_AuthenticateRequest Application_Error Session_End Application_End serão específicos para qualquer página Web específica. O ASP.NET gerenciará e fará um cache da coleção de instâncias do objeto TGlobal. (Se você é um usuário do WebBroker/ WebSnap, o TGlobal objeto será gerenciado e armazenado da mesma forma que os WebModules). Assim, quando adicionar códigos para estes eventos, você precisa se lembrar que estas classes podem ser “sujas,” quer dizer que a instância da classe que você pegou para usar pode ter sido usada antes, e pode ter deixado um estado para trás que precisa ser reinicializado. A TGlobal é como qualquer outra classe do Delphi e você pode adicionar métodos, eventos, e propriedades à ela. Se você clicar na tab Design, você poderá adicionar componentes não visuais no designer, e eles serão mostrados como qualquer outro componente, permitindo que você ajuste suas propriedades no Object Inspector. Por exemplo, a classe TGlobal é um bom lugar para você gerenciar suas conexões de banco de dados. A classe TGlobal expõe um número de eventos para os quais você pode escrever seu código de apontamento de eventos. A tabela da figura 1 discute os oito eventos padrões e suas funções. Há mais que apontamentos de eventos no objeto TGlobal. A classe também expõe várias propriedades valiosas que contém informações críticas em nível de aplicação (veja a Figura 2). Descrição Este evento é disparado uma única vez quando a aplicação é inicializada. Ou, colocando de outra maneira, ele é disparado somente quando você inicializa o IIS, e não será disparado novamente. Use ele para iniciar variáveis que são consideradas globais para toda a aplicação. Não utilize para iniciar variáveis que são usadas por requisição ou por instanciamento. Para isto, sobreescreva o método Init ou use o método InitializeComponents fornecido com a classe TGlobal. Este evento é disparado sempre que um novo visitante desconhecido chega ao seu site. Um visitante desconhecido é aquele que não tem um cookie de sessão válido. Toda vez que um novo visitante faz uma nova requisição, uma nova sessão é inicializada, e este evento é disparado. Use-o para escrever o código que você quer que ocorra cada vez que um novo usuário chegar. Este evento é disparado no começo de cada requisição individual HTTP. Você pode usar este código para fazer qualquer inicialização que precise para ficar pronto para responder a uma requisição. Este evento é disparado quando o processamento de uma requisição HTTP foi completada. Este evento é a última chance de influenciar o que está sendo enviado de volta como resultado de uma requisição. Este evento é disparado quando o sistema de segurança do ASP.NET identificou um usuário específico. Este evento é disparado quando uma exceção que não foi tratada em seu código é disparada. Este é disparado quando uma sessão de um usuário individual é expirada via time-out, ou quando uma sessão de usuário é finalizada, por exemplo via logout. Isto ocorre quando a aplicação é desligada. Como o evento Application_Start, este evento é disparado somente uma vez na vida da aplicação, normalmente quando o IIS é desligado ou reinicializado. Figura 1: Eventos da classe TGlobals. MeGAZINE 27 ASP.NET Propriedade Descrição Application Esta aponta para o objeto Application, que contém informações disponíveis de todos os usuários por toda a aplicação. Em outras palavras, a informação contida aqui é global, assim todos os usuários vêem a mesma informação. Context Esta aponta para uma instância da classe HTTPContext para determinada requisição Modules Aponta para uma coleção de todos os módulos que estão na aplicação corrente. Request Esta aponta para uma instância da classe HTTPRequest que representa a requisição corrente. Você pode acessar esta informação quando necessário para responder adequadamente a uma requisição corrente. Response Esta aponta para uma instância da classe HTTPResponse que representa a resposta corrente. Você pode ajustar as propriedade desta classe para responder a requisição quando necessário. Server Esta aponta para uma instância da classe HTTPServerUtility que contém informações sobre o servidor físico que está rodando a aplicação. Session Esta aponta para o objeto da sessão corrente, o qual contém informações sobre o usuário único. Em outras palavras, as mesmas variáveis estão disponíveis para todos os usuários, mas os valores destas variáveis variarão dependendo do usuário. User Esta aponta para uma instância da interface IPrincipal que contém informações sobre o usuário corrente Figura 2: Propriedades da classe TGlobal O arquivo Web.Config Também está incluído em sua aplicação um arquivo chamado web.config. O arquivo web.config contém informações de configuração para sua aplicação. Você pode pensar nele como um arquivo *.ini, embora ele seja mais útil que os arquivo *.ini convencionais. Para começar, ele é um arquivo XML, então ele é um pouco mais complicado que um arquivo padrão *.ini, e certamente é mais poderoso e pode conter qualquer tipo de informação. Um arquivo web.config tem um esquema padrão que contém informações que o framework irá buscar e as utilizará. Um arquivo web.config pode ser utilizado para controlar a aplicação como um todo ou ainda para controlar ‘partes’ da aplicação. Por exemplo, toda aplicação ASP.NET precisa de um arquivo web.config que fique no diretório principal da aplicação, contudo, você também poderá colocar um arquivo web.config em um diretório abaixo do seu diretório principal, e fornecer configurações customizadas para este diretório e seus subdiretórios, e ambos podem sobreescrever e somar-se aos arquivos web.config de seus diretórios pais. Observe que essa herança hierárquica não é baseada nos diretórios físicos de seu HD, mas na estrutura de diretório virtual definida por sua aplicação e o servidor Web. Por exemplo, você talvez tenha uma função de administrador que que esteja acessível somente aos usuários autenticados. Para tornar esse subdiretório e todos os diretórios abaixo dele disponível somente para usuários autenticados, você pode 28 adicionar um arquivo web.config especificamente neste diretório com a seguinte configuração: <system.Web> <authorization> <deny users=”?”/> </authorization> </system.Web> O arquivo web.config é um arquivo XML, e assim deve conter o XML apropriado para que o framework consiga lê-lo. Por exemplo, todos os elementos tags devem estar com a nomenclatura correta. (Infelizmente, a nomenclatura para estes arquivos não é compatível com a nomenclatura do Delphi.) As informações do web.config principal de sua aplicação pode tanto aumentar como sbreescrever os ajustes de seu arquivo machine.config. As informações de configuração dadas à uma aplicação podem ser acessadas via classe ConfigurationSettings no namespace System.Configuration. O arquivo padrão web.config para uma aplicação ASP.NET do Delphi possui basicamente a seguinte estrutura: <?xml version=”1.0" encoding=”utf-8" ?> <configuration> <system.Web> <compilation debug=”true” defaultLanguage=”c#”> MeGAZINE ASP.NET </compilation> <customErrors mode=”RemoteOnly”/> <authentication mode=”Windows” /> <trace enabled=”false” requestLimit=”10" pageOutput=”false” traceMode=”SortByTime” localOnly=”true”/> <sessionState mode=”InProc” stateConnectionString= ”tcpip=127.0.0.1:42424" sqlConnectionString= ”data source=127.0.0.1;userid= sa; password=” cookieless=”false” timeout=”20"/> <globalization requestEncoding=”utf-8" responseEncoding=”utf-8"/> </system.Web> </configuration> Os ajustes padrões do web.config fornecem informações de configuração sobre seis pontos básicos de informação, as quais são explicadas na tabela mostrada na Figura 3. O esquema atual para o arquivo é muito complicado é pode ser visto em http://msdn.microsoft.com/library/default.asp?url=/ library/en-us/cpgenref/html/ gngrfASPNETConfigurationSectionSchema.ASP.NET. Há alguns outros itens que devem ser observados sobre os arquivos web.config. Primeiro, como os arquivos global.asax, o framework ASP.NET impede a visualização destes via um browser cliente. Segundo, o ASP.NET framework armazena estes arquivos para prover acesso rápido, mas você observará que este arquivo é atualizado, relido e reaplicado quando houver alguma alteração no mesmo. Isto permite que você mude a configuração de sua aplicação sem precisar desligar e ligar o servidor. Bem, com isso finalizamos esta série de artigos sobre ASP.NET onde procuramos demonstrar o funcionamento do mecanismo por trás do ASP.NET. Nas próximas edições estaremos abordando tópicos mais específicos como desenvolvimento de sites, etc... Até a próxima. Tag Name Descrição <compilation> Esta seção determina como o framework tratará o código em sua aplicação. O atributo mais importante aqui é o atributo de debug, o qual, quando ajustado para true, fornecerá uma mensagem de erro completa e rastreará por quaisquer erros que aconteçam em sua aplicação. Esta seção também pode ser configurada para usar scripts dinâmicos de outras linguagens, como Perl ou Delphi. <customErrors> Esta tag define como o framework lidará com os erros customizados. Se o atributo for ajustado para On, então uma mensagem de erro genérica será retornada. Se Off, então uma mensagem de erro detalhada será exibida, o que é útil para desenvolvedores. Se estiver ajustada para RemoteOnly, então um erro detalhado será exibido somente na máquina local, e os usuários remotos verão uma mensagem de erro genérico. Você pode adicionar sub-tags aqui que controlem exatamente o que os usuários verão para erros específicos de http. <authentication> Esta tag determina como os usuários são autenticados com sua aplicação. Ela pode ser definida somente em nível de aplicação ou por arquivos de configuração mais altos. Você diz para sua aplicação para usar a autenticação do Windows, baseado em Forms, Passport, ou sem autenticação. <trace> Esta seção determina se o rastreamento está ligado ou desligado para uma aplicação. Quando ligado, um rastreamento completo de sua aplicação irá ser executado até ter uma página de resposta. Isto obviamente é útil durante o desenvolvimento. <sessionState> Esta seção determina como a aplicação lidará com a informação de sessão do usuário. A informação de sessão pode ser armazenada no processo, em um processo separado projetado para apontar a informação de sessão, no SQL Server, ou nenhum deles. <globalization> Esta seção define os ajustes globais para uma aplicação. Você pode determinar os métodos de codificação para as requisições de chegada e respostas de saída, bem como ajustar uma cultura para sua aplicação. Figura 3: Ajustes padrões para o web.config MeGAZINE 29 Dicas & Truques ADO – Como cancelar a execução de um consulta. Os objetos DataSet pertencentes ao AdoExpress possuem um evento chamado OnFetchProgress através do qual podemos interceptar a execução de uma query e caso necessário cancelar o seu processamento, veja o código a seguir: // Código do botão OK. procedure TForm1.SpeedButton1Click (Sender: TObject); var FoundAt: LongInt; Private CancelarQuery: Boolean; implementation procedure TForm1.ADODataSet1FetchProgress(DataSet: TCustomADODataSet; Progress, MaxProgress: Integer; var EventStatus: TEventStatus); begin if CancelarQuery then Begin DataSet.Recordset.Cancel; Application.ProcessMessages; end;; end; No evento OnShow do formulário: CancelarQuery := False; Depois, no evento OnClick de um botão que será utilizado para cancelar: CancelarQuery := True; RichEdit – Como pesquisar e substituir texto. Nesta dica iremos demonstrar como pesquisar e substituir texto em um RichEdit que contenha texto formatado. A abordagem mais conhecida é através da utilização da função POS, contudo tratando-se de texto formatado ela pode falhar e não localizar a posição correta do texto e, neste caso lançamos mão do método FindText existente no próprio RichEdit, acompanhe o código a seguir: 30 StartPos, ToEnd: Integer; begin while FoundAt <> -1 do begin with RichEdit1 do begin if SelLength <> 0 then StartPos := SelStart + SelLength else StartPos := 0; ToEnd := Length(Text) - StartPos; FoundAt := FindText(edPesquisar.Text, StartPos, ToEnd, [stWholeWord]); if FoundAt <> -1 then begin SetFocus; SelStart := FoundAt; SelLength := Length(edPesquisar.Text); SelText := edTrocaPor.Text; end; end; end; end; O projeto de exemplo referente esta dica está disponível para download em: http://www.theclub.com.br/revista/download/ RichEdit_PesqSub.zip. MeGAZINE