Revista The Club Megazine - 04/2004 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. Copyright© The Club® 2004 EDITORIAL Editorial Salve amigos, 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. Aqui estamos com mais uma edição da The Club Megazine, especialmente feita para você, desenvolvedor! Primeiramente, gostaria de agradecer os emails “extrasuporte” que recebemos, parabenizando nossos técnicos pelos artigos que vêm sendo publicados em nossa revista, nos quais temos buscado utilizar uma linguagem técnica, porém sem exageros, e acima de tudo, expor temas comuns ao cotidiano do desenvolvedor, o que acredito ser o anseio da maioria de nossos associados, e aproveitando o ensejo, deixo aqui o convite aberto para que sugiram temas para que nossos técnicos possam estar desenvolvendo e dessa forma, facilitar ainda mais o seu dia-a-dia. Estamos muito felizes neste mês em contar com a volta do articulista Marcelo Nogueira, o qual esteve conosco por algum tempo trazendo assuntos relacionados a UML e metodologias relacionadas ao desenvolvimento, e que neste mês marca sua volta com um excelente artigo sobre metodologia de desenvolvimento aplicada a internet, vale a pena conferir! Nossos técnicos preparam alguns artigos com base em assuntos que tiveram maior relevância no suporte técnico neste mês, e que, poderão ser de grande utilidade aos demais amigos do The Club, onde posso destacar a Importação e Exportação de informações utilizando o banco Interbase/Firebird, o esclarecimento sobre porque o Delphi 8 é diferente em relação as versões anteriores, e como prevenir um erro muito conhecido entre os desenvolvedores Delphi, ou seja, o “Access Violation”. Para finalizar, nosso amigo de todas as batalhas Emerson Facunte demonstra uma abordagem muito interessante sobre a apresentação e imagens na WEB. Boa leitura à todos e como já mencionei, envie seus comentários e sugestões para que possamos estar enriquecendo cada dia mais nossa revista! Copyright© The Club® 2004 Impressão e acabamento: Impressos Gril - Gril Gráfica e Repr. Ind. Ltda. Tel.: (0xx14) 3762.1345 - Fax: (0xx14) 3762.1259 Rua São Paulo, 447 - Cep 18.740-000 Taquarituba - SP Tiragem: 5.000 exemplares Diretor - Presidente Celso Jefferson M. Paganelli Diretor Técnico Mauro Sant’Anna Colaboradores Emerson Facunte Marcelo Nogueira Delphi é marca registrada da Borland International, as demais marcas citadas são registradas pelos seus respectivos proprietários. Celso Jefferson Paganelli Presidente - The Club Editorial ............................................................................ 03 News ............................................................................... 04 Imagens para WEB ............................................................. 05 IB/FB - importação e exportação de dados diretamente do banco de dados ............................................................ 08 Retrospectiva .................................................................... 16 Delphi 8 - Porque ele é diferente ....................................... 18 Metodologia de desenvolvimento de sistemas de informação para internet ................................................... 24 Prevenindo o Access Violation em sua aplicação ............... 29 MeGAZINE 3 NEWS Kylix: Delphi para Linux com Interbase e Firebird Autor: Mercado, Eduardo Editora: Brasport ISBN: 8574521515 Idioma Portugues Páginas: 223 Publicação: 2004 Encadernação: Brochura Descrição: Com a forte chegada do sistema operacional Linux, surge um novo mercado para desenvolvedores de aplicações. O Kylix (Delphi para Linux) nasce acompanhando esta nova tendência de mercado, trazendo toda a bagagem, qualidade e segurança da mais poderosa e premiada ferramenta de desenvolvimento para ambiente Windows, o Delphi. Este livro aborda de forma clara, através de exemplos práticos, algumas qualidades, e explica com detalhes como solucionar as principais dificuldades encontradas no desenvolvimento com Kylix. Principais tópicos abordados no livro: · Instalação do Interbase e Firebird no Linux; · Diferenças entre Interbase e Firebird; · Criação de bancos de dados e seus objetos (tabelas, triggers, procedures, generators, etc.); · Configurações do Kylix (teclado, libs, etc.); · Aplicações de exemplo DbExpress na prática; · O poder do ClientDataset; · Trabalhando com DataSetProvider; · Utilizando Transações com DbExpress; · Conceito Client Server; · Execução de procedures através da aplicação; · Distribuição da aplicação. Onde comprar:http://www.brasport.com.br/ Guia de Certificação Windows Server 2003 Cobertura completa de todos os objetivos do exame 70-290! (Managing and Maintaining a Microsoft Windows Server 2003 Environment). Este livro é voltado para a certificação Microsoft MCSA/MCSE e tem como objetivo preparar o leitor para o exame 70-290. Desenvolvido como um guia para a certificação, aborda todos os tópicos do exame, de forma simples e eficiente. Foi especialmente planejado para ajudar o profissional a alcançar seus objetivos mais rapidamente. De forma técnica e abrangente, fornece ainda ao leitor a capacidade de implementar e gerenciar o Windows Server 2003 utilizando este livro como referência. Daniel Donda é especializado em sistemas operacionais de rede e Technical Support Intelligence. Atua no mercado de TI desde 1996. Possui as certificações Microsoft Certified Professional, Microsoft Certified Systems Engineer, Microsoft Certified Systems Administrator em Windows 2000 e Windows Server 2003, Microsoft Certified Systems Administrator Messaging e Microsoft Certified Trainer. É Analista de Sistemas da empresa Impacta Tecnologia, onde atualmente trabalha como Instrutor, ministrando treinamentos e palestras sobre produtos Microsoft, preparando e formando profissionais para os exames oficiais. É autor de diversos artigos técnicos de Informática. Paralelamente trabalha no desenvolvimento e administração de sites como o www.mcsesolution.com. 4 Sumário: Introdução 1. Conhecendo a Família do Windows Server 2003 2. Preparando o Windows 2003 para Administração 3. Implementando o Active Directory 4. Criando e Gerenciando Contas de Usuários e Computadores 5. Criando Contas de Computadores 6. Gerenciando Dados Usando o NTFS 7. Shadow Copies of Shared Folders 8. Implementando Group Policy 9. Implementando uma infra-estrutura de Redes 10. Administrando e Implementando Recuperação de Desastre 11. Configurando e Gerenciando Discos 12. Microsoft Software Update Services (SUS) 13. Gerenciando Servidores Remotamente 14. Monitorando o Windows Server 2003 15. O Internet Information Services (IIS) 16. Configurando um Servidor de Impressão 17. Guia de Referência das Ferramentas de Linha de Comando 18. Distributed File System (DFS) Apêndice. Questões para Fixação Glossário Índice Remissivo Onde comprar:http://www.brasport.com.br/ MeGAZINE Delphi Imagens para Web Por Emerson Facunte No evento onAction insira o código que segue: Salvem Delphianos! Muitas pessoas me perguntam como enviar imagens para Internet. Seja uma simples imagem armazenada num arquivo, uma imagem criada on-demand, ou até mesmo, imagens armazenadas em banco de dados. var Picture:TPicture; imagemJpg:TJPEGImage; imagemStream:TMemoryStream; Neste artigo demonstrarei algumas técnicas para envio de imagem para Internet, utilizando a gloriosa tecnologia WebBroker. begin Picture := TPicture.Create; Picture.Bitmap := TBitmap.Create; imagemJpg := TJPEGImage.Create; imagemStream := TMemoryStream.Create; Vamos ao exemplo: Inicie um novo projeto do tipo WebServer Application, selecione a opção de acordo com a configuração do seu servidor (Isapi, CGI, ou até mesmo WebApp Debugger para quem possui a versão 6 ou superior). Grave a unit como un_exemplo1, e o projeto como exemplo1.dpr. Em nosso exemplo utilizaremos funções das units Graphics e JPEG. Vamos adiciona-las à nossa unit um_exemplo1: uses Windows, Messages, SysUtils, Classes, HTTPApp, Graphics, Jpeg; try with Picture.BitMap do begin Width := 400; Height := 50; with Canvas do begin Brush.Color := clSilver; Brush.Style:=bsBDiagonal; FloodFill(0,0,clSilver,fsBorder); // mensagem Vamos criar uma action padrão com as seguintes características: Name PathInfo Font.Size:=30; Font.Name:=’Verdana’; Font.Color:=clNavy; TextOut(205,-3,’The Club’); ActImagem1 /Imagem1 end; MeGAZINE 5 Delphi Você poderá alterar o projeto de acordo com a sua necessidade. // armazena stream imagemJPG.Assign(Picture.Bitmap); imagemJPG.SaveToStream(imagemStream); imagemStream.Position:=0; Vamos analisar o código: Neste primeiro bloco estamos declarando objetos que serão utilizados na rotina: // envia imagem para browser Response.ContentType := ‘image/jpeg’; Response.ContentStream := imagemStream; Response.SendResponse; end; Finally Picture.Free; imagemJPG.Free; end; end; var Picture:TPicture; imagemJpg:TJPEGImage; imagemStream:TMemoryStream; Picture - base da nossa imagem, baseado em Tpicture (procure maiores informações no Help do Delphi) ImagemJpg - Objeto utilizado para transformar a imagem padrão BMP em JPG imagemStreamStream - necessário para enviar imagem para Browser. Vamos testar nossa aplicação: Faça a chamada no browser, exemplo: http://localhost/scripts/exemplo1.dll/imagem1 Em seguida, criamos nossos objetos em memória. A figura 1 ilustra o nosso primeiro exemplo: Importante: todo objeto criado em memória deve ser destruído, impreterivelmente. begin Picture := TPicture.Create; Picture.Bitmap := TBitmap.Create; imagemJpg := TJPEGImage.Create; imagemStream := TMemoryStream.Create; A seguir definimos o tamanho de nossa imagem. Figura 1 – Exemplo 1 Continuando com nosso exemplo, vamos sofisticá-lo de maneira sutil. Altere as linhas que seguem. try with Picture.BitMap do begin Width := 400; Height := 50; TextOut(205,-3,Request.QueryFields.Values[‘PALAVRA’); Recompile e faça uma nova chamada, da seguinte maneira: No bloco que segue, pintamos nossa figura (FloodFill), e “estampamos” a palavra na posição 205, -3. http://localhost/scripts/exemplo1.dll/ imagem1?PALAVRA=FACUNTE A figura 2 ilustra nossa alteração: with Canvas do begin Brush.Color := clSilver; Brush.Style:=bsBDiagonal; FloodFill(0,0,clSilver,fsBorder); // mensagem Font.Size:=30; Font.Name:=’Verdana’; 6 MeGAZINE Delphi objeto imagemStream, que é destruído pelo método SendResponse. Font.Color:=clNavy; TextOut(205,-3, Request.QueryFields.Values [‘PALAVRA’]);); end; Finally Picture.Free; imagemJPG.Free; end; end; Este é um dos mais interessantes trechos do código. Associamos o objeto Picture.Bitmap ao imagemJpg, em seguida armazenamos no objeto Stream (imageStream), definimos o inicio da posição do stream, e enviamos ao browser. Amigos, continuarei a série nas próximas edições, demonstrando outras técnicas. // armazena stream imagemJPG.Assign(Picture.Bitmap); imagemJPG.SaveToStream(imagemStream); imagemStream.Position:=0; // envia imagem para browser Response.ContentType := ‘image/jpeg’; Response.ContentStream := imagemStream; Response.SendResponse; end; Forte abraço Sobre o autor Emerson Facunte é Consultor de Tecnologia com diversos livros publicados, especialista em desenvolvimento de aplicações e-business utilizando a ferramenta Delphi, baseado em webSnap, dataSnap, BizSnap e ISAPI/Apache Modules. Neste ponto destruímos os objetos criados. Com exceção do MeGAZINE [email protected] 7 Delphi IB/FB Importação e Exportação de dados diretamente do banco de dados Uma das opções que sempre temos necessidade de ter em nosso sistema é a importação e exportação de dados através de arquivos textos. E existem diversas formas para realizar essas operações tendo todas elas um resultado positivo, mas o que difere entre elas é a velocidade com que o processo é executado, pois dependendo da quantidade de registros exportados o processamento poderá ficar lento devido a necessidade de ler os registros do banco de dados, montando um cache dos dados, e somente depois descarregá-los para o arquivo texto. Mas para nós que utilizamos o Interbase/FireBird temos a disposição uma opção de criar uma tabela dentro do banco de dados que utiliza um arquivo texto externo ao banco para gravar os registros. Sendo assim com essa tabela poderemos ler ou gravar dados dentro do arquivo texto usando diretamente comandos SQL, tornando o processo de importação ou exportação de dados bastante rápido, mesmo que a quantidade de dados a serem processados for grande. Criando a tabela externa O comando que utilizaremos para criar a tabela externa dentro do banco de dados é o CREATE TABLE com a opção EXTERNAL FILE, veja a sintaxe da instrução SQL: Como primeiro exemplo, vamos montar uma exportação de dados para um arquivo texto, isso é, iremos ler os dados de uma tabela existente dentro do banco de dados e iremos exportá-los para o arquivo texto. Os comandos que iremos executar a seguir são comandos SQL, portanto podem ser executados diretamente pelo IBConsole, IBExpert ou qualquer outra ferramenta de manutenção no banco que você utilize. No exemplo a seguir estarei trabalhando com a tabela EMPLOYEE do banco EMPLOYEE.GDB, que está disponível no seguinte diretório: C:\Program Files\Common Files\Borland Shared\Data\EMPLOYEE.GDB Dessa tabela irei utilizar somente alguns campos, veja exemplo no Select abaixo: SELECT EMP_NO, FIRST_NAME, HIRE_DATE, SALARY FROM EMPLOYEE CREATE TABLE TABEXPORTA EXTERNAL FILE ‘C:\EXPORTAR\ARQUIVO.TXT’ ( CODIGO char(12), NOME char(15) , QUEBRA char(2) ) Na instrução de CREATE TABLE acima indicamos o nome TABEXPORTA que é o nome ao qual a tabela ficará visível dentro do banco de dados. Após a instrução de EXTERNAL FILE indicamos a opção ‘C:\EXPORTAR\ARQUIVO.TXT’ esse é o caminho e o nome do arquivo texto que será gerado e que conterá os registros da tabela externa. Ao final do comando indicamos a estrutura que o arquivo texto terá: ( CODIGO char(12), NOME char(20), QUEBRA char(2) ) Como estaremos trabalhando com arquivo texto, devemos indicar no final de cada linha a instrução de quebra de linha, por esse motivo que criei no final da estrutura um campo chamado QUEBRA ao qual armazenará exatamente o caracter de quebra de linha. 8 Exportando dados para o arquivo texto Para exportar os dados dessa tabela EMPLOYEE para um arquivo texto, iremos primeiro criar o arquivo texto dentro do banco de dados, portanto usaremos a instrução de Create Table, conforme exemplo abaixo: CREATE TABLE TABEXPORTA EXTERNAL FILE ‘C:\EXPORTAR\ARQUIVO.TXT’ (CODIGO char(12), NOME char(20), DATA char(11), SALARIO char(20), QUEBRA char(2) ) Observe que todos os campos foram criados do tipo CHAR, pois estaremos trabalhando com um arquivo texto, e os tamanhos foram definidos para haver compatibilidade entre a estrutura da tabela de origem dos dados, no caso a tabela CADASTRO, e a estrutura do arquivo texto gerado que será o destino dos registros na exportação dos dados. MeGAZINE Delphi Bem, após executar a instrução acima a tabela externa será criada e assim poderemos fazer a exportação dos dados. A exportação dos dados será realizada diretamente através da instrução SQL descrita abaixo: INSERT INTO TABEXPORTA (CODIGO, NOME, DATA, SALARIO) SELECT EMP_NO, FIRST_NAME, HIRE_DATE, SALARY FROM EMPLOYEE Neste momento os dados foram copiados para a tabela TABEXPORTA. E poderão ser lidos através de uma instrução de SELECT, como se fosse uma tabela normal. Execute o exemplo que segue e veja que os dados estarão visíveis normalmente: NOME VARCHAR(20), DATA DATE, SALARIO DOUBLE PRECISION ) Após criar a tabela no banco de dados, podemos ler os dados do arquivo texto e importá-los para a nova tabela. E para isso utilizaremos a seguinte instrução: INSERT INTO TABELA_DESTINO (CODIGO, NOME, DATA, SALARIO) SELECT CODIGO, NOME, DATA, SALARIO FROM TABEXPORTA Neste momento os registros do arquivo texto foram importados para a nova tabela criada dentro do banco. SELECT CODIGO, NOME, DATA, SALARIO FROM TABEXPORTA Utilizando o NotePad também poderemos visualizar o arquivo texto gerado ao qual ficará parecido com a imagem que segue abaixo: Veja que apenas utilizando as instruções SQL do Interbase e do FireBird, já podemos importar e exportar dados através de arquivos textos externos. Criando um projeto de exportação no Delphi A idéia do exemplo que iremos montar é fazer uma exportação de dados genérica, isso é, iremos indicar através de um select os dados que iremos exportar, a rotina irá ler a estrutura desse Select, gerar uma tabela externa e depois efetuar a exportação dos dados para o arquivo texto. Portanto mãos a obra. Crie um novo projeto; Abaixo estou listando os componentes que irei utilizar neste projeto e as propriedades que configurei, a lista está na seqüência que devemos colocar os componentes para evitar diferenças no projeto. Observe que os registros não estão separados por linha, isso ocorre porque como as instruções executadas acima foram executadas diretamente pelo IBExport ou IBConsole, então não utilizamos o campo QUEBRA para armazenar o caracter de salto de linha para o arquivo texto. Componente StatusBar Name = StatusBar1 Componente Panel Name = Panel1 Align = alClient Caption = vazio Importando dados do arquivo texto Aproveitando o arquivo texto criado acima, através da exportação dos dados, iremos fazer o inverso agora, importar os dados do arquivo texto para uma tabela do banco de dados. Dentro do componente Panel iremos colocar os demais componentes que seguem abaixo: Como primeiro passo, vamos criar uma nova tabela dentro do banco de dados com a estrutura parecida com a tabela externa. Veja instrução abaixo: Componente Label Name = Label3 Caption = Instrução SQL para ler o arquivo de origem dos dados Top = 6 Left = 13 Componente Memo CREATE TABLE TABELA_DESTINO ( CODIGO INTEGER, Name = Memo_SQL MeGAZINE 9 Delphi Top = 22 Left = 8 Height = 83 Componente Label Name = Label4 Caption = Path/Nome do arquivo texto que será gerado Top = 112 Left = 13 Componente Edit Essa propriedade UniDirectional é utilizada para que não seja criado o Cachê de registros na memória, pois no momento em que o projeto ler a estrutura da tabela de origem não é necessário visualizar os registros do mesmo. Para esses três componentes de conexão basta você conectálos ao seu banco de dados, portanto não irei detalhar esse procedimento. Name = Edt_ArqTxt Text = EXPORTAR.TXT Top = 126 Left = 8 Componente CheckBox Após montar o form do projeto o mesmo ficará parecido com a imagem abaixo: Name = Check_Cabec Caption = Cabeçalho State = cbChecked Top = 155 Left = 19 Componente Label Name = Label2 Caption = Separador de campos Top = 156 Left = 119 Componente Edit Name = Edit_Separador Text = , Top = 153 Left = 231 Componente CheckBox Name = CheckBox1 Caption = Visualizar o arquivo texto ao final Top = 155 Left = 299 Componente Button Name = Button3 Caption = Processar exportação dos dados Top = 179 Left = 8 Estando com o nosso form construído, iremos montar as instruções de programação do delphi. Como primeiro passo acesse o evento onShow do form e inclua a seguinte instrução: Componente Label Name = Label1 Caption = Log de execução Top = 209 Left = 13 procedure TForm1.FormShow(Sender: TObject); begin IBDataBase1.Open; IBTransaction1.Active := True; { path e nome do arquivo texto a ser gerado } Edt_ArqTxt.Text := ExtractFilePath (Application.ExeName)+’EXPORTAR.TXT’; end; Componente Memo Name = Memo_Log Top = 225 Left = 8 Height = 202 Componente Button Name = Button1 Caption = Visualizar arquivo texto Top = 432 Left = 270 Componente IBDatabase Name = IBDatabase1 DatabaseName = C:\Program Files\Common Files\ Borland Shared\Data\EMPLOYEE.GDB Componente IBTransaction Name = IBTransaction1 Agora iremos criar uma procedure ao qual irá nos auxiliar a executar as instruções SQL no componente IBQuery e criar um Log das instruções executadas. Portanto crie a procedure descrita a seguir: procedure TForm1.UsaIBQuery (cSQL, cMsg: String; cExec: Boolean); begin StatusBar1.SimpleText := cMsg; Componente IBQuery Name = IBQuery1 UniDirectional = True 10 MeGAZINE Delphi try IBQuery1.Close; IBQuery1.SQL.Text := cSQL; { Apresenta a instrução que será executada na IBQuery } Memo_Log.Lines.Add( ‘=======’+cMsg+’========’ ); Memo_Log.Lines.Add( IBQuery1.SQL.Text ); Memo_Log.Lines.Add( ‘’ ); if cExec then begin IBQuery1.ExecSQL; IBTransaction1.Commit; end else IBQuery1.Open; except on E: EDataBaseError do begin ShowMessage(‘Erro: ‘+cMsg +#13+’Original: ‘+E.Message); Form1.Panel1.Enabled := True; IBTransaction1.Rollback; Abort; end; end; end; ftDate, ftTime: nTam := 11; ftDateTime: nTam := 20; end; { Se o tamanho do nome do campo for maior que nTam encontrado, então deixa o nTam do tamanho do nome do campo } if Length( IBQuery1.Fields[i].FieldName ) > nTam then nTam := Length( IBQuery1.Fields[i].FieldName ); {inclui a vírgula entre os campos do script} if cScript <> ‘’ then cScript := cScript +’,’; Nesta instrução acima é lido a estrutura da tabela de origem para que assim possamos criar o arquivo texto de destino com a estrutura idêntica a tabela de origem. Alguns tamanhos de campos foram definidos como padrão para que as estruturas fiquem compatíveis. { o usuário indicou que precisa do cabeçalho no arquivo texto } if (Check_Cabec.Checked) and (cCabecalho <> ‘’) then begin {inclui o separador de campos definido pelo usuário} if Trim(Edit_Separador.Text) <> ‘’ then cCabecalho := cCabecalho + ‘||’+ QuotedStr (‘ ‘+Edit_Separador.Text+’ ‘); cCabecalho := cCabecalho + ‘,’; end; cCabecalho := cCabecalho + QuotedStr(UpperCase ( IBQuery1.Fields[i].FieldName )); Essa procedure será declarada dentro da seção private, conforme exemplo: private procedure UsaIBQuery (cSQL, cMsg: String; cExec: Boolean); public { Public declarations } end; Agora iremos criar o evento onClick do Button3, que será o botão responsável pela exportação dos dados. E é exatamente neste botão que iremos montar todas as instruções SQL dos passos descritos acima para a exportação dos dados. Nesta instrução é criada uma string que conterá as instruções do cabeçalho do arquivo texto, observe que já estamos incluindo os separadores dos campos. Abaixo irei descrever somente algumas partes da procedure, pois são as partes importantes da rotina de exportação: for i:=0 to IBQuery1.Fields.Count-1 do begin Case IBQuery1.Fields[i].DataType of ftString: nTam :=IBQuery1.Fields[i].DataSize; ftSmallint, ftInteger, ftWord: nTam := 8; ftFloat, ftCurrency, ftBCD: nTam := 20; MeGAZINE cScript := cScript + UpperCase ( IBQuery1.Fields[i].FieldName ) + ‘ CHAR ( ‘ + IntToStr(ntam+4)+’ ) ‘; Application.ProcessMessages; end; { Define o início do script para criação da tabela externa } cScript := ‘CREATE TABLE ‘+nArqInt+’ EXTERNAL FILE ‘ + QuotedStr(nArqTxt)+’ ( ‘+cScript; { Define o final do script para criação da tabela externa 11 Delphi usuário, para que ao exportar os dados os separadores já sejam incluídos automaticamente. incluimos o caracter de quebra de linha } cScript := cScript + ‘, QUEBRA CHAR(2) ) ‘; Nesta instrução geramos o script que irá criar a tabela externa dentro do banco de dados, criando também o arquivo texto. { Registra a tabela externa dentro do banco de dados } UsaIBQuery(cScript, ‘Criando tabela externa’, True); Neste momento o script gerado é enviado ao componente IBQuery para ser executado gerando a tabela externa. if (Check_Cabec.Checked) then begin cScript := ‘ INSERT INTO ‘+nArqInt+ ‘ SELECT ‘+cCabecalho+’,’+QuotedStr(#13#10)+’ FROM RDB$DATABASE’; { Exportando cabeçalho para a tabela externa } UsaIBQuery(cScript, ‘Exportando cabeçalho para a tabela externa’, True); end; Se o usuário checou a opção que indica para criar o cabeçalho no arquivo texto, então o projeto irá executar a instrução SQL que irá incluir as informações de cabeçalho no arquivo texto. { Monta o script de insert que irá exportar os dados para o arquivo texto } { Pega o SQL do início até o FROM } cScript := Copy(Memo_SQL.Text, 1, Pos(‘FROM’, Memo_SQL.Text)-1); { Inclui os separadores nos campos caso o usuário tenha definido } if Trim(Edit_Separador.Text) <> ‘’ then cScript := StringReplace(cScript, ‘,’ , ‘||’+QuotedStr(‘ ‘+Edit_Separador.Text+’ ‘)+’,’ ,[rfReplaceAll]); cScript := cScript + ‘ ,‘ + QuotedStr(#13#10)+’ ‘; { Pega o SQL do FROM até o Fim } cScript := cScript + Copy(Memo_SQL.Text, Pos(‘FROM’, Memo_SQL.Text),Length(Memo_SQL.Text)); { Exportando dados para o arquivo texto } cScript := ‘ INSERT INTO ‘+nArqInt+’ ‘+cScript; Nesta instrução acima criamos o script responsável pela exportação dos dados da tabela de origem para o arquivo texto de destino. Nela já estamos incluindo os separadores, definidos pelo 12 UsaIBQuery(cScript, ‘Exportando dados para a tabela externa’, True); Após concluir o script o mesmo é enviado ao componente IBQuery para ser executado. StatusBar1.SimpleText := ‘Exportação concluida’; Panel1.Enabled := True; finally if nTabCriada then begin {apaga o registro de dentro do banco de dados} cScript := ‘DROP TABLE ‘+nArqInt; UsaIBQuery(cScript, ‘Excluindo registro da tabela externa do banco’, True); end; { fecha todas as conexões } StatusBar1.SimpleText := ‘Fechando o acesso ao banco de dados’; IBQuery1.Close; end; Para finalizar o processo de exportação a tabela externa gerada dentro do banco de dados é excluída do banco, mas esse processo não irá apagar o arquivo texto gerado na exportação. Na verdade isso fará com que o mesmo seja liberado, pois o banco não terá mais nenhuma ligação com o arquivo externo. { visualiza o arquivo txt } if FileExists( nArqTxt ) then begin Form2.Memo_Arquivo.Lines.LoadFromFile( nArqTxt ); Form2.ShowModal; end; end; Caso o arquivo texto tenha sido criado corretamente, então iremos visualizá-lo através de um componente Memo colocado no Form2. A procedure completa do evento onClick do Button3 poderá ser visualizada no final da matéria. Finalizando a Unit do Form1 Bem, neste momento toda a nossa rotina responsável pela exportação dos dados já foi criada, agora somente iremos finalizar os eventos desse Form1. Declare na seção implementation a unit do Form2, conforme MeGAZINE Delphi exemplo: Form2.Close; end; implementation uses Unit2; {$R *.dfm} Após construir o Form2 o mesmo ficará com a seguinte aparência: Crie o evento onClick do Button1, ao qual irá visualizar o conteúdo do arquivo texto através de um memo no form2. procedure TForm1.Button1Click(Sender: TObject); begin { visualiza o arquivo txt } if FileExists( UpperCase( Edt_ArqTxt.Text ) ) then begin Form2.Memo_Arquivo.Lines.LoadFromFile ( UpperCase( Edt_ArqTxt.Text ) ); Form2.ShowModal; end; end; E crie o evento onClose do Form1 ao qual irá fechar as conexões do banco de dados: procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); begin { Fecha as conexão com o banco de dados } IBTransaction1.Active := False; IBDataBase1.Close; end; Criando o Form2 O form2 é bastante simples, pois a sua utilização é somente para mostrar o conteúdo do arquivo texto gerado na exportação. Neste form coloque os seguintes componentes: Componente Panel Neste momento nosso pequeno e interessante projeto está pronto para ser compilado e testado, mas antes vamos verificar as dicas importantes descritas abaixo. Dicas importantes 1- A instrução SQL a ser utilizada para visualizar os dados, deve ser escrita contendo o nome dos campos, pois a rotina irá utilizar esses nomes para montar a instrução de exportação dos dados e a inclusão dos separadores. Exemplo da instrução SQL: SELECT E.EMP_NO, E.FIRST_NAME FROM EMPLOYEE E Poderíamos ter montado de uma forma que não fosse obrigatória a indicação dos campos na instrução SQL, mas o problema não se encontra nos SELECTS simples e sim nos compostos de várias tabelas, pois nesses devemos indicar o nome das tabelas e o nome dos campos no Select, veja exemplo de um SELECT composto: Align = alBottom Caption = vazio SELECT E.EMP_NO, E.FIRST_NAME, E.HIRE_DATE, E.SALARY, E.DEPT_NO, D.DEPARTMENT FROM EMPLOYEE E LEFT OUTER JOIN DEPARTMENT D ON (D.DEPT_NO = E.DEPT_NO) ORDER BY E.EMP_NO Componente Memo Name = Memo_Arquivo Align = alClient Dentro do Panel coloque um componente Button com o Caption = Fechar E no evento onclick deste Button coloque a seguinte instrução: procedure TForm2.Button1Click(Sender: TObject); begin Neste SELECT de exemplo estamos visualizando os registros de duas tabelas e esses registros serão exportados para o arquivo texto normalmente. 2- Outra dica muito importante para quem estiver utilizando o FireBird 1.5. Nessa versão devemos habilitar para que o mesmo MeGAZINE 13 Delphi possa trabalhar com arquivos externos, pois por padrão essa opção está desligada. Para habilitar essa opção simplesmente devemos acessar o arquivo Firebird.conf que está no diretório principal do FireBird_1_5. Esse arquivo pode ser acessado através do NotePad. Dentro desse arquivo iremos incluir como última linha a seguinte instrução: ExternalFileAccess = Full Após incluir essa instrução feche o arquivo e reinicialize o servidor. Testando o projeto de exemplo Para utilizar o projeto é bastante simples, o primeiro passo é escrever a instrução SQL que irá visualizar os dados a serem exportados. Em seguida devemos indicar a path e o nome do arquivo texto ao qual será gerado na exportação, indicar se vai incluir Cabeçalho e o Separador de Campos no arquivo texto e pronto. Agora basta clicar sobre o botão para iniciar o processo de exportação dos dados. Ao final da exportação o arquivo texto poderá ser visualizado pelo componente Memo do Form2. Segue abaixo a procedure completa do evento onclick do Button3, ao qual faz todo o processamento de exportação dos dados. procedure TForm1.Button3Click(Sender: TObject); var nArqTxt, nArqInt, cCabecalho, cScript : string; nTam, i: INTEGER; nTabCriada: Boolean; begin try Panel1.Enabled := False; { Nome da tabela externa criada dentro do banco } nArqInt := ‘TABEXPORTA’; { limpa as variáveis strings onde serão armazenadas a estrutura da tabela } nTabCriada := False; cCabecalho := ‘’; { Nome dos campos incluidos no cabecalho do texto } nTam := 0; { Tamanho de cada campo a ser exportado } cScript := ‘’; { Script para gerar a tabela externa } {se o arquivo texto já existe, apaga o arquivo } if FileExists( nArqTxt ) then DeleteFile( nArqTxt ); { Instrução que irá ler a instrução SQL colocada pelo usuário no Memo_SQL } UsaIBQuery(Memo_SQL.Text, ‘Lendo estrutura da tabela de origem’, False); StatusBar1.SimpleText := ‘ Montando estrutura da tabela externa ‘; { lê a estrutura da origem para gerar o arquivo texto de destino } for i:=0 to IBQuery1.Fields.Count-1 do begin Case IBQuery1.Fields[i].DataType of ftString: nTam := IBQuery1.Fields[i].DataSize; ftSmallint, ftInteger, ftWord: nTam := 8; ftFloat, ftCurrency, ftBCD: nTam := 20; ftDate, ftTime: nTam := 11; ftDateTime: nTam := 20; end; { Se o tamanho do nome do campo for maior que nTam encontrado, então deixa o nTam do tamanho do nome do campo } if Length( IBQuery1.Fields[i].FieldName ) > nTam then nTam := Length( IBQuery1.Fields[i].FieldName); {inclui a vírgula entre os campos do script} if cScript <> ‘’ then cScript := cScript +’,’; { o usuário indicou que precisa do cabeçalho no arquivo texto } if (Check_Cabec.Checked) and (cCabecalho <> ‘’) then begin { inclui o separador de campos definido pelo usuário } if Trim(Edit_Separador.Text) <> ‘’ then cCabecalho := cCabecalho +‘||’+QuotedStr (‘ ‘+Edit_Separador.Text+’ ‘); cCabecalho := cCabecalho + ‘,’; end; { nome do arquivo texto a ser gerado } nArqTxt := UpperCase( Edt_ArqTxt.Text ); 14 MeGAZINE cCabecalho := cCabecalho + QuotedStr (UpperCase( IBQuery1.Fields[i].FieldName ) ); cScript := cScript + UpperCase ( IBQuery1.Fields[i].FieldName ) + Delphi cScript := cScript + Copy(Memo_SQL.Text, Pos(‘FROM’, Memo_SQL.Text),Length (Memo_SQL.Text)); { Exportando dados para o arquivo texto } cScript := ‘ INSERT INTO ‘+nArqInt+’ ‘+cScript; UsaIBQuery(cScript, ‘Exportando dados para a tabela externa’, True); StatusBar1.SimpleText := ‘Exportação concluida’; Panel1.Enabled := True; finally if nTabCriada then begin {apaga o registro de dentro do banco de dados} cScript := ‘DROP TABLE ‘+nArqInt; UsaIBQuery(cScript, ‘Excluindo registro da tabela externa do banco’, True); end; { fecha todas as conexões } StatusBar1.SimpleText := ‘Fechando o acesso ao banco de dados’; IBQuery1.Close; end; { visualiza o arquivo txt } if FileExists( nArqTxt ) then begin Form2.Memo_Arquivo.Lines.LoadFromFile ( nArqTxt ); Form2.ShowModal; end; end; ‘ CHAR( ‘+inttostr(ntam+4)+’ ) ‘; Application.ProcessMessages; end; { Define o início do script para criação da tabela externa } cScript := ‘CREATE TABLE ‘+nArqInt+’ EXTERNAL FILE ‘+QuotedStr(nArqTxt)+’ ( ‘+cScript; { Define o final do script para criação da tabela externa incluimos o caracter de quebra de linha } cScript := cScript + ‘, QUEBRA CHAR(2) ) ‘; { Registra a tabela externa dentro do banco de dados } UsaIBQuery(cScript, ‘Criando tabela externa’, True); nTabCriada := True; if (Check_Cabec.Checked) then begin cScript := ‘ INSERT INTO ‘+nArqInt+ ‘ SELECT ‘+cCabecalho+’,’+ QuotedStr(#13#10)+’ FROM RDB$DATABASE’; { Exportando cabeçalho para a tabela externa } UsaIBQuery(cScript, ‘Exportando cabeçalho para a tabela externa’, True); end; { Monta o script de insert que irá exportar os dados para o arquivo texto } { Pega o SQL do início até o FROM } cScript := Copy(Memo_SQL.Text, 1, Pos (‘FROM’, Memo_SQL.Text)-1); Conclusão Bem é isso amigos, neste artigo podemos conhecer mais uma característica do banco de dados Interbase/FireBird. O projeto que criamos foi até simples, a idéia é mostrar como podemos utilizar essas instruções para criar uma exportação de dados diretamente do banco para o arquivo texto. Um grande abraço a todos. { Inclui os separadores nos campos caso o usuário tenha definido } if Trim(Edit_Separador.Text) <> ‘’ then cScript := StringReplace(cScript,’,’,’||’+ QuotedStr(‘ ‘+Edit_Separador.Text+’ ‘)+’,’,[rfReplaceAll]); O projeto de exemplo referente a este artigo está disponível para download no seguinte link: http://www.theclub.com.br/revista/download/ Exporta_IBFB.zip Sobre o autor cScript := cScript + ‘ , ‘ + QuotedStr(#13#10)+’ ‘; André Colavite Consultor Técnico do The Club [email protected] { Pega o SQL do FROM até o Fim } MeGAZINE 15 Delphi Retrospectiva Neste mês a nossa retrospectiva chega ao ano de 1995. Neste ano, o The Club ainda não existia. A empresa era somente o Clipper's Club e ainda não havia uma linguagem de programação para Windows suportada pela nossa empresa. Destaque da edição de setembro, era a utilização do BBS do Clipper's Club, pois a internet ainda não havia "chegado" aqui na terra tupiniquim. Também publicamos um artigo sobre os comandos a serem utilizados no Clipper para utilização da impressora HP Deskjet 500C, um padrão para a época. Merece destaque também um pequeno artigo, sobre o Blinker 3, o melhor linkeditor para Clipper. Você também está vendo neste mês, extraordináriamente, a capa do lançamento da revista sobre o Delphi, ainda como Delphi's Club. Nesta primeira edição tivemos um artigo que explicava o Delphi escrito pelo Leonardo Tolomeli, na época ainda na Engine representante da Borland no Brasil. Hoje o Leonardo está na Microsoft trabalhando ainda na área de programação, porém com o Visual Studio.NET. No mês que vem continuamos com nossa retrospectiva! Até lá. 16 MeGAZINE Delphi Delphi 8 Por que ele é diferente? Por Alessandro Ferreira ([email protected]) Introdução Você pode estar se perguntando, Delphi é Delphi e pronto! Bem, essa afrmação era verdadeira até o lançamento do Delphi 8, o qual na realidade chama-se “Delphi 8 For the Microsoft .NET Framework”. Isso mesmo, esta versão do Delphi é única e exclusivamente para gerar aplicativos compatíveis com o Microsoft .NET Framework! Bem, as perguntas devem estar surgindo em sua cabeça e se indagando, “qual a diferença?”, “o que isso muda?”, o que eu e meu cliente temos haver com isso?”. A resposta é bem curta, “muda tudo!”. Para um melhor entendimento, vamos começar do início! Em junho/2000 durante o “Fórum 2000”, os principais executivos da Microsoft, Bill Gates e Steve Balmer, apresentaram uma nova plataforma de desenvolvimento de software chamada “.NET Plataform”. A Internet e os aplicativos Muitos dos leitores desenvolveram programas para o sistema operacional DOS, na maior parte dos casos usando o Clipper da Nantucket/Computer Associates. O Clipper era uma ferramenta muito poderosa e produtiva. No entanto, no início dos anos 90, o Windows - que existia desde 1985 - se popularizou. O Windows impôs novas necessidades para os programadores, que acabaram migrando para outras ferramentas, principalmente Delphi e Visual Basic. Hoje em dia, estamos assistindo a uma mudança igualmente profunda. Embora os sistemas operacionais não tenham mudado muito, a Internet abre novas possibilidades para o 18 desenvolvimento de aplicativos. Em um futuro muito próximo, todos os softwares serão escritos levando-se em conta a Internet. Se por um lado a Internet abre novas possibilidades, ela também traz novas imposições aos programas. Para atender estas novas imposições, a Microsoft criou uma nova plataforma de execução (e também desenvolvimento) chamada “.NET”. Esta plataforma inclui as seguintes novidades: · É independente da CPU e do sistema operacional. Você leu direito: o software desenvolvido na nova plataforma NÃO é dependente do sistema operacional Windows nem exige uma CPU Intel. Ele depende sim de um “runtime” que pode ser portado para diversos sistemas operacionais. Por enquanto, a Microsoft só prometeu suporte para os próprios sistemas operacionais: diversos Windows e Pocket PC (antigo Windows CE), Atualmente existe um projeto “Open-Source” chamado Mono, o qual é uma versão do “.NET Framework” para Linux, http://www.go-mono.org//. · Os programas são escritos para uma “máquina virtual” e compilados para a plataforma final em tempo de instalação ou mesmo de execução. Este esquema é semelhante ao Java, mas a Microsoft não impõe nenhuma linguagem de programação. Várias linguagens estão sendo portadas para o novo ambiente, desde BASIC até COBOL, é agora o Delphi. · Vários recursos atuais do Windows passam a ser considerados obsoletos. Alguns deles: toda a API do Windows, o MeGAZINE Delphi “Registry” e objetos COM. existiriam bem menos programadores, não é mesmo? · Os programas dependem de uma biblioteca de classes que faz parte do ambiente de execução. Estas classes fazem as funções que normalmente seriam atribuições do sistema operacional. Mas será que não dá para aproveitar o código que temos hoje e através de alguma ferramenta mágica “transformá-lo” em código para Internet? Bem, isto é tão possível como transformar um código de DOS para Windows... · O ambiente de execução pode controlar perfeitamente o que os programas fazem e, eventualmente, impedir operações inseguras como acesso a arquivos, comunicação via TCP/IP e uso de ponteiros. Os aplicativos passam a ter “atributos de segurança”, de forma semelhante aos usuários hoje. Muitos programadores no tempo do Clipper esperaram anos até se convencerem que o suposto “Clipper para Windows”, o Visual Objects não era milagroso, afinal de contas. Além de não funcionar direito, a Computer Associates promoveu o Visual Objects como uma ferramenta que faria seu código rodar sob Windows com um passe de mágica. Isto é simplesmente impossível: a informação necessária para rodar como programa Windows (menus, caixas de diálogo, orientação a eventos) simplesmente não existia nos programas DOS. Da mesma forma, a informação necessária para rodar adequadamente “sob Internet” não existe nos aplicativos de hoje. Se você não acredita nisso, pense bem: será que após todos estes anos de Internet ninguém quis virar milionário escrevendo esta ferramenta mística para portar de Windows para Internet, caso isto fosse possível? · Invocação remota de funções através do protocolo “SOAP”. O SOAP é uma maneira muito simples de trocar informações via HTTP e foi desenvolvido em conjunto pela Microsoft e IBM. O padrão COM/DCOM/COM+ ainda é utilizado, mais, a recomendação é a adoção ao SOAP. · ADO.Net para acesso a bancos de dados. A principal característica do ADO.Net é que os dados podem estar tanto em um servidor local quanto na Internet: não faz diferença! Na verdade, ele foi feito para acessar banco de dados pela Internet. Se os dados estiverem em rede local, o mesmo mecânismo é usado. · Para instalar um aplicativo, basta copiar os arquivos para um diretório, como no velho e bom DOS. Nada de arquivos .INI compartilhados ou Registry! Para desinstalar o aplicativo, basta apagar os arquivos. · Os programas executáveis são bem pequenos. A melhor comparação que temos hoje é um programa Delphi compilado para funcionar com pacotes (Project | Options | Packages | Build with runtime packages). Um programa executável escrito para a nova plataforma tem características que o tornam ideal para “rodar na Internet”, em conjunto ou ao invés do navegador. Veja bem: ele é pequeno (dezenas/centenas de kilobytes), é fácil de instalar, acessa banco de dados via Internet, faz chamada de funções via Internet, é seguro e tem uma interface com usuário rica (Windows, ao invés de HTML). Para que o navegador, então? Reescrever os programas, de novo? Alguns programadores recentemente terminaram a migração de aplicativos DOS para Windows. Quer dizer que teremos que escrever os programas novamente, levando em conta a Internet? A resposta curta é sim. Não fiquem desanimados: se ainda estivéssemos no DOS com Clipper, Mesmo que você não fique convencido que migrar para a plataforma “.NET” seja a solução, você terá que reescrever os seus programas para a Internet de alguma maneira. Não tem jeito: você terá que usar alguma tecnologia como CGI, WebBroker, WebSnap, IntraWeb, Java ou ASP. E, já que você vai ter que reescrevê-los, não seria melhor escrever em uma plataforma completa e produtiva como o “.NET”? ASP.Net Um programa .NET pode substituir com muitas vantagens o navegador Internet. Mas existe aqui um grande problema: para você poder distribuir um programa “.NET”, a maioria dos clientes teria que usar um computador com um “runtime .NET”. Mesmo que a Microsoft seja muito bem sucedida na distribuição da nova plataforma, levará vários anos antes que ela seja de uso geral. O que fazer até então? A resposta é: páginas ASP.Net. O desenvolvimento de aplicativos Windows hoje em dia segue o modelo introduzido pelo Visual Basic e copiado por várias outras ferramentas (Delphi, Power Builder etc): temos um “formulário” no qual são colocados “componentes”. Ajustamos “propriedades” e colocamos código para processar “eventos”. Infelizmente, o modelo de desenvolvimento de aplicativos para Web segue um modelo muito diferente dos aplicativos Windows. De uma maneira geral, os ambientes de desenvolvimento atuais para Web proporcionam uma abstração muito limitada em MeGAZINE 19 Delphi relação aos protocolos HTTP e HTML: Transitional//EN”> · Precisamos processar “variáveis de ambiente” e “variáveis de formulário” a toda hora. <html> <head> <title></title> <meta name=”GENERATOR” content= ”Borland Package Library 7.1"> </head> · Precisamos nos preocupar em gerar a saída em HTML, com todas as suas restrições. · Manter estado entre as páginas é trabalhoso, mesmo para coisas tão simples como preservar o conteúdo de um campo de edição entre duas chamadas da mesma página. · Cada formulário HTML gera apenas um único evento para todos os componentes. Isto é bastante diferente dos aplicativos Windows, onde cada componente tem vários eventos. · Devemos nos preocupar com as diversas versões de HTML e navegadores existentes. Para piorar, o HTML é um padrão em evolução e que está sendo substituído pelo XML. · Coisas simples como trocar uma imagem quando o mouse passa sobre ela ou validar se um campo está em branco deve ser feito com um “script de cliente”, usualmente em JavaScript, com enorme complexidade em relação ao resultado final. O ASPX traz uma novidade realmente revolucionária: usa o mesmo modelo de programação de aplicativos Windows tradicionais. Um sofisticado sistema de runtime rodando sob o servidor web “traduz os protocolos” entre um modelo baseado em componentes e as páginas HTML/HTTP. Este sistema de runtime é capaz também de saber as capacidades do navegador remoto e explorar as suas características, mantendo a simplicidade e unidade do código fonte original. Criando um aplicativo ASP.Net Vejamos a criação de uma página ASP simples com o Delphi 8. Primeiramente pedimos um novo projeto. (ver figura 1) <body ms_positioning=”GridLayout”> <form runat=”server”> <p> <asp:label id=Label1 runat=”server”> Entre dois números:</asp:label> </p> <p> <asp:textbox id=TextBox1 runat=”server”> </asp:textbox> <asp:textbox id=TextBox2 runat=”server”> </asp:textbox> </p> <p> <asp:button id=Button1 runat=”server” text=”Somar”> </asp:button> <asp:button id=Button2 runat=”server” text=”Multiplicar”> </asp:button> </p> <p> <asp:label id=Label2 runat=”server”>Label </asp:label> </p> </form> </body> </html> Listagem 1 – código Asp.Net gerado referente exemplo AloAsp A seguir, acrescentamos componentes no formulário. Note que alguns componentes são análogos a campos HTML, mas outros como para acesso a bancos de dados são completamente novos. (ver figura 2) Veja a página HTML. Note as “tags” especiais e também a referência ao programa fonte associado à página: <%@ Page language=”c#” Debug=”true” Codebehind=”WebForm1.pas” AutoEventWireup= ”false” Inherits=”WebForm1.TWebForm1" %> <!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.0 20 Cada botão tem diversos eventos associados. Estamos interessados no evento OnClick do botão. (ver figura 3) Após dar um clique duplo na linha do evento, acrescentamos o código para cada botão: procedure TWebForm1.Button1_Click(sender: System.Object; e: System.EventArgs); begin Label2.Text := Convert.ToString((Convert.ToDouble (TextBox1.Text)+Convert.ToDouble(TextBox2.Text))); MeGAZINE Delphi Figura 1 – Novo projeto Asp.Net Figura 2 – Componentes adicionados em um projeto Asp.Net MeGAZINE Figura 3 – Eventos do botão 21 Delphi end; <p> procedure TWebForm1.Button2_Click (sender: System.Object; e: System.EventArgs); begin Label2.Text := Convert.ToString((Convert.ToDouble (TextBox1.Text)*Convert.ToDouble(TextBox2.Text))); end; Listagem 2 – Código adicionado ao evento OnClick dos botões <input name=”TextBox1" type=”text” value=”20" id=”TextBox1" /> <input name=”TextBox2" type=”text” value=”20" id=”TextBox2" /> </p> <p> <input type=”submit” name=”Button1" value=”Somar” id=”Button1" /> <input type=”submit” name=”Button2" value=”Multiplicar” id=”Button2" /> </p> <p> <span id=”Label2">40</span> </p> </form> </body> </html> Listagem 3 – Espionando o código gerado no browser Em tempo de execução, o evento do formulário é mapeado para a rotina de processamento do evento do componente correto. As páginas geradas podem incluir também código JavaScript para rodar no cliente. Acrescentamos alguns componentes para validação no exemplo anterior. Agora, o navegador irá exigir que entremos apenas números. Esta validação é colocada de maneira declarativa e feita tanto no cliente como no servidor. Não precisamos criar código JavaScript; os componentes do ASP.Net fizeram isto por nós. O sistema de runtime detecta as características do navegador e envia código compatível. Figura 4 – Aplicação exemplo sendo executado no browser <!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.0 Transitional//EN”> <html> <head> <title></title> <meta name=”GENERATOR” content= ”Borland Package Library 7.1"> </head> Observe as seguintes características do ASP.Net: <body ms_positioning=”GridLayout”> <form name=”_ctl0" method=”post” action=”WebForm1.aspx” id=”_ctl0"> <input type=”hidden” name=”__VIEWSTATE” value=”dDwtMTU0NDc3NDUzMjt0PDtsPGk8MT47 PjtsPHQ8O2w8aTwxMT47PjtsPHQ8cDxwPGw8VGV4dDs+ O2w8NDA7Pj47Pjs7Pjs+Pjs+Pjs+LC7fT/gHuPxTKr OP8dFjpczTdmQ=” /> <p> <span id=”Label1">Entre dois números:</span> </p> 22 · Os componentes têm a tag “runat=”SERVER””. Estes componentes são gerenciados no servidor. · “id” permite referenciar o componente no código. · Os atributos da tag mapeiam para propriedades dos componentes. · As propriedades podem ser ajustadas em tempo de desenvolvimento de maneira declarativa ou em tempo execução com código. · Os atributos são mantidos entre duas invocações da página, mas este mecânismo pode ser desligado com a propriedade “MantainState”, caso desejado. · Nenhum estado é armazenado no servidor; todo estado é armazenado em “tags” escondidas, no cliente; as sessões podem ser mantidas sem cookies. · Existem eventos “change” que são processados no próximo MeGAZINE Delphi envio de página e eventos “action”, que causam o envio imediato de dados ao servidor. · Você pode facilmente criar uma página (“pagelet”) que funciona como um componente, com uma “tag” própria. · É possível criar componentes novos para funcionar sob a plataforma. Esta é uma ótima maneira de efetuar tarefas complexas sem onerar a programação final. · Para atualizar um site basta copiar as páginas, mesmo que elas mesmas estejam em uso (na verdade, o ambiente de execução sempre as copia para outro diretório “de produção”). · Os componentes podem emitir código JScript para rodar no cliente e efetuar tarefas como validação. Existem diversos tipos de componentes: · Componentes que mapeiam diretamente a campos HTML como “textbox” e “button”. · Componentes que fazem abstrações como o “label” ou “calendar”. · Componentes que atuam no servidor, como para acesso a banco de dados. · Componentes para validação no servidor e, caso o cliente permita, também no cliente. · Em versões futuras, existirão componentes para WML (celulares, etc) e outros. Delphi 8 – Por que ele é diferente? A este ponto você já deve ter percebido o que torna o Delphi 8 diferente das versões anteriores do Delphi. Na realidade, o Delphi 8 gera aplicações 100% compatíveis com o “.Net Framework” as quais só irão rodar em cima desta plataforma. Por exemplo, um aplicativo escrito em Delphi 7, roda diretamente em cima do sistema operacional Windows. Um aplicativo escrito em Kylix 3, roda diretamente em cima do sistema operacional Linux. Uma aplicação escrita em Delphi 8, roda em cima do “.Net Framework” que nada mais é que uma “camada” intermediária entre a aplicação e o sistema operacional. Sua aplicação depende deste “run-time” para rodar, pois, ela não “conhece” o sistema operacional e sim somente o “.Net Framework”, o que permite torná-la portável para qualquer sistema operacional onde exista o “.Net Framework” instalado. Figura 5 – Estrutura de funcionamento da “.Net Framework” Analisando a estrutura apresentada na figura 5, pode perceber-se que existem várias linguagens para desenvolvimento de aplicativos para a plataforma .Net, entre elas o Delphi. Todas estas linguagem geram um objeto final em uma linguagem intermediária que é interpretada pelo .Net Framework e apresentada na forma de interfaces Asp.Net ou Windows Forms Conclusão A plataforma “.NET” da Microsoft é um conjunto muito completo e bem feito de tecnologias. Elas resolvem com relativa simplicidade problemas reais como produtividade no desenvolvimento de software, portabilidade e uso de novas tecnologias Internet. O Delphi 8 tem tudo para tornar-se uma das melhores, senão a melhor IDE de desenvolvimento para este ambiente, aproveitando o conhecimento que você já possui em object pascal, agora “Delphi Language”, oferencendo produtividade via abstrações já implementadas, principalmente relacionadas ao acesso a dados (BDP – Borland Data Provider) e outros recursos interessantes, os quais estaremos tratando nos próximos artigos. Abraço e sucesso à todos, Referências A arquitetura .Net da Microsoft, Mauro Sant’Anna, The Club Megazine, Set/2000 Microsoft MSDN, http://msdn.microsoft.com/ Borland BDN, http://bdn.borland.com/ A estrutura básica de funcionamento do “.Net Framework” pode ser visualizada na Figura 5. MeGAZINE Sobre o autor Alessandro Ferreira, Consultor Técnico do The Club [email protected] 23 Delphi Metodologia de Desenvolvimento de Sistemas de Informação para Internet por Marcelo Nogueira Resumo - As empresas de desenvolvimento de sistemas de informação com o advento do surgimento da internet, tiveram seus recursos organizacionais, humanos e tecnológicos submetidos a mudanças radicais diante da demanda a elas submetidas. Porém a não adoção de uma metodologia específica para desenvolvimento de sistemas para internet, que possui características e comportamento diferenciados com relação aos sistemas legados, pode comprometer o sucesso desse novo paradigma. 1. Objetivo Este trabalho tem por objetivo principal apresentar uma metodologia de desenvolvimento de sistemas de informação para internet denominada “PRÁTICA”, baseada nas melhores práticas da engenharia de software, como processo fundamental e fator crítico de sucesso no desenvolvimento de software através de aplicação de um modelo estruturado para levantamento das questões apresentadas pelos clientes / usuários. Este artigo pretende contribuir com outros estudos de metodologias para desenvolvedores de software para internet. 2. Introdução A partir da década de 90, houve incremento natural impulsionado pela visão de negócios do comércio eletrônico, B2B,B2C, Intranets, Extranets, etc. Os sistemas de informação na internet têm passado por uma expansão fantástica, acompanhando o crescimento da grande rede. Os portais diversos fornecem informações respectivas sobre diversos ambientes de trabalho: Livrarias fornecem informações sobre obras e publicações, portais de notícias fornecem informações diversas, grandes magazines lançaram lojas virtuais que fazem venda de seus produtos e recebem o pagamento via eletrônica, os bancos oferecem quase todos seus serviços em ambiente virtuais. Nesse ambiente competitivo, dinâmico e cada vez mais complexo, a internet intensificou a preocupação com a gestão adequada da Informação assumindo importância decisiva no 24 processo de tomada de decisão nas organizações. A adoção da Engenharia de Software como linha base da Gestão da Informação, possibilitará, não só desenvolver e consolidar os conhecimentos no desenvolvimento de software para internet, bem como prepara-los para encarar com confiança os novos desafios no mundo dos negócios, e também reforçar as competências profissionais, mantendo-se atualizado em relação ao potencial dos sistemas de informação e das novas tecnologias numa perspectiva empresarial e competitiva globalmente. A sua adequação juntamente com uma metodologia específica para sistemas de informação para internet será fator crítico de sucesso nesses novos desafios que os desenvolvedores estão enfrentando. No estudo da Engenharia de Software, o autor Roger S. Pressman, demonstra preocupação com a “Crise do Software” que atualmente ele intitula como “Aflição Crônica”, chegando a determinar números expressivos sobre a não finalização de projetos de sistemas começados e não terminados. Existem várias técnicas de levantamento de requisitos e modelagem de software e o desenvolvedor que não às implementam tem dificuldades de realizar um projeto de sistemas livre de manutenções e re-trabalhos, condenando diretamente a qualidade do produto. Para os sistemas específicos para internet, que requerem atenções diferenciadas, o desenvolvedor pode debater-se com os mesmos problemas já estudados nos sistemas tradicionais e este artigo está disposto justamente a prestar esta contribuição, já que uma nova plataforma foi criada e muitos sistemas serão refeitos com este novo formato. 3. Relevância Segundo o Ministério da Ciência e Tecnologia, 32% dos sistemas desenvolvidos no Brasil, são sistemas de informações para internet. Considerado por Brooks como problema essencial: “A parte mais difícil do desenvolvimento de software é decidir precisamente o que será desenvolvido. Nenhuma outra parte do trabalho é tão difícil quanto estabelecer (definir) os detalhes técnicos necessários incluindo todas as interfaces para pessoas, MeGAZINE Delphi máquinas e para outros sistemas de software. Nenhuma outra parte do trabalho é tão possível de ocasionar erros no sistema como essa. Nenhuma outra parte é tão difícil de ser posteriormente consertada”. A expressão “Crise do Software”, que começou a ser utilizada na década de 60, tem historicamente aludido a um conjunto de problemas recorrentemente enfrentados no processo de desenvolvimento (Construção, implantação e manutenção) de software. Apesar da enorme variedade de problemas que caracterizam a crise do software, engenheiros de software e gerentes de projetos para desenvolvimento de sistemas computacionais tendem a concentrar suas preocupações no seguinte aspecto: “A enorme imprecisão das estimativas de cronogramas e de custos de desenvolvimento” (Tabelas 1, 2). A não implementação da engenharia de software permite erros no levantamento dos requisitos do sistema, e somente percebidos na implantação do sistema, gerando assim uma fase de manutenção e correção do software interminável, excedendo no custo desta fase (Tabela 1) e alongando o prazo de término substancialmente (Tabela 2). TABELA 1 EXCEDENTES DE CUSTO. TABELA 2 A falta de cultura ou por desconhecimento da sua existência de uma metodologia para desenvolvimento de sistemas para internet, levam projetos de suma relevância ao insucesso e aumentando ainda mais a quantidade de casos dos sistemas inacabados, conseqüentemente desperdiçando tempo, recursos financeiros e não atendendo as necessidades dos clientes e nem do desenvolvedor. “Muitos desses erros poderiam ser evitados se as organizações dispusessem de um processo de engenharia de requisitos definido, controlado, medido e aprimorado. No entanto, percebe-se que para muitos profissionais de informática esses conceitos não são muito claros, o que certamente dificulta a ação dos gerentes no sentido de aprimorar os seus processos de desenvolvimento”. 4. Engenharia de Software Engenharia de Software é a metodologia de desenvolvimento e manutenção de sistemas modulares, com as seguintes características: · Adequação aos requisitos funcionais do negócio do cliente e seus respectivos procedimentos pertinentes; ·fetivação de padrões de qualidade e produtividade em suas atividades e produtos; · Fundamentação na tecnologia da informação disponível, viável e oportuna; · Planejamento e gestão de atividades, recursos, custos e datas. Segundo Pressman, engenharia de Software é: · “O estabelecimento e uso de sólidos princípios de engenharia para que se possa obter economicamente um software que seja confiável e que funcione eficientemente em máquinas reais”; · “Descendente da engenharia de sistemas e de hardware. Abrange um conjunto de 3 elementos fundamentais (métodos, ferramentas e procedimentos), que possibilita, ao gerente, o controle do processo de desenvolvimento do software e oferece ao profissional uma base para a construção de software de alta qualidade”. Segundo Martin, E ngenharia de Software é: · “É o estudo dos princípios e sua aplicação no desenvolvimento e manutenção de sistemas de software”; EXCEDENTE DE PRAZO Como conclusão, pode-se relatar que engenharia de software é um conjunto de práticas para desenvolvimento de soluções de software, ou seja, roteiro que pode utilizar diversas técnicas. 5. Objetivos da Engenharia de Software De um modo geral, considera-se que os objetivos primários da Engenharia de Software são o aprimoramento da qualidade dos produtos de software e o aumento da produtividade dos engenheiros de software, além do atendimento aos requisitos de MeGAZINE 25 Delphi eficácia e eficiência, ou seja, efetividade. A Engenharia de Software visa sistematizar a produção, a manutenção, a evolução e a recuperação de produtos intensivos de software, de modo que ocorra dentro de prazos e custos estimados, com progresso controlado e utilizando princípios, métodos, tecnologia e processos em contínuo aprimoramento. Os produtos desenvolvidos e mantidos, seguindo um processo efetivo e segundo preceitos da Engenharia de Software asseguram, por construção, qualidade satisfatória, apoiando adequadamente os seus usuários na realização de suas tarefas, operam satisfatória e economicamente em ambientes reais e podem evoluir continuamente, adaptando-se a um mundo em constante evolução. 6. Qualidade de Software Atingir um alto nível de qualidade de produto ou serviço é o objetivo da maioria das organizações. Atualmente não é mais aceitável entregar produtos com baixa qualidade e reparar os problemas e as deficiências depois que os produtos foram entregues ao cliente. A globalização da economia vem influenciando as empresas produtoras e prestadoras de serviços de software a alcançar o patamar de qualidade e produtividade internacional para enfrentarem a competitividade cada vez maior. A norma internacional NBR ISO/IEC 12207 – Tecnologia da Informação – Processos de Ciclo de Vida de Software é usada como referência em muitos países, inclusive no Brasil, para alcançar esse diferencial competitivo. Diante deste fato, podemos afirmar que por falta de utilização de métodos e modelos de gerenciamento da qualidade de software com base em requisitos, produzimos softwares de qualidade contestável e participando efetivamente da “Crise do Software”. 7. Produto de Software Quando entregamos a um cliente um pacote bem delimitado e identificado, podemos dizer que entregamos um produto. A definição para produto de software segundo a norma IEEE-STD-610 é: “O conjunto completo, ou qualquer dos itens individuais do conjunto, de programas de computador, procedimentos, e documentação associada e dados designados para liberação para um cliente ou usuário final”. 8. Processo de Software O conceito de processo de software se baseia no conceito generalizado de processo, que pode ser definido como uma seqüência de estados de um sistema que se transforma. O 18 (Software Engineering Institute), da Carnegie Melon University propõe o seguinte: “O processo de software pode ser definido como um conjunto 26 de atividades, métodos, práticas, e transformações que as pessoas empregam para desenvolver e manter software e os produtos associados (ex. planos de projeto, documentos de projeto (design), código, casos de teste, e manual do usuário)”. 9. Requisitos Os problemas que os engenheiros de software têm para solucionar são, muitas vezes, imensamente complexos. Compreender a natureza dos problemas pode ser muito difícil, especialmente se o sistema for novo. Conseqüentemente, é difícil estabelecer com exatidão o que o sistema deve fazer. As descrições das funções e das restrições são os requisitos para o sistema . Segundo Tonsig, Os requisitos compõem o conjunto de necessidades estabelecido pelo cliente / usuário do sistema que definem a estrutura e comportamento do software que será desenvolvido. 10.Engenharia de Requisitos Engenharia de requisitos, uma subárea da engenharia de software, tem por objetivo tratar o processo de definição dos requisitos de software. Para isso estabelece um processo pelo qual o que deve ser feito é elicitado, modelado e analisado. Esse processo deve lidar com diferentes pontos de vista e usar uma combinação de métodos, ferramentas e pessoal. O produto desse processo é um modelo, do qual um documento chamado ‘requisitos’ é produzido. Esse processo é perene e acontece em um contexto previamente definido e que chamamos de ‘Universo de informações’. “O conjunto de técnicas empregadas para levantar, detalhar, documentar e validar os requisitos de um produto forma a engenharia de requisitos”. 10.1 E specificação de Requisitos “Na industria de software, as necessidades dos clientes são muito difíceis de serem acessados ou descobertos. Geralmente deve-se deixar margens nos sistemas para futuras mudanças. Os requisitos geralmente são vagos”. A seguir, vários problemas que nos ajudam a compreender por que a elicitação de requisitos é difícil: · Problemas de escopo; · Problemas de entendimento; · Problemas de volatilidade; Para ajudar a contornar esses problemas, os engenheiros de sistemas devem abordar a atividade de coleta de requisitos de um modo organizado. Uma vez reunidos os requisitos, os produtos de trabalho mencionados anteriormente formam a base para a análise de requisitos. A análise categoriza os requisitos e os organiza em MeGAZINE Delphi subconjuntos relacionados; explora cada um em relação aos demais; examina-os quanto à consistência, omissões e ambigüidade; e ordena-os com base nas necessidades dos clientes / usuário. 10.2 Modelagem do Sistema Cada sistema baseado em computador pode ser modelado como uma transformação de informação usando um gabarito entrada – processamento – saída. Essa visão pode ser estendida para incluir duas características adicionais dos sistemas – processamento e manutenção de interface com o usuário e autoteste. 10.3 Validação de Requisitos Os produtos de trabalho produzidos como conseqüência da engenharia de requisitos são avaliados quanto à qualidade durante o passo de validação. A validação de requisitos examina a especificação para garantir que todos os requisitos do sistema tenham sido declarados de modo não-ambíguo; que as inconsistências, omissões e erros tenham sido detectados e corrigidos e que os produtos de trabalho estejam de acordo com as normas estabelecidas para o processo, projeto e produto. 10.4 Gestão de Requisitos Gestão de requisitos é um conjunto de atividades que ajuda a equipe de projeto identificar, controlar e rastrear requisitos e modificações de requisitos em qualquer época, à medida que o projeto prossegue. 11. Metodologia de Desenvolvimento de Sistemas Baseado nas melhores práticas da engenharia de software, processos alinhados as normas de qualidade de software e definidos de forma a se adaptar as características de software para internet, através desse modelo sugerido, pretende-se a sistematizar o processo de desenvolvimento de sistemas de informação para internet. Apresentamos a metodologia “PRÁTICA”. A metodologia “PRÁTICA”, propõe as seguintes fases fundamentais: · Especificação de Requisitos; · Definição de Lay-out; · Desenho; · Implementação; · Integração; · Publicação; E as seguintes fases de consolidação do projeto: · Verificação e Validação; · Testes e Aceitação; FIGURA 1 METODOLOGIA “PRÁTICA”. 11.1 especificação de Requisitos Nessa fase, é realizada a especificação dos requisitos do software, funcionais, não funcionais, e de domínio específico da WEB. Atividades desta fase: Contratação, Entrevistas, análise, documentação, elaboração de escopo. 11.2 Verificação e Validação Após a especificação dos requisitos, o desenvolvedor faz-se uma verificação para confrontar aquilo que o cliente solicitou com o que ele levantou e documentou. Atividades desta fase: Reuniões, revisões de documentos de requisitos. O desenvolvedor apresenta ao cliente um documento de requisitos ao cliente para que se faça a Validação, ou seja o cliente confrontará aquilo que ele solicitou com o que desenvolvedor entendeu. Atividades desta fase: Reuniões, validação de documentos de requisitos, e relatório de alterações. 11.3 Definição do Lay-out Esta fase consiste na elaboração de um Lay-out básico por página a ser desenvolvida. Prevê a diagramação que o será submetida à página. Local e tamanho das imagens, dos textos, das publicidades, das entradas e saídas de dados. Atividades desta fase: Entrevistas, análise, documentação, elaboração da diagramação digital. 11.4 Verificação e Validação Após a criação do lay-out, o desenvolvedor faz-se uma verificação para confrontar aquilo que o cliente solicitou com o que ele elaborou. Atividades desta fase: Reuniões, revisões de documentos de lay-out. O desenvolvedor apresenta ao cliente o lay-out elaborado ao cliente para que se faça a Validação, ou seja o cliente confrontará aquilo que ele solicitou com o que desenvolvedor realizou. Atividades desta fase: Reuniões, validação de documentos de MeGAZINE 27 Delphi lay-out, e relatório de alterações. 11.5 Desenho Esta fase consiste na criação do desenho da página. Em cima da diagramação feita na atividade lay-out, as imagens, espaços de texto, serão criadas e adicionadas, formando uma imagem estática, correspondendo a um protótipo da pagina que está sendo desenvolvida. Atividades desta fase: Entrevistas, análise, documentação, elaboração das imagens digitais. 11.6 Verificação e Validação Após a criação do desenho, o desenvolvedor faz-se uma verificação para confrontar aquilo que o cliente solicitou com o que ele elaborou. Atividades desta fase: Reuniões, revisões de documentos de desenho. O desenvolvedor apresenta ao cliente o desenho elaborado ao cliente para que se faça a Validação, ou seja o cliente confrontará aquilo que ele solicitou com o que desenvolvedor realizou. Atividades desta fase: Reuniões, validação de documentos de desenho, e relatório de alterações. 11.7 Implementação Esta fase consiste na fase de codificação, e inserção efetivamente dos espaços de textos e das imagens, construindo efetivamente no editor, a página “Real”. Atividades desta fase: Análise, codificação, documentação, elaboração das imagens digitais. 11.8 Testes & Aceitação Após a implementação, o desenvolvedor realiza testes para avaliar funcionalidade, usabilidade e interatividade do software que ele desenvolveu. Atividades desta fase: Reuniões, Testes no código e revisões de documentos de implementação. O desenvolvedor apresenta a página implementada ao cliente para que ele faça a avaliação e aceitação, do software o qual solicitou o seu desenvolvimento. Atividades desta fase: Reuniões, Aceitação do software implementado, validação de documentos de implementação, e relatório de alterações. As fases anteriores a esta devem ser repetidas num ciclo único até que todas as páginas sejam desenvolvidas. Após toda implementação concluída, testada e aceita pelo cliente, passa-se para a fase a seguir. 11.9 Integração Nesta fase, após todas as páginas elaboradas e construídas, são integradas entre si, através de chamadas e acoplamentos necessários para seu pleno funcionamento. Atividades desta fase: Análise, codificação, documentação. 11.10 Testes & Aceitação Após realizar as integrações necessárias, o desenvolvedor realiza testes para verificar se possui erros ou se as chamadas estão funcionando perfeitamente no software que ele 28 desenvolveu. Atividades desta fase: Reuniões, Testes no código e revisões de documentos de integração. O desenvolvedor apresenta as páginas integradas ao cliente para que ele faça a avaliação e aceitação, do software o qual solicitou o seu desenvolvimento, liberando-as para publicação. Atividades desta fase: Reuniões, Aceitação do software integrado, validação de documentos de integração, e relatório de alterações, e termo de autorização para publicação. 11.11 Publicação Esta fase consiste na efetiva publicação das páginas desenvolvidas, já testadas e aceitas pelo cliente. Atividades desta fase: Transferência de arquivos, verificação e/ou criação de domínio virtual, contratação e/ou liberação de espaço lógico para hospedagem dos arquivos, documentação. 12. Conclusão É importante que os desenvolvedores de software reconheçam que não é possível desenvolver sistemas com qualidade, cumprir prazos e custos e atender às expectativas dos usuários sem ter um processo de desenvolvimento de sistemas para internet, compreendido e utilizado por toda a equipe. A modelagem aqui apresentada possui: · Adequação aos princípios e objetivos da engenharia de Software. · O nível de complexidade da sua implementação pode ser dimensionada de acordo com o porte do sistema, viabilizando para as pequenas organizações desenvolvedoras de software. · Possibilita então ser fator crítico para o sucesso no desenvolvimento de software. · Pode ser utilizada alinhada as normas ISO de qualidade de software 12207, 9000-3. · Com a sua implementação é possível contribuir para o fim da “Crise do Software”. · Com os processos de desenvolvimento de software controlados, documentados e gerenciados o desenvolvedor poderá assumir projetos de alta complexidade, aliados a técnica e criatividade, pois terá mais chance de sucesso. · Melhor capacitado e provedor de metodologias que levam ao desenvolvimento de software com qualidade, o desenvolvedor poderá criar soluções que atendam as necessidades e os requisitos da empresa, contribuindo para criação de vantagens competitivas, sustentando as bases estratégicas das organizações. Sobre o autor Marcelo Nogueira é bacharel em Análise de Sistemas, Mestrando em Engenharia de Produção com ênfase em Gestão da Informação, Professor Universitário, Instrutor e Desenvolvedor Delphi desde 1995. e-mail: [email protected] MeGAZINE Delphi Prevenindo o Access Violation em sua aplicação. Por Claudinei Rodrigues Access Violation, General Protection Fault ou Invalid Page Fault, os nomes mudam, mas a origem do erro é sempre a mesma. Access Violation é uma frase que os usuários de computador vêem quando sua aplicação está rodando e ela tenta acessar alguma informação que não está mais disponível. Se as aplicações Windows fossem capazes de escrever além dos limites da sua área de armazenamento ela poderia escrever sobre outra aplicação ou instrução do sistema do operacional ou ainda algum outro dado. Se isto acontecer o sistema operacional deixaria de funcionar e você teria que reiniciar o sistema. Por exemplo, quando ocorre um erro em um programa no Windows NT/2000, o Dr. Watson passa e para o programa fazendo um diagnostico rápido e grava-o em um arquivo texto. Access Violation é um dos erros mais frustrantes encontrados na programação Windows. O propósito deste artigo é lhe ajudar a encontrar uma solução para este problema. Nós podemos dividir o Access Violation durante o desenvolvimento de uma aplicação utilizando o Delphi em dois tipos: 1 - Em tempo de execução. 2 - Em tempo de desenvolvimento. Access Violation em tempo de desenvolvimento O erro Access Violation foi verificado quando se está iniciando ou fechando a IDE do Delphi ou construindo um projeto. Hardware O erro Access Violation que surge enquanto o seu computador está em operação pode ser originado por vários motivos diferentes, incluindo a BIOS, o sistema operacional, ou rotinas que acessam drivers de hardware. Como por exemplo alguma placa de vídeo, som ou rede podem causar o erro Access Violation no Delphi. Quer saber o por quê? Qualquer placa em sua máquina vem com um determinado driver. Dependendo do fabricante, da versão do Windows, e da versão do Delphi utilizado você pode ter estes tipos de problemas. Existem alguns passos que podem ser feitos para lhe ajudar a resolver estes problemas. · Verifique se não existe nenhum conflito entre os drivers instalados. · Algumas vezes diminuindo a resolução do monitor poderá lhe ajudar a estabilizar alguma placa de vídeo que tenha algum problema. · Assegure-se que se você estiver utilizando uma máquina com mais de um processador que a etapa de revisão para cada processador é a mesma. · Sempre utilize a ultima versão do driver para todos os componentes de seu sistema. Software Todo mundo sabe que o Windows pode deixar de funcionar e algumas vezes ele se reinicia espontaneamente. Existem caminhos que podem ajudar você a de ter um ambiente de programação mais estável. O qual por sua vez ajudará impedir o erro Access Violation. · Ainda que o Windows 9x seja o mais popular, o Windows NT/2000/XP tem comprovado ser o ambiente mais estável. · Assegure que você tenha instalado os últimos Service Packs para o NT/2000/XP. Com todos os service packs atualizados você notará que sua aplicação ficará muito mais estável. · Uma excelente prática de prevenção de erros é sempre MeGAZINE 29 Delphi manter os softwares atualizados. Mantenha o seu Delphi, BDE, ADO, etc com a última atualização. A cada nova atualização o número de Access Violation será drasticamente diminuído. · Se você está recebendo Access Violation aleatoriamente na sua IDE, você provavelmente tem componentes de terceiros que foram instalados de forma incorreta ou existem componentes que não foram feitos na versão do Delphi que você está utilizando. Para resolver o problema tente desinstalar os componentes um a um até que o problema tenha sido resolvido. Assim você terá certeza de qual componente está apresentando o problema e daí sim você poderá entrar em contato com o fabricante do mesmo e solicitar uma nova versão. · Verifique se existe algum software que seja shareware ou beta. Estes tipos de software podem apresentar o erro Access Violation. · Um erro Access Violation também pode ocorrer por causa de um sistema que esteja configurado errado. Se você repetidamente encontrar o mesmo erro, armazene as informações e entre em contato com a empresa que desenvolveu o software e lhe envie as informações que você armazenou para que eles corrijam o erro. Isto é tudo que posso sugerir para o erro Access Violation em tempo de desenvolvimento, agora vamos tratar sobre este erro em tempo de execução. Objeto não existe Uma das causas mais comuns do Access Violation na programação em Delphi é o uso de um objeto que ainda não foi criado. Se o segundo endereço for FFFFFFF (ou 0000000) você pode quase apostar que você está tentando acessar um objeto que ainda não foi criado. Por exemplo, se você chamar um método de um form que ainda não foi criado, ou não foi auto criado pelo Delphi ou ainda não foi instanciado você receberá este erro. Veja o código a seguir: procedure TForm1.Button1Click(Sender: TObject); begin // Isto vai dar um Access Violation Form2.Refresh; end; Vamos supor que o Form2 esteja listado em Available Forms na janela Project Options, ou seja, na lista em que os forms devem ser criados e destruídos via programação. Ao executar o código anterior e se a opção “Stop on Delphi Exceptions” na pasta Language Exceptions em Debugger Options estiver habilitada, você receberá o seguinte erro: Os Access Violation mais comuns e como impedílos. Acontece com qualquer software que você desenvolveu. Você escreve a aplicação, testa-a e envia para o seu cliente. Ele instala a sua aplicação e quando vai utilizá-la, pronto aparece o erro Access Violation. Quando ocorre o erro Access Violation no seu cliente é muito importante se concentrar sobre o que ele estava fazendo naquele momento. Assim fica mais fácil para se encontrar uma solução para o problema. Com este tipo de erro, esta é a única maneira que você encontrará o problema e assim poderá encontrar um meio de resolvê-lo. Esta mensagem informa que um erro Access Violation ocorreu. A exceção EAccessViolation é uma classe de exceção para erros de acesso a memória. Esta tela é a que você verá durante o desenvolvimento da sua aplicação. A próxima tela é mostrada quando o programa for executado. Localizando o local do erro Agora vamos ver como encontrar a rotina exata e a linha onde ocorreu o erro Access Violation quando você não tem mais do que o endereço do erro: Access violation at address <HEX_value> in module <Application.Exe> Read of address <HEX_value_2> Se você tem a sua aplicação compilada com as informações de debug, você pode localizar a linha de origem do código correspondente ao código compilado que causou o Access Violation. 30 O primeiro número que consta nesta mensagem de erro é 00432818. Este é o endereço do erro no código compilado, ou seja, onde o erro aconteceu neste nosso exemplo. Na IDE do Delphi vá até a opção Search | Find Error, digite o número do erro que no nosso caso é 00432818 depois clique em OK. Ele irá mostrar onde ocorreu o erro. Vamos ver agora uma relação de casos onde é mais comum acontecer o Access Violation em Delphi durante o desenvolvimento. Esta lista não é e não pode ser entendida com uma solução definitiva para o erro Access Violation, mas com certeza vai lhe ajudar bastante. MeGAZINE Delphi Chamando um objeto que não existe Como mencionei anteriormente a causa mais provável para o Access Violation é quando se tenta usar um objeto que ainda não existe ou ele já tenha sido destruído. Para prevenir este tipo de Access Violation, tenha certeza de que qualquer objeto que você for utilizar tenha sido criado. Por exemplo, você pode estar abrindo um componente Table em um form no evento OnCreate e este componente está em um Data Module que ainda não foi criado ou ainda ele foi removido da lista auto-create. Isto irá ocasionar um Access Violation. // Isto causa um Access Violation end; end; Indexando uma string vazia Uma string vazia não tem um valor válido. Então, tentar indexar uma string vazia é como tentar acessar um valor nulo e o resultado será um Access Violation. Veja o exemplo: procedure TForm1.Button3Click(Sender: TObject); var s: string; begin s := ‘’; s[1] := ‘a’; //Isto gera um Access Violation end; Parâmetros inválidos para a API Se você tentar passar um parâmetro inválido para a API do Windows um erro Access Violation pode ocorrer. O melhor caminho para resolver este tipo de erro é acessar o help para obter as informações corretas sobre a API que você quer chamar. Deixar o Delphi liberar Referenciando ponteiros Quando um objeto é proprietário de outro objeto, deixe-o fazer a remoção. Visto que, por default, todos os forms autocriados são de propriedade do objeto Application, quando a aplicação termina ele libera o objeto Application e também todos os forms são liberados. Por exemplo, se você tem dois forms, Form1 e Form2, ambos são auto criados quando a aplicação é inicializada e se você tentar executar o código a seguir, você receberá um erro Access Violation: Você deve referenciar os ponteiros, senão você estará movendo o endereço do ponteiro e possivelmente corrompendo outra localização de memória. procedure TForm1.Button1Click(Sender: TObject); var p1 : pointer; p2 : pointer; begin GetMem(p1, 128); GetMem(p2, 128); //Esta linha pode causar um access violation Move(p1, p2, 128); //Esta linha está correta Move(p1^, p2^, 128); FreeMem(p1, 128); FreeMem(p2, 128); end; procedure TForm1.Button2Click(Sender: TObject); begin Form2.ShowModal; Form2.Free; Form2.ShowModal; end; Cancelando a exceção Quando você está fazendo um tratamento de exceção jamais destrua um objeto temporário exception (E). Se você fizer isto a aplicação também o tentará destruir e como não vai encontrá-lo você receberá o erro Access Violation. Se você fizer algo semelhante ao código a seguir você receberá o erro Access Violation. Conclusão É isso ai pessoal, espero ter auxiliado da melhor forma possível na solução deste erro que tem deixado muito programador de cabelo branco. zero := 0; try res := 10 / zero; except on E: EZeroDivide do begin MessageDlg(‘Não pode ser divido por zero!’, mtError, [mbOK], 0); E.free; MeGAZINE Até a próxima. Sobre o autor Claudinei Rodrigues, Consultor Técnico do The Club [email protected] 31