Upload
doanngoc
View
232
Download
2
Embed Size (px)
Citation preview
Revista The Club Megazine - 07/2003A utilização, reprodução, apropriação, armazenamento em banco de dados,sob qualquer forma ou meio, de textos, fotos e outras criações intelectuaisem cada publicação da revista “The Club” são terminantemente proibidos
sem autorização escrita dos titulares dos direitos autorais.Copyright© The Club® 2003
MeGAZINEMeGAZINEMeGAZINEMeGAZINEMeGAZINE 33333
EDITORIALEDITORIALEDITORIALEDITORIALEDITORIAL
Editorial
Celso Jefferson PaganelliPresidente - The Club
Editorial ............................................................................ 03Livros ............................................................................... 04Intraweb com Banco de Dados .......................................... 06IBObjects - Acesso nativo ao Interbase/Firebird ................. 08Soluções para impressão Clipper emWindows e portas USB ...................................................... 10Quando Zero não é igual a Zero ......................................... 16Calculando o Dígito Verificador ......................................... 19Dicas & Truques ................................................................. 23Perguntas & Respostas ...................................................... 29
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]ções: [email protected]
DúvidasCorrespondência ou fax com dúvidas devem serenviados 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® 2003
Impressão e acabamento:Impressos Gril - Gril Gráfica e Repr. Ind. Ltda.
Tel.: (0xx14) 3762.1345 - Fax: (0xx14) 3762.1259Rua São Paulo, 447 - Cep 18.740-000
Taquarituba - SPTiragem: 5.000 exemplares
Diretor - Presidente
Celso Jefferson M. Paganelli
Diretor Técnico
Mauro Sant’AnnaColaboradoresEmerson Facunte
Delphi é marca registrada da BorlandInternational, as demais marcas citadas são
registradas pelos seus respectivos proprietários.
Olá amigos,
Neste mês estamos trazendo muitas matérias interessantes. Quem nunca teveproblemas com a comparação de números no formato de ponto flutuante. Nesta ediçãovocê irá entender porque este problema acontece e como resolvê-lo.
Vamos mostrar também como você pode criar o seu próprio cálculo de dígitoverificador, algo que é muito solicitado ao suporte.
Outro assunto também muito solicitado está sendo como utilizar impressoras comporta USB no Clipper, nesta edição existe uma explanação completa sobre o assunto.
Nós fizemos uma entrevista com Jason Wharton, criador do IBOjects. Para quemnão conhece, este componente serve para acessar o Interbase e o Firebird nativamentee está sendo muito comentado entre os programadores Delphi.
Aproveito a oportunidade para agradecer a todos os associados que nos enviam e-mails sobre questões que gostariam de ver em nossa revista. Caso você tenha alguma,pode enviar para [email protected]. A sua participação é muito importante paranós.
Até a próxima...
MeGAZINEMeGAZINEMeGAZINEMeGAZINEMeGAZINE44444
Autor: Cantù, MarcoEditora: Makron BooksISBN: 8534615187Série Dominando - A BíbliaIdioma PortuguesPáginas: 896Publicação: 2003Edição 1Encadernação: BrochuraDisponibilidade: Em estoque - Prazo de entrega: 3 diasPeso: 1795.00 gramasHome Page: http://www.livrosdeprogramacao.com.br/
Descrição:Tanto para quem deseja aprender Delphi 7 como para quem está migrando de uma versão anterior, este livro é a única fonte
necessária para atualizar-se. Prático, inclui as técnicas mais atuais em bancos de dados, cliente-servidor e programação para aInternet. Acompanhando a visão do renomado autor Marco Cantù, você obterá o conhecimento necessário para aproveitar ao máximoo Delphi 7 totalmente atualizado e expandido. Livro best-seller no Brasil em vários outros países em tdo o mundo.
Dominando o Delphi 7 - A Bíblia
LivrosLivrosLivrosLivrosLivros
Aprendendo Delphi 7 Guia PráticoAutor: Spanghero, AldoEditora: AdvancedISBN: 8574131415Idioma PortuguesPáginas: 333Publicação: 2003Edição 1Encadernação: BrochuraDisponibilidade: Momentaneamente sem estoque - Prazo de entrega: 7 diasPeso: 333.00 gramasHome Page: http://www.livrosdeprogramacao.com.br/
Descrição:Aprendendo Delphi 7 Guia Prático foi feito para quem quer aprender a usar com eficiência os componentes do Delphi 7, não
somente mediante a teoria, mas praticando com programas reais.
Os exemplos foram elaborados de modo que o leitor possa aplicar na prática o que aprendeu. O leitor é incentivado a modificar osexemplos e a experimentar as diversas propriedades dos componentes. Assim, o aprendizado é mais rápido do que apenas saber comotais componentes funcionam. Afinal, este é um guia prático !
A construção de cada exemplo é feita por meio de uma descrição passo a passo, a fim de que o leitor se sinta seguro do que deve serfeito em cada etapa.
Aprendendo Delphi 7 Guia Prático abrange: Como usar o ambiente de desenvolvimento do Delphi 7, Componentes básicos, Menus, Caixasde diálogo, Componentes avançados e complementares, Bancos de dados, Vários outros componentes
Além disso, o leitor encontrará dicas de como criar seus próprios componentes e também como personalizá-los.
MeGAZINEMeGAZINEMeGAZINEMeGAZINEMeGAZINE 55555
Autor: Minasi, MarkEditora: Makron BooksISBN: 8534615195Série Dominando - A BíbliaIdioma PortuguesPáginas: 1408Publicação: 2003Edição 1Encadernação: BrochuraDisponibilidade: Em estoque - Prazo de entrega: 3 diasPeso: 2525.00 gramasHome Page: http://www.livrosdeprogramacao.com.br/
Descrição:Este livro é a única fonte de informação sobre o Windows Server de que você precisa. É o mais compreensível e bem escrito livro
sobre o assunto. Ensina como projetar e gerenciar uma rede multiplataforma, construir uma intranet baseada em Windows,encontrar a melhor estratégia de backup, evitar e recuperar desastres, e muito mais.
As instruções práticas levarão você a experimentar tudo o que é possível fazer com o Windows Server 2003. O premiado autor,Mark Minasi, que conquistou milhares de seguidores em todo o mundo, mostra como planejar, configurar e instalar sua rede, mantê-la funcionando da melhor forma possível e como solucionar os problemas. Inclui informação jamais documentada de administradoresde rede, consultores e vários outros profissionais da área, especialistas em redes Windows.
Dominando o Windows Server 2003 - A Bíblia
LivrosLivrosLivrosLivrosLivros
Sistema Comercial Integrado com Delphi 7 - Cadastro e Estoque
Autor: Oliviero, CarlosEditora: ÉricaISBN: 8571949158Idioma PortuguêsPáginas: 566Publicação: 2003Edição 1Encadernação: BrochuraDisponibilidade: Momentaneamente sem estoque - Prazo de entrega: 6 diasPeso: 566.00 gramasHome Page: http://www.livrosdeprogramacao.com.br/
Descrição:Este livro é destinado aos interessados em aprender a criar uma aplicação comercial completa utilizando o Delphi 7 ou 6 com o
banco de dados Cliente/Servidor - InterBase.Aborda a criação de menus, barra de ferramentas e de status, execução de programas externos, login do sistema, configuração de
perfis de usuários, herança de formulários e o uso de componentes IBX e da linguagem SQL.A metodologia orientada por projeto permitirá ao leitor, ao concluir o livro, desenvolver o menu principal da aplicação e os módulos
de cadastro e estoque.Para acompanhar a obra, é necessário possuir conhecimentos básicos em Delphi, linguagem SQL e InterBase, temas abordados
nos primeiros livros da série.
MeGAZINEMeGAZINEMeGAZINEMeGAZINEMeGAZINE66666
DelphiDelphiDelphiDelphiDelphi
Salve, salve Delphianos! Perderam o medo de desenvolveraplicações para Web? Ainda não? Não percam tempo, o mercadoprecisa de aplicações e-business.
Neste artigo teremos uma simples aplicação Intrawebacessando banco de dados.
Através das opções File/New/Other..., selecione a seçãoIntraweb e escolha o modelo Stand Alone Application with DataModule (figura 1).
Intraweb com Banco de DadosIntraweb com Banco de DadosIntraweb com Banco de DadosIntraweb com Banco de DadosIntraweb com Banco de Dados
Por: Emerson Facunte
Figura 1: Iniciando a aplicação
A opção with Data Module, cria automaticamente um DataModule, bem como suas referências.
Insira um objeto do tipo TSQLConnection, e através do duplo-clique, já na tela de configuração, aponte para a sua conexãodbExpress. Neste artigo estou utilizando uma conexão padrãopreviamente criada.
Veja o exemplo de conexão:
edadeirporP rolaV
niateRtimmoC eslaF
esabataD bdg.setneilc\bewosruc\:c:tsohlacol
drowssaP yekretsamasomafa
emaNresU ABDSYSosomafo
emaN DBoaxenoC
edadeirporP rolaV
noitcennoCLQS DBoaxenoC
txeTdnammoC ETNEILCBTmorf*tceles
evitcA eurT
Altere também a propriedade LoginPrompt para false.Nunca esqueça de fazer esta alteração, pois numa aplicaçãoservidora não existe a possibilidade do usuário interagir no logindo banco de dados.
Insira um objeto do tipo TSQLDataSet, e altere as seguintespropriedades:
Repare que estamos trazendo todas as informações daentidade TBCLIENTE.
Ótimo, agora vamos para o formulário principal.
Insira a unit DataModuleUnit na cláusula uses, e grave aaplicação.
Insira os componentes que seguem.
MeGAZINEMeGAZINEMeGAZINEMeGAZINEMeGAZINE 77777
DelphiDelphiDelphiDelphiDelphi
A figura 2 ilustra nosso formulário principal.
Não colocamos nenhum código nesta aplicação. Assim comoem aplicações desktop, apenas associamos os objetos.
Vamos executar a aplicação e ver o resultado (figura 3).
Amigos, apesar de simples, o exemplo demonstra adisponibilidade de banco de dados na Internet.
Que tal desenvolver uma lista de preços para Web, só paracomeçar?
Forte abraço e muita luz a todos!
Figura 3:exemplo em execução
Figura 2:Formulário
principal
MeGAZINEMeGAZINEMeGAZINEMeGAZINEMeGAZINE88888
DelphiDelphiDelphiDelphiDelphi
Nós da equipe técnica do The Club sempre estamosprocurando por novidades para nossos associados. Informaçõesque ajudem no seu dia a dia. E com o aumento da utilização doInterbase e do Firebird tivemos a oportunidade de conhecer umcomponente chamado IBOjects. O IBOjects na verdade é umconjunto de componentes de acesso nativo ao Interbase/Firebirdque segundo o seu fabricante é o melhor componente para acessoao Interbase/Firebird da atualidade. Fiquei curioso sobre ocomponente e então entrei em contato com o seu fabricante. Onome dele é Jason Wharton, americano, casado, pai de quatrofilhos. Aproveitando a oportunidade eu lhe fiz algumasperguntas, veja o que ele me respondeu:
Porque você criou o IBOjects?Eu realmente gostei muito do Delphi e do Interbase, mas eu
não gostei da tecnologia de acesso a dados que havia disponível.Então eu decidi criar o meu próprio componente com melhorescaracterísticas e principalmente com um desempenho muitomelhor. Eu também queria utilizar corretamente apotencialidade de transação disponível no Interbase/Firebird e aúnica maneira que eu poderia fazer isto era escrevendo meuspróprios componentes.
Quais são as vantagens do IBOjects?Agora como este componente está muito mais maduro e
estável, eu lhe aconselharia a tirar um pouco do seu tempo para
aprendê-lo. Você irá notar que será possível criar aplicações comcaracterísticas muito mais ricas e fáceis de usar além dodesempenho que é muito mais rápido.
O IBOjects é compatível com quais versões doDelphi ?
Ele é compatível com todas as versões a partir do Delphi 2.0.Sendo o IBOjects um conjunto de componentes, como eles
estão divididos.São vários componentes divididos em acesso a base de dados,
controles visuais, caixas de diálogo, ferramentas deprodutividade, replicação, pesquisa, internet, etc...
Quais são os arquivos que devo disponibilizar parao usuário final se eu desenvolver uma aplicaçãoutilizando o IBOjects ?
Não há necessidade de levar nenhum arquivo adicional. Tudoo que você vai precisar estará incorporado ao seu executável.
Existe alguma versão do IBOjects para o Kylix ?Sim, existe uma versão BETA, mas eu ainda não terminei os
componentes visuais, terminei apenas o material não visual.
O que você pensa sobre o Kylix ?Eu penso que é uma grande idéia um pouco antes do seu
tempo. O LINUX precisa amadurecer mais antes de podermos
IBOjectsIBOjectsIBOjectsIBOjectsIBOjectsAcesso nativo aoAcesso nativo aoAcesso nativo aoAcesso nativo aoAcesso nativo ao
Interbase/Firebird.Interbase/Firebird.Interbase/Firebird.Interbase/Firebird.Interbase/Firebird.
Por Claudinei Rodrigues – [email protected]
MeGAZINEMeGAZINEMeGAZINEMeGAZINEMeGAZINE 99999
DelphiDelphiDelphiDelphiDelphi
fazer um analise sobre criar aplicações utilizando o Kylix para ousuário final.
Como você vê o futuro do Firebird em relação aoInterbase ?
Eu vejo ambos os produtos com muito bons olhos. Cada umrepresenta uma área de interesse e de foco. O Open Source é umagrande idéia, mas ainda existe uma necessidade de que aBorland esteja oferecendo uma versão comercial do Interbase.
Falando em versão comercial, quanto custa oIBOjects ?
A licença para utilização do IBOjects é chamada deTrustware. Que vem a ser um caminho para pessoas poderemutilizar IBObjects e paguem quando puderem. Se alguém estivernuma situação financeira não muito favorável e não tivercondições para pagar pelo componente, ele poderá pagar após terdesenvolvido o seu software e ganho algum dinheiro com ele. Se apessoa não ganhar nenhum dinheiro eu ficarei feliz mesmoassim porque eu permiti que utilizassem o poder o IBOjects semter que pagar nada por isto. Esta é a minha maneira de emitir
uma mensagem positiva de confiança de integração entre osseres humanos.
ConclusãoBem amigos do The Club, este componente parece ser
realmente muito bom. Eu andei olhando as listas de discussões epelo visto já tem muito programador utilizando este componente.Agora é botar a mão na massa para confirmar tudo que o Jasonme disse.
Nas próximas edições vamos analisar melhor estecomponente. Espero que vocês tenham gostado desta matéria, ese você deseja sugerir algum assunto para ser publicado emnossa revista, fique a vontade. Envie um e-mail [email protected]. A sua sugestão é muito importantepara nós.
Um grande abraço a todos e até a próxima.
Claudinei RodriguesEquipe de suporte do The Club.
MeGAZINEMeGAZINEMeGAZINEMeGAZINEMeGAZINE1 01 01 01 01 0
ClipperClipperClipperClipperClipper
IntroduçãoMuitos programadores que possuem aplicativos rodando em
Clipper estão em busca de soluções para que seus aplicativospossam fazer impressão em Windows e portas USB, devido estetipo de device estar tornando-se muito comum hoje. Neste artigoiremos mostrar algumas soluções sendo algumas freeware eoutras sharewares.
O ProblemaOs fabricantes de impressoras estão notoriamente projetando
impressoras cada vez mais compatíveis com Windows, deixando osuporte ao bom e velho “DOS” de lado, desenvolvendo apenasdrivers para Windows e fazendo com que estas impressorassequer reconheçam os tão utilizados códigos de controles (ESC)para formatação de fontes, espaçamento de linhas, etc.
Isto gera um grande problema para aplicações “DOS”, comoas em Clipper que não podem fazer uso dos drivers instalados noWindows e só fazem acesso diretamente as impressoras.
Um problema relacionado é uma impressora conectada por
USB: não há nenhuma forma de uma aplicação “DOS” conseguiracessar uma impressora conectada via USB diretamente. (Vejaabaixo mais informações sobre este caso...)
A SoluçãoA melhor solução é evitar estes tipos de impressoras
completamente, e usar impressoras que aceitam aplicaçõesbaseadas em “DOS”.
Se isto não for possível, você terá que recorrer a produtos deterceiros que permitam enviar sua saída de impressora aosistema de impressão do Windows. Há dois tipos de soluções:
Bibliotecas, as quais possibilitam linkar sua aplicaçãodiretamente ao sistema de impressão do Windows.
Spoolers, programas independentes que capturam sua saídade impressão tradicional, e enviam isto ao sistema de impressãodo Windows.
Vejamos mais detalhes:
Soluções para impressãoSoluções para impressãoSoluções para impressãoSoluções para impressãoSoluções para impressãoClipper em Windows eClipper em Windows eClipper em Windows eClipper em Windows eClipper em Windows e
portas USBportas USBportas USBportas USBportas USB
Adaptação: Suporte The Club, [email protected]
MeGAZINEMeGAZINEMeGAZINEMeGAZINEMeGAZINE 1 11 11 11 11 1
ClipperClipperClipperClipperClipper
nalruFodranoiuG-SPC
etisbeW /rb.moc.gph.tfosoiug.www odanimreted-érpoiróteridmuodnarotinomacif)revreSretnirPreppilC(SPCOoaodaivneáresomsemo,oiróteridetsenodaregrofoviuqramueuqmissaesetsujasnuglaoirássecenoãres,odutnoC.swodniWodoãsserpmiedametsisarapoãsserpmiaraivneárevedamsemaednoreppilCoãçacilpaausme
.oãsserpmiedadíasaarapetnemateridsiamoãneoviuqra
oãçulosadopiT reloopS
setnofsoraretlaatisseceN miS
tifotuA miS
socifárGatropuS oãN
"CSE"sogidócatropuS oãN
weiverPmeT oãN
oçerP eraweerF
cnI,tseBehtylpmiS-TNIRPSOD
etisbeW moc.tnirpsod.www eodnamocedahnilanoãsserpmiedoviuqraodemonoebecerTNIRPSODOsnuglaedoirártnocoA.swodniWodoãsserpmiedametsisodsévartaemirpmiooiróteridmumeoãsserpmiedoviuqramurop"odnarepse"acifoãn,sotudorpodemonoes-odnamrofniodatucexeresevedaditrapartnocmE...reuqlauqadetnofogidócodoãçaretlaaossimocodnatissecen,odatucexeresaoviuqrasogidócedacsubmeoãsserpmiedoviuqraoerravTNIRPSODO.oãçacilpa
.swodniWodoãsserpmiedametsisoaodnaivneaterpretnisoe"CSE"
oãçuloSadopiT reloopS
setnofsoraretlaatisseceN miS
tifotuA miS
socifárGatropuS miS
"CSE"sogidóCatropuS miS
weiverPmeT miS
oçerP 00,99$SU
BibliotecasAs bibliotecas contêm funções que podem ser utilizadas na
programação Clipper que lhe permitem que sua aplicação possaenviar saída diretamente à impressora Windows. A vantagemdesta solução é que você terá grande controle e flexibilidade emcima do que será impresso, e como deverá ser impresso. Adesvantagem é que você precisará modificar seu código fonte eem caso de grandes aplicações isso poderá demandar tempo.
SpoolersSpoolers são programas que recebem a saída padrão da
impressora produzido por uma aplicação “DOS”, e após issoenviam para uma impressora no Windows. A vantagem destasolução é que não requer nenhuma mudança nas aplicações
existentes, e trabalhará com qualquer aplicação fundamentadaem “DOS” (assim não só o Clipper).
A única exigência é que estas aplicações deverão poderredirecionar a saída de impressora para o disco. Contudo, emboranão serem necessários ajustes na aplicação, isso não será umaregra, visto algum destes gerenciadores de spoller fazer o controleda fonte, porém, muitos deles trabalham perfeitamente com oscódigos de controle (ESC) comumente utilizados em aplicaçõesClipper para formatação da fonte a ser impressa.
Os ProdutosVeja um pequeno resumo das soluções disponíveis no
mercado:
MeGAZINEMeGAZINEMeGAZINEMeGAZINEMeGAZINE1 21 21 21 21 2
ClipperClipperClipperClipperClipper
erawtfoStneipaS-tnirPniWsoD
etisbeW moc.erawtfos-tneipas.www esanulocesolutítmocsoirótalerrimirpmiarapodatejorpioftnirPniWsoDOsetnofedoãçazilituaetimreP.oãsserpmiadlausivorarohlemetimrepritrapasarrabedsogidócraregredopamargorpO.IICSAe,sianoicroporpadatucexeéseõçnufsatsedairoiamA.sodibecersoremúnedaodarugifnocresedopahlabartamargorpoeuqodomO.etnemacitamotuaratsujaarapsortemârapmétnocoviuqraetsE.INIoviuqramuedritrapanmailixuaeuqsortemârapmébmate,.cte,oãçatneiro,snegramolpitlúmotnujnocmurebeceradniaedoP.sanuloceanigápadoãçarugifnoc
.soirótaleredsopitsosrevidralortnocarapsortemâraped
oãçulosadopiT reloopS
setnofsoraretlaatisseceN oãN
tifotuA miS
socifárGatropuS sarrabedogidóCetnemoS
"CSE"sogidóCatropuS miS
weiverPmeT miS
oçerP 59,42$SU
smetsySsbaLeebA-tpircsegaP
etisbeW moc.sbaleeba.www oãritimrepehleuqseõçnufedotnujnocmumétnoctpircSegaPacetoilbibAarosserpmimuarapreppilCoãçacilpaamuedetnemateridrimirpmie,sohnamat,setnofedsopitsoirávmeosserpmiresedopotxetO.swodniWsodahnesedresmedoP.rocaetropusesociláti,otirgenomocsotiefemocadotnemomonspamtibedoãsulcniaetimrepadniaesolucrícesahnilsocifárgeotxetedotnemanoicisopedelortnocomitómuetimreP.oãsserpmiatnemarrefartuoamumocetnematnuJ.oãsicerpetnatsabmocanigápan
.oãsserpmiedoãçazilausivraregetimreptnirPeniFadamahc
oãçulosadopiT acetoilbiB
setnofsoraretlaatisseceN miS
tifotuA oãçamargorP
socifárGatropuS miS
"CSE"sogidóCatropuS levínopsidnI
weiverPmeT )tnirPeniF(onretxE
oçerP 00,011$SU
edivaDolouG-liftnirP
etisbeW mth.hsilgne/liftnirp/moc.oloug.www ehleuqseõçnufedotnujnocmumétnoctpircSegaPacetoilbibAmuarapreppilCoãçacilpaamuedetnemateridrimirpmioãritimrepedsopitsoirávmeosserpmiresedopotxetO.swodniWarosserpmi.rocaetropusesociláti,otirgenomocsotiefemoce,sohnamat,setnof
edoãsulcniaetimrepadniaesolucrícesahnilsodahnesedresmedoPedelortnocomitómuetimreP.oãsserpmiadotnemomonspamtib.oãsicerpetnatsabmocanigápansocifárgeotxetedotnemanoicisopraregetimreptnirPeniFadamahcatnemarrefartuoamumocetnematnuJ
.oãsserpmiedoãçazilausiv
oãçulosadopiT reloopS
setnofsoraretlaatisseceN miS
tifotuA miS
socifárGatropuS miS
"CSE"sogidóCatropuS oãN
weiverPmeT miS
oçerP 00,99oruE
MeGAZINEMeGAZINEMeGAZINEMeGAZINEMeGAZINE 1 31 31 31 31 3
ClipperClipperClipperClipperClipper
pureLreteP-eliFtnirP
etisbeW eliftnirp/moc.purel.www ,selpmisotxetsoviuqrarimirpmietimrepehleuqoirátilitumuéeliFtnirPOA.soditubme"CSE"sogidócmocsoviuqraeSPEsoviuqra,tpircstsoPedahnilaivomsemuoswodniWecafretniaivatiefresedopoãçarugifnocreuqlauq,ossimoceodarotinomresàoiróteridmurinifedodnedop,sodnamocedsiaicepsesotiefE.osserpmiáresoviuqraetsenodaregrofeuqoviuqraropomoc,oãçarugifnocedsoviuqramesodarugifnocresoãredopoãsserpmiedépadoreolutít,)ahnilropseretcaracedoremún(etnofedohnamatolpmexesortuososrevide,swodniWselortnocarap"CSE"sogidócedoãçudart,anigáp
.selortnoc
oãçulosadopiT reloopS
setnofsoraretlaatisseceN oãN
tifotuA oãN
socifárGatropuS oãN
"CSE"sogidóCatropuS urhtssaP
weiverPmeT oãN
oçerP eraweerF
erawtfoSnessumsaR-draziWtnirP
etisbeW moc.oizna.www edadíasedsopitsoirávrassecorpetimrepeuqerawtfosmuéziWtnirPOacigólamuodnasuassaplauqo(selpmisotxetolpmexeropomoc,oãsserpmietimreplauqo("txetwar",)anigápedetsujaorezafarapadacitsifostifotuaedswodniWodreloopsoaodaivneetnemateridéeuq)tpircstsope"CSE"sogidócedsévartaLMTHsogidócretnocodnedopetse("txeTpUksaM"adniaeamicmeelortnocriamraçnaclaedopoãçacilpaamueuqmoc,LMWPsodnamocedohnamat,setnofracificepseáredopêcov,ossimoC.osserpmiéeuqodoraretlaeuqáretêcovetnemaivbO.sarrabedogidócesocifárg,roc,setnofsatsesadotaossecaretredoparapamargorpuesedetnofogidócadazilituresedopeuqLLDamumocmevmébmatziWtnirPO.sedadilanoicnuf
.BVeihpleDmeolpmexeropomoc,swodniWseõçacilpame
oãçulosadopiT reloopS
setnofsoraretlaatisseceN oãN
tifotuA miS
socifárGatropuS miS
"CSE"sogidóCatropuS urhtssaP
weiverPmeT oãN
oçerP 00,99$SU
asiarA-NIWTRP
etisbeW moc.asiara.www arap)setnerefidsarosserpmievonarap(soiróteridevonétaerravNIWTRPOedametsisoaaivnesoe,soiróteridsetsensodaregoãsserpmiedsoviuqra,olpmexeropomoc,"CSE"sogidócsoirávecehnoceR.swodniWodoãsserpmi"CSE"sodnamocsoirávazilitu,etnemlanoicidA.sotamrofsortuoertne,nospEad,latnozirohodommeoãsserpmimatilibahesocifárgrimirpmiarapsoiráteirporp
.somsemsodoãçarugifnocalevíssopodnes
oãçulosadopiT reloopS
setnofsoraretlaatisseceN oãN
tifotuA oãçamargorP
socifárGatropuS miS
"CSE"sogidóCatropuS miS
weiverPmeT miS
oçerP 00,42$SU
MeGAZINEMeGAZINEMeGAZINEMeGAZINEMeGAZINE1 41 41 41 41 4
ClipperClipperClipperClipperClipper
rJledniK.EselrahC-tnirPniW
etisbeW moc.lednik.www .swodniWarapIICSAsoviuqraedoãsserpmiedrodaicneregmuétnirPniWOaodacovniresedopmébmatmissa,odnamocedahniledecafretniamumeTedseõçpoáH.otxetoviuqramurimirpmiarap"SOD"oãçacilpaamuedritrapoãçacifissalceetnofedopitomocseõçporanoicelesarapsodnamocedahnilseõçarugifnocedritrapaotiefresedoposuueS.snegrameohnamatoodnugessalpitlúmedoãsserpmi,anigápedoãçatneiroedoãçinifedalevíssopéednoseretcarace"deefmrof"ecehnoceR.cte,acisífanigápacinúamumesanigápoãçalubatansoçapseededaditnauqarinifedlevíssopée(oãçalubated
.)adazilitu
oãçulosadopiT reloopS
setnofsoraretlaatisseceN miS
tifotuA oãN
socifárGatropuS miS
"CSE"sogidóCatropuS oãN
weiverPmeT oãN
oçerP 00,52$SU
ihcnoRoreiP-tnirPniW
etisbeW lmths.9299/dp/bup/ten.letmis.www murimirpmiarapoirássecenodnauqodanoicaresevedtnirPniWOranoicelesarapsodnamocedahniledseõçposasrevidetimreP.oviuqraotarter(oãçatneiro,)cte,otirgen,ociláti(sotiefe,etnofadohnamat,etnofsairávecehnoceR.cte,snegramedoãçarugifnoc,)megasiape,)emarfniamehsotnicaM,xinU,CP(ahniledoãçanimretedseõçnevnoc
ocinúmumeseõçpoedsolpitlúmsotnujnocsodazilituresodnedopmeboãçnetunamaanrotetnemlevimuserpeuqsortemârapedoviuqraosuarapotsucmetelaosseposuaraperaweerfétnirPniWO.licáfsiam
.laicremoc
oãçulosadopiT reloopS
setnofsoraretlaatisseceN miS
tifotuA miS
socifárGatropuS miS
"CSE"sogidóCatropuS oãN
weiverPmeT oãN
oçerP 00,05$SU
aissuR,ksninbO,dtLtroP-tnirPniW
etisbeW mth.litu/ur.ksninbo.trop.www ededadissecenarevuohodnauqodamahcresevedtnirPniWetsEahniledseõçpoedsévartaoãçarugifnocaetimreP.oviuqramurimirpmiertneotnemaçapse,etnofedohnamatranoicelesarapsodnamocedresmedopsotiefesomsemsO.)megasiapeotarter(oãçatneiro,sahnilogidócmu,olpmexerop(otxetonsocifícepsesogidócodnitubmesoditbooviuqramuetsixeomsemoaotnuJ.)seretcaracrasnednocarap"CSE"mébmaT.atnemarrefatsedotnemanoicnufoodacilpxeéedno"eMdaeR"arapedadilanoicnufzarteuq)00,81$SU(erawerahsoãsrevamuáh
.etnofedsortemârapedoãçarugifnocesogidócedoãçatamrof
oãçulosadopiT reloopS
setnofsoraretlaatisseceN miS
tifotuA oãN
socifárGatropuS oãN
"CSE"sogidóCatropuS oãN
weiverPmeT oãN
oçerP eraweerF
MeGAZINEMeGAZINEMeGAZINEMeGAZINEMeGAZINE 1 51 51 51 51 5
ClipperClipperClipperClipperClipper
Mais algumas dicas para você testarAlém de todos os produtos apresentados neste artigo, você
também poderá assumir um desafio técnico “faça você mesmo”,utilizando as ferramentas que o próprio Windows disponibiliza.
A idéia geral é criar um arquivo de impressão, e entãoinvocar um programa Windows que poderá imprimir o arquivogerado. Existem várias possibilidades, veja abaixo:
Bloco de notasTeoricamente, você poderá invocar o Bloco de notas para
imprimir um arquivo ASCII puro. O Bloco de notas porém, é umprograma muito simples, com virtualmente nenhuma“inteligência” própria, e não há nenhum modo de você controlar asaída para impressora.
Não é nem mesmo possível forçar quebra de páginautilizando um controle “formfeed” no arquivo a ser impresso.
HTMLVocê poderá criar um arquivo com tags HTML embutidas, e
utilizar o Internet Explorer ou outro navegador para fazer aimpressão do mesmo. Podem ser convertidos relatórios comcolunas utilizando tabelas HTML, deixando o controle a cargo doHTML.
RTF e WordpadVocê poderá também criar um documento RTF (Rich Text
Format) e utilizar o Wordpad para a impressão do mesmo.Embora o formato RTF gere um pouco de receio a primeira vista,ele deve ser estudado com carinho, visto não ser tão difícil assim.
O formato RTF oferece diversos recursos como exemplo tipo e
tamanho de fontes, efeitos, etc.
Impressoras USB“USB-only printers” (ou seja, impressora que não possuem
interface paralela) podem ser um problema especial, pois elas nãopodem ser endereçadas diretamente no ambiente “DOS”, porém,todos os produtos acima mencionados resolverão este problema.
Uma solução alternativa é descrita logo abaixo. Trabalha emWindows 2000 e XP e também trabalha em Windows NT, mascomo o NT não da suporte a USB, não há porque utilizar estasolução neste sistema operacional.
· Defina a conexão USB de sua impressora no Windows.· Faça o compartilhamento da mesma para rede· Mapeie a LPT1: para esta impressora de rede: algo mais
como:. NET USE LPT1 \\servidor\impressora
A princípio, isso só irá funcionar se seu PC estiver conectadoa uma rede.
Conclusão
Este artigo é uma adaptação do conteúdo disponível no site:
http://www.dse.nl/~tmk/clipper/clpwinprint.htm#AutoPrint
Aqui estão sem dúvida nenhuma, as melhores soluções paraque aplicativos “DOS” possam fazer acesso a impressoras“Windows-Only” e portas USB, permitindo assim que estasaplicações possam acompanhar as inovações tecnológicas quediariamente são disponibilizadas aos usuários. Boa sorte.
pmurKrenieR-tnirPotuA
etisbeW mth.e_tnirpotua/tnirpotua/erawtfos/ed.pmurk-srh.www -érpsatsapsairávuoamuodnacehcaciftnirPotuAOuoNRP,TXTsoviuqraedacsubmesadarugifnocsetsedreuqlauqedaicnêtsixeaodnatceteD.PMBoarapsol-áivneárietnemacitamotuaele,soviuqraétnirPotuAO.swodniWodoãsserpmiedametsiszededsonememirpmieuqsoiráusuarapsitárg
.zevropsoviuqra
oãçulosadopiT reloopS
setnofsoraretlaatisseceN oãN
tifotuA oãN
socifárGatropuS miS
"CSE"sogidócetropuS oãN
weiverPmeT oãN
oçerP )eerfuo(00,04$SU
MeGAZINEMeGAZINEMeGAZINEMeGAZINEMeGAZINE1 61 61 61 61 6
DelphiDelphiDelphiDelphiDelphi
Todo mundo sabe que a comparação de númerosarmazenados no formato de ponto flutuante pode conduzir aresultados inexatos, especialmente quando os númerosrepresentam valores monetários. Para remediar isto, o Delphi 2introduziu um novo tipo chamado Currency.
A idéia é que o tipo Currency não seja passível de erros searredondando da forma que os tipos de ponto flutuante fazem, edeveria então ser usado no lugar de Single, Real, Double eExtended onde o valor monetário está envolvido. Infelizmente,existe muito pouca informação sobre o tipo Currency nadocumentação do Delphi. Através de pesquisas encontramosalgumas informações. Estas informações resultaram nesteartigo.
FloatsVeja o exemplo mostrado na figura 1. Quando você executar
este exemplo, você receberá a mensagem “dCounter <> 0”. Agoracoloque um breakpoint sobre a linha if dCounter = 0 then e rodeo programa novamente. Coloque o mouse sobre a variáveldCounter. A princípio o valor desta variável seria igual a zero,certo? Errado. Você verá que o hint mostrará o valor -1.1102907873e-17.
procedure TForm1.Button1Click(Sender: TObject);
var
dCounter: Double;
begin
dCounter := 0;
dCounter := dCounter + 0.05;
dCounter := dCounter + 0.05;
dCounter := dCounter + 0.05;
dCounter := dCounter - 0.05;
dCounter := dCounter - 0.05;
dCounter := dCounter - 0.05;
if dCounter = 0 then
ShowMessage(‘dCounter = 0’)
else
ShowMessage(‘dCounter <> 0’);
end;
Figura 1: Testando valores
Agora coloque um breakpoint na segunda linha abaixo dobegin, ou seja na linha dCounter := dCounter + 0.05; e rodenovamente o programa. Assim que o programa parar no seubreakpoint chame a janela CPU pressionando as teclas<CTRL><ALT><C> e a janela FPU através das teclas<CTRL><ALT><F>. Mantenha estas duas janelas de umamaneira de fácil visualização e ative a janela CPU como mostra afigura 2.
Execute o Step Over pressionando a tecla F8 para executarum dos comandos dCounter := dCounter + 0.05;. Vá até a janelaFPU e clique com o botão direito do mouse no centro da janela ena opção Display As selecione a opção Words.
Esta janela ficará igual ao que está sendo mostrada nafigura 3. Agora o registro ST7 contém o seguinte numerohexadecimal 3FFA CCCC CCCC CCCC CCCD.
Quando o zeroQuando o zeroQuando o zeroQuando o zeroQuando o zeronão é igual a zero.não é igual a zero.não é igual a zero.não é igual a zero.não é igual a zero.
MeGAZINEMeGAZINEMeGAZINEMeGAZINEMeGAZINE 1 71 71 71 71 7
DelphiDelphiDelphiDelphiDelphi
Figura 2: A janela CPU no primeiro breakpoint
Figura 3: Carregando .05 no registro ST7 com um Double.
Vamos olhar além de nosso exemplopor um momento. O Delphi gera ocódigo, que usa somente o FPU paraexecutar cálculos com os números noformato ponto flutuante.
Não importa que precisão você usaem seu programa, Single, Double ouExtended, porque o FPU armazena eprocessa todos os números somente noformato Extended.
Este formato é definido pelo IEEE(Institute of Electrical and ElectronicsEngineers) e tem a seguinte expressão:
(-1)s x2E-16383 x(m63.m
62..m
0),
onde S = sign (bit No. 79),
E = expoente (bitsq No.
78..64), e m63.m
62..m
0 = mantissa
(bits No. 63..0).
Agora, transforma o númerohexadecimal localizado no registro ST7para o formato decimal usando afórmula acima.
A calculadora do Windows noformato cientifico pode ser muito útil.As figuras 4 e 5 podem ajudar vocêneste processo.
Após a substituição de todos oscomponentes na fórmula, nós teremos oseguinte:(-1)0 x216378-16383
x(1.1001100110011001100110011
00110011001100110011001100110011001101)
O número reduzido tem a seguinteexpressão:2-5
x1.1001100110011001100110011001
100110011001100110011001100110011012
Ou tem esta expressão:
Figura 4: Valor doregistro ST7 em hexa-
decimal e binary
lamicedaxeH oirániB
AFF3 0101.1111.1111.1100
CCCC 0011.0011.0011.0011
CCCC 0011.0011.0011.0011
CCCC 0011.0011.0011.0011
DCCC 1011.0011.0011.0011
ngiS 010=20
tnenopxE 0187361=2010111111111110
assitnaM1001100110011001100110011001100110011001.1
210110011001100110011001
Figura 5:Substituindo os
valores de ST7 nafórmula IEEE
MeGAZINEMeGAZINEMeGAZINEMeGAZINEMeGAZINE1 81 81 81 81 8
DelphiDelphiDelphiDelphiDelphi
Figura 6: Lendo .05 no registro ST0 com o tipo Currency.
0.0000110011001100110011001100110011
00110011001100110011001100110011012
Agora, nós precisamos transformar o resultado obtido em umformato decimal. Considere o seguinte:x11.00110011001100110011001100110
0110011001100110011001100110011012
Remova a parte fracional e obtenha o seguinte:
2-6 x112 = 3
10/64
10=0.046875
10
Repita os mesmos passos com níveis diferentes de precisão.
2-10 x1100112=51
10/1024
10=0.0498046875
10
2-14 x11001100112=819
10/16384
10=0.04998779296875
10
O número máximo de dígitos disponíveis que você pode usarna transformação através da calculadora é 41. O cálculo de 41digitos é igual a:2-41 x
11001100110011001100110011001100110012=109951162777
10/
219902325555210=0.049999999999727151
10
A análise da mantissa mostra que este número tem umfragmento decimal.
1.10011001100110011001100110011
00110011001100110011001100110011012
Baseado nisto, nós determinamos que é impossível conseguira precisão absoluta do número 0.05 noformato de ponto flutuante. O número ésempre um valor aproximado.
Você pode usar a seguinte regra paradeterminar se um numero pode serapresentado no formato de pontoflutuante com precisão absoluta.Multiplique o seu número por 2 até eleser maior ou igual a 1.
Se o resultado não tem um partefracional, o número pode ser apresentadoprecisamente no formato de pontoflutuante. Por exemplo, se você colocar .5no código mostrado no inicio deste artigo,
você receberá o resultado correto.
CurrencyAgora vamos retornar para aquele exemplo. Modifique o tipo
da variável dCounter de Double para Currency. Configure obreakpoint na segunda linha dCounter := dCounter + 0.05; erode o programa. Quando o programa para no breakpoint chamenovamente as janelas CPU e FPU. Execute o Step Over e troqueo modo de mostrar a janela FPU para Extended, como mostra afigura 6.
Este modo executa automaticamente a transformaçãoexecutada anteriormente. Você pode ver que .05 é apresentadocomo 500. Todos os números no formato Currency sãoarmazenados como inteiros. Conseqüentemente todos os cálculossão executados como inteiros também. Então, se você usar oformato Currency ao invés de formatos de ponto flutuante vocênão encontrará problemas com respeito a precisão de cálculos. Dequalquer forma o formato Currency permite que somente a partefracionária de quatro dígitos, no máximo, seja armazenada.
ConclusãoSe você calcular o trajeto de um satélite, a quantidade de
átomos em metros cúbicos de ar, ou um campo de futebol empolegadas, o formato de ponto flutuante seria a melhor escolha.Entretanto, se você quiser desenvolver um balanço geral parafinalidades de contabilidade ou desenvolver um pacote derelatórios financeiros, o formato de ponto flutuante seráproblemático.
Nesses casos, o tipo Currency é o formato ideal.
MeGAZINEMeGAZINEMeGAZINEMeGAZINEMeGAZINE 1 91 91 91 91 9
Alguns de nossos sócios têm ligado ao suporte técnicosolicitando informações sobre como criar o cálculo de dígitoverificador. Sendo assim resolvi escrever este artigo ensinandouma forma simples de resolver este problema utilizando o módulo11.
Mas atenção, nem sempre você poderá utilizar este código.Mais adiante neste artigo eu explicarei o motivo.
Todo o código que se verifique com cálculo tipo “dígitoverificador” consta de duas partes:
A primeira parte é o corpo e a segunda o dígito verificador.
O cálculo básico é o seguinte:Imagine que você tem o seguinte código 2003715-5. Neste
caso o corpo seria o numero 2003715 e o dígito 5.
Para verificarmos se o dígito está correto façamos o seguinte:
1 - Pegue o corpo e multiplique pelos pesos. Estes pesos sãocriados na seqüência de 2 até 9 em ordem decrescente. Veja atabela a seguir:
Calculando oCalculando oCalculando oCalculando oCalculando oDígito VerificadorDígito VerificadorDígito VerificadorDígito VerificadorDígito Verificador
Tabela 1: Exemplo do calculo.
oproC 2 0 0 3 7 1 5
soseP 8 7 6 5 4 3 2
odatluseR 61 0 0 51 82 3 01
Por Claudinei Rodrigues – [email protected]
2 - Agora some os resultados:
16 + 0 + 0 + 15 + 28 + 3 + 10 = 72
3) Agora calcule o modulo 11 desse resultado: 72 mod 11 = 6
4) Subtraia o resultado de 11: 11 - 6 = 5
O resultado do cálculo é 5. Ou seja, igual ao dígito do códigomencionado anteriormente.
Em alguns casos não é possível utilizar o módulo 11. Paraalguns documentos existem órgãos que definem os cálculos paraseus documentos, tratando-os de forma diferente.
Por exemplo, utilizando o cálculo acima quando o resto for 0ou 1, o dígito será 11 ou 10, então alguns orgãos decidem que odígito seja 0, 1 ou alguma letra.
Muitos códigos como, por exemplo, inscrições estaduais, usamrotinas bem diferentes desta que estamos utilizando neste artigo.
Existem códigos onde são necessários dois cálculos.
O primeiro dígito encontrado se soma ao corpo e para se obtero segundo dígito, que são os casos do CPF e CGC.
Agora chega de teoria e vamos para prática.
Chame o Delphi e inclua no Form1 um componente TEdit eum componente TButton como mostra a figura 1.
DelphiDelphiDelphiDelphiDelphi
MeGAZINEMeGAZINEMeGAZINEMeGAZINEMeGAZINE2 02 02 02 02 0
DelphiDelphiDelphiDelphiDelphi
Figura 1: Exemplo de como ficará o form.
Agora vá até o unit do seu form e digite a rotina, mostradana Listagem 1, que fará o cálculo do dígito verificador.
// Função que calcula o dígito verificador
function Calcula_Dígito( codigo : string ):String;
var
SR, Resto, R, I, Dígito : Integer;
Peso : string;
begin
// Esta linha remove o ponto caso existe algum no
código
Codigo :=
StringReplace(Codigo,’.’,’’,[rfReplaceAll]);
// Esta linha remove a virgula caso exista alguma
no código
Codigo :=
StringReplace(Codigo,’,’,’’,[rfReplaceAll]);
// Esta linha remove o traço caso exista algum no
código
Codigo := StringReplace(Codigo,’-
’,’’,[rfReplaceAll]);
// Esta linha remove os espaços em branco caso
exista algum no código
Codigo := StringReplace(Codigo,’
‘,’’,[rfReplaceAll]);
// Aqui informamos o peso de cada dígito. Aqui
estamos trabalhando
// com sete dígitos. A quantidade de dígitos
utilizada na variável
// peso deve ser igual a quantidade de dígitos
existente na variável
// código.
Peso := ‘8765432’;
// Aqui vamos montar um for para ler todos os
dígitos da variável código
for i := 01 to Length( Codigo ) do
begin
// Agora vamos fazer o cálculo de cada dígito
do código
// com o seu respectivo peso.
R := (StrToInt(Codigo[I]) *
StrToInt(Peso[I]));
// Aqui vamos armazenar a soma do resultado da
multiplicação
// de cada dígito do codigo com o seu
respectivo peso
SR := SR + R;
end;
// Aqui vamos pegar o resto da divisão da soma dos
resultados
Resto := SR mod 11;
// Aqui vamos pegar o dígito
Dígito := 11 - Resto;
Result := IntToStr(Dígito);
end;
Listagem 1: Rotina de cálculo do dígito verificador
Como você pode observar na rotina mostrada na listagem 1,eu tentei explicar detalhadamente o que faz cada linha.
Para que possamos testar esta rotina, inclua o código abaixono evento OnClick do componente Button, como mostrado nalistagem 2.
procedure TForm1.Button1Click(Sender: TObject);
begin
ShowMessage(‘O dígito é ‘+ Calcula_Dígito(
Edit1.Text ));
end;
Listagem 2: Mostra como chamar a nossa rotina
Para que este exemplo funcione corretamente, não informe odígito verificador no componente Edit. Ou seja, digite apenas onumero 2003715. Pois a intenção deste artigo é mostrar como secalcula o dígito verificador. Como já sabemos qual é o dígito destecódigo fica muito fácil de sabermos se a nossa função está ou nãofuncionando.
ConclusãoEspero ter esclarecido ao menos um pouco sobre como fazer o
cálculo do dígito verificador. Com base neste exemplo você poderáentender melhor os outros tipos de cálculos de dígito verificador.Aproveito mais uma vez lhe avisar que se você tem algumassunto que gostaria que fosse publicado em nossa revista, sinta-se a vontade de enviar um e-mail para [email protected] participação é muito importante para nós.
Download: http://www.theclub.com.br/revista/download/dv106.zip
MeGAZINEMeGAZINEMeGAZINEMeGAZINEMeGAZINE 2 12 12 12 12 1
O tipo Record é uma estrutura de dados do Delphi que podemisturar vários tipos de variáveis. Vamos supor que você precisearmazenar em uma variável algumas informações como o código,nome e salário de um funcionário. A primeira idéia seria criaruma array tridimencional. Mas existe um problema. O arrayteria que ser de apenas um tipo ou seja, do tipo string. Se vocêprecisar, por exemplo, fazer algum cálculo com o salário você teráque converter a variável de string para double.. O tipo Recordpode lhe auxiliar muito neste sentido.
Vamos agora a estrutura do tipo Record.
type
TFuncionario = Record
Codigo : string;
Nome : string;
Salario : double;
end;
Como você pode ver, uma estrutura de dados do tipo Recordpode misturar vários tipos de variáveis. Cada item, é como umavariável, consistindo de nome e tipo.
O tipo TFuncionario contém três itens, o Codigo e o Nome dotipo string e o Salario do tipo Double.
Agora que já temos o tipo Record definido, vamos criar umavariável do tipo Record. Aliás, você pode criar quantas variáveisdo tipo Record forem necessárias. Vale lembrar que a declaraçãoTFuncionario não aloca nenhuma informação na memória paraCodigo, Nome e Salario.
Para instanciar o tipo TFuncionario nós podemos criar umavariável da seguinte forma:
Var
Adm : TFuncionario;
Prod : TFuncionario;
Agora para ter acesso a cada item de cada variável queacabamos de criar, basta colocar o nome da variável seguindo deponto, por exemplo:
Adm.Codigo := ‘000001’;
Adm.Nome := ‘José da Siva’;
Utilizando o tipoUtilizando o tipoUtilizando o tipoUtilizando o tipoUtilizando o tipoRecord.Record.Record.Record.Record.
DelphiDelphiDelphiDelphiDelphi
MeGAZINEMeGAZINEMeGAZINEMeGAZINEMeGAZINE2 22 22 22 22 2
Adm.Salario := 1500;
Prod.Codigo := ‘000156’;
Prod.Nome := ‘Antonio da Conceição’;
Prod.Salario := 3000;
Como você pôde ver é bem simples. Um outro recurso quetemos disponível neste caso é a utilização do operador with, vejacomo é simples.
with Adm do
begin
Codigo := ‘000001’;
Nome := ‘José da Siva’;
Salario := 1500;
end;
with Prod do
begin
Codigo := ‘000156’;
Nome := ‘Antonio da Conceição’;
Salario := 3000;
end;
Se você quiser é possível copiar todo o conteúdo da variávelAdm para a variável Prod da seguinte forma:
Prod := Adm;
ArraysComo o tipo TFuncionario trabalha como qualquer outro tipo
do Delphi, nós podemos declarar um array deste tipo, por exemplo
var Empresa : array[1..50] of TFuncionario;
Para acessar o décimo elemento deste array você pode fazerda seguinte forma:
with Empresa[10] do
begin
Codigo := ‘000025’;
Nome := ‘Antonio Ribeiro’;
Salario := 8000;
end;
Ou, por exemplo, montar um contador para mostrar osnomes contidos neste array:
var i : integer;
for i := 1 to 50 do
ShowMessage(Empresa[i].Nome);
Como foi dito anteriormente que o tipo Record trabalha comoqualquer outro tipo do Delphi, nós podemos ir ainda mais além.Você pode criar um tipo Record dentro de outro Record. Veja.
type
TDepartamento = record
Codigo : string;
Func : TFuncionario;
end;
Para preencher todas as informações necessárias deste novoRecord basta você seguir a mesma regra.
Veja como fazer:
var Depto : TDepartamento;
Depto.Codigo := ‘000001’;
Depto.Func.Codigo := ‘000101’;
Depto.Func.Nome := ‘Antonio da Silva’;
Depto.Func.Salario := 3500;
Considerações finais
O tipo Record pode ter uma parte variante. Esta partevariante pode ser usada, por exemplo, quando você quer criar umtipo Record que tenha campos de tipos diferentes de dados, masnós sabemos que não precisaremos usar todos os campos em umainstancia simples do Record.
Na próxima edição nós vamos falar mais sobre este assunto.Até lá.
DelphiDelphiDelphiDelphiDelphi
MeGAZINEMeGAZINEMeGAZINEMeGAZINEMeGAZINE 2 32 32 32 32 3
Como exportar tabelas através do ADO, parte II.Exportando dados de um arquivo TXT para o
Access.
Errata:Na revista anterior publicamos a primeira parte desta dicaexportando para Paradox, Excel E HTML, mas infelizmentea rotina saiu com erro de impressão. Sendo assim a seguirpublicaremos novamente a rotina da última revista:
var
Path: string;
begin
Path := ExtractFilePath(Application.ExeName);
{ Exportar dados para Paradox }
ADOConnection1.Execute(‘SELECT * INTO Clientes IN
“‘ + Path + ‘“ “Paradox 7.x;” FROM CLIENTES’);
{ Exportar dados para o Excel }
ADOConnection1.Execute(‘SELECT * INTO Clientes IN
“‘ + Path + ‘clientes.xls” “Excel 8.0;” FROM
CLIENTES’);
{ Exportar dados para o html }
ADOConnection1.Execute(‘SELECT * INTO
[Clientes.htm] IN “‘ + Path + ‘“ “HTML Export;”
FROM CLIENTES’);
end;
Exportando para Paradox, Excel e HTML
Exportando dados de um arquivo TXT para oAccess.
Para fazermos a exportação dos dados do TXT para o Accessprimeiramente iremos preparar o arquivo TXT para que omesmo fique visível como uma tabela, isso é, que seus dadosfiquem separados por colunas.
Para isso criaremos um arquivo chamado Schema.ini ondeindicaremos a estrutura do nosso arquivo TXT.
[Pessoal.txt]
ColNameHeader=True
Format=Delimited(;)
Col1=Empresa Char Width 4
Col2=Area_RH Char Width 4
Col3=Sub-Area Char Width 4
Col4=N.Pessoal Char Width 8
Col5=Nome Char Width 30
Col6=Cargo float
Col7=Descricao Char Width 20
Col8=Subordinacao Char Width 6
Col9=Descricao Char Width 30
Estrutura do arquivo Schema.ini criado para o arquivoPessoal.txt
Estando com o arquivo TXT e o arquivo .INI prontos, agorapodemos criar a string de conexão no componenteADOConnection para acessar o TXT usando o Jet.
Para isso iremos selecionar como Provider o Jet.OLEDB e noDataSource devemos somente indicar o caminho onde seencontra o arquivo TXT.
Dicas & TDicas & TDicas & TDicas & TDicas & Truquesruquesruquesruquesruques
MeGAZINEMeGAZINEMeGAZINEMeGAZINEMeGAZINE2 42 42 42 42 4
A string de conexão ficará da seguinte forma:
Provider=Microsoft.Jet.OLEDB.4.0;Data
Source=D:\Exemplos\ADO – LER ARQUIVO
TXT\ARQUIVOS\;Mode=Read;Extended
Properties=Text;Persist Security Info=False
Criada a string de conexão agora temos que montar ainstrução para exportar os dados do arquivo TXT para o arquivoMDB, sendo assim montaremos a instrução de exportação daseguinte forma:
var Path : String;
begin
Path := ExtractFilePath
(Application.ExeName);
ADOConnection1.Execute(‘SELECT * INTO
Pessoal IN “‘+Path+’Novo.MDB” “Jet
2.x;” FROM PESSOAL.TXT’);
end;
Exportando dados do arquivo TXT para oAccess
Neste momento se você fez o teste recebeuuma mensagem indicando que o arquivoNovo.MDB não foi encontrado, isso ocorreporque a exportação criará somente a tabela comos dados e essa tabela deve ser criada dentro deum arquivo MDB, portanto antes da exportaçãotemos que criar o arquivo .MDB, mesmo quevazio, e para isso utilizaremos outro componentechamado AccessApplication, da aba Servers.
Após incluir o componente AccessApplication no formpodemos complementar a nossa rotina de exportação incluindo ainstrução para criar o arquivo MDB.
Abaixo segue as instruções para criar o arquivo .MDB vazio edepois exportamos os dados do arquivo TXT para esse MDB.
procedure TForm1.Button2Click(Sender: TObject);
var Path : String;
begin
// Nome do arquivo TXT de origem dos dados,
Pessoal.txt
// Nome do arquivo INI contendo a estrutura do
arquivo txt, Schema.ini
// Nome do arquivo MDB a ser criado, Novo.MDB
// Nome da tabela que será criada dentro do MDB,
Dados
Path :=
ExtractFilePath(Application.ExeName)+’ARQUIVOS\’;
{ Cria o MDB via programação usando o componente da
Pasta Servers }
AccessApplication1.Connect;
AccessApplication1.NewCurrentDatabase(Path+’Novo.MDB’);
AccessApplication1.Disconnect;
{ Exporta os dados do TXT para o MDB criando a
tabela dentro do MDB }
ADOConnection1.Execute(‘SELECT * INTO Dados IN
“‘+Path+’Novo.MDB” “Jet 2.x;” FROM PESSOAL.TXT’);
end;
O projeto de exemplo pode ser baixado em nosso site noseguinte link:
http://www.theclub.com.br/revista/download/ADO_TXTparaMDB.zip
Figura 1: Estrutura do TXT de origem dos dados
FireBird/Interbase - Retornar as tabelas Detalhesa partir da Master.
Nesta dica iremos utilizar as tabelas de sistema do bancopara verificar se uma determinada tabela tem outras tabelasligadas a ela através de Foreign Key.
A tabela Master é a PEDIDO.
select
R1.rdb$relation_name as MASTER,
R5.rdb$field_name as CAMPO_MASTER,
R3.rdb$relation_name AS DETALHE,
R4.rdb$field_name AS CAMPO_DETALHE
from RDB$RELATION_CONSTRAINTS R1
left outer join RDB$REF_CONSTRAINTS R2
on (R2.rdb$const_name_uq = R1.RDB$CONSTRAINT_NAME)
left outer join RDB$RELATION_CONSTRAINTS R3
Dicas & TDicas & TDicas & TDicas & TDicas & Truquesruquesruquesruquesruques
MeGAZINEMeGAZINEMeGAZINEMeGAZINEMeGAZINE 2 52 52 52 52 5
Dicas & TDicas & TDicas & TDicas & TDicas & Truquesruquesruquesruquesruques
Abreviando nomes
Veja a seguir como você pode abreviar um nome de formasimples. Inclua no seu form um componete TEdit e umcomponente TButton. Inclua o código abaixo no evento OnClickdo componente TButton
procedure TForm1.Button1Click(Sender: TObject);
begin
ShowMessage(AbreviaNome(Edit1.Text));
end;
Agora inclua na sua unit a rotina que faz a
abreviação de nomes.
function AbreviaNome(Nome: String): String;
var
Nomes: array[1..20] of string;
i, TotalNomes: Integer;
begin
Nome := Trim(Nome);
Result := Nome;
{Insere um espaço para garantir que todas
as letras sejam testadas}
Nome := Nome + #32;
{Pega a posição do primeiro espaço}
i := Pos(#32, Nome);
if i > 0 then
begin
TotalNomes := 0;
{Separa todos os nomes}
while i > 0 do
begin
Inc(TotalNomes);
Nomes[TotalNomes] := Copy(Nome, 1, i - 1);
Delete(Nome, 1, i);
i := Pos(#32, Nome);
end;
if TotalNomes > 2 then
begin
{Abreviar a partir do segundo nome,
exceto o último.}
for i := 2 to TotalNomes - 1 do
begin
{Contém mais de 3 letras? (ignorar
de, da, das, do, dos, etc.)}
if Length(Nomes[i]) > 3 then
{Pega apenas a primeira letra do
on (R2.rdb$constraint_name = R3.RDB$CONSTRAINT_NAME)
left outer join RDB$INDEX_SEGMENTS R4
on (R4.rdb$index_name = R3.rdb$index_name)
left outer join RDB$INDEX_SEGMENTS R5
on (R5.rdb$index_name = R1.rdb$index_name)
where (R2.rdb$constraint_name is not Null)
and R1.rdb$relation_name = ‘PEDIDO’
Neste exemplo retornaremos o nome da Tabela Master, onome do campo dessa tabela Master usado na ligação, o nome databela ligada à Master através da Foreign Key e o nome do campodessa tabela encontrada que faz parte da Foreign key.
Veja exemplo:
Master Campo_Master Detalhe Campo_detalhePEDIDO CODPEDIDO PEDITENS CODPEDIDO
FireBird/Interbase – Usando um For Select dentroda StoredProcedure
Neste exemplo iremos criar um StoredProcedure dentro dobanco
para retornar registros de duas tabelas usando para isso oFor Select.
create procedure SP_RETORNO(PCOD INTEGER)
returns (COD INTEGER, NOME VARCHAR(30),
VALOR NUMERIC(15,4))
as
begin
for select CODIGO, NOME from CLIENTES
where CODIGO = :PCOD
into :COD, :NOME do
begin
select VALOR from VALORES
where CODIGO = :COD
into :VALOR;
if ((VALOR IS NULL) or (VALOR = 0)) then
VALOR = 1;
suspend;
end
end;
Para visualizar os registros retornados destaStoredProcedure podemos fazer um Select dentro da Query,
ficando a instrução da seguinte forma:select * from SP_RETORNO( 10 )
MeGAZINEMeGAZINEMeGAZINEMeGAZINEMeGAZINE2 62 62 62 62 6
nome e coloca um ponto após.}
Nomes[i] := Nomes[i][1] + ‘.’;
end;
Result := ‘’;
for i := 1 to TotalNomes do
Result := Result + Trim
(Nomes[i]) + #32;
Result := Trim(Result);
end;
end;
end;
Agora pressione a tecla F9 para rodar o programa. Digite umnome no componente TEdit e clique no botão. Você receberá umamensagem mostrando o nome abreviado.
Criando arquivos DBF com índices compostosQuem trabalha com DBF’s já encontrou problemas para criar
índices compostos, ou seja, um índice que tenha mais de umcampo, em tempo de execução.
Isto ocorre devido a existência de um parâmetro nãodocumentado, necessário para arquivos DBF’s ixExpression queinforma o Delphi que se trata de um índice com mais de umcampo. Como trabalhar com DBF’s é comum para a maioria dosprogramadores que vem do Clipper, acho interessante solucionareste problema da melhor forma possível.
Assim a criação do índice fica para logo depois da criação databela, como mostra o segmento de código abaixo.
uses
SysUtils, WinTypes, WinProcs, Messages, Classes,
Graphics, Controls, Forms, Dialogs, StdCtrls, DB,
DBTables;
procedure TForm1.Button1Click(Sender: TObject);
var
Table1 : TTable;
begin
{ Criar arquivos }
Table1 := TTable.create(Application);
{ Cria arquivo }
with Table1 do
begin
Active := False;
DatabaseName := ‘C:\’;
TableName := ‘teste’;
TableType := ttdBASE;
with FieldDefs do
begin
Clear;
Add(‘Name1’, ftString, 20, False);
Add(‘Name2’, ftString, 20, False);
Add(‘Name3’, ftString, 20, False);
Add(‘Name4’, ftString, 20, False);
end;
CreateTable;
AddIndex(‘Indice1’, ‘Name1 + Name2’,
[ixExpression]);
AddIndex(‘Indice2’, ‘Name2 + Name3’,
[ixExpression]);
AddIndex(‘Indice3’, ‘Name3 + Name4’,
[ixExpression]);
end;
end;
Na prática, criar os índices com AddIndex() logo apósCreateTable, não vai influenciar em nada o seu programa.
Colocar uma ProgressBar numa StatusBar
Coloque uma StatusBar no form.Adicione dois painéis na StatusBar (propriedade Panels).Ajuste as propriedades do primeiro painel conforme abaixo:Style = psOwnerDrawWidth = 150Coloque uma ProgressBar no form e mude sua propriedadeVisible para false.No evento OnDrawPanel da StatusBar digite o código abaixo:
procedure TForm1.StatusBar1DrawPanel(StatusBar:
TStatusBar;
Panel: TStatusPanel; const Rect: TRect);
begin
{ Se for o primeiro painel... }
if Panel.Index = 0 then
begin
{ Ajusta a tamanho da ProgressBar de acordo
com o tamanho do painel }
ProgressBar1.Width := Rect.Right -
Rect.Left +1;
ProgressBar1.Height := Rect.Bottom -
Rect.Top +1;
{ Pinta a ProgressBar no DC
(device-context) da StatusBar }
ProgressBar1.PaintTo(StatusBar.Canvas.Handle,
Rect.Left, Rect.Top);
end;
end;
Dicas & TDicas & TDicas & TDicas & TDicas & Truquesruquesruquesruquesruques
MeGAZINEMeGAZINEMeGAZINEMeGAZINEMeGAZINE 2 72 72 72 72 7
Coloque um Button no form
Digite no evento OnClick do Button o código abaixo:
procedure TForm1.Button1Click(Sender: TObject);
var
I: integer;
begin
for I := ProgressBar1.Min to ProgressBar1.Max do
begin
{ Atualiza a posição da ProgressBar }
ProgressBar1.Position := I;
{ Repinta a StatusBar para forçar a
atualização visual }
StatusBar1.Repaint;
{ Aguarda 50 milisegundos }
Sleep(50);
end;
{ Aguarde 500 milisegundos }
Sleep(500);
{ Reseta (zera) a ProgressBar }
ProgressBar1.Position := ProgressBar1.Min;
{ Repinta a StatusBar para forçar a
atualização visual }
StatusBar1.Repaint;
end;
Execute e clique no botão para ver o resultado.
Como mover um componente em Run-timePara montar este exemplo vamos incluir um componente
Button. Para testar este exemplo mantenha a tecla CTRLpressionada clique com o mouse sobre o componente Button earraste-o para qualquer lugar do form.
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes,
Graphics, Controls, Forms, Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1MouseDown(Sender: TObject;
Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure Button1MouseMove(Sender: TObject;
Shift: TShiftState; X,
Y: Integer);
procedure Button1MouseUp(Sender: TObject;
Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
private
{ Private declarations }
public
{ Public declarations }
MouseDownSpot : TPoint;
Capturing : bool;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
// Evento OnMouseDown do botão
procedure TForm1.Button1MouseDown(Sender: TObject;
Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if ssCtrl in Shift then
begin
SetCapture(Button1.Handle);
Capturing := true;
MouseDownSpot.X := x;
MouseDownSpot.Y := Y;
end;
end;
// Evento OnMouseMove do botão
procedure TForm1.Button1MouseMove(Sender: TObject;
Shift: TShiftState; X,
Y: Integer);
begin
if Capturing then
begin
Button1.Left:= Button1.Left-
(MouseDownSpot.x-x);
Button1.Top:= Button1.Top -
(MouseDownSpot.y-y);
end;
end;
// Evento OnMouseUp do botão
Dicas & TDicas & TDicas & TDicas & TDicas & Truquesruquesruquesruquesruques
MeGAZINEMeGAZINEMeGAZINEMeGAZINEMeGAZINE2 82 82 82 82 8
procedure TForm1.Button1MouseUp(Sender: TObject;
Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if Capturing then
begin
ReleaseCapture;
Capturing := false;
Button1.Left := Button1.Left -
(MouseDownSpot.x -x);
Button1.Top := Button1.Top -
(MouseDownSpot.y - y);
end;
end;
Veja abaixo alguns exemplos de código SQL.
Formato 01 - Pesquisa igual, maior menor, etc
procedure TForm1.BitBtn1Click(Sender: TObject);
begin
// Fecha o componente Query
Query1.Close;
// Limpa a propriedade SQL
Query1.Sql.Clear;
// Nome dos campos
Query1.Sql.Add(‘Select Teste1.Codigo,
Teste1.Nome’);
// Nome do banco de dados
Query1.Sql.Add(‘From Teste1 ‘);
// Condições do Filtro
Query1.Sql.Add(‘Where ‘);
// :Codigo1 e :Codigo2 são as variáveis que
// receberão os parâmetros.
// O nome destas variáveis não importam, pode
// ser usado qualquer nome.
Query1.Sql.Add(‘(Teste1.Codigo >= :Codigo1) and’);
Query1.Sql.Add(‘(Teste1.Codigo <= :Codigo2)’);
// Passagem do parâmetro para a variável
// criada acima
Query1.Params[0].AsString := Edit1.Text;
Query1.Params[1].AsString := Edit2.Text;
// Abre o componente Query
Query1.Open;
end;
Formato 02 - Pesquisa por parte de uma string
procedure TForm1.BitBtn1Click(Sender: TObject);
begin
// Fecha o componente Query
Query1.Close;
// Limpa a propriedade SQL
Query1.Sql.Clear;
// Nome dos campos
Query1.Sql.Add(‘Select Teste1.Codigo,
Teste1.Nome’);
// Nome do banco de dados
Query1.Sql.Add(‘From Teste1 ‘);
// Condições do Filtro
Query1.Sql.Add(‘Where ‘);
// :Nome1 é a variável que receberá o parâmetro.
// O nome desta variável não importa,
// pode ser usado qualquer nome.
Query1.Sql.Add(‘(Teste1.Nome like :Nome1) ‘);
// Passagem do parâmetro para a variável
// criada acima
Query1.Params[0].AsString := ‘%’+Edit1.Text+’%’;
// Abre o componente Query
Query1.Open;
end;
Formato 03 - Filtro de OrdemServiço e Data em branco
procedure TForm1.BitBtn1Click(Sender: TObject);
begin
// Fecha o componente Query
Query1.Close;
// Limpa a propriedade SQL
Query1.Sql.Clear;
// Nome dos campos
Query1.Sql.Add(‘Select Teste1.Codigo,
Teste1.Nome’);
// Nome do banco de dados
Query1.Sql.Add(‘From Teste1 ‘);
// Condições do Filtro
Query1.Sql.Add(‘Where ‘);
// :Var1 é a variável que receberá o parâmetro.
// O nome desta variável não importa, pode ser
// usado qualquer nome.
Query1.Sql.Add(‘(Teste1.OrdemServico=:Var1)and ‘);
// Aqui está sendo informado que o campo data
// está vazio
Query1.Sql.Add(‘(Teste1.DataServico is Null) ‘);
// Passagem do parâmetro para a variável acima
Query1.Params[0].AsString := MaskEdit5.Text;
// Abre o componente Query
Query1.Open;
end;
Dicas & TDicas & TDicas & TDicas & TDicas & Truquesruquesruquesruquesruques
MeGAZINEMeGAZINEMeGAZINEMeGAZINEMeGAZINE 2 92 92 92 92 9
Pergunta: Como saber no evento onClose do form se omesmo
foi apresentado com Show ou ShowModal?
Resposta: Para saber se o form foi chamado comoShowModal, podemos utilizar a seguinte instrução:
procedure TForm2.Button1Click(Sender: TObject);
begin
if Form2.FormState = [fsModal] then
ShowMessage(‘Form chamado como ShowModal’)
else
ShowMessage(‘Form chamado como Show’);
end;
Dúvida enviada por Paulo Geloramo – Assis – SP
Pergunta: Como tratar um conjunto de teclas em todo oprojeto ?
Resposta: Para fazer este tratamento você deve utilizar oevento OnShortCut do componente ApplicationEvents e declarara unit Menus.
Veja abaixo um exemplo que trata as teclas Shift F2
implementation
uses Menus;
{$R *.dfm}
procedure TForm1.ApplicationEvents1ShortCut(var Msg:
TWMKey;
var Handled: Boolean);
var
ShortCut: TShortCut;
ShiftState: TShiftState;
begin
ShiftState := KeyDataToShiftState(Msg.KeyData);
ShortCut := Menus.ShortCut(Msg.CharCode,
ShiftState);
if TextToShortCut(‘Shift+F2’) = ShortCut then
ShowMessage(‘Pressionou as teclas Shift+F2’);
end;
Dúvida enviada por Juarez – Capivari – SP
Resolvendo o problema de campos numéricos doOracle com o DBExpress
Dica enviada por sócioEstou migrando as aplicações da empresa do BDE para o
DBExpress utilizando o Oracle como banco de dados. Ao tentarincluir um registro numa tabela que contém campos NUMBERem sua estrutura, o evento OnReconcileError do ClientDataSetretorna a seguinte mensagem
Perguntas & RespostasPerguntas & RespostasPerguntas & RespostasPerguntas & RespostasPerguntas & Respostas
MeGAZINEMeGAZINEMeGAZINEMeGAZINEMeGAZINE3 03 03 03 03 0
“ORA 01722-Invalid Number” e o registro não é incluído.
A solução que encontrei é que se deve alterar a configuraçãodo Oracle no registro do Windows.
Alterar a chave do registro do Windows :
HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE\HOME0
de
NSL_LANG=BRAZILIANPORTUGUESE_BRAZIL.WE8ISO8859P1
para
NSL_LANG=BRAZILIANPORTUGUESE_AMERICA.WE8ISO8859P1
O erro está na forma que o Oracle está recebendo os valoresnuméricos do DBExpress trocando o símbolo de separaçãodecimal de ‘.’ por ‘,’ provocando o erro.
A solução aplicada ainda está em testes pois não sei se tereiefeitos colaterais em minhas aplicações que usam o BDE. Casoseja encontrada alguma outra solução ou encontrado algumefeito colateral, por favor entrem em contato conosco.
Informação enviada pelo sócio Marcelo Marcolongo – SãoPaulo – SP
Pergunta: Como posso validar os itens de um PickListexistente em uma coluna do DBGrid ?
Resposta: Você pode fazer esta validação no eventoOnColExit. Veja a seguir como deve ficar a sua rotina.
procedure TForm1.DBGrid1ColExit(Sender: TObject);
var
Indice : integer;
Informacao : string;
begin
// Pega o indice da coluna
Indice := DBGrid1.SelectedField.Index;
// Pega o texto da coluna
Informacao := DBGrid1.SelectedField.DisplayText;
// Verifica se a coluna tem PickList
if DBGrid1.Columns[Indice].PickList.Count > 0 then
begin
// Pesquisa a informação digitada no PickList
if DBGrid1.Columns[Indice].PickList.
IndexOf(Informacao) < 0 then
begin
ShowMessage(‘Informação inválida.’);
Abort;
end;
end;
end;
Dúvida enviado por SAMUEL DELLA SAVIA DE OLIVEIRA– São Paulo – SP
Pergunta: Possuo uma aplicação que usa ADO para seconectar a um banco SQL Server.
Tenho no sistema uma tela de lançamento de Pedidos onde,quando entro na tela dou um BeginTransaction no Banco deDados e quando finalizo o pedido dou um Commit Transaction.
Caso de algum erro, RollBack... Só que, se eu estivertrabalhando com dois computadores e nos dois emitindo pedidosao mesmo tempo, o usuário que der commit primeiro grava opedido e o outro quando der commit dá um erro dizendo queexistem registros alterados na tabela e o sistema não pode lerestes registros e cancela a operação.
Tem alguma configuração que o ADOConnection precisepara que ele controle as transações no Banco?
Resposta: O problema que ocorre é que por default todos oscampos são utilizados para localizar o registro para Update e comisso, como algum dos campos foi alterado, o registro não consegueser encontrando para ser atualizado.
Para resolver este problema bastará setar para que aatualização seja feita com base no campo chave, para isso, noevento AfterOpen do AdoTable adicione o seguinte código:
ADODataSet1.Properties[‘Update Criteria’].value :=
adCriteriaKey;
// Declarar a unit AdoInt na lista de uses.
Dúvida enviada por Gabriel Jank – Horizontina - RS
Envie-nos suas dicas para quepossamos compartilhá-las com todos
Perguntas & RespostasPerguntas & RespostasPerguntas & RespostasPerguntas & RespostasPerguntas & Respostas