megazine 3 - the club · muita enforia na comunidade delphi com o recente lançamento do delphi...
TRANSCRIPT
MeGAZINE 3
EDITORIAL
Editorial
Celso Jefferson PaganelliPresidente - The Club
Editorial ............................................................................ 03Dicas & Truques .............................................................. 04Indy - Obtendo a cotação do dólar on-line .................... 05SIntegra - Abordagem completa - Parte 3 ...................... 09Acessando o Active Directory via ADO .......................... 13Delphi 8 - Visualizando Imagens na Web (thumbnail) .. 16Ajustes no Firewall do Windows XP Service Pack 2
para rodar o Interbase/Firebird ............................ 21Aspectos relevantes na gestão de
projetos e Software .............................................. 24Perguntas & Respostas.................................................. 27
THE CLUBAv. Celso Ferreira da Silva, 190
Jd. Europa - Avaré - SP - CEP 18.707-150Informações: (0xx14) 3732-3689
Suporte: (0xx14) 3733-1588 - Fax: (0xx14) 3732-0987
Internethttp://www.theclub.com.br
Cadastro: [email protected]: [email protected]
Informações: [email protected]
DúvidasCorrespondência ou fax com dúvidas devem ser
enviados ao - THE CLUB, indicando "Suporte".
OpiniãoSe 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çãoA utilização, reprodução, apropriação,
armazenamento em banco de dados, sob qualquerforma 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 direitosautorais.
Copyright© The Club® 2004
Impressão e acabamento:GRAFILAR
Tel.: (0xx14) 3841-2587 - Fax: (0xx14) 3841-3346Rua Cel. Amando Simôes, 779 - Cep 18.650-000
São Manuel - SPTiragem: 5.000 exemplares
Diretor - Presidente
Celso Jefferson M. Paganelli
Diretor TécnicoMauro Sant’Anna
Colaboradores
Victory Fernandes, Marcelo Nogueira
Delphi é marca registrada da Borland International, as
demais marcas citadas são registradas pelos seus
respectivos proprietários.
Editorial
Olá amigos,
Muita enforia na comunidade Delphi com o recente lançamento
do Delphi 2005, a mais nova versão do Delphi. Conforme já
mencionamos na edição de Outubro/2004, são muitas as novidades do
novo Delphi, onde destacamos a integração do desenvolvimento Delphi
Win32 (análogo ao Delphi 7), Delphi For .NET (análogo ao Delphi 8) e a
linguagem C# (análogo ao C#Builder). Além das novidades, foram
efetuadas muitas correções de bugs e melhorias nos componentes já
existentes. Confira o tour do Delphi 2005 pelo Brasil, para maiores
informações acesse: http://info.borland.com.br/delphi/.
Deixando a euforia de lado, trazemos até você mais uma edição
da The Club Megazine, com artigos, dicas e muita informação para
tornar o dia-a-dia do programador Delphi, boa leitura e abraços à todos.
MeGAZINE4
QuickReport – Criando controle de número decópias
O QuickReport possui vários problemas relacionados a
incompatibilidade com muitos drivers de impressoras existentes
no mercado. Uma destas incompatibilidades, faz com que a
propriedade ‘Copies’ responsável em enviar várias cópias de um
mesmo relatório à impressora, não funcione e até o momento,
sem solução por parte do fabricante, pelo menos na versão
standard do QuickReport que acompanha o Delphi. Aqui
apresentamos um solução paliativa para o problema, na qual
efetuamos uma cópia da imagem gerada pelo preview do
QuickReport e depois, fazemos a impressão da mesma quantas
vezes necessário.
Para estes exemplo, vamos utilizar um componente
TspinEdit o qual será responsável em setar o número de cópias à
imprimir e um botão para chamar o relatório. Declare na sessão
private uma variável chamada Copia, do tipo TQRPrinter.
private { Private declarations } Copia: TQRPrinter; { declarar na listauses QrPrNtr } public { Public declarations } end;
var Form1: TForm1;
implementation
{$R *.dfm}
{ Evento AfterPrint do QuickReport }procedure TForm1.QuickRep1AfterPrint(Sender:
TObject);var i: Integer;begin if (QuickRep1.QRPrinter.PrinterOK) and(Tag=0) and (Spin_Copias.Value > 1) then begin Tag := 1; { Propriedade Tag do formulário} for i := 1 to Spin_Copias.Value-1 do Copia.Print; { Imprime as cópias } end;end;
procedure TForm1.Button1Click(Sender:TObject);begin { Propriedade Tag do formulário } Tag := 0; { instância objeto que irá receber a cópiado relatório } Copia := TQRPrinter.Create; try QuickRep1.Prepare; { Copia a imagem do preview gerado } Copia := QuickRep1.QRPrinter; QuickRep1.Preview; finally Copia.Free; end;end;
O projeto de exemplo referente esta dica está disponível para
download em http://www.theclub.com.br/revista/download/
qrcopies.zip
Dicas & Truques
MeGAZINE 5
Delphi
IntroduçãoUma solicitação que temos recebido frequentemente aqui no
suporte técnico The Club, é de como buscar a cotação on-line do
dólar para ser utilizada em aplicações desenvolvidas em Delphi.
Existem várias abordagens que poderiam ser utilizadas para esta
implementação e particularmente acho a mais prática e viável
fazer acesso a um serviço de web ou seja, um WebService,
contudo, desconheço algum serviço gratuíto que disponibilize este
tipo de informação. Dentro deste contexto, vamos demonstrar
aqui uma abordagem paliativa que disponibilizará esta
informação (cotação do dólar), utilizando como fonte o site do
Banco Central do Brasil (http://www.bcb.gov.br) , o qual
disponibiliza uma página com a cotação do dólar no endereço:
http://www.bcb.gov.br/htms/infecon/taxas/taxas.htm.
Nossa abordagem será bastante simples, consistindo em
acessar o endereço da página que possui a cotação do dólar,
contudo, trazendo o seu código fonte. De posse do código fonte da
página iremos processá-lo a fim de extrair somente as
informações que nos interessam. Este tipo de abordagem tem um
problema, pois, caso a página sofra alguma alteração, teremos
que fazer um novo estudo do código fonte da mesma para
conseguir extrair a informação desejada. (Por isso, a utilização de
um webservice seria o mais indicado!). Para a obtermos o código
fonte da página, iremos utilizar o componente TIdHTTP
(pertencente a suite de componente Indy), o qual através do
método GET devolve o código fonte de um URL informada como
parâmetro.
Verificando o código HTMLAo executarmos o método GET do componente TIdHTTP,
iremos receber o código fonte apresentado na listagem 1.
<HTML><HEAD><TITLE>BCB - Taxas de Câmbio</TITLE><Link rel=”stylesheet” href=”http://www.bcb.gov.br/css/corpoInterno.css”><STYLE TYPE=”text/css”><!— A:hover{color:blue;}—></STYLE></HEAD><BODY class=”semTemplate”><br><blockquote><table> <tr><td><img src=”/gifs/quadro-p.gif”align=middle></td><td>Cotação de fechamentodo dólar no dia 05/11/2004, sexta-feira:</td></tr><tr><td> </td><td><blockquote><li>Dólar-dos-EUA:<br><table cellspacing=1><TR><th VALIGN=TOPclass=”fundoPadraoBEscuro3">Data</th><th class=”fundoPadraoBEscuro3" NOWRAP>Taxade Compra</th><th class=”fundoPadraoBEscuro3"NOWRAP>Taxa de Venda</th></TR><tr><td ALIGN=CENTER class=”fundoPadraoBClaro2">05/11/200405/11/200405/11/200405/11/200405/11/2004</td><td ALIGN=RIGHTclass=”fundoPadraoBClaro2">2,81782,81782,81782,81782,8178</td><tdALIGN=RIGHT class=”fundoPadraoBClaro2">2,81862,81862,81862,81862,8186</td></tr></table></td></tr></table></blockquote></OL></CENTER></BODY></HTML>
Listagem 1 – Código fonte da página
Analisando o código fonte recebido, não é muito difícil
identificar as informações que nos serão úteis, ou seja, a data, a
cotação de compra e a cotação de venda. Contudo, para facilitar
nossa abordagem, iremos utilizar uma unit de terceiros
(HtmlUtils) que disponibiliza uma função (HTMLToPlainText)para ‘limparmos’ o código HTML, deixando o ‘texto puro’, o qual
IndyIndyIndyIndyIndyObtendo a cotação do dólar on-lineObtendo a cotação do dólar on-lineObtendo a cotação do dólar on-lineObtendo a cotação do dólar on-lineObtendo a cotação do dólar on-line
por Alessandro Ferreira, [email protected]
MeGAZINE6
ficará mais simples de manipularmos. (O código fonte da
HTMLUtils está disponível junto ao projeto de exemplo que será
apresentado neste artigo, o qual está disponível para download no
endereço indicado no final deste artigo).
Após submetermos o código fonte da página a função
HTMLToPlainText, teremos o resultado apresentado na listagem 2.
BCB - Taxas de CâmbioCotação de fechamento dodólar no dia 05/11/2004, sexta-feira: Dólar-dos-EUA:DataTaxa de CompraTaxa de Venda05/11/20042,81782,8186
Listagem 2 – Código fonte sem as tags HTML
Bem, agora o ‘texto’ ficou bem mais simples e fácil de ser
manipulado!
Usando o componente TIdHTTPBem, vamos agora implementar nosso projeto para trazer a
cotação do dólar. Para isso, vamos utilizar um componente
TIdHTTP, o qual poderá ser nomeado como ‘IdHTTP_PegaDolar’,
um componente TEdit, nomeie como ‘EdURL’ e configure a
propriedade Text=’ http://www.bcb.gov.br/htms/infecon/taxas/taxas.htm’(que é o endereço onde iremos buscar a cotação do dólar), um
Tlabel, ajuste a propriedade Caption=’ URL para obtenção da cotação doDólar’, um componente TSpeedButton, nomeie como ‘sbtnDolar’ e
finalmente um componente TMemo o qual será responsável em
apresentar as informações obtidas, nomeie como ‘Memo_Dolar’.
Na figura 1 poderá verificar o layout sugerido para o formulário de
nosso projeto de exemplo.
Figura 1 – layout sugerido
Vamos agora implementar o código fonte que irá fazer a‘coisa’
funcionar. Primeiramente, vamos criar uma procedure que irá
receber como parâmetro o código fonte (HTML) obtido via
TIdHTTP, e três parâmetros de saída onde retornaremos a data, o
valor de venda e o valor de compra. Acompanhe o codigo na listagem 3.
implementationuses HtmlUtils; { Responsável pela função{ Responsável pela função{ Responsável pela função{ Responsável pela função{ Responsável pela função
HTMLToPlainText }HTMLToPlainText }HTMLToPlainText }HTMLToPlainText }HTMLToPlainText }
{$R *.dfm}
procedure DevolveUS(var HTML: String; outDia: String; out UsVenda, UsCompra: Double);var PosI, PosF: Integer; Tmp: String;begin { Remove formatação HTML } HTML := HTMLToPlainText(HTML); { converte tudo para minúsculo } HTML := AnsiLowerCase(HTML); { Apaga o início do texto até a palavra“dia” } Delete(HTML, 1, Pos(‘dia’, HTML)+2); { Pega a data } Dia := Trim(Copy(HTML, 1, Pos(‘,’, HTML)-1)); { Apaga a primeira data encontrada } Delete(HTML, 1, Pos(‘,’, HTML)); { Apaga a segunda data e deixa apenas osvalores na string } Delete(HTML, 1, Pos(Dia, HTML)+9); { Tenta converter valor de compra } if not TryStrToFloat(Copy(HTML, 1, 6),UsCompra) then raise Exception.Create(‘Problemas aoobter valor do dólar!’); { Tenta converter valor de venda } if not TryStrToFloat(Copy(HTML, 7, 6),UsVenda) then raise Exception.Create(‘Problemas aoobter valor do dólar!’);end;
Listagem 3 – procedimento DevolveUS.
A lógica da procedure DevolveUS é bastante simples.
Primeiro, efetuamos um tratamento para retirar as tags HTML
do código fonte recebido (veja listagem 1 e 2 anteriormente
apresentadas). Para evitar problemas com caixa alta/baixa,
converteremos tudo para minúsculo e após isso, apagaremos todo
o texto até a primeira ocorrência da palabra ‘dia’. Após isso,
apenar iremos copiando e apagando o texto e retornando apenas o
que nos interessa. (Através da função TryStrToFloat tentamos
fazer a conversão dos valores obtidos e caso a conversão não seja
bem sucedida, levantaremos um exceção).
Delphi
MeGAZINE 7
Prosseguindo, vamos agora codificar o evento OnClick do botão
‘sbtnDolar’, confira o código apresentado na listagem 4.
var HTML, Dia: String; UsVenda, UsCompra: Double;begin { Buscar página com a cotação do dolar } HTML := IdHTTP_PegaDolar.Get(EdURL.Text); DevolveUS(HTML, Dia, UsVenda, UsCompra); Memo_Dolar.Lines.Add(‘Cotação do Dólar’); Memo_Dolar.Lines.Add(Format(‘Dia: %s,Venda: %g, Compra: %g’, [Dia, UsVenda,UsCompra]));end;
Listagem 4 – Código responsável em buscar a cotação do dólar
O código utilizado no evento OnClick do botão ‘sbtnDolar’ é
bastante simples. Primeiro, chamamos o método GET do
componente TIdHTTP e atribuímos o resultado para a variável
string HTML. Depois, executamos a procedure DevolveUS
passando o “HTML” e as variáveis que irão receber/retornar a
data e a cotação de venda e compra do dólar, as quais serão
apresentada no componente TMemo.
Validando a URLNosso código poderia parar por aqui, contudo, antes de
tentarmos obter a cotação do dólar seria interessante verificar se
o endereço (URL) está ‘respondendo’, ou seja, se a referida URL
está ‘no ar’ e dessa forma evitar uma mensagem de erro
desagradável ao usuário. Uma forma para efetuar este tipo de
verificação é disparar um ‘PING’ contra o endereço desejado e
analisar a resposta. Para isso, vamos lançar mão do componente
TIdIcmpClient, também pertecente a suíte de componente Indy, o
qual serve exatamente para este fim. Mãos a massa, adicione um
componente TIdIcmpClient e vamos nomeá-lo como ‘ICMP’.
Continuando nossa implementação, declare uma variável
chamada aBytesReceived do tipo integer na sessão private
(abaixo o type TForm1). Vamos agora criar um método para
‘disparar’ o ping e verificar se o endereço está respondendo, veja a
listagem 5.
procedure TForm1.PingBCB;var i: integer;begin aBytesReceived := 0; ICMP.ReceiveTimeout := 1000; ICMP.Host := ‘www.bcb.gov.br’;
{ Vamos disparar 4 pings } try for i := 1 to 4 do begin ICMP.Ping; Application.ProcessMessages; end; except {exceção silenciosa. Trataremos o valor davariável aBytesReceived.} end;end;
Listagem 5 – método para executar o ping.
· Lembre-se de declarar o método PingBCB abaixo do type
TForm1. Para isso, poderá utilizar o atalho Shift+Ctrl+C.
Vamos agora codificar o evento OnReply do componente
TIdIcmpClient. É através deste evento que iremos analisar o
retorno da execução do Ping, onde iremos verificar a quantidade
de bytes recebidos acumulando na variável aBytesReceived, confira
a listagem 6.
procedure TForm1.ICMPReply(ASender:TComponent; const AReplyStatus: TReplyStatus);begin { Totaliza bytes recebidos na execução doping } aBytesReceived := aBytesReceived +AReplyStatus.BytesReceived;end;
Listagem 6 – Evento OnReply.
E para finalizar, vamos efetuar uma pequena
implementação no evento OnClick do botão ‘sbtnDolar’,
acompanha na listagem 7.
procedure TForm1.sbtnDolarClick(Sender:TObject);var HTML, Dia: String; UsVenda, UsCompra: Double;begin { Testa a URL executando ping } PingBCB; { Verifica número de bytes recebidos } if aBytesReceived = 0 then
Delphi
MeGAZINE8
raise Exception.Create(‘URL indisponívelno momento! Verifique sua conexão deinternet.’); { Buscar página com a cotação do dolar } HTML := IdHTTP_PegaDolar.Get(EdURL.Text); DevolveUS(HTML, Dia, UsVenda, UsCompra); Memo_Dolar.Lines.Add(‘Cotação do Dólar’); Memo_Dolar.Lines.Add(Format(‘Dia: %s,Venda: %g, Compra: %g’, [Dia, UsVenda,UsCompra]));end;
Listagem 7 – Evento OnClick do sbtnDolar com implementação
do ping.
A alteração é bem simples. Primeiramente, vamos executar o
método ‘PingBCB’ o qual irá disparar 4 pings contra a URL do
Banco Central do Brasil. Depois, testamos o valor da variável
aBytesReceived e caso o resultado seja igual a zero, indica que a
URL não está respondendo e dessa forma levantaremos uma
exceção informando ao usuário para verificar a conexão internet
ou, caso o retorno seja maior que zero, continuaremos o
processamento e apresentaremos a cotação do dólar ao usuário.
ConclusãoApresentamos aqui uma abordagem demonstrando a
utilização dos componentes TIdHTTP e TIdIcmpClient da suite
Indy, a qual possui muitos componentes interessantes para
diversas situações do dia-a-dia. Como mencionamos no início
deste artigo, o ideal seria obter este tipo de informação através de
um webservice, contudo, na falta deste, a abordagem aqui sugerida
funciona bem, lembrando que o único cuidado à ser tomando
seria em relação a possíveis mudanças na página HTML
utilizada para obtenção das informações, apesar ainda, de ser
possível criar parâmetros na aplicação a fim de deixar
‘customizável’ o endereço (URL) e posicionamento dos campos na
mesma.
Abraços à todos e até a próxima...
Download disponível em:
http://www.theclub.com.br/revista/download/indydolar.zip.
Sobre o autorAlessandro Ferreira,
Consultor Técnico do The Club
Delphi
MeGAZINE 9
No segundo artigo da série, foram abordados os conceitos
gerais acerca da implementação do Sintegra, estruturação básica
do sistema gerencial e o fluxograma de procedimentos a serem
seguidos para a geração do 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 Sintegra a partir de informações contidas
em um banco de dados Interbase.
Continuando a nossa série de artigos sobre o
Sintegra, iremos agora abordar o processo de
validação, visualização e transmissão do arquivo
gerado, utilizando as ferramentas oficiais disponíveis
relacionadas ao tema. Serão abordados o ProgramaValidador, Programa Visualizador de Arquivos do
Sintegra, Programa Visualizador de Notas Fiscais de
Arquivos do Sintegra e o Programa para
Transferência Eletrônica de Documentos (TED) sob a
ótica de aplicação do desenvolvedor.
O Programa ValidadorUma vez gerado o arquivo de saída, estamos
prontos para verificar no Programa Validador a
consistência do arquivo gerado. Vamos agora
conhecer um pouco mais sobre o Programa Validador,
mostrado na Figura 04, que verifica a consistência dos
dados informados pelos contribuintes e prepara os arquivos para
entrega às repartições fazendárias estaduais, com uso de
algoritmos de integridade e criptografia. O programa evita o
fornecimento de dados incorretos, como Inscrições Estaduais e
CNPJ inválidos, registros inexistentes, inconsistência entre os
registros informados, etc.
Após a validação, o programa permite gerar um arquivo de
mídia para ser enviado às repartições fiscais. Criado o arquivo de
mídia, pode-se emitir um recibo, contendo dados informativos
sobre a validação.
Se o arquivo for transmitido pela Internet, através do
SIntegraSIntegraSIntegraSIntegraSIntegraAbordagem Completa - Ferramentas RelacionadasAbordagem Completa - Ferramentas RelacionadasAbordagem Completa - Ferramentas RelacionadasAbordagem Completa - Ferramentas RelacionadasAbordagem Completa - Ferramentas Relacionadas
Parte 3Parte 3Parte 3Parte 3Parte 3
por Victory Fernandes
programa de Transmissão Eletrônica de Documentos (TED), é emitido
também um recibo comprovando a transmissão do documento ao
órgão competente. Este recibo garante que o arquivo passou pela
validação prévia e foi encaminhado corretamente.
Figura 04: Programa oficial do Fisco para validação de arquivos
do Sintegra
Validando um arquivo .txt1- Ative a página Validar2- Selecione o arquivo do documento.
3- Clique no botão Abrir.
4- Clique no botão Validar.
Se a validação não for cancelada pelo usuário, a página
Resumo ficará ativa, onde poderão ser analisados os resultados da
Delphi
MeGAZINE10
validação e a quantidade de registros aceitos e/ou rejeitados.
Após a validação, a página Criticas lista todos os erros e/ou
advertências encontrados durante o processamento.
Teoricamente, se o seu programa foi bem implementado, o
nível de falhas apresentados na validação será mínimo, mas
ainda assim existem erros de operação por parte do usuário no
momento da entrada de dados que podem gerar problemas na
validação. Neste momento o usuário deve ser capaz de identificar
as falhas apresentadas, voltando ao programa gerencial, para
realizar as alterações nos dados que apresentarem problemas e
gerar o arquivo .txt novamente.
Acontece que nem sempre seu usuário será capaz de
interpretar as informações de erro e associá-las com o tipo de
alteração que deve ser feita em seu programa gerencial. Nestes
casos, a experiência mostra que a melhor solução é pedir que o
usuário envie por e-mail o arquivo .txt gerado com erro e o relatório
de críticas do Validador, para que você interprete o mesmo e sugira
as devidas correções no banco de dados. Este serviço de
consultoria na geração do arquivo do Sintegra é, na maioria dos
casos, indispensável ao usuário inexperiente e é mais um serviço
que pode ser oferecido pela software house e acrescido ao valor de
manutenção do software.
Para exportar o Relatório de Críticas para um arquivo texto,
clique no botão Exportar na tela de críticas. O arquivo do Relatório deCríticas exportado é do tipo texto ASCII e contém campos de
tamanho fixo conforme o seguinte formato, sendo a primeira
linha a identificação do Contribuinte e
Declaração: (ver tabela acima).
Além do arquivo de Relatório de
Críticas, constituem também ferramentas
poderosas para a análise das informações
dos clientes, o programa Visualizador de
Arquivos Texto e o programa Visualizador
de Notas Fiscais.
O Programa Visualizador deArquivos do Sintegra
É uma ferramenta para leitura de
arquivos no padrão do Sintegra com o
objetivo esclarecer dúvidas quanto ao
conteúdo dos mesmos, através da
visualização campo a campo dos registros
contidos no arquivo.
Quando a opção de navegação campo a
campo está ativa, ao selecionar um campo
como mostrado na Figura 05, são mostradas
na barra inferior as informações
referentes de Número da linha, Número
da coluna, Tipo de Registro, Posição do campo na linha
(intervalo) e Descrição do campo.
Descrição Tamanho PosiçãoInicial
PosiçãoFinal
Nº Seqüencial do Erro 010 01 10
Linha do Erro 010 11 20
Tipo do Registro 002 21 22
Nome do Campo 025 23 47
Documento Item 015 48 62
Conteúdo do Campo 025 63 87
Mensagem de Erro 100 88 187
Tipo do Erro 011 188 198
Esta ferramenta é super importante quando nós
desenvolvedores estamos testando nossas implementações ou
desejamos obter informações mais detalhadas sobre um
determinado campo do arquivo gerado. Em arquivos muito
grandes, fica praticamente impossível se verificar visualmente,
por exemplo, se um determinado campo foi colocado na posição
correta durante a construção do arquivo. Neste momento a
ferramenta entra em ação, permitindo o cruzamento imediato
entre as informações passadas pelo programa e o respectivo valor
encontrado no campo.
Figura 05: Programa oficial do Fisco para visualização de
arquivos do Sintegra.
Delphi
MeGAZINE 11
O Programa Visualizador de Notas Fiscais deArquivos do Sintegra
Constitui, a partir dos registros 50, 51, 53, 54 e 75, o espelho
completo das notas fiscais de entrada e saída, permitindo ao
usuário, a conferência e análise do arquivo magnético
selecionado.
Com ele é possível navegar de forma rápida e intuitiva nas
notas fiscais contidas em um determinado arquivo, visualizando
todos os parâmetros das notas individualmente e com a
possibilidade de filtrar as notas para visualização apenas das
notas de saída ou entrada.
Ao contrário do programa Visualizador de Arquivos do
Sintegra descrito anteriormente, o programa Visualizador de
Notas Fiscais de Arquivos do Sintegra é muito mais aplicável aos
usuários finais, que desejam fazer a leitura do arquivo magnético
gerado sob uma ótica de mais alto nível, na maioria das vezes,
para ver se as notas fiscais lançadas no sistema gerencial para
um determinado mês correspondem às notas fiscais listadas no
arquivo final.
Figura 06: Programa
oficial do Fisco para
visualização de Notas
Fiscais em arquivos do
Sintegra
Caso contrário, houve erro no lançamento do documento
fiscal em questão ou erro na implementação da seleção dos dados
no sistema gerencial utilizado.
O Programa para Transferência Eletrônica deDocumentos (TED)
Uma vez validado o arquivo magnético .txt e gerado o arquivo
de mídia no formato .zip, o programa validador pergunta de você
deseja enviar as informações e em caso positivo chama o TED,
para que seja efetuada a transmissão dos documentos pela
Internet.
O TED é um programa muito simples, e devemos apenas
instruir nossos clientes a operá-lo, uma vez que a transmissão
dos arquivos para o Fisco é de responsabilidade do informante.
Para efetuar o envio basta selecionar o arquivo de mídia
gerado pelo validador, testar a conexão com a secretaria do estado
respectivo através da página Testar, e por fim enviar o arquivo
clicando no botão Enviar.
Após o envio, aconselha-se que o cliente guarde em local
Delphi
MeGAZINE12
Figura 07: Programa oficial do Fisco para Transferência
Sobre o autorVictory Fernandes é Mestrando em Redes de Computadores
e desenvolvedor sócio da TKS Software - Soluções de
Automação Softwares Dedicados.
Pode ser contactado em [email protected], ou através
dos sites www.victory.hpg.com.br – www.igara.com.br
seguro o comprovante de validação e envio do arquivo, bem como
o arquivo magnético .txt e a mídia .zip geradas, para caso seja
solicitado durante fiscalização ou em caso de eventual
necessidade de reenvio.
ConclusãoCom esta série de artigos, espero ter esclarecido critérios e
questionamentos básicos sobre a sistemática do Sintegra, sua
implementação e utilização das ferramentas relacionadas, bem
como ter trazido ao seu conhecimento a SIntegra32Dll.dll, uma
solução única no mercado, capaz de simplificar, e muito, o
trabalho de implementação ou adaptação do seu software ao
Sintegra.
Delphi
MeGAZINE 13
Neste artigo eu vou mostrar como você pode acessar o Active
Directory através do ADO. O Active Directory é instalado a partir
do Windows 2000. Ele armazena informações sobre todos os
recursos em uma rede, como usuários, grupos, computadores,
arquivos, impressoras e aplicativos.
O Active Directory armazena informações sobre recursos em
uma estrutura hierárquica. Ele contém objetos que representam
os diferentes tipos de recursos da rede: usuários, impressoras,
etc. Cada objeto tem atributos, como o nome, o sobrenome e o
endereço eletrônico de um usuário, a localização de uma
impressora. Os objetos são mantidos em um domínio. Um
domínio é a unidade básica de organização e segurança no Active
Directory.
Bem, agora vamos criar a nossa aplicação. Chame o seu
Delphi e crie um novo projeto. Adicione um Data Module a este
projeto.
Vá até a palheta de componentes na aba ADO e arraste um
componente ADOConnection e um componente ADOQuery para
o Data Module. Clique no componente ADOConnection
e altere a propriedade LoginPrompt para False e
configure a propriedade Provider para ADsDSOObject,
como mostrado na figura 1.
Agora dê um duplo clique sobre o componente
ADOConnection para que possamos montar a string de
conexão. Agora clique no botão Build..., veja figura 2.
Acessando oAcessando oAcessando oAcessando oAcessando o
Active Directory via ADOActive Directory via ADOActive Directory via ADOActive Directory via ADOActive Directory via ADO
Por Claudinei Rodrigues
Figura 1:
Propriedades do
componente
ADOConnection
Figura 2: Montagem da string de conexão
Após clicar no botão Build... você terá acesso a
próxima tela. Na aba Provider selecione o item OLE DB
Provider for Microsoft Directory Services e depois clique
no botão Next >>
(ver figura 3)
Sobre o autorClaudinei Rodrigues,
Consultor Técnico do The Club
Delphi
MeGAZINE14
Na próxima tela (figura 4) selecione o radiobutton Use
Windows NT Integrated Security.
Não há necessidade de alterar nenhuma informação das
abas Advanced e All, apenas clique no botão OK. Agora nós
vamos testar a conexão alterando a propriedade Connected para
True. Agora estando conectado ligue o componente ADOQuery ao
componente ADOConnection através da propriedade Connection.
A instrução SQL que você vai usar é muito similar às
instruções padrão. O código da listagem 1 mostra um exemplo de
instrução SQL que retorna as informações de um determinado
usuário cadastrado no ActiveDirectory.
procedure procedure procedure procedure procedure TDataModule2.GetUserInfo;var Query: stringstringstringstringstring;begin ADOQuery1.Sql.Clear; Query := ‘SELECT Name, distinguishedName, ‘+ ‘sAMAccountName, PrimaryGroupID ‘ + ‘FROM‘’LDAP://DC=teste2000server, DC=com, DC=br’’‘+‘WHERE sAMAccountName = ‘’antonio’’’; ADOQuery1.Sql.Add(Query); ADOQuery1.Open;end;
Listagem 1: Este trecho utiliza uma query LDAP para obter
informações de usuários do ActiveDirectory.
A interface ADSI fornece um caminho para determinar o seu
domínio de modo que um domínio especifico não seja requerido.
Cada diretório servidor tem uma entrada chamada RootDSE.
Através do RootDSE, você pode determinar o domínio que o
usuário atual está logado. Ele fornece um caminho fácil para
adicionar flexibilidade ao seu programa. Para usar o RootDSE,
você precisa importar a biblioteca ADSI
Para isto vá até o menu do Delphi e clique em Project |
Import Type Library.
Figura 5: Opção do menu do Delphi
Selecione o item Active DS Type Library como mostrado na figura
6 e clique no botão Create Unit. Uma unit ActiveDs_TLB.pas
será criada e adicionada ao seu projeto. Adicione esta unit a
cláusula uses da unit1. (ver figura 6)
Existem duas funções que nós precisamos criar para poder
receber o RootDSE. São elas, GetObject e GetDefaultPath. Veja
as funções na listagem 2.
function function function function function GetObject(constconstconstconstconst Name: stringstringstringstringstring):IDispatch;var Moniker: IMoniker;
Figura 4:
Informações
para a conexão
Figura 3:
Selecionando o
Provider
Delphi
MeGAZINE 15
Eaten: integer; BindContext: IBindCtx; Dispatch: IDispatch;begin OleCheck(CreateBindCtx(0, BindContext)); OleCheck(MkParseDisplayName(BindContext,PWideChar(WideString(Name)),Eaten,Moniker)); OleCheck(Moniker.BindToObject(BindContext,nil, IDispatch, Dispatch)); Result := Dispatch;end;function function function function function GetDefaultPath: string;: string;: string;: string;: string;var RootDse : Iads;begin Result := ‘’; try rootDSE := GetObject(‘LDAP://rootDSE’) asIAds; Result := ‘LDAP://’+rootdse.Get
(‘defaultNamingContext’); rootdse := nil; except on E:Exception do begin Result := ‘LDAP://DC=activenet,
DC=com,DC=br’; ififififif not InputQuery]
(‘Dominio não encontrado.’, ‘Por favor, informe o dominio
correto.’,
Result) thenthenthenthenthen RaiseRaiseRaiseRaiseRaise Exception.Create(E.Message); end; end;end;
Listagem 2: Funções usadas para pegar o path do dominio
corrente
Usando o caminho do seu domínio como o nome da tabela em
suas querys, você pode construir instruções SQL para pesquisar
um usuário ou grupo especifico. Veja a seguir na listagem 3
alguns exemplos de pesquisa.
// Retorna informações de um usuárioespecificoQuery := ‘SELECT Name,distinguishedName,sAMAccountName, ‘ + ‘PrimaryGroupID,MemberOfFROM ‘’’+GetDefaultPath + ‘’’ WHEREsAMAccountName = ‘’’ + FUsername + ‘’’’;// Retorna a lista de Organizational Units.Query := ‘SELECT name FROM ‘’’ +GetdefaultPath + ‘’’ WHERE objectclass=’’organizationalunit’’’;// Retorna uma lista de usuários.Query := ‘SELECT distinguishedName FROM‘’’+GetDefaultPath + ‘’’ WHERE objectclass=’’user’’’;// Se você configurar Groupnname =’Domain Users’ você recebe um VarArray// dos membros daquele grupo.Query := ‘SELECT member FROM‘’’+GetDafaultPath+‘’’ WHERE sAMAccountName=‘’’+GroupName+’’’’;// Recebe a lista de computadores.Query := ‘SELECT distinguishedName FROM‘’’+GetDefaultPath+ ‘’’ WHERE objectclass=’’computer’’’;
Listagem 3: Alguns exemplos de pesquisa
ConclusãoAcessar o Active Directory através do ADO é o caminho mais
fácil para obter as informações de usuário que você precisa. Você
pode obter maiores informações sobre o ActiveDirectory no
próprio site da Microsoft no link http://www.microsoft.com/
windows2000/techinfo/howitworks/activedirectory/adsilinks.asp.
Até a próxima edição e um forte abraço a todos.
http://www.theclub.com.br/revista/download/AD_ADO.ZIP
Figura 6:
Importando
a biblioteca.
Delphi
MeGAZINE16
IntroduçãoMontando projetos para web algumas vezes nos deparamos
com a necessidade de apresentar uma lista de imagens ao
usuário e para facilitar a visualização essas imagens devem ser
apresentadas em miniatura, mas também devem permitir ao
usuário clicar sobre a imagem para visualizá-la em seu tamanho
real.
Sendo assim o propósito dessa matéria é exatamente esse,
montar um projeto em Delphi8 Web Application para a
visualização de imagens em tamanho reduzido.
Configurando o DataListVamos criar nosso projeto no Delphi8 do tipo ASP .NET Web
Application e como primeiro passo vamos montar uma grade
para visualização das imagens pelo usuário.
Esse processo é bastante simples sendo que para essa
visualização usaremos um componente do tipo DataList.
Portanto coloque na janela um componente DataList e neste
componente iremos configurar as propriedades para definir a
apresentação da grade, são elas:
CellSpacing = 5RepeatColumns = 6RepeatDirection = Vertical
O componente DataList é uma componente de grade que
utiliza outros componentes para apresentar valores ao usuário.
Ao incluir um componente dentro desse DataList, como por
exemplo um Label, esse Label será apresentado sequencialmente
seguindo a estrutura de linha e coluna da grade do DataList.
Neste momento iremos incluir os componentes dentro do
DataList e para isso iremos visualizar a codificação ASPX do
projeto para incluir no DataList um itemtemplate, pois é dentro
desse itemtemplate que iremos incluir os componentes utilizados
para a visualização dos valores na grade.
Portanto clique na aba WebForm1.aspx e procure a
codificação do DataList, conforme o exemplo abaixo:
<asp:datalist id=DataList1 runat=”server”></asp:datalist>
Dentro dessa instrução iremos incluir a codificação que
define o itemtemplate e dentro desse itemtemplate iremos incluir
os componentes para visualização dos dados que serão, um Label
utilizado para apresentar o nome do arquivo, e um ImageButton
utilizado para apresentar a imagem com a possibilidade de clicar
sobre essa imagem.
Abaixo poderemos observar a instrução do itemtemplate
contendo o Label e o ImageButton:
<itemtemplate><asp:label id=lbArquivo runat=”server”>
LbArquivo</asp:label><p><asp:imagebutton id=ImageButton1
runat=”server”></asp:imagebutton></p>
</itemtemplate>
Após incluir essa codificação a instrução do DataList ficará
da seguinte forma:
<asp:datalist id=DataList1 runat=”server”repeatcolumns=”6">
Delphi 8Delphi 8Delphi 8Delphi 8Delphi 8Visualizando imagens na Web (Thumbnail )Visualizando imagens na Web (Thumbnail )Visualizando imagens na Web (Thumbnail )Visualizando imagens na Web (Thumbnail )Visualizando imagens na Web (Thumbnail )
por André Colavite
Sobre o autorAndré Colavite
Consultor Técnico do The Club
Delphi
MeGAZINE 17
<itemtemplate><asp:label id=lbArquivo
runat=”server”>LbArquivo</asp:label><p><asp:imagebutton id=ImageButton1
runat=”server”></asp:imagebutton></p>
</itemtemplate></asp:datalist>
Voltando a visualização do Design podemos observar que o
DataList irá apresentar os dois componentes, conforme figura 1:
Figura1: Visualizando o DataList
Lendo os arquivos do diretórioNeste momento iremos criar a instrução para ler os arquivos
de imagens que estão num subdiretório IMAGENS do projeto,
sendo que para isso iremos utilizar a seguinte instrução no
evento Page_Load.
procedure TWebForm1.Page_Load(sender:System.Object; e: System.EventArgs);var dirInfo: System.IO.DirectoryInfo;begin if (not IsPostBack) then begin { lê o subdiretório imagens do projeto } dirInfo := System.IO.DirectoryInfo.Create
(Server.MapPath(‘.\imagens’)); { Retorna informações dos
arquivos com extensão JPG } DataList1.DataSource := dirInfo.
GetFiles(‘*.jpg’); { atualiza a visualização do DataList } DataList1.DataBind(); end;end;
Podemos observar que atribuímos diretamente para o
DataList a lista de arquivos que visualizamos.
Observação: Devemos declarar a unit System.IO na lista de
uses.
A nossa visualização está quase pronta, na verdade agora
somente devemos configurar no DataList qual o tipo de
informação que iremos apresentar ao usuário, pois essa classe
System.IO.DirectoryInfo utilizada nos permite visualizar
diversas informações, como por exemplo:
Name - apresenta somente o nome do arquivo
FullName - apresenta o caminho e o nome do arquivo
Extension - apresenta somente a extensão do arquivo
Conforme já indicado iremos apresentar no DataList o nome
do arquivo e visualizar a imagem, portanto iremos trabalhar com
a propriedade Name e FullName.
Sendo assim visualize novamente a codificação
WebForm1.aspx e inclua no label a seguinte codificação:
<%# DataBinder.Eval(Container.DataItem, “Name”) %>
Ficando a instrução do Label da seguinte forma:
<asp:label id=lbArquivo runat=”server”><%# DataBinder.Eval(Container.
DataItem, “Name”) %></asp:label>
Agora iremos incluir no componente ImageButton a
codificação que irá atribuir às propriedades imageurl e
commandname o caminho com o nome do arquivo a ser
apresentado ao usuário no DataList. Sendo assim atribua ao
ImageButton a seguinte instrução:
‘<%# DataBinder.Eval(Container.DataItem, “FullName”) %>’
Segue abaixo como ficou a codificação do ImageButton:
<asp:imagebutton id=ImageButton1runat=”server” imageurl=’<%# DataBinder.Eval(Container.DataItem,
“FullName”) %>’ commandname=’<%# DataBinder.Eval
(Container.DataItem, “FullName”) %>’></asp:imagebutton>
A propriedade imageurl é utilizada para ler o arquivo da
imagem a ser apresentada, já a propriedade commandname é
Delphi
MeGAZINE18
utilizada para definir um comando que será lido no evento
ItemCommand acessado quando o usuário clica sobre a imagem.
Esse evento será codificado mais a frente.
Após incluir os dois componentes e a instrução para ler os
valores a codificação do DataList ficará da seguinte forma:
<asp:datalist id=DataList1 runat=”server”repeatcolumns=”6"><itemtemplate><asp:label id=lbArquivo runat=”server”><%#DataBinder.Eval(Container.DataItem, “Name”)%></asp:label><p><asp:imagebutton id=ImageButton1runat=”server” imageurl=’<%#DataBinder.Eval(Container.DataItem,“FullName”) %>’ commandname=’<%#DataBinder.Eval(Container.DataItem,“FullName”) %>’>
</asp:imagebutton> </p>
</itemtemplate></asp:datalist>
Pronto, podemos voltar a visualização do Design.
Neste momento podemos compilar e executar o projeto ao
qual irá apresentar as imagens existentes no subdiretório
imagens do diretório do projeto.
Observação: Não se esqueça de criar esse subdiretório e
incluir algumas imagens para serem visualizadas.
Visualizando as imagens reduzidasNesta segunda parte do projeto iremos incluir as instruções
para visualizar as imagens num tamanho reduzido dentro do
DataList, permitindo assim que todas as imagens fiquem visíveis
com o mesmo tamanho.
Para montar esse visualização iremos utilizar o método
GetThumbnailImage do objeto System.Drawing.Image, ao qual
permitirá gerar um cópia da imagem no tamanho desejado.
Para fazer esse processo iremos ler a imagem no tamanho
real e atribuí-la ao DataList. Antes de apresentar a imagem ao
usuário o evento ItemDataBound do DataList é executado e neste
momento é gerado uma miniatura da imagem, apresentando
essa miniatura ao usuário. Veja abaixo como ficou a instrução
dentro do evento ItemDataBound do DataList:
procedureTWebForm1.DataList1_ItemDataBound(sender:System.Object; e: System.Web.UI.WebControls.DataListItemEventArgs);var Nome_Arq, Nome_Mini: String;begin { pesquisa o item colocado dentro doDatalist } if e.item.FindControl(‘ImageButton1’) <>Nil then begin{ lê a informação da propriedade imageurldo item do datalist } Nome_Arq :=ImageButton(e.item.FindControl (‘ImageButton1’)).ImageUrl; { gera a imagem em miniatura } Nome_Mini := Gerar_Miniatura( Nome_Arq ); { apresenta a imagem em miniatura no item
dentro do datalist } ImageButton(e.item.FindControl
(‘ImageButton1’)).ImageUrl :=Nome_Mini;
end;end;
Neste evento foi utilizado a function Gerar_Miniatura, sendo
que essa function irá ler a imagem no seu tamanho original
calcular uma porcentagem de diminuição para chegar ao
tamanho miniatura. Essa porcentagem é necessária para poder
diminuir o tamanho da imagem por igual tanto na sua altura
como no seu comprimento evitando assim deformar a imagem.
Veja abaixo a function contendo algumas explicações das
linhas utilizadas:
function TWebForm1.Gerar_Miniatura(NomeArqOrigem: String): String;
var Img, Img2: System.Drawing.Image; myCallback:System.Drawing.Image.GetThumbnailImageAbort; nTamImg, nP, nT : Integer;begin nTamImg := 100; {tamanho das mini-imagens } try Img := System.Drawing.Image.FromFile
( NomeArqOrigem ); try { verifica se a imagem apresentada jánão é menor que o tamanho pré-definido } if (Img.Width > nTamImg) or (Img.Height
Delphi
MeGAZINE 19
> nTamImg) then begin myCallback := System.Drawing.Image.
GetThumbnailImageAbort(ThumbnailCallback);
{ calcula a porcentagem de diminuiçãoda imagem. Essa porcentagem é utilizada paradefinir o novo tamanho da imagem na altura eno comprimento } if (Img.Width > Img.Height) and(Img.Width > nTamImg) then begin nP := Round((nTamImg*100)/
img.Width); nT := Round((img.Height*nP)/100); {gera uma nova imagem em miniatura } img2 := img.GetThumbnailImage
(nTamImg, nT, myCallback ,System.IntPtr.Zero);
end else if img.Height > nTamImg then begin nP := Round((nTamImg*100)/
img.Height); nT := Round((img.Width*nP)/100); {gera uma nova imagem em miniatura } img2 := img.GetThumbnailImage(nT,
nTamImg, myCallback ,System.IntPtr.Zero);
end; try {cria a string contendo a path e o nomeda imagem no sub-diretório imagens_mini } Result := GetTempPath +‘imagens_mini\’ + PrepareFileName(Path.GetFileName(NomeArqOrigem) ); { salva a imagem em miniatura nosubdiretorio } img2.Save( Result , ImageFormat.
Jpeg); finally img2.Free; end; end else { imagem já é miniatura, portantovisualiza ela mesma } Result := NomeArqOrigem; finally img.Free;
end; except end;end;
Dentro dessa function utilizamos três functions, são elas:
Function ThumbnailCallback, sendo uma function de
controle obrigatório no uso do método GetThumbnailImage.
function ThumbnailCallback: boolean;begin Result := false;end;
Function GetTempPath, utilizada para retornar o caminho
físico do servidor onde o projeto está.
function TWebForm1.GetTempPath: string;begin Result := Page.Request.
PhysicalApplicationPath;end;
Function PrepareFileName, utilizada para preparar o nome
do arquivo a ser gerado em miniatura.
function TWebForm1.PrepareFileName(aName: string): string;
begin Result := aName.Replace(‘ ‘, ‘’) + ‘.jpg’;end;
Observação: Devemos declarar a unit
System.Drawing.Imaging na lista de uses e declarar também as
functions criadas na seção private, veja exemplo abaixo:
private function Gerar_Miniatura
(NomeArqOrigem: String): String; function GetTempPath: string; function PrepareFileName
(aName: string): string; public
Para concluir o nosso projeto iremos criar o evento
ItemCommand do componente DataList, pois através desse
evento iremos controlar quando o usuário clicar sobre a
miniatura da imagem ao qual irá apresentar uma nova janela
mostrando a imagem em seu tamanho original.
Delphi
MeGAZINE20
Segue a instrução do evento ItemCommand do DataList:
procedure TWebForm1.DataList1_ItemCommand(source: System.Object; e:System.Web.UI.WebControls.DataListCommandEventArgs);var Img: System.Drawing.Image; nW, nH: integer;begin { verifica o tamanho da imagem paracontrolar o tamanho da janela } nW := 200; nH := 200; try Img := System.Drawing.Image.
FromFile(e.CommandName); if Img.Width > nW then nW := Img.Width+20; if Img.Height > nH then nH := Img.Height+20; Img.Free; except end; { Executa uma instrução Java Script paraabrir uma nova janela contendo a página webform2.aspx} Response.Write(‘<scriptlanguage=”javascript”>window.open(“webform2.aspx?arq=’+ Path.GetFileName(e.CommandName)+ ‘“,”_blank”,[“toolbar=no,width=
’+nW.ToString+’,height=’+nH.ToString+’”] ) </script>’);
end;
Crie essa nova página webform2.aspx no projeto e dentro dela
coloque um componente Image ao qual irá apresentar a imagem
em seu tamanho original.
No evento Page_Load dessa nova página coloque a instrução
que irá atribuir o arquivo original para o componente Image, veja
a instrução do evento PageLoad.
procedure TWebForm2.Page_Load(sender:System.Object; e: System.EventArgs);begin Image1.ImageUrl :=Page.Request.PhysicalApplicationPath+’imagens\’+Request.Params[‘arq’].ToString;end;
Observação: Devemos criar um subdiretório do projeto
chamado Imagens, contendo algumas imagens, e criar também
um subdiretório chamado imagens_mini.
Neste momento nosso pequeno projeto está pronto, podemos
executá-lo normalmente ao qual irá apresentar as imagens em
miniatura, conforme figura 2 e clicando sobre a imagem
poderemos vê-las em seu tamanho original, conforme figura 3.
Figura2: Apresentando imagem em miniatura
ConclusãoConforme podemos observar nesta matéria, utilizando o
Framework é bastante simples mostrar uma grade de imagens
em miniatura no browse, com isso poderemos montar projetos
com visualização de imagens no Delphi 8 com bastante
facilidade.
Um abraço a todos e até a próxima.
Download: http://www.theclub.com.br/revista/download/
Visual_Imagem_D8.zip
Figura3: Apresentando imagem no tamanho original
Delphi
MeGAZINE 21
Ajustes no Firewall doAjustes no Firewall doAjustes no Firewall doAjustes no Firewall doAjustes no Firewall doWindows XP Service Pack 2Windows XP Service Pack 2Windows XP Service Pack 2Windows XP Service Pack 2Windows XP Service Pack 2
para rodar o Interbase/Firebirdpara rodar o Interbase/Firebirdpara rodar o Interbase/Firebirdpara rodar o Interbase/Firebirdpara rodar o Interbase/FirebirdPor Paulo Emílio R. Del Cistia, [email protected]
IntroduçãoRecentemente a Microsoft disponibilizou um pacote de
atualização para o Windows XP no qual entre várias novidades,
foi disponibilizado um Firewall a fim de deixar o ambiente mais
seguro. Isso é muito bom, contudo, temos recebido consultas de
vários associados mencionando que após a atualização, o
Interbase/Firebird não consegue fazer acesso ao servidor e coisas
deste tipo. Isso ocorre devido ao fato de uma das finalidades dos
firewalls é fechar portas de comunicação nos micros, e o
Interbase/Firebird necessita da porta 3050 aberta para que possa
se comunicar (cliente/servidor). A seguir iremos demonstrar
passo a passo como configurar o Firewall no Windows XP Service
Pack 2 para permitir que o Interbase/Firebird possa comunicar-
se sem problemas.
Configurando o Firewall
1 – Entrar no painel de controle e selecionar a opção “Firewall
do Windows”
2 – Caso esteja ativado a opção “Não permitir exceções”
desmarque-a.
Windows
MeGAZINE22
3 – Clique na aba “Exceções”, e depois em “Adicionar Porta”
4 – Digite um nome para a porta como no exemplo abaixo
“Firebird TCP”, selecione a opção “TCP” e digite o número da
porta “3050”, que é a porta usada pelo Firebird.
5 - Clique em alterar escopo e depois selecione a opção que
mais lhe convenha, no nosso caso é a opção “Minha rede (sub-
rede) Somente” e depois em “OK”
6 - Digite um nome para a porta como no exemplo abaixo
“Firebird UDP”, selecione a opção “UDP” e digite o número da
porta “3050”, que é a porta usada pelo Firebird.
7 - Clicar em alterar escopo e depois selecione a opção que
mais lhe convenha, no nosso caso é a opção “Minha rede (sub-
rede) Somente” e depois em “OK”
Windows
MeGAZINE 23
8 – Veja abaixo como ficou após adicionar as duas portas no
Firewall
ConclusãoVimos aqui como configurar o Firewall do Windows XP
Service Pack 2 a fim de liberar a porta 3050 para permitir ao
Interbase/Firebird comunicar-se pela rede.
Esta dica, apesar de termos mencionado o banco Interbase/
Firebird, pode ser utilizada para liberar portas para outras
aplicações ou bancos de dados que necessitem se comunicar desta
forma, visto que o Firewall por padrão, irá fechar todas as portas,
exceto as portas nativas de comunicação, como exemplo, http, ftp,
etc.
Abraço à todos e até a próxima.
Download do Service Pack 2 para o Windows XP
Português: http://download.microsoft.com/download/0/5/f/
05fcbd3f-fb50-43be-a995-ad12ee4dcbe5/WindowsXP-KB835935-
SP2-PTB.exe
Inglês: http://download.microsoft.com/download/1/6/5/165b076b-aaa9-443d-84f0-73cf11fdcdf8/WindowsXP-KB835935-SP2-ENU.exe
9 – Pronto, agora é só clicar em “OK”.
Sobre o autorPaulo Emilio,
Consultor Técnico do The Club
Estamos chegando ao final de mais um ano. Esperamos quenossos serviços tenham atendido as expectativas de todosvocês, e que o trabalho de todos tenha sido produtivo.
Agora neste final de ano, vamos aproveitar dois feriadospara darmos férias para nossos consultores.
Portanto o suporte técnico não atenderá no período de 20/12/2004 à 02/01/2005, voltando as suas atividades normais apartir de 03/01/2005.
A T E N Ç Ã OA T E N Ç Ã OA T E N Ç Ã OA T E N Ç Ã OA T E N Ç Ã O
Windows
MeGAZINE24
Segundo o Standish Group (STANDISH, 1995), através de um
estudo chamado “Chaos Report”, para projetos na área de Tecnologia
da informação, obteve as seguintes conclusões:
* 16,2% dos projetos terminam no prazo e no orçamento
previsto;
* 52,7% dos projetos são contestados.
* 31,1% são cancelados antes de sua colocação no mercado.
Quanto a custo e prazo foram levantados:
* Excedente de custo médio é de 189% do custo original
estimado.
* Excedente de prazo médio é de 222% no cronograma
original estimado.
Outros dados levantados:
* 94% dos projetos têm pelo menos um reinício;
* 9% dos projetos em empresas de grande porte entram em
operação dentro dos custos e prazos estimados inicialmente.
* Nos projetos de empresas de grande porte somente 42% dos
requisitos originalmente propostos estão presentes no final.
* Nos projetos de empresas de pequeno porte 74,2% dos
requisitos originalmente propostos estão presentes no final.
Num mundo cada vez mais de recursos financeiros escassos,
como é possível aceitar tal desperdício de tempo e dinheiro.
Números desse porte podem comprometer seriamente a faceta
competitiva de uma organização, bem como ocasionar até a sua
saída do mercado.
Gestão de ProjetosAs organizações executam trabalho.
O trabalho envolve serviços continuados e/ou projetos, embora
possa haver superposição entre os dois. Serviços continuados e
projetos possuem muitas características comuns; por exemplo,
ambos são:
· Executados por pessoas
· Restringidos por recursos limitados
· Planejados, executados e controlados
O que é Projeto?“Um projeto é um empreendimento temporário com o objetivo
de criar um produto ou serviço único.” (PMBOK, 2000)
Gerência de Projetos é a aplicação de conhecimentos,
habilidades, e técnicas para projetar atividades que visem atingir
ou exceder as necessidades e expectativas das partes envolvidas,
com relação ao projeto.
O ato de atingir ou exceder as necessidades e expectativas das
partes envolvidas, invariavelmente envolve o equilíbrio entre
demandas concorrentes:
· Escopo, prazo, custo e qualidade
· Diferentes necessidades e expectativas das partes
envolvidas
· Necessidades concretas e expectativas
Os processos de gerência de projetos podem ser organizados
em cinco grupos, cada um deles contendo um ou mais processos:
· Processos de encerramento – Formalizar a aceitação do
projeto ou fase e encerrá-lo de uma forma organizada.
· Processos de iniciação – reconhecer que um projeto ou fase
deve começar e se comprometer para executá-lo.
· Processos de planejamento – planejar e manter um
esquema de trabalho viável para se atingir aqueles objetivos de
negócios que determinaram a existência do projeto.
· Processos de execução – coordenar pessoas e outros recursos
para realizar o plano.
· Processos de controle – assegurar que os objetivos do projeto
estão sendo atingidos,através da monitoração e da avaliação do
seu progresso, tomando ações corretivas quando necessárias.
Aspectos relevantes na gestãoAspectos relevantes na gestãoAspectos relevantes na gestãoAspectos relevantes na gestãoAspectos relevantes na gestãode projetos de softwarede projetos de softwarede projetos de softwarede projetos de softwarede projetos de software
por Marcelo Nogueira
Gerência de IntegraçãoA Gerência da Integração do Projeto inclui os processos
requeridos para assegurar que os diversos elementos do projeto
estão adequadamente coordenados. Ela envolve fazer
compensações entre objetivos e alternativas eventualmente
concorrentes, a fim de atingir ou superar as necessidades e
expectativas.
Por exemplo, a gerência de integração do projeto começa
quando uma estimativa de custo é necessária para um plano de
contingência ou quando os riscos associados com várias
alternativas de recursos humanos precisam ser definidas.
Entretanto, para um projeto ser completado com sucesso, a
integração, da mesma forma, deve também ocorrer em diversas
outras áreas.
O trabalho do projeto deve ser integrado com as operações
continuadas da organização executora:
· O escopo do produto e o escopo do projeto devem ser
Delphi
MeGAZINE 25
integrados.
· Os subprodutos de diferentes especialidades funcionais (tais
como desenhos de projetos de engenharia civil, elétrica, e
mecânica) devem ser integrados.
Gerência de Escopo
A Gerência do Escopo do Projeto inclui os processos
requeridos para assegurar que o projeto inclua todo o trabalho
necessário, e tão somente o trabalho necessário, para
complementar de forma bem sucedida o projeto Iniciação.
No contexto de projeto, o termo escopo deve se referir a:
· Escopo do produto – aspectos e funções que devam ser
incluídos no produto ou serviço.
· Escopo do projeto – o trabalho que deve ser feito com a
finalidade de entregar um produto de acordo com os aspectos e as
funções especificados.
Gerência de TempoGerência do Tempo do Projeto inclui os processos necessários
para assegurar que o projeto será implementado no prazo
previsto.
Em alguns projetos, especialmente os menores, o
seqüenciamento das atividades, a estimativa da duração das
atividades e o desenvolvimento do cronograma estão tão unidos
que podem ser vistos como um único processo ( por exemplo,
podem ser realizados por um único indivíduo, durante um curto
intervalo de tempo ).
Esses processos são aqui apresentados como processos
distintos porque as ferramentas e técnicas são diferentes para
cada um.
Gerência de CustoA Gerência do Custo do Projeto inclui os processos necessários
para assegurar que o projeto será concluído dentro do orçamento
aprovado.
A gerência do custo do projeto consiste, fundamentalmente,
nos custos dos recursos necessários à implementação das
atividades do projeto. Entretanto, a gerência do custo do projeto
deve, também, considerar os efeitos das decisões do projeto no
custo de utilização do produto do projeto.
Por exemplo, limitar o número de revisões do projeto pode
reduzir os custos do projeto à custa de um aumento no custo de
operação do cliente. Esta visão mais ampla da gerência do custo
do projeto é, freqüentemente, chamada de custo do ciclo de vida
(life-cycle costing).
Gerência de QualidadeA Gerência da Qualidade do Projeto inclui os processos
requeridos para garantir que o projeto irá satisfazer as
necessidades para as quais ele foi empreendido. Isto inclui “todas
as atividades da função de gerência geral que determinam as
políticas de qualidade, objetivos e responsabilidades e para a
implementação destes, por meio de planejamento da qualidade,
controle da qualidade, garantia da qualidade e melhoria da
qualidade, dentro do sistema de qualidade”.
A gerência da qualidade do projeto deve ser direcionada tanto
para a gerência do projeto quanto para o produto do projeto. O
fracasso em se atingir os requisitos de qualidade em qualquer
das dimensões, pode trazer conseqüências negativas sérias para
uma ou até mesmo para todas as partes envolvidas do projeto.
Por exemplo:
· O atendimento aos requisitos dos clientes, através de
trabalho extra da equipe do projeto, pode produzir conseqüências
negativas na forma de aumento de rotatividade de empregados.
· O atendimento aos objetivos de cronograma do
projeto realizando-se as inspeções planejadas de qualidade
apressadamente, pode vir a gerar conseqüências negativas caso
algum erro não seja detectado.
Gerência de Recursos HumanosA Gerência dos Recursos Humanos do Projeto inclui os
processos requeridos para possibilitar o uso mais efetivo das
pessoas envolvidas com o projeto. Isto inclui todos os interessados
do projeto – patrocinadores, clientes, contribuintes individuais e
outros.
Existe um substancial corpo de literatura sobre como lidar
com pessoas no contexto produtivo e operacional. Alguns dos
FIGURA 1:
Ciclo de vida do desenvolvimento de software
Delphi
MeGAZINE26
principais tópicos incluem:
· Liderar, comunicar, negociar, Principais;
· Habilidades da Administração Geral;
· Delegar, motivar, treinar, monitorar e outros assuntos
relacionados ao trato com indivíduos;
· Formação da equipe, tratamento de conflitos, e outros
assuntos relacionados ao trato com grupos;
· Avaliação do desempenho, recrutamento, manutenção,
relações de trabalho, regulamentações de saúde e segurança e
outros assuntos relacionados à administração da função de
recursos humanos.
Gerência de ComunicaçõesA Gerência das Comunicações do Projeto inclui os processos
requeridos para garantir a geração apropriada e oportuna, a
coleta, a distribuição, o armazenamento e o controle básico das
informações do projeto.
Fornece ligações críticas entre pessoas, idéias e informações
que são necessárias para o sucesso. Todos os envolvidos no projeto
devem estar preparados para enviar e receber comunicações na
“linguagem” do projeto e devem entender como as comunicações,
que eles estão individualmente envolvidos, afetam o projeto como
um todo.
A comunicação é um contexto mais amplo e envolve um corpo
de conhecimento substancial que não é único para o contexto de
projeto. Por exemplo:
· Modelos emissor-receptor – ciclos de feedback, barreiras à
comunicação, etc.
· Escolha de meio de comunicação - quando comunicar por
escrito, quando comunicar de forma oral, quando escrever um
memorando informal, quando escrever um relatório formal, etc.
· Estilo de redação: voz ativa ou voz passiva, estrutura da
frase, escolha das
· palavras, etc.
· Técnicas de apresentação: linguagem corporal, desenho dos
visuais de suporte, etc.
· Técnicas de gerência de reuniões: preparação de agenda,
tratamento de conflitos, etc.
Gerência de RiscosA Gerência de Risco do Projeto inclui os processos envolvidos
na identificação, análise e resposta aos riscos do projeto. Isto
inclui a maximização dos resultados de eventos positivos e
minimização das conseqüências de eventos negativos.
Diferentes áreas de aplicação usam, freqüentemente,
diferentes nomes para os processos descritos aqui. Por exemplo:
· A identificação dos riscos e a quantificação dos riscos são
tratados às vezes como um processo único, e o processo
resultante é conhecido como análise de risco ou avaliação de
riscos;
· O desenvolvimento de respostas aos riscos é, algumas
vezes, chamado de planejamento de respostas ou redução de
riscos;
· O desenvolvimento de respostas aos riscos e o controle de
respostas aos riscos são, às vezes, tratados como um processo
único e o processo resultante pode ser chamado de gerência de
riscos.
Gerência de AquisiçõesA Gerência de Aquisições do Projeto inclui os processos
necessários à obtenção de bens e serviços externos à organização
executora. Para simplificação, os bens e serviços, seja um ou
vários, serão geralmente referidos como um “produto”. (PMBOK,
2000).
A Gerência de Aquisições do Projeto é discutida do ponto de
vista do comprador na relação comprador-fornecedor.
A relação comprador-fornecedor pode existir em muitos níveis
do projeto.
Dependendo da área de aplicação, o fornecedor pode ser
chamado de contratado, ou um vendedor. O fornecedor
tipicamente irá gerenciar o seu trabalho como um projeto. Nestes
casos:
· O comprador torna-se o cliente e é portanto um stakeholderchave para o fornecedor.
· A equipe de gerência de projetos do fornecedor deve se
preocupar com todos os processos de gerência de projetos, e não
somente com aqueles dessa área de conhecimento.
· Os termos e condições do contrato tornam-se uma entrada
chave para muitos dos processos do fornecedor.
O contrato pode conter exatamente a entrada (principais
subprodutos, marcos chaves, objetivos de custo) ou ele pode
limitar as opções da equipe do projeto (a aprovação do comprador
sobre as decisões de alocação de pessoal é freqüentemente exigida
em projetos de design).
ConclusãoAqui foi apresentado as áreas de conhecimento da gestão de
projetos sob a visão do PMBOK.
A não adoção desses processos no desenvolvimento de
software , aumentam as chances de fracasso e o ciclo de vida da
crise do software.
Sobre o autorMarcelo Nogueira é bacharel em Análise
de Sistemas, Mestre em Engenharia deProdução com ênfase em Gestão daInformação, Professor Universitário,Instrutor e Desenvolvedor Delphi desde1995. e-mail: [email protected]
Delphi
MeGAZINE 27
Perguntas & Respostas
Pergunta: Tenho na janela sobre o Label:
www.meusite.com.br. Como transformar este Label em
hiperlink?
Resposta: No evento OnClick do TLabel adicione a seguinte
instrução:
implementationuses UrlMon;{$R *.DFM}
procedure TForm1.Button1Click(Sender:TObject);begin HLinkNavigateString(Nil,’http://www.theclub.com.br’);end;
Dúvida enviada por Paulo Geloramo, Assis/SP.
Pergunta: Gostaria de saber como mapear uma unidade de
rede via Delphi.
Resposta: Para mapear uma unidade de rede via Delphi
poderá utilizar a API WNetAddConnection2:
var Username, Password: String; NetResource: TNetResource;begin Username := ‘servidor’; Password := ‘abc.456.123’;
with NetResource do begin NetResource.dwType := RESOURCETYPE_DISK; NetResource.lpLocalName := ‘Y:’; NetResource.lpRemoteName :=‘\\SERVIDOR\C$’; NetResource.lpProvider := nil; end; if WNetAddConnection2(NetResource,PChar(Password), PChar(Username), 0) <> 0then ShowMessage(SysErrorMessage(GetLastError));end;
Dúvida enviada por Care Plus Medicina Assistencial Ltda,
Barueri/SP.
Pergunta: Gostaria de saber como verificar e alterar a
configuração de horário de verão do Windows via programação
Delphi.
Resposta: Existe chave no registrador que possibilita
verificar/alteração esta configuração no Windows, veja o código a
seguir:
Primeiro, vamos criar a função para verificar a configuração:
Implementation
uses Registry;
{$R *.dfm}
MeGAZINE28
function GetDisableAutoDaylightTimeSet:Boolean;const cDisableAutoDaylightTimeSet =‘DisableAutoDaylightTimeSet’;var oRegistry : TRegistry;begin Result := False; oRegistry := TRegistry.Create(KEY_READ); try oRegistry.RootKey := HKEY_LOCAL_MACHINE; if oRegistry.OpenKeyReadOnly(‘SYSTEM\
CurrentControlSet\Control\TimeZoneInformation’) then
begin if oRegistry.ValueExists
(cDisableAutoDaylightTimeSet) then begin if (oRegistry.GetDataType
(cDisableAutoDaylightTimeSet) =rdInteger)then
begin Result := oRegistry.ReadBool
(cDisableAutoDaylightTimeSet); end; end; end; finally oRegistry.Free; end;end;
Para utilizar:
if not GetDisableAutoDaylightTimeSet thenbegin CheckBox1.Checked := True; Caption := ‘Ativado’;endelsebegin CheckBox1.Checked := False; Caption := ‘Desativado’;end;
Agora, vamos para a função que irá fazer a alteração na
configuração:
function SetDisableAutoDaylightTimeSet(OnOff:
Boolean): Boolean;const cDisableAutoDaylightTimeSet =‘DisableAutoDaylightTimeSet’;var oRegistry : TRegistry; b: Boolean; dwReturnValue: Cardinal;begin Result := False; oRegistry := TRegistry.Create; try oRegistry.RootKey := HKEY_LOCAL_MACHINE; if oRegistry.OpenKey(‘SYSTEM\
CurrentControlSet\Control\T imeZoneInformation’, False) then
begin { Caso a chave exista, apenas lê/altera o valor. } ifoRegistry.ValueExists(cDisableAutoDaylightTimeSet)then begin if(oRegistry.GetDataType(cDisableAutoDaylightTimeSet)= rdInteger) then begin b := oRegistry.ReadBool
(cDisableAutoDaylightTimeSet); oRegistry.WriteBool
(cDisableAutoDaylightTimeSet, not OnOff);
Result := (b <> oRegistry.ReadBool(cDisableAutoDaylightTimeSet));
end; end else { Caso a chave não exista, criar eatribui o valor } begin oRegistry.WriteBool
(cDisableAutoDaylightTimeSet,not OnOff);
Result := True; end; end; finally if Result then SendMessageTimeout(HWND_BROADCAST,WM_SETTINGCHANGE, 0,
Perguntas & Respostas
MeGAZINE 29
LParam(pchar(‘Environment’)),SMTO_ABORTIFHUNG, 5000, dwReturnValue); oRegistry.Free; end;end;
Para testar, utilize o evento OnClick doCheckBox:
procedure TForm1.CheckBox1Click(Sender:TObject);begin SetDisableAutoDaylightTimeSet(CheckBox1.Checked); if not GetDisableAutoDaylightTimeSet then Caption := ‘Ativado’ else Caption := ‘Desativado’;end;
O projeto de exemplo referente este dica está disponível para
download em: http://www.theclub.com.br/revista/download/
WindowsHorarioVerao.zip.
Dúvida enviada por Prófruta - Software e Consultoria Ltda,
Vacaria/RS.
Pergunta: Como faço para excluir via programação Delphi,
os arquivos temporários e o histórico do Internet Explorer?
Resposta: Uma abordagem para isso seria apagar o
conteúdo das pastas referente o histórico e arquivos temporários
de internet. Abaixo segue uma rotina que possibilita retornar o
path destas pastas ‘especiais’ e após isso, apagar o seu conteúdo:
implementationuses ShlObj, ShellApi;{$R *.dfm}
{ Retorna o path de pastas especiais }function GetSpecialPath(Folder: integer):string;var pidl: PItemIDList; Path: array[0..MAX_PATH] of Char;begin SHGetSpecialFolderLocation
(0, Folder, pidl); SHGetPathFromIDList(pidl, Path); Result := Path;
end;{ Apagar todos os arquivos de uma pasta }procedure DeleteAll(aFolder: string);var SearchRec: TSearchRec; Result: Integer;begin Result := FindFirst(aFolder + ‘\*.*’,faAnyFile, SearchRec); while Result = 0 do begin DeleteFile(aFolder + ‘\’ +SearchRec.Name); Result := FindNext(SearchRec); end;end;
Apagar conteúdo do Histórico:
DeleteAll(GetSpecialPath(CSIDL_HISTORY));
Apagar conteúdo temporário:
DeleteAll(GetSpecialPath(CSIDL_INTERNET_CACHE));
O projeto de exemplo referente esta dica está disponível para
download em: http://www.theclub.com.br/revista/download/
LimpaTempHist.zip
Dúvida enviada por Gustavo Koehler Fraga, Vitório/ES.
Pergunta: Estou desenvolvendo uma aplicação em MDI e
gostaria de saber o que tenho que fazer para ter um menu
parecido com os dos aplicativos Microsoft, ou seja, eles tem uma
opção de janela no menu o qual conforme você vai abrindo os
formulários eles vão sendo adicionados como ítens nesse menu
janela e também com as opções de organizar as janelas em
cascata, lado a lado, etc.
Resposta: Adicione
um componente
TActionList em seu
formulário principal. Após
isso, dê um duplo clique
sobre o mesmo e
encontrará as ações
padrões (New Standard
Action) para manipulação
de janelas em aplicações
MDI, veja a imagem ao
lado:
Perguntas & Respostas
MeGAZINE30
Após isso, crie itens de menu e ligue-os em cada ação que
desejar... através da propriedade ‘Action’ o ítem de menu. Em
relação a ‘lista’ de formulário que vão sendo abertos, vá ao seu
MDIForm e na propriedade WindowMenu do mesmo, informe o
ítem de menu referente seu menu ‘Janelas’, pois com isso
automaticamente os formulários serão adicionados ao menu.
Dúvida enviada por Sandro Luis Dias Maia, Praia Grande/SP.
Pergunta: Como posso atribuir a um campo o conteúdo de
um Edit sendo o
nome desta Edit a concatenação de alguns textos?
Resposta: Poderá utilizar a função ‘FindComponent’ para
retornar um objeto a partir de uma string, como exemplo:
Var C: TComponent; NomeComp: String;Begin NomeComp := ‘Edit10’; C := FindComponent(NomeComp); if (C<>Nil) and (C is TEdit) then Table.FieldByName(‘SeuCampo’).
AsString := TEdit(C).Text;End;
Dúvida enviada por Olavo Tessaro, Atibaia/SP.
Pergunta: Como posso deixar a aba do PageControl com as
letras em negrito, destacando a que foi selecionada?
Resposta: Para gerar este tipo de efeito será necessário
trabalhar com o evento OnDrawTab do PageControl, veja abaixo
simples exemplo:
{ Alterar a propriedade OwnerDraw doPagecontrol para true }
procedure TForm1.PageControl1DrawTab(Control: TCustomTabControl;
TabIndex: Integer; const Rect: TRect;Active: Boolean);begin with PageControl1.Canvas do begin if Active then Brush.Color := clAqua
else Brush.Color := clYellow; FillRect(Rect); Font.Color := clNavy; Font.Name := ‘Verdana’; Font.Style := [fsBold]; if TabIndex = 0 then TextOut(Rect.left+5,Rect.top+2, ‘Primeira’); if TabIndex = 1 then TextOut(Rect.left+5,Rect.top+2, ‘Segunda’); if TabIndex = 2 then TextOut(Rect.left+5,Rect.top+2, ‘Terceira’); end;end;
Dúvida enviada por Systema Informática Com. e Serviço
Ltda, Olinda/PE.
Pergunta: Tem alguma função do IBQuery que me retorne
o nome da tabela principal que esta sendo acessada no Select?
Resposta: Existe uma função chamada
GetTableNameFromSQL que retorna o nome da tabela principal
existente na propriedade SQL de um Query ou IBQuery:
Uses DBCommon;
Caption := GetTableNameFromSQL(IBQuery.SQL.Text);
Dúvida enviada por Domingos Waller, Porto Alegre/RS.
Pergunta: Estou a procura de um componente para
integrar aplicação Clipper DBF/NTX com Delphi. Encontrei o
APOLLO, mais é pago, teria outra opção?
Resposta: Existe o componente TDataSetDescendent
disponibilizado pela Renet Tecnologia (www.renet.com.br), o qual
permite acesso a DBF/NTX.
Para maiores informações recomendo consultar o artigo:
‘Advantage Database Server 7.1 - Conhecendo o B.D. na prática’.
Neste artigo mencionamos a utilização do referido componente,
vale lembrar que a utilização apenas deste componente é
gratuíto. Caso não possua a revista poderá acessar em nosso site,
www.theclub.com.br.
Dúvida enviada por Marcos Franklin Costa, São Paulo/SP.
Perguntas & Respostas