Baixe o app para aproveitar ainda mais
Prévia do material em texto
3 THE CLUB Av. Profº Celso Ferreira da Silva, 190 Jd. Europa - Avaré - SP - CEP 18.707-150 Informações: (14) 3732-3689 Suporte: (14) 3733-1588 - Fax: (14) 3732-0987 Internet http://www.theclub.com.br Cadastro: cadastro@theclub.com.br Suporte: suporte@theclub.com.br Informações: info@theclub.com.br 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 Megazine” são terminantemente proibidos sem autorização escrita dos titulares dos direitos autorais. Impressão e acabamento: GRAFILAR Tel.: (14) 3841-2587 - Fax: (14) 3841-3346 Rua Cel. Amando Simôes, 779 Cep 18.650-000 - São Manuel - SP Tiragem: 5.000 exemplares Copyright The Club Megazine 2006 Diretor Técnico Mauro Sant’Anna Colaboradores Marcelo Nogueira, Mário Bohm, Aguinaldo P. Silva EDITORIAL Editorial Editorial .................................................................................. 03 SEF - Sistema de Escrituração Fiscal - Implementação ....... 04 O novo componente TrayIcon do Delphi 2006 ....................... 11 Visual Studio 2005 e Visual Basic Produtividade no Código .. 13 Criando arquivo de instalação para projeto Web (Windows Installer) ................................................................ 16 Delphi, uma questão de sobrevivência .................................. 19 Fortes Report - Uma boa opção de gerador de relatório Freeware ............................................................. 21 Perguntas & Respostas ......................................................... 26 Dicas & Truques .................................................................... 28 Delphi é marca registrada da Borland International, as demais marcas citadas são registradas pelos seus respectivos proprietários. Olá amigos, Aqui estamos com mais uma edição da revista The Club Megazine trazendo até você mais informações importantes. Começamos pela segunda parte da matéria sobre SEF - Sistema de Escrituração Fiscal escrita por nossos colaboradores Victory Fernandes e Airton Miranda. O nosso consultor técnico Claudinei Rodrigues traz uma matéria muito útil falando sobre um novo componente do Delphi 2006 chamado TrayIcon. O nosso colaborador Alexandre Tarifa mostra nesta edição a produtividade no Visual Studio 2005. Nesta matéria você verá como ganhar tempo nesta excelente ferramenta. O nosso consultor Marcos César Silva traz até vocês a informação sobre como criar um arquivo de instalação para um projeto Web no Visual Studio 2005. O nosso amigo Emerson Facunte traz na sua matéria intitulada, “Delphi, uma questão de sobrevivência”, a sua opinião sobre o futuro do Delphi. Estamos trazendo também informações sobre um componente chamado Fortes Report. Para quem não conhece, este é um gerador de relatórios freeware, bastante interessante. E finalizando com seção Perguntas e Respostas com algumas das solicitadas feitas ao nosso suporte técnico durante o ultimo mês. Boa leitura a todos. 4 SEF No primeiro artigo da série, foram abordados os conceitos e características gerais do SEF, tendo sido apresentada a estrutura básica do arquivo e seus principais registros, incluindo o exemplo de montagem do registro 50 como forma de demonstrar a estruturação geral de um registro do SEF. Continuando a nossa série de artigos sobre o SEF, abordaremos a implementação do arquivo propriamente dita. Através do demo que acompanha o artigo, é demonstrada a geração de todos os registros do SEF e a geração dos principais registros do SEF descritos no artigo anterior a partir de dados pré-definidos. Visão geral da Implementação Como o SEF se baseia em uma série de informações fornecidas pelo usuário do sistema gerencial em questão, e como estas informações devem ser cuidadosamente tratadas antes de serem enviadas para o banco de dados do sistema e por fim utilizadas na geração do arquivo de texto, sob pena de recusa do arquivo gerado por parte do Programa Validador, foi desenvolvida a SEFPE32dll.dll. Esta é uma solução que visa facilitar e agilizar o processo de tratamento destas informações, uma vez que seus usuários podem abstrair a camada de geração dos registros e validação das informações, se preocupando apenas em fazer as chamadas à dll passando os parâmetros necessários para a criação dos registros. É importante lembrar que o arquivo do SEF será gerado referente a um período anterior (ex. Fevereiro gera-se o SEF de Janeiro), com base em informações que já foram adicionadas em um banco de dados e que devem ser coerentes com o SEF. Então, a SEFPE32dll.dll deve ser usada na verdade em dois momentos, a exemplo: · Momento A: Em um sistema de controle de notas fiscais com SEF, as entradas e saídas de notas fiscais e demais operações sujeitas ao SEF, devem ser feitas levando em consideração que o banco de dados gerado será usado para geração do arquivo magnético. Assim, logo após o preenchimento de cada informação, o sistema deve antes de tudo chamar a dll para os registros correspondentes e testar se houve erro, salvando as informações no banco de dados, caso nenhum problema seja encontrado. · Momento B: No momento da geração do arquivo magnético propriamente dita, o sistema deve ler as informações do banco de dados e fazer as chamadas às funções da dll de acordo com os registros desejados. por Victory Fernandes e Airton Miranda Figura 01: Processo de Implementação do SEF Sobre o autores Victory Fernandes é Engenheiro, Mestrando em Redes de Computadores e desenvolvedor sócio da TKS Software - Soluções de Automação Softwares Dedicados. Pode ser contactado em victory@igara.com.br, ou através dos sites www.victory.hpg.com.br – www.igara.com.br Airton Miranda é estudante do Engenharia Mecatrônica e desenvolvedor da TKS Software - Soluções de Automação Softwares Dedicados. Pode ser contactado em airtonwmj@yahoo.com.br SEF - Sistema de Escrituração FiscalSEF - Sistema de Escrituração FiscalSEF - Sistema de Escrituração FiscalSEF - Sistema de Escrituração FiscalSEF - Sistema de Escrituração Fiscal ImplementaçãoImplementaçãoImplementaçãoImplementaçãoImplementação SEF - Sistema de Escrituração FiscalSEF - Sistema de Escrituração FiscalSEF - Sistema de Escrituração FiscalSEF - Sistema de Escrituração FiscalSEF - Sistema de Escrituração Fiscal ImplementaçãoImplementaçãoImplementaçãoImplementaçãoImplementação 5 SEF Na Figura 01 vemos os passos envolvidos na implementação do SEF que são descritos a seguir. Os passos 01, 02, 04 e 05 são aqueles que devem ser implementados no sistema gerencial e os passos em 03, 07 e 08 (em verde) podem ser abstraídos a partir da utilização da SEFPE32dll.dll. 1. Tabelas e Campos de acordo com o SEF: Todas as tabelas do sistema gerencial em questão devem estar formatadas de acordo com os campos dos registros do SEF, observando-se tipos de campo (numérico ou alfanumérico) e tamanho máximo dos mesmos. 2. Telas de Cadastro de Dados do SEF: As telas do sistema gerencial devem estar de acordo com o banco de dados e, as necessidades do SEF. Atenção principalmente para as telas de Vendas, Entrada de Nota Fiscal e Saída de Nota Fiscal que normalmente precisam ser revistas sendo necessário fazer pelo menos pequenas alterações não previstas até então. Atenção também para telas de Cadastro de Informante (Registro 10 e 11) e etc que precisam ser criadas para satisfazer a geração de alguns registros específicos do SEF. 3. Validação das Informações + Tratamento de Erros: Para garantir o máximo de integridade e o mínimo deimprevistos no momento da geração do arquivo, é aconselhável que os dados passem pela camada de validação de informações antes de ir para o banco de dados. Assim, no momento da geração, você garante que os dados do banco estão consistentes. 4. Seleção das informações do Período: Esta é a tela de geração do arquivo propriamente dita, e nela deve haver uma implementação de seleção das informações a serem utilizadas para a geração do arquivo, normalmente feita através de Querys no banco de dados, aplicando à Select os filtros referentes ao período das informações, tipo de registros, bem como ordenação dos campos (order by) e agrupamentos (group by) caso necessário. 5. Chamadas para as Geração dos registros: As informações retornadas pelo banco de dados serão então passadas como parâmetros para as chamadas de geração dos registros sob a forma de loops nas Querys de seleção. As funções de geração dos registros, executam novamente o procedimento de validação das informações (Passo 3) e por fim, caso não seja encontrado erro nas informações transmitidas, executa a Composição dos Registros, colocando os parâmetros passados sob a forma descrita na legislação do SEF. Implementando o SEF com a SEFPE32Dll.dll A SEFPE32dll.dll vem acompanhada de um aplicativo que demonstra o uso de suas funcionalidades. Para o Momento A há o demo sem utilização de banco de dados, onde são mostradas chamadas a todas as funções presentes na dll. Através de cliques nos botões respectivos você pode fazer os testes de cada função separadamente, como mostra a Figura 02. Assim, ao clicar no botão “Registro 50” o seguinte código é executado para a geração da linha do registro 50 conforme a especificação do SEF. (…) Function Registro50(CNPJ, Insc_Est, Data_Emissao_Recebimento, UF, Modelo, Serie, Figura 02: Demo sem banco de dados. Chamadas a todas as funções disponíveis na SEFPE32dll.dll através do clique nos botões respectivos 6 SEF Nro, CFOP, Emitente, Valor_Total_CFOP, Base_ICMS, Valor_ICMS, Isenta, Outras, Aliquota,Situacao, Data_Operacao, Nro_Lanc_Cont, CODUNC, Cod_Classe_Energia, Data_Inicial_Consumo, Data_Final_Consumo, Complemento_Nro_NF,Demanda_Contratada, Demanda_Contratada_Fora, Nro_Consumidores, Valor_Total_NF,Base_Calculos, Valor_ICMS_Total, Operacoes_Isentas, Outras_Total, Observacao: ShortString): Integer; stdcall; external ‘SEFPE32Dll.dll’; (…) procedure TForm1.Button3Click(Sender: TObject); var TempInt: Integer; begin //Registro50 - Registro de Total de Nota Fiscal TempInt := Registro50(’23.859.507/0001-09', //CNPJ ‘7.075.793.310.062’, //Insc_Est ’01/01/2006', //Data_Emissao_Recebimento ‘BA’, //UF, ‘01’, //Modelo ‘2’, //Serie ‘6’, //Nro ‘5111’, //CFOP ‘P’, //Emitente ‘518,19’, //Valor_Total ‘518,19’, //Base_ICMS ’36,27', //Valor_ICMS ‘’, //Isenta ‘0,00’, //Outras ‘7,00’, //Aliquota ‘N’, //Situacao ‘’, //Data de Emissão doDocumento ‘1’, //Código de Lançamento //Associado à Operação ‘’, //Complemento do Número //da Nota Fiscal ‘’, //CODUNC ‘’, //Código de Consumo de //Energia Elétrica ’01/01/2006', //Data Inicial do Consumo ’01/01/2006', //Data Final do Consumo ‘’, //Demanda Contratada Ponta ‘’, //Demanda Contratada //Fora-Ponta ‘’, //Número de Consumidores ‘518,19’, //Valor Total ‘518,19’, //Base de Cálculo do //ICMS - Total ’36,27', //Valor Total do ICMS ‘’, //Operações Isentas // Total ‘’, //Valor Total que Não //Confira Débito ou //Crédito ‘’ //Observação ); Trata_SEF_Int(TempInt); end; Para o Momento B mostraremos como implementar em seu software as chamadas aos principais registros do SEF descritos anteriormente. As chamadas às funções da dll deverão ser feitas passando como parâmetros os valores contidos em um banco de dados, refletindo o exato comportamento que deve ser implementado pelo desenvolvedor quando na adaptação do seu sistema. A seguir, são descritos os passos gerais do algorítmo para a utilização da SEFPE32dll.dll no seu software: 1- Inicia o uso da SEFPE32dll.dll a partir de uma chamada à função Inicia_SEF que recebe como parâmetro os locais onde serão armazenados o Arquivo_SEF, Arquivo_Erro e Arquivo_Log, respectivamente. Neste momento, vale fazer uma ressalva, a função Inicia_SEF executa a verificação se o arquivo de saída já existe e, caso exista, exclui o arquivo existente no local de destino. 2- Realiza a chamada a uma determinada função de registro, que faz uma Query no banco de dados respectivo, buscando pelas informações necessárias à geração do registro dentro do período desejado e na ordem de apresentação definida (order by). 3- Realiza um loop na Query fazendo chamadas à SEFPE32dll.dll, passando como parâmetros os resultados retornados pela Query, e armazenando em uma variável temporária um valor integer retornado pela dll (valor -1, caso ocorra algum erro, ou valor 0, caso não ocorra nenhum problema). 4- Caso o valor integer temporário seja de erro, é efetuada a descrição completa do erro no arquivo de erro cujo caminho é indicado ao iniciar o uso da dll– ver Figura 03. Caso contrário, o registro é devidamente formatado e adicionado ao arquivo SEF, cujo caminho também é indicado ao iniciar o uso da dll. 5- Repete-se os passos 2, 3 e 4 para todos os registros do SEF que se deseja gerar, tendo em vista características específicas do informante, como por exemplo, se ele é ou não contribuinte do IPI (deve-se gerar registro 51), se ele é ou não Substituto Tributário (deve-se gerar registro 53). 7 SEF Vamos agora mostrar passo a passo a implementação do algoritmo descrito anteriormente para a confecção do registro 50 já apresentado nas situações anteriores. No passo 1, faz-se a chamada a função Inicia_SEF com os parâmetros descritos anteriormente. procedure TSEF_ListFrm.BitBtn1Click(Sender: TObject); Arquivo_SEF, Arquivo_Erro, Arquivo_Log: String; begin Arquivo_SEF := ‘c:\SEF.txt’; Arquivo_Erro := ‘c:\LOG_ERRO.txt’; Arquivo_Log := ‘c:\LOG_USO.txt’; Inicia_SEF(Arquivo_SEF, Arquivo_Erro, Arquivo_Log); (…) No passo 2, realiza-se a chamada a uma determinada função de registro, que faz uma Query no banco de dados respectivo, buscando pelas informações necessárias à geração do registro dentro do período desejado e na ordem de apresentação definida (order by). procedure TForm1.sRegistro50; begin //Geração de Registro50 quanto Nota Fiscal //Executa a seleção dos registros no banco de dados with QrySEF do begin Close; UnPrepare; SQL.Clear; SQL.Add(‘SELECT * FROM tabela_notas_fiscais WHERE ‘); SQL.Add(‘(datahora_emissao BETWEEN :datahora_ini AND :datahora_fim)’); SQL.Add(‘ORDER BY datahora_emissao’); ParamByName(‘datahora_ini’).asdatetime := DataHora_Inicial; ParamByName(‘datahora_fim’).asdatetime := DataHora_Final; Prepare; Open; end; No passo 3, realiza-se um loop na Query, fazendo chamadas à SEFPE32dll.dll, passando como parâmetros os resultados retornados pela Query, e armazenando em uma variável temporária o valor integer retornado pela dll. procedure TForm1.sRegistro50; begin (…) if QrySEF.RecordCount > 0 then begin while not QrySEF.EOF do begin {Faz a chamada da dll passando as informações do banco de dados e armazena numa string temporária} TempInt := Registro50(QrySEF.FieldByName (‘cnpj_destino’).AsString, //CNPJ QrySEF.FieldByName(‘ie_destinatario’). AsString, //IE datetostr(QrySEF.FieldByName (‘datahora_emissao’).AsDateTime), //Data QrySEF.FieldByName(‘uf_destinatario’). AsString, //UF QrySEF.FieldByName(‘modelo_nf’). AsString, //Modelo QrySEF.FieldByName(‘serie_nf’). AsString, //Serie QrySEF.FieldByName(‘num_nf’). AsString, //Nro QrySEF.FieldByName(‘cfop’).AsString, //CFOP QrySEF.FieldByName(‘emitente_nf’). AsString, //Emitente formatcurr(‘0.00’, QrySEF.FieldByName (‘subtotal’).AsFloat), //Valor_Total formatcurr(‘0.00’,QrySEF.FieldByName (‘base_icms’).AsFloat), //Base_ICMS formatcurr(‘0.00’, QrySEF.FieldByName (‘valor_icms’).AsFloat), //Valor_ICMS formatcurr(‘0.00’, QrySEF.FieldByName (‘isento_icms’).AsFloat), //Isenta formatcurr(‘0.00’, QrySEF.FieldByName (‘outras_despesas’).AsFloat), //Outras formatcurr(‘0.00’, QrySEF.FieldByName (‘aliquota_icms’).AsFloat), //Aliquota QrySEF.FieldByName(‘situacao_nf’). AsString //Situação datetostr(QrySEF.FieldByName(‘data_emissao’). AsDateTime), //Data Emissão QrySEF.FieldByName(‘cod_lanc’). AsString, //Cod Lançamento QrySEF.FieldByName(‘complemento_nf’). 8 SEF AsString, //Comp. do Nro da NF QrySEF.FieldByName(‘cdunc’). AsString, //CODUNC QrySEF.FieldByName(‘cod_energia_eletrica’). AsString, //Consumo de Energia Elétrica datetostr(QrySEF.FieldByName(‘data_inicial’). AsDateTime), //Data Inicial Consumo datetostr(QrySEF.FieldByName(‘data_final’). AsDateTime), //Data Final Consumo QrySEF.FieldByName(‘demanda’). AsString, //Demanda Contratada Ponta QrySEF.FieldByName(‘demanda_fora’). AsString,//Demanda Contratada Fora-Ponta QrySEF.FieldByName(‘num_consumidores’). AsString, //Número Consumidores formatcurr(‘0.00’, QrySEF.FieldByName (‘valor_total’).AsFloat), //Valor Total formatcurr(‘0.00’, QrySEF.FieldByName (‘base_calc’).AsFloat), //Base Cálculo //ICMS Total formatcurr(‘0.00’, QrySEF.FieldByName (‘total_icms’).AsFloat), //V. ICMS formatcurr(‘0.00’, QrySEF.FieldByName (‘operacoes_total’).AsFloat), //Op. // Isentas Total formatcurr(‘0.00’, QrySEF.FieldByName (‘sem_credito’).AsFloat), //Valor Tot. //sem Débito/Crédito QrySEF.FieldByName(‘observacao’).AsString); //Observação end; end; Nos passos 3 e 4, deve-se criar um procedimento que irá receber como parâmetro um valor integer fornecido por cada registro chamado, com o objetivo de verificar se o valor contém descrição de erro ou se o registro foi devidamente formatado. procedure TForm1.Trata_SEF_Int(retorno: integer); begin if retorno = -1 then showmessage(‘Erro na chamada do Registro, verifique o erro em ‘ + edit2.text) else if retorno = 0 then showmessage(‘Registro OK, verifique o registro em ‘ + edit1.text) else showmessage(‘Retorno desconhecido’); end; No passo 5, repete-se, os passos 2, 3 e 4 para todos os registros do SEF que se deseja gerar, tendo em vista características específicas do informante, como por exemplo se ele é ou não contribuinte do IPI (deve-se gerar registro 51), se ele é ou não Substituto Tributário (deve-se gerar registro 53). Assim o código para chamada e geração dos registros é conforme segue: procedure TSEF_ListFrm.BitBtn1Click (Sender: TObject); Arquivo_SEF, Arquivo_Erro, Arquivo_Log: String; begin Arquivo_SEF := ‘c:\SEF.txt’; Arquivo_Erro := ‘c:\LOG_ERRO.txt’; Arquivo_Log := ‘c:\LOG_USO.txt’; DataHora_Inicial := StartOfTheMonth(Datetimepicker1.DateTime); DataHora_Final := EndOfTheMonth(Datetimepicker1.DateTime); Inicia_SEF(Arquivo_SEF, Arquivo_Erro, Arquivo_Log); sRegistro10; sRegistro11; sRegistro50; (…) sRegistro90; Finaliza_SEF; end; Onde as funções sRegistro10, sRegistro11, sRegistro50 e etc executam internamente as funcionalidades descritas nos passos 2, 3, 4 para suas respectivas tabelas do banco de dados. Para concluir o processo de geração, deve-se por fim fazer a chamada do registro 90, obrigatório a todo arquivo e SEF, e finalizar o uso da dll através da chamada da função Finaliza_SEF. Ao chamar a função Finaliza_SEF são gerados 3 arquivos, cujo detalhamento é descrito a seguir. Arquivo de Erro Caso ocorra algum erro durante as chamadas dos registros, é gerado um arquivo de erro, conforme mostrado na Figura 03, descrevendo com detalhes todos os erros encontrados durante a geração do SEF. Definições de campos do arquivo de erro: 1 – Registro em que ocorreu o problema; 2 – Parâmetros passados pelo usuário para a dll; 3 – Parâmetros passados pelo usuário após formatação e tratamento da dll; 4 – Erros ocorridos no registro; 5 – Observações que foram geradas no registro. 9 SEF Arquivo de Log de Uso O arquivo de Log de Uso, mostrado na Figura 04, sintetiza informações sobre a quantidade de registros gerados no Arquivo SEF, observações e erros encontrados durante a geração. Arquivo SEF O Arquivo SEF é o arquivo que contém as informações devidamente formatadas conforme a legislação do SEF e ao final do processo de geração, uma vez que não tenham sido gerados erros, o Arquivo SEF está pronto para ser validado. A Figura 05 mostra a estrutura do arquivo montado. Para o arquivo SEF ser validado, ele necessita de uma quantidade mínima de registros, os quais estão implementados no demo, clicando com o botão direito do mouse “Seqüência 01(10, 11, 88, 90)”. A SEFPE32Dll.dll vem acompanhada da documentação completa sobre como utilizar suas funções e quais os tipos de Figura 03: Texto com os erros gerados na SEF32Dll.dll Figura 04: Arquivo_Log que mostra o resumo dos registros do SEF chamados durante a geração do Arquivo SEF. erros retornados por cada função. Há ainda um demo completo em Delphi que mostra como conectar a dll ao seu programa e testar a saída da mesma sem banco de dados. Para obter uma cópia e maiores informações sobre a SEFPE32Dll.dll visite o site: http://www.igara.com.br/produto.php?cod_produto=86 10 SEF Figura 05: Arquivo SEF gerado com a “Seqüência 01” do demo pronto para ser validado Conclusão Com este artigo, cobrimos os conceitos gerais acerca da implementação do SEF, estruturação básica do sistema gerencial e o fluxograma de procedimentos a serem seguidos para a geração arquivo. Tendo sido demonstrado a partir do exemplo do registro 50 a forma geral de implementação, geração e tratamento de erros de um registro do SEF a partir de informações contidas em um banco de dados. Conforme demonstrado a SEFPE32Dll.dll pode ser usada com qualquer banco de dados (do Paradox ao Oracle) uma vez que seus parâmetros são do tipo String, só é preciso gerar as querys e passar os parâmetros para a dll como tipo String. No próximo artigo da série será descrito todo o processo de validação, visualização e transmissão do arquivo gerado, abordando as ferramentas oficiais disponíveis relacionadas ao tema. 11 Delphi O novo componenteO novo componenteO novo componenteO novo componenteO novo componente TrayIcon do Delphi 2006TrayIcon do Delphi 2006TrayIcon do Delphi 2006TrayIcon do Delphi 2006TrayIcon do Delphi 2006 O novo componenteO novo componenteO novo componenteO novo componenteO novo componente TrayIcon do Delphi 2006TrayIcon do Delphi 2006TrayIcon do Delphi 2006TrayIcon do Delphi 2006TrayIcon do Delphi 2006 Por Claudinei Rodrigues – nei@theclub.com.br O Delphi 2006 traz nativamente um componente que é muito procurado pelos programadores. Com certeza quem ainda não utilizou agora vai utilizar. O componente TrayIcon pode ser encontrado na palheta Additional e é muito simples de ser utilizado. Crie um novo projeto e adicione-o ao formulário. Altere a sua propriedade Visible para True. Agora pressione a tecla F9 para que o projeto seja compilado e executado. Assim que o seu programa for executado, veja que aparecerá um ícone ao lado do relógio na barra de tarefa do seu Windows. Muito simples não? A função básica de um trayicon é permitir ao usuário esconder e restaurar a sua aplicação. Esta é uma maneira muito interessante de manter um atalho para a sua aplicação. Mas este componente não se limita apenas a isto. Ele tem mais recursos que com certeza serão muito úteis a sua aplicação. Trabalhando com o componente Vamos começar com a função básica de um trayicon. Para esconder a sua aplicação você deve executar o método Hide de cada formulário visível. Isto removerá automaticamente o ícone da sua aplicaçãoda barra de tarefas do Windows. O comando Application.Minimize pode opcionalmente ser chamado também, mas note que resultará em uma animação do formulário que está sendo minimizado para a barra da tarefa. É importante que você esconda os formulários a partir do formulário principal, e restaure os formulários na ordem inversa. Isto irá assegurar que a ordem esteja preservada ao restaurar sua aplicação. Isto é muito importante ao tratar os formulários modais. Veja na listagem 1 a rotina que utilizaremos para esconder os formulários de nossa aplicação. procedure TFRM_TrayIcon.Esconde; var i: integer; begin Application.Minimize; for i := 0 to Screen.FormCount - 1 do Screen.Forms[i].Hide; end; Listagem 1: Exemplo para esconder a aplicação Para restaurar a aplicação nós podemos utilizar a rotina mostrada na listagem 2. procedure TFRM_TrayIcon.Restaura; var i: integer; begin for i := Screen.FormCount - 1 downto 0 do Screen.Forms[i].Show; with Application do begin Restore; BringToFront; end; end; Listagem 2: Exemplo para restaurar a aplicação Utilizando um menu Adicionar um menu ao nosso componente trayicon é muito fácil. Para obter este recurso basta adicionar um componente TPopupMenu, que está na palheta Stantard, ao formulário e atribuí-lo à propriedade de PopupMenu do componente TrayIcon. Feito isto, agora vamos adicionar dois itens em nosso componente TPopupMenu. Um para restaurar e outro para sair do programa. Sendo assim, inclua dois itens um com o nome Restaura e outro com o nome Sair. No evento OnClick do item Restaura nós vamos chamar a nossa procedure Restaura, como está sendo mostrado na listagem a seguir. 12 Delphi procedure TFRM_TrayIcon.R1Click (Sender: TObject); begin Restaura; end; No evento OnClick do item Sair nós vamos encerrar a nossa aplicação como está sendo mostrado na listagem a seguir. procedure TFRM_TrayIcon.Sair1Click (Sender: TObject); begin Application.Terminate; end; Agora execute novamente a sua aplicação. Vá até o ícone da sua aplicação que está ao lado do relógio e clique com o botão direito. Ao fazer isto você verá os dois itens do componente de TPopupMenu. Basta clicar sobre eles para realizar os testes. Trabalhando com imagens Por padrão, o ícone utilizado pelo componente TrayIcon é o ícone da própria aplicação, mas você pode carregar um outro ícone através da propriedade Icon ou ainda utilizar um componente ImageList ajustando um valor apropriado para a propriedade de IconIndex. Se você estiver usando um componente ImageList você pode, ainda, animar os ícones ajustando a propriedade Animate do componente TrayIcon para True. Isto fará com que cada ícone na lista do componente TImageList seja indicado por sua vez. Você ainda pode controlar a velocidade desta animação através da propriedade AnimateInterval. Trabalhando com Hints A utilização do hint é muito fácil. Atribua algum texto a propriedade hint e esse texto será apresentado quando o usuário pausar o cursor do mouse sobre o ícone que está no relógio. Se a propriedade Hint estiver vazia então o título da aplicação será mostrado. Se você não sabe como mudar o titulo da sua aplicação faça o seguinte. Vá até o menu do Delphi e clique em Project e depois em Options. Na próxima tela, clique no item Application que estará sendo mostrado do seu lado esquerdo. Do lado direito você tem a opção Title. É ali que fica armazenado o título da sua aplicação. Atenção, o Windows limita o tamanho máximo deste campo em 127 caracteres. Trabalhando com balões de aviso Um recurso bastante interessante é a utilização de avisos. Eu consegui utilizar este recurso a partir do Windows 2000. Você já deve ter visto alguma aplicação que indica sugestões através de um hint de balão. Uma vez que um balão é mostrado para o usuário ele pode fazê-lo desaparecer. Se um usuário não clicar sobre que o balão, o mesmo desaparecerá automaticamente após um determinado tempo. Se o computador estiver inativo, então o balão permanecerá visível até que o usuário comece usar o computador outra vez. O intervalo de parada pode ser ajustado pela aplicação, mas o Windows reforça os valores mínimos e máximos que são ajustados tipicamente entre 10 e 30 segundos. Para fazer com que este aviso seja mostrado é muito simples, veja abaixo o código que estou utilizando no projeto de exemplo que você poderá fazer o download. procedure TFRM_TrayIcon.bt_MostraClick(Sender: TObject); begin // Aqui definimos o icone a ser mostrado if rbErro.Checked then TrayIcon1.BalloonFlags := bfError else if rbInfo.Checked then TrayIcon1.BalloonFlags := bfInfo else if rbAviso.Checked then TrayIcon1.BalloonFlags := bfWarning else if rbNulo.Checked then TrayIcon1.BalloonFlags := bfNone; // Aqui configuramos as informações // e mostramos a mensagem TrayIcon1.BalloonTitle := edTitulo.Text; TrayIcon1.BalloonHint := memMensagem.Lines.Text; TrayIcon1.ShowBalloonHint; end; Listagem x Conclusão Este componente é muito útil e com certeza vai lhe auxiliar bastante no seu dia a dia. Download do projeto em: http://www.theclub.com.br/revista/ download/TrayIcon0306.zip Sobre o autor Claudinei Rodrigues, Consultor Técnico do The Club nei@theclub.com.br 13 Visual Studio Visual Studio 2005 e Visual BasicVisual Studio 2005 e Visual BasicVisual Studio 2005 e Visual BasicVisual Studio 2005 e Visual BasicVisual Studio 2005 e Visual Basic Produtividade no CódigoProdutividade no CódigoProdutividade no CódigoProdutividade no CódigoProdutividade no Código Visual Studio 2005 e Visual BasicVisual Studio 2005 e Visual BasicVisual Studio 2005 e Visual BasicVisual Studio 2005 e Visual BasicVisual Studio 2005 e Visual Basic Produtividade no CódigoProdutividade no CódigoProdutividade no CódigoProdutividade no CódigoProdutividade no Código O Visual Studio 2005 traz diversos controles com recursos inovadores e produtivos, porém a produtividade não para por ai. Muitos recursos relacionados a melhora de produtividade no código fonte foi adicionado trazendo benefícios expressivos aos desenvolvedores. Os dois principais recursos são: Code Snippets e Refactory. Code Snippets Os Snippets são códigos pré-progamados armazenados Principais Vantagens dos Snippets · Maior produtividade do desenvolvedor. · Padronização o Dentro de equipes de desenvolvimento, é muito comum cada desenvolvedor programar a sua maneira, com os Snippets é possível adicionar os padrões específicos de uma empresa e todos os desenvolvedores vão seguir uma codificação única. Categorias A imagem abaixo ilustra as categorias de códigos já adicionados no Visual Studio 2005. Refactory A refatoração do código é uma prática muito utilizada em diversas ferramentas e o Visual Studio não poderia abrir mão deste benefício. O Visual Studio passa a ter esse benefício e isso é muito comemorado pela comunidade .net no mundo todo. Obs: Nas versões beta é necessário baixar o pacote de refactory (www.msdn.com/vbasic). Basicamente refatorar o código significa reescrever um código já programado, porém que não seguiu as melhores práticas de programação, ou que repita mais de uma vez uma funcionalidade idêntica entre outras técnicas. A combinação perfeita A combinação entre Code Snippets e Refatoração é perfeita, podemos ser altamente produtivos utilizando os recursos apresentados. Será criado um exemplo de uma aplicação simples para demonstração dos benefícios apresentados. A aplicação Abra o Visual Studio 2005 e crie um projeto do tipo Windows Aplication com Visual Basic.Net. Adicione um novo formulário chamado frmExemplo conforme a imagem a seguir: Imagem 1 – Categorias já adicionadas. 14 Visual Studio A aplicação é bem simples, em um textbox será exibidoo conteúdo de um arquivo texto localizado no computador ao clicar no botão Exibir. Obs: para o textbox aceitar diversas linhas basta alterar a propriedade multi-line para true. De um duplo clique no botão exibir para a entrada do código. Após aberto o editor de código, clique com o botão direito do mouse dentro do evento click, e clique em Insert Snippet. Imagem 3 – Code Snippet. Ao clicar todas as categorias são exibidas conforme mostrado na imagem 4. Selecione a categoria File System e Read Text From File. Pronto, o código de leitura de arquivo texto é adicionado, com isso é necessário somente complementar o código. Código adicionado: Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim allText As String Try allText = My.Computer.FileSystem. ReadAllText(“test.txt”) Catch fileException As Exception Throw fileException End Try End Sub Todo o conteúdo do arquivo texto é passado para a variável allText, com isso, só devemos adicionar: TextBox1.Text = allText O valor do caminho é passado diretamente dentro do método ReadAllText, porém podemos passar esse valor para uma variável com apenas um clique, simples, basta clicar com o botão direito do mouse sobre o valor Text.txt , Refactor! e Introduce Constant. Com isso automaticamente é criada uma constante com o valor, e o parâmetro é alterado: Private Const STR_Testtxt As String = “test.txt” Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim allText As String Try allText = My.Computer.FileSystem.ReadAllText(STR_Testtxt) TextBox1.Text = allText Catch fileException As Exception Throw fileException End Try End Sub Imagem 4 – Categorias. Imagem 2 – Formulário 15 Visual Studio Altere o valor da variável para um caminho válido de qualquer arquivo texto, execute a aplicação e pronto, a aplicação já está funcionando. O que podemos concluir: “Digitamos” oito linhas de código, como o mouse. Isso foi um simples exemplo de muitos outros códigos já contidos no Visual Studio. Explorando outros recursos de refatoração No mesmo projeto, adicione uma nova classe clExemplo.vb. Crie uma sub simples chamada ExibirMensagem conforme abaixo: Public Sub ExibirMensagem(ByVal Nome As String, ByVal Idade As Integer) MessageBox.Show(“Nome: “ & Nome & “ - Idade: “ & Idade) End Sub Adicione outra sub Teste para a chamada da sub, chame diversas vezes como valores diferentes conforme abaixo: Private Sub Teste() ExibirMensagem(“Alexandre”, 23) ExibirMensagem(“João”, 45) ExibirMensagem(“Maria”, 53) ExibirMensagem(“Jorge”, 73) ExibirMensagem(“Bill”, 99) ExibirMensagem(“Joaquim”, 2) ExibirMensagem(“Mario”, 28) End Sub Agora vem a melhor parte, clique com o botão direito do mouse sobre o parâmetro Nome da sub ExibirMensagem, Refactor, Reorder Parameters conforme abaixo mostrado na imagem 5. Com isso é possível reordenar os parâmetros, clique com a seta para direita e com um efeito muito interessante os parâmetros são invertidos conforme mostrado na imagem 6. Para confirmar dê um enter, com isso todas as chamadas da sub passam a ter problema, pois os parâmetros ficam invertidos. Automaticamente é avisado o problema conforme imagem 7. Duas opções são dadas: Alterar um a um (Enter) ou todos (Ctrl + Enter), e com isso todas as chamadas podem ser alteradas. Imagine isso em um projeto com chamadas em diversos formulários!? Para criar um overload da sub ExibirMensagem é muito simples, clique com o botão direito do mouse sobre ExibirMensagem, Refactor! e Create Overload. Confirme com um enter e já é duplicado o código solicitado. Conclusão A produtividade no código está muito maior com esses dois recursos principalmente combinando a utilização deles, use e abuse dessas facilidades e consiga uma produtividade e qualidade muito maior em suas aplicações. Imagem 5 – Instruções de refatoração. Imagem 6 – Parâmetros invertidos. Imagem 7 – Parâmetros invertidos na chamada. 16 Criando arquivo de instalaçãoCriando arquivo de instalaçãoCriando arquivo de instalaçãoCriando arquivo de instalaçãoCriando arquivo de instalação para projeto Web (Windows Installer)para projeto Web (Windows Installer)para projeto Web (Windows Installer)para projeto Web (Windows Installer)para projeto Web (Windows Installer) Visual Studio Quando me deparei desenvolvendo minha primeira aplicação Web, uma das minhas preocupações foi pensar em como iria distribuií-la entre meus clientes, uma vez que a instalação de um WebSite implicaria em Configurar o IIS (Internet Informatiom Service) criando um diretório virtual, dando permissões de execução entre outras tarefas. Assim, vou abordar neste artigo, um recurso simples e de grande utilidade para o desenvolvedor que é a criação de arquivo de instalação para aplicação web. Preparativos Quando formos distribuir uma aplicação seja ela de qualquer tipo, WebForms ou WinForms, temos que definir quais os arquivos que realmente são necessários de serem instalados no cliente. No caso da aplicação web estes arquivos são gerados quando o Web site é publicado pelo Visual Studio, assim como neste artigo a finalidade é criar apenas uma instalação da aplicação e não publicá-la num servidor web, vamos criar um diretório chamado D:\Arquivos_Instalação onde iremos “publicar” os arquivo que realmente são úteis na instalação. Para isto na solução web (que no exemplo se chama TC_Website) clique com o botão direito sobre o projeto e selecione a opção Publish Web Site (Imagem 1). Na janela Publish Web Site apenas informe o Taget Location (Imagem 2), que é o diretório criado para conter meus arquivos compilados e outros arquivos como web.config, arquivos de dados, temas e estilos. Ao confirmar este processo veja que no diretório foram gerados todos os arquivos que deverão ser distribuídos no cliente para o perfeito funcionamento da aplicação. Criando arquivo de instalaçãoCriando arquivo de instalaçãoCriando arquivo de instalaçãoCriando arquivo de instalaçãoCriando arquivo de instalação para projeto Web (Windows Installer)para projeto Web (Windows Installer)para projeto Web (Windows Installer)para projeto Web (Windows Installer)para projeto Web (Windows Installer) Por Marcos César Silva Imagem 2 Imagem 1 Sobre o autor Marcos César Silva, Consultor de Sistemas e Consultor Técnico do The Club, Bacharel em Ciência da Computação, MCAD (Microsoft Certified Application Developer) e MCSD.NET (Microsoft Certified Solution Developer .NET) marcos@datasmart.com.br 17 Veremos mais à frente que para usarmos em nosso projeto de instalação estes arquivos compilados de forma que sejam acessíveis ao projeto, devemos adicionar na solução o diretório de arquivos de instalação como um WebSite já existente. Assim em Solution Explorer File selecione Add -> Existing Web Site e selecione o D:\Arquivos_Instalação onde estão os arquivos que acabamos de publicar (Imagem 3). Ao confirmar esta operação o Visual Studio irá exibir uma mensagem informando que você deseja abrir um WebSite pré-compilado, continue confirmando no botão sim. Imagem 3 O instalador Agora vamos a criação do projeto de instalação. Para criá-lo clique com o botão direito sobre a solução existente em Solution Explorer File e selecione Add -> New Project , em Project Types vá em Other Project Types - > Setup and Deployment e Selecione a opção Web Setup Project, em Name informe o nome do novo projeto onde neste exemplo chamará TC_WebSetup, e em Location informe o diretório desejado para a criação deste projeto (Imagem 4). Ao criar o projeto, você observará que um Folder chamado Web Application Folder será criado (ondeneste caso estaremos visualizando o File System do projeto), nesta pasta conterá todos os arquivos e pastas de nosso Website. Veremos agora que temos duas maneiras de relacionar os arquivos ao projeto, a primeira seria selecionado arquivo a arquivo, onde para isto clique com o botão direito do mouse sobre a pasta Web Application Folder e selecione Add - > Web Folder, após criar todas as pastas e subpastas do site, adicione os arquivos que serão publicados nas suas respectivas pastas clicando com o botão direito sobre a pasta Web Application Folder e selecione Add - > File. Nesta primeira situação que considero menos eficiente e mais trabalhosa, teríamos o problema onde no caso de alteração do projeto adicionando ou removendo arquivos, o projeto de instalação ficará desatualizado tendo assim que corrigí-lo a cada mudança do projeto web. Assim, a maneira que considero mais adequada será o segundo método, que é adicionar ao Web Application Folder um Project OutPut, assim, clique com o botão direito do mouse sobre a pasta Web Application Folder e selecione Add - > Project OutPut (Imagem 5), ao exibir a caixa de diálogo Add Project Output Group (Imagem 6) selecione em Project D:\Arquivos_Instalação. Desta maneira a cada novo Release de instalação serão lidos sempre os arquivos e pastas que estão no diretório dos arquivos para instalação, necessitando apenas que a cada alteração seja “Publicado” neste diretório nosso Website. Desta forma não teremos que alterar nada no projeto de instalação, o que não iria acontecer caso tivéssemos configurado nosso projeto da primeira maneira mencionado acima.Imagem 4 Visual Studio 18 Imagem 5 Imagem 6 Configurações Para que nossa aplicação funcione perfeitamente necessitamos configurar pelo menos o Virtual Directory do IIS, para isto selecione a pasta Web Application Folder e em Properties na propriedade VirtualDirectory digite TC_WebSite, propriedade responsável por indicar o nome do diretório Virtual que será criado no IIS e o nome do diretório de instalação da aplicação web. Outras propriedades do instalador podem ser definidas no próprio projeto assim selecione em Solution Explorer o projeto WebSetup1, veja abaixo algumas propriedades úteis para personalizar a aplicação. (ver tabela a seguir) Podemos também traduzir as mensagens das caixas de diálogo da instalação, para isto com o botão direito no projeto de instalação selecione a opção View -> User Interface, verá assim todos os Diálogos de interface do usuário (Imagem 7). Propriedade Descrição AddRemoveProgramIcon Define o ícone exibido emAcionar/Remover Programa Autor Autor da Aplicação Manufacturer Nome da Empresa ManufacturerURL URL da Empresa ProductName Nome do Produto RestartWWWService Especifica se IIS irá para e reiniciar o serviço na instalação da aplicação Title Titulo do instalador Version Numero da versão daaplicação Finalmente vamos gerar o instalador, com o botão direito no projeto clique em Build, após o termino verá que no diretório \Release do projeto de instalação foi criado o arquivo setup.exe. Conclusão Observando com maior atenção os recursos disponíveis no Visual Studio para a criação do projeto de instalação, veremos que temos um grande leque de possibilidades na instalação de nossas aplicações, mas podemos também observar neste artigo o quanto pode ser simples a criação de um projeto de instalação de uma aplicação web, recurso este simples, mas de grande utilidade para o desenvolvedor. Vou ficando por aqui, um abraço a todos e até o próximo artigo. Imagem 7 Visual Studio 19 Delphi, uma questão deDelphi, uma questão deDelphi, uma questão deDelphi, uma questão deDelphi, uma questão de sobrevivênciasobrevivênciasobrevivênciasobrevivênciasobrevivência Delphi Delphi, uma questão deDelphi, uma questão deDelphi, uma questão deDelphi, uma questão deDelphi, uma questão de sobrevivênciasobrevivênciasobrevivênciasobrevivênciasobrevivência Salve, salve Delphianos! Durante uma longa jornada de 11 anos tivemos em nossas mãos o que pode ser chamado de “O ESTADO DO ARTE” das ferramentas de desenvolvimento, o todo poderoso Delphi. Quantos milhares de projetos foram desenvolvidos com essa fantástica ferramenta? Quantos Delphianos nasceram neste período? Quantas batalhas conquistamos por conta do poder da ferramenta? Quantos sorrisos e alegrias ganhamos de clientes, gerentes e diretores após apresentar um nobre projeto desenvolvido com as novas tecnologias que surgiam a cada versão? Quantas apostas ganhamos de amigos que trabalhavam com ferramentas concorrentes? Delphianos ainda temos uma longa batalha pela frente, mas vamos relembrar um pouco nosso passado de glórias. Delphi 1 A primeira versão entrou timidamente no mercado, mas aos poucos foi conquistando seus seguidores. Desde estudantes até grandes corporações, incluindo aí o Governo Federal, que corajosamente desenvolveu um dos mais grandiosos projetos do mundo: IRPF. Delphi 2 Em 1995 a Microsoft lançou o seu sistema operacional de 32 bits: Windows 95, e logo em seguida a nossa Nave-Mãe, Borland, colocou no mercado a versão 2 do glorioso Delphi, que trazia como principal mudança o compilador para 32bits, além da VCL com novos controles da API Win32. Novos adeptos e simpatizantes entraram no Clube dos Delphianos! Delphi 3 Já em 1997 tínhamos uma tecnologia em franca expansão: Internet! Existiam poucas linguagens de desenvolvimento que contemplavam a tecnologia. Eu utilizava o Perl para gerar scripts CGI (Common Gateway Interface). Minhas aplicações eram executadas em sistemas operacionais baseados em UNIX. Sinceramente eu achava o máximo ver meu banco de dados na Web, mas um pouco incomodado com a falta de recursos e uma IDE completa para facilitar o ciclo de desenvolvimento. Eis que surge a versão 3 do Delphi (meados de 1997), com uma grata surpresa: WebBroker, uma das mais fantásticas tecnologias para desenvolvimento de aplicações Web. Até hoje surgem tecnologias baseadas em WebBroker. Sensacional! Delphi 4 O número de Delphianos não parava de crescer, assim como os milhares de sites especializados. Em meados de 1998, foi lançada a versão 4 da ferramenta, com pequenas mudanças. Na época alguns engraçadinhos previam o fim da hegemonia Borland. Estavam completamente enganados. A energia positiva iluminava a criatividade dos engenheiros da Nave-Mãe, que surpreendiam o mundo com grandes novidades, conquistando uma grande parcela de simpatizantes e uma excelente posição no ranking das maiores empresas de software do mundo. Delphi 5 Dessa energia surgiu uma das mais estáveis e produtivas versões: Delphi 5 (minha preferida). Com forte melhoria na tecnologia Midas (presente desde a versão 3), o suporte ao ADO e a estabilidade do WebBroker. Delphi 6 Em 2001, quase 2 anos após o lançamento da versão 5, estréia no mercado a versão 6, com dezenas de novidades: nova 20 Delphi IDE, DataSnap, WebSnap e BizSnap, debugger integrado para aplicações Web, entre outras. Realmente foi um grande salto, mas haviam alguns problemas que incomodavam o desenvolvedor. A Borland trabalhou rápido, corrigindo alguns bugs, investindo em novos componentes e parceiros, e lançou o todo poderoso Delphi 7. Delphi 7 Sete, um número místico, ideal para a nova versão, que trazia consigo o revolucionário Intraweb, encorajando a todos adentrarem o mundo Web. Além disso, disponibilizou uma nova ferramenta para criação de relatórios, o Rave Reports. Outra grande novidade despertou o interesse de muitos: NET Preview. Sim, a Borland disponibilizou uma ferramenta integrada à IDE, que compilava Delphi Language para plataforma .NET. Era apenas o começo. Delphi 8 Eis que surge a versão 8 for .NET. Isso mesmo Delphi 8 for .NET. Totalmente remodelada com centenas de novidades na IDE e o suporte total à plataforma.NET. Imagine desenvolver aplicações .NET com uma linguagem que você domina!? Imaginou? Pois bem, a ferramenta não decolou! Haviam dezenas de problemas, a barreira da nova plataforma, entre outras barreiras. Delphi 2005 Seria a salvação? Pelo menos a Borland agilizou e criou (ressucitou) o BDS (Borland Developer Studio) integrando as linguagens Delphi Language, C# e VB.Net (para algumas soluções). Isso mesmo: VB.Net. Ok, mas esta não é a questão. A questão aqui é que o Delphi estava perdendo grande terreno para as outras tecnologias (Java e .Net). Sinceramente pensei que a versão 2005 daria a volta por cima e conquistaria novamente os Delphianos. Infelizmente isso não aconteceu! Mas a batalha continuou... Delphi 2006 Com grande alarde o Delphi 2006 foi lançado. Dezenas de novas features, uma nova implementação da tecnologia ECO, melhorias no compilador, correções na IDE, entre outros recursos inteligentes. Ao meu ver o único problema é que a implementação .Net contempla apenas a versão 1.1 da tecnologia, sendo que a 2.0 com centenas de novos recursos já está quente na ferramenta concorrente. Além disso não foi implementado de maneira plena o C.F. (Compact Framework), que segundo a Borland não foi licenciado pela Microsoft. Ok Delphianos, fizemos um rápido passeio entre as versões, mas uma questão ainda assombra o nosso mercado. Será que o Delphi irá sobreviver? Com o anúncio da Borland sobre a possível venda das IDEs para outra empresa, assustou ainda mais o mercado. Gerou dúvidas em todos os Delphianos. Seria esse o fim do Delphi? Sinceramente não vejo desta forma, já que a Borland irá continuar com parte do controle dessa nova empresa, além de termos que garantem a constante atualização das ferramentas. Obviamente não teremos a Microsoft dentro desse grupo, por questões éticas e pela saudável concorrência no mercado. Agora imagine se um gigante como o Google (houve especulação no mercado) adquire parte dessa nova empresa? Ou então uma IBM, eterna concorrente Microsoft? Bem, como todos vocês sabem, prefiro o Visual Studio 2005 por diversas razões: . trabalha com .net framework 2.0 . estável . compact framework . fácil implantação de sistemas . custos . mercado . curva de aprendizado muito pequena . entre outras. Mas o que poucos sabiam é que eu nunca irei abandonar o glorioso Delphi, que aliás ainda sustenta esse que vos escreve. Finalizando, vale a dica: estudem framework 2.0, conheçam o Visual Studio 2005, trabalhem com a linha Express do VS, explorem todo o potencial do .Net, dominem o C#, e se tiverem coragem como eu, estudem também Visual Basic .Net. O mercado está aí, esperando por você! Forte abraço e muito sucesso! Facunte. Sobre o autor Emerson Facunte, é Consultor de Tecnologia com diversos livros publicados, especialista em desenvolvimento de aplicações e-business. emersonf@livrariasaraiva.com.br 21 Delphi Durante o desenvolvimento de uma aplicação qual o desenvolvedor não se deparou com a duvida de saber qual gerador de relatório iria utilizar? Diversas vezes fui questionado por amigos desenvolvedores me pedindo sugestões sobre boas ferramentas geradoras de relatórios, quando começava a falar o nome de algumas como ReportBuilder, CristalReport entre outras, vinha a segunda pergunta que era: Estas “Estas ferramentas são free?” E quando dizia que “não” já esperava ao reação de desaprovação de meus colegas desenvolvedores, assim muitos deles continuavam a utilizar o QuickReport. Bom, alguns de vocês devem estar pensando: “Mas também posso utilizar o Rave Report a partir do Delphi 7”, realmente quem está pensando isto têm razão, mas observei que algumas pessoas que já estava acostumado a utilizar o QuickReport tinham dificuldade de se adaptar com RaveReport e continuavam a utilizá-lo mesmo reclamando da falta de alguns recursos ou de outros problemas. Algum tempo atrás tive contato com uma ferramenta que me chamou a atenção, com o conceito de trabalho e interface baste parecido com o nosso bom e velho Quickreport, esta ferramenta geradora de relatório chamada FortesReport da empresa Fortes Informática, nos mostra ser uma boa opção, por possuir um Report Designer de desenvolvimento bastante familiar e recurso e filtros bastante interessantes e úteis nos quais veremos mais a seguir. 1. A instalação O ForteReport pode ser baixando do site do fabricante www.fortesreport.com.br, sugiro também baixar o Help do pacote que contém os arquivos no formato windows hlp para o FortesReport, inclusive com o instalador do help. Verá que na área de downloads existe 2 versões disponíveis do pacote, para algumas das versões do Delphi VCL ou CLX, C++Builder ou Kylix, para nossos exemplos iremos baixar a versão 3.23 para Delphi 7 VCL. A instalação é bastante simples, para isto siga os seguintes passos: Agora chame o seu Delphi. Aqui nós vamos trabalhar no Delphi 7. Estando com o seu Delphi aberto, vá até o menu Tools - > Environment Options e clique na aba Library como mostrado na figura a seguir: Por Marcos César Silva Fortes Report - Uma boa opção deFortes Report - Uma boa opção deFortes Report - Uma boa opção deFortes Report - Uma boa opção deFortes Report - Uma boa opção de gerador de relatório Freewaregerador de relatório Freewaregerador de relatório Freewaregerador de relatório Freewaregerador de relatório Freeware Fortes Report - Uma boa opção deFortes Report - Uma boa opção deFortes Report - Uma boa opção deFortes Report - Uma boa opção deFortes Report - Uma boa opção de gerador de relatório Freewaregerador de relatório Freewaregerador de relatório Freewaregerador de relatório Freewaregerador de relatório Freeware Clique no botão que fica ao lado direito do item Library Path para que possamos incluir o caminho onde foi descompactado o componente. Ao clicar no botão você verá uma tela igual à mostrada a seguir: 22 Delphi Informe o path como foi mostrado na tela anterior e depois clique no botão Add e depois em Ok. Agora vamos adicionar o componente. Agora volte ao menu do Delphi em Component -> Install Packages. Feito isto você terá uma tela semelhante a seguir: Clique no botão Add e vá até o diretório D:\Comps\RLibD7vcl.3.23 e localize o arquivo RLibWinD7vcl.bpl. Depois de selecionar o arquivo clique no botão Open e depois no botão OK. Pronto o seu componente já está instalado. 2. Visão geral dos componentes 2.1. Bandas · RLReport O componente RLReport contém as definições do relatório e também é o Container de componentes de impressão do pacote · RLBand Banda de impressão que para representar registros de dados ou quebras de seqüências de dados, uma característica interessante é que a banda além de pode ser deve inserida dentro de um Report, também pode ser colocada dentro de outras bandas do tipo Group ou SubDetail. Sendo o comportamento da banda controlada a partir da propriedade BandType. · TRLBandType (btHeader, btTitle, btColumnHeader, btDetail, btColumnFooter, btSummary, btFooter); · RLDetailGrid Banda semelhante a uma banda detalhe, mas com a característica de impressão de colunas; · RLGroup Banda de quebra de grupos de impressão; · RLSubDetail Banda para impressão de Subdetalhes; 2.2. Componentes de Texto 23 Delphi · TRLLabel Caixa de texto padrão; · TRLDBText Caixa de texto ligada a campo de dataset; · TRLMemo Caixa de texto multilinhas; · TRLDBMemo Caixa de texto multilinhas ligada a campo de dataset; · TRLAngleLabel Caixa de texto, onde o texto pode ser rotacionado no ângulo desejado; · TRLRichEdit Caixa de texto multilinhas em formato de texto RTF; · TRLDBRichEdit Caixa de texto multilinhas em formato de texto RTF ligada a campo de dataset; 2.3. Filtros de Impressão · RLDraftFilter Implementação do filtro de impressão draft. · RLRichFilter Implementaçãodo filtro para geração de arquivos no formato RichText. · RLHTMLFilter Implementação do filtro para criação de páginas web. · RLPDFFilter Implementação do filtro para criação de arquivos PDF. · RLXLSFilter Implementação do filtro para criação de planilhas do Excel. 3. Exemplo 3.1. Os dados Primeiramente antes de começarmos a trabalhar com os componentes do pacote gerador de relatórios iremos criar os componentes de acesso a dados, assim após criarmos um novo projeto no delphi em File | New | Application, adicione dois ClientDataSets e dois DataSources no form principal criado na criação do projeto. Como neste artigo não tenho intenção de explorar a conexão com o banco de dados, vou criar um simples relacionamento mestre detalhe entre arquivos XML, usando os ClientDataSets com os arquivos Customer.xml e Orders.xml que encontram-se no diretório C:\Arquivos de programas\Arquivos comuns\Borland Shared\Data\, veja abaixo as propriedades configuradas dos componentes: ClientDataSet 1 (Mestre) DataSource 1 Propriedade Valor Name cdsMaster FileName C:\Arquivos de programas\Arquivos comuns\Borland Shared\ Data\customer.xml IndexFieldNames CustNo Propriedade Valor Name dsMaster DataSet cdsMaster Propriedade Valor Name cdsDetalhe FileName C:\Arquivos de programas\Arquivos comuns\Borland Shared\Data\orders.xml IndexFieldNames CustNo MasterSource dsMaster MasterFiels CustNo Active True ClientDataSet 2 (Detalhe) 24 Delphi Propriedade Valor Name dsDetalhe DataSet cdsDetalhe DataSource 2 3.2. O Relatório Agora sim vamos aos componentes do relatório, no form adicione um component RLReport e altere as seguintes propriedades: RLReport1 Propriedade Valor DataSource dsMaster Title The Club - Usando Fortes Report Dentro deste componente adicione um RLBand que será o cabeçalho, para que ele se comporte assim altere sua propriedade BandType para btHeader, nele adione os RLlabel para exibirmos o cabeçalho desejado. Adicione mais uma RLBand no RLReport, observe que a propriedade BandType desta banda está como btDetail, assim ela irá listar todos os registros da tabela Mestre. Continuando no componente RLReport adicione um RLSubDetail e altere as seguinte propriedades: RLSubDetail1 Propriedade Valor Margins | LeftMargin 10 DataSource dsDetalhe Dentro da banda RLSubDetail adicione duas bandas RLBand onde a primeira será a banda responsável por exibir os registros da tabela detalhe, logo onde deverão ser inseridos os componentes de texto, a segunda banda será a banda de sumario onde iremos totalizar o valor dos registros detalhes impressos para cada registro mestre, assim altere a propriedade BandType desta ultima banda para btSummary. Veja que estas ultimas duas bandas inseridas dentro da banda RLSubDetail ficaram alinhadas a partir da margem esquerda definida na banda RLSubDetail. Na banda definida para ser um sumario adiciono o componente RLDBResult1, responsável por somar os valores da coluna desejada, e altere as seguintes propriedades: Propriedade Valor Propriedade Valor DataSourde dsDetalhe DataField AmountPaid Info riSum Title Total MasterFiels CustNo Active True RLDBResult1 Finalmente iremos adicionar um botão de preview e inserir no seu evento OnClick a chamada do Preview do componente RLReport: procedure TForm1.Button1Click(Sender: TObject); begin RLReport1.Preview; end; 4. Recursos Adicionais Este gerador de relatório possui diversos outros recursos e componentes que ainda não foram mencionados neste artigo, como não seria possível num único artigo comentar sobre todos eles, veja abaixo alguns destes recursos que elegi como sendo úteis e interessante: 4.1. Mensagens Multilíngua O Fortes Report possui um unit chamada RLConts com mensagens definidas em 3 diferentes idiomas estas mensagem estão em variáveis da unit e podem ser alteradas conforme a necessidade veja abaixo algumas destas variáveis (parte da tabela retirada do site do fabricante). (ver tabela a esquerda.) As bandas do FortesReport podem ser adicionadas em Frames (Containers), permitindo assim que todas as configurações a características definidas e criadas na banda 25 Imagem do layout do Relatório Variável Significado Meaning Signification* LS_PrintingInProgressStr Imprimindo... Printing... Impression... LS_PreparingReportStr Preparando o relatório... Preparing report... Préparation du rapport... LS_PrinterNotFoundStr Não há impressora cadastrada Printer not found Imprimante non trouvée LS_LoadDefaultConfigStr Será carregada a configuraçãopadrão Load default configuration Chargement de la configuration standard Sobre o autor Marcos César Silva, Consultor de Sistemas e Consultor Técnico do The Club, Bacharel em Ciência da Computação, MCAD (Microsoft Certified Application Developer) e MCSD.NET (Microsoft Certified Solution Developer .NET) marcos@datasmart.com.br possam ser reaproveitadas, permitindo assim termos cabeçalhos e rodapés padrão que podem ser reaproveitados em todos nossos relatórios 4.3. Filtros Os Filtros permitem salvamos nossos relatórios em diversos formatos de arquivos como RTF, HTML, PDF ou XLS, bastando apenas incluir o componente de filtro desejado no form do Relatório para que no Preview | Salvar Como.. Tenhamos a opções de salvamento do relatório. 5. Conclusão Como já foi dito o FortesReport possui diversos outros recursos a serem explorados, mas já nos mostrou ser um boa opção de gerador de relatório como acredito que puderam constatar neste artigo, não se esquecendo de lembrar que é freeware o que é razão de alegria de muitos amigos desenvolvedores. Caro amigo leitor um grande abraço e até o próximo artigo Delphi 26 Pergunta: Estou tentando compilar um exemplo que peguei no site do The Club,http://www.theclub.com.br/revista/download/ AcessandoFirebird.zip e estou recebendo o erro Bad file format: ‘C:\Giovani\Acessandofirebird\Firebird.Data.Firebird.dcpil’. Como resolver este problema? Resposta: Você está recebendo este erro porque este exemplo foi desenvolvido no Delphi 8. Para resolver, feche o Delphi, delete este arquivo, chame o Delphi novamente e compile o sistema. O problema estará resolvido. Dúvida enviada por Giovani, Caxias do Sul – RS Pergunta: Existe alguma forma de fechar todas as tabelas de uma aplicação? Estou utilizando o BDE. Resposta: Para fechar todas as tabelas, você pode utilizar o objeto Session, por exemplo: var i: integer; begin with Session do for i:= 0 to DatabaseCount - 1 do Databases[I].Close; end; Dúvida enviada por João, Barretos – SP Pergunta: Preciso verificar se um diretorio existe, se existir mostrar mensagem ao usuario para excluir ou nao o diretorio. O diretorio será passado por parametro. Preciso tambem de renomear um diretorio. Como faço estas duas coisas, pois tentei de varias maneiras sem sucesso. Resposta: Para verificar se o diretório existe, você pode utilizar a função DirectoryExists, o exemplo abaixo verifica se o diretório existe. Caso contrário o diretório é criado. uses FileCtrl; procedure TForm1.Button1Click(Sender: TObject); begin if not DirectoryExists(‘c:\temp’) then if not CreateDir(‘C:\temp’) then raise Exception.Create(‘Cannot create c:\temp’); end; Para deletar o diretorio, você pode utilizar a função RemoveDir, por exemplo: RemoveDir(‘c:\temp’); Para renomear um diretório você pode utilizar a rotina abaixo: procedure TForm1.Button1Click(Sender: TObject); var f : file; begin AssignFile(f, ‘C:\2’); Perguntas & Respostas 27 Perguntas & Respostas Canvas.TextOut(5, 10, ‘Renomeando C:\2 para C:\3’); Rename(f, ‘C:\3’); end; Dúvida enviada por Bruno, Três Pontas – MG Pergunta: Existe alguma forma, de pegar o valor docomponente QRExpression do QuickReport. Pois tenho este componente para somatório, e estou necessitando utilizar o valor gerado por ele. Resposta: Para pegar o valor de um QRExpression você pode utilizar a instrução QRExpr1.Value.dblResult. Veja o exemplo abaixo pegando o valor e atribuindo a um QRLabel. procedure TForm1.QRLabel4Print(sender: TObject; var Value: String); begin Value := FloatTostr(QRExpr1.Value.dblResult); end; Dúvida enviada por Alessandro, Araras – SP Pergunta: Gostaria de ver um exemplo para a criação de aplicações em pacotes. Há alguma matéria publicada? Resposta: Nós temos uma matéria a este respeito que pode ser acessada no link http://www.theclub.com.br/revista/ pacotes.doc. Dúvida enviada por Rafael, Belo Horizonte – MG Pergunta: Gostaria de saber como faco para criar uma rotina dentro da minha aplicacao onde o proprio usuario possa rodar os scripts de atualizacao do sistema(Banco de dados). Existe algum componente que faca este tipo de execucao, onde eu coloco os scrip sql num arquivo e o componente executa o mesmo. Resposta: Para rodar scripts no banco de dados você pode utilizar um componente chamado SQLScript que pertence ao DBExpressPlus. O DBExpressPlus é uma suíte de componentes gratuítos que facilitam a execução de tarefas comuns no dia-a-dia do programador Delphi. Você poderá fazer o download do DBExpressPlus no seguinte endereço: http://sourceforge.net/projects/dbexpressplus A instalação é bastante simples, basta descompactar o arquivo baixado preferencialmente criando uma pasta em $(Delphi)\Source\dbExpressPlus, onde “$(Delphi)” indica a pasta de instalação de seu Delphi. Após isso, abra o pacote dbExprPlus_r?0.dpk (?=versão do Delphi, 6 ou 7) e clique no botão “Compile”. Continuando, abra o pacote dbExprPlus_d?0.dpk, clique em “Compile” e depois em “Install”. Para concluir, acesso o menu “Tools | Environment Options | Library | Library Path” e adicione o path onde os arquivos foram descompactados, ou seja, $(Delphi)\Source\dbExpressPlus e com isso finalizamos a instalação do dbExpressPlus. Se tudo ocorreu sem problemas, você poderá visualizar os novos componentes na paleta de componentes dbExpress. Para conhecer as funcionalidades de todos os componentes, você poderá abrir o projeto de exemplo que acompanha o dbExpressPlus, podendo ser encontrado na pasta Demo ($(Delphi)\Source\dbExpressPlus\Demo). Dúvida enviada por Sebastião, Salvador – BA Pergunta: Por favor, necessito pegar a tabela de Nota/Item Fiscal e envia-los para um cliente no formato xml. Como faço para gerar um arquivo xml a partir do delphi?? Vocês teriam algum projeto exemplo para me enviar???? Resposta: Nós temos duas matérias sobre este assunto que podem ser localizadas em nossa Home page nos links: http://www.theclub.com.br/revista/tran0403.aspx: http://www.theclub.com.br/revista/tran0503.aspx. Duvida enviada por Wagner, Campinas - SP 28 Dicas & Truques Problemas para executar aplicações ASP.NET com Delphi 2005. Aparece a mensagem Unable to attach to ASP.NET worker process (typically aspnet_wp.exe or w3wp.exe)”. Para resolver o problema basta registrar o .NET framework para o IIS. Abra a caixa de dialogo Executar (Clique no botão Iniciar, e Executar), digite o texto abaixo e clique no botão OK: c:\windows\microsoft.net\framework\v1.1.4322\ aspnet_regiis.exe -i Pronto, feche o Delphi 2005 e compile o sistema novamente. Arredondar casas decimais de forma personalizada Na seção de procedures digite: Function Arredondar (value: double;casas : integer): double; Na seção implementation digite a função conforme descrita abaixo. Function Tform1.Arredondar(value: double;casas : integer): double; Var fracao, Total:real; decimal:string; begin try fracao:=Frac(value); //Retorna a parte fracionária de um número decimal:=(RightStr(floattostr(fracao), length(floattostr(fracao))-2)); //decimal recebe a parte decimal //enquanto o tamanho da variavel decimal for maior que o número de casas faça while length(decimal) > casas do begin //Verifica se o último digito da variável decimal é maior que 5 if strtoint(RightStr(decimal,1))>5 then begin //Descarta o último digito da variável Decimal decimal:=leftstr(decimal,length(decimal)-1); //Soma o valor número da variavel decimal + 1 decimal:=floattostr(strtofloat(decimal) + 1); end else decimal:=leftstr(decimal,length(decimal)-1); //Descarta o último digito da variável 29 Decimal end; result:=(int(value) + (strtofloat(decimal)/ 100)); //devolve o resultado para a função except Raise Exception.Create(‘Erro no arredondamento’); end; end; Como usar... arredondar(Campo ou vaiável do tipo Real (Float) , número de casas decimais desejado); Ex: Var valor,Resultado:real; Valor:=10.005.526 Resultado :=Arredondar(valor,2); Resultado=10.005,53 Obs: O codigo foi escrito em Delphi 6 porém isso não a impede de funcionar no Delphi 4 ou 5, é pouco provavel que ocorra erro. Verificar o estado de uma tabela procedure CheckState(ATable: TTable); var strMessage : String[25]; wrdMessageResult : word; begin ATable.UpdateRecord; { Atualiza a tabela sem gravar } if ( ATable.Modified ) and ( ATable.State <> dsSetKey ) then begin if ATable.State = dsEdit then strMessage := ‘Editando registro, ‘; if ATable.State = dsInsert then strMessage := ‘Inserindo registro, ‘; wrdMessageResult := MessageDlg(strMessage+ ‘as informações que ainda não ‘+ ‘foram salvas serão perdidas!’+#10+ ‘Salva as informações ?’, mtConfirmation, [mbYes,mbNo,mbCancel],0); case wrdMessageResult of mrCancel: Abort; mrYes : ATable.Post; mrNo : ATable.Cancel; end; end else ATable.Cancel; end; Verificando se um alias está instalado var vList: TStringList; x: Integer; begin vList := TStringList.Create; Session.Open; Session.GetAliasNames(vList); if vList.Find(‘NomeDoAlias’, x) then // x receberá a posição do alias na lista // Alias encontrado else // Alias não encontrado end; Que usuário está logado na rede? Existe na API do BDE uma funcao chamada DbiGetNetUserName, que retorna o nome do usuário logado. Tente o seguinte: function GetUserName:string; var Nome: array[0..64] of char; begin if DbiGetNetUserName(Nome) <> DBIERR_NONE then Nome:=’’; Result:=StrPas(Nome); end; Usando Locate com mais de um campo Use VarArrayOf() no segundo parâmetro. Return := Table1.Locate(‘Campo1;Campo2’, VarArrayOf([Campo1, Campo2]), []); Dicas & Truques 30 procedure TForm1.Button2Click(Sender: TObject); var vList: variant; begin vList := VarArrayCreate([0, 1], varVariant); vList[0] := ‘Christiansted’; vList[1] := ‘VIP Divers Club’; table1.locate(‘city;company’, vList, []); end; Testa se a janela está aberta Testa se a janela ja foi criada. Obs.: Coloque no evento OnCreate do form: if IsWindowInMemory (Self.Caption) then ----------- Halt; function IsWindowInMemory (WndTitle : String) : Boolean; var hSem : THandle; hWndMe : HWnd; begin Result := False; hSem := CreateSemaphore (nil, 0, 1, ‘NomeDoSemaforo’); if (hSem <> 0) and (GetLastError() = ERROR_ALREADY_EXISTS) then begin CloseHandle (hSem); hWndMe := FindWindow (nil, PChar (WndTitle)); SetWindowText (hWndMe, ‘olzfgowtjoyug’); hWndMe := FindWindow (nil, PChar (WndTitle)); if hWndMe <> 0 then begin if IsIconic (hWndMe) then begin ShowWindow (hWndMe, SW_SHOWNORMAL); end else begin SetForegroundWindow (hWndMe); end; end; Result := True; end; end; Verificar se o programa já está aberto program Project1; uses Forms, Windows, Unit1 in ‘Unit1.pas’ {Form1}; {$R *.RES} // Declare a variavel var Hwnd : THandle; begin // FindWindow vai procurar pela classe TApplication // que tenha o nome do Title que vc configurou Hwnd := FindWindow(‘TApplication’, ‘Teste’); // se o Handle e’ 0 significa // que naoencontrou if Hwnd = 0 then begin Application.Initialize; // Esta linha e’ colocada automaticamente pelo Delphi // ao se configurar o Title Application.Title := ‘Teste’; Application.CreateForm(TForm1, Form1); Application.Run; end else // Esta funcao traz para frente (da o foco) // para a janela // da aplicacao que ja esta rodando SetForegroundWindow(Hwnd); end. Dicas & Truques Capanull Editorialnull Sumárionull SEF - Sistema de Escrituração Fiscal - Implementaçãonull O novo componente TrayIcon do Delphi 2006null Visual Studio 2005 e Visual Basic - Produtividade no códigonull Criando arquivo de instalação para projeto Web (Windows Installer)null Delphi, uma questão de sobrevivêncianull Fortes Report - Uma boa opção de gerador de relatório Freewarenull Perguntas & Respostasnull Dicas & Truquesnull
Compartilhar