Post on 22-Mar-2018
novembro 2008
novembro 2008
novembro 2008 03
LegendaIniciante
Intermediário
Avançado
Índice
Editorial
04 05
Coluna Fábio Camara
Muitas pessoas equivocadamente enten-dem que agilidade significa falta de estrutura e organização, porém ausência de estrutura e organização significa – na verdade – caos.
Uma metodoligia ágil SCRUM
Delphi
Transações com múltiplo ClientDataSet
.NET
Olá pessoal como tinha dito vamos fazer uma serie de artigos falando de LINQ, mês passado falei sobre sua teoria geral e nos aprofundamos mais no LINQ To SQL...
Linq to XML
Dicas Delphi Dicas .NET
Como Utilizar Left Join em Consultas LINQ to SQL
Abrindo um arquivo exis-tem através da aplicação
Formatando valo-res numéricos com máscara 28
30
Arquivo – Lista os arquivos e seus atributos
Arredondamento – Valores Extensos
BDE – Retorna a quantida-de Total de Registros mesmo com a tabela filtrada
Componente – Saber qual componente recebeu foco
DBChart – Salvando o conteúdo em uma Imagem JPEG/BMP
DBGrid - Colocando um CheckBox em uma coluna lógica
Delphi – Verifica se a tecla foi pres-sionada 25
09
Considerações sobre desempenho de Banco de Dados
Neste mês também tenho um artigo na re-vista, onde mostro para vocês as novidades que a Embarcadero incluiu na VCL do Delphi 2009, são novos componentes visuais, que podem dar um “toque” especial na aplicação. 19
21
Desafio The CLub
Teste seus conhe-cimentos.
Novidades na VCL do Delphi 2009 16
novembro 200804
Av. Profº Celso Ferreira da Silva, 190 Jd. Europa - Avaré - SP - CEP 18.707-150
Informações: (14) 3732-1529 Suporte: (14) 3733-1588
Internethttp://www.theclub.com.br
Cadastro: cadastro@theclub.com.brSuporte: suporte@theclub.com.br Informações: info@theclub.com.brSkype Cadastro: theclub_cadastro
Skype Suporte: theclub_linha1 theclub_linha2
Copyright The Club Megazine 2008
Diretor TécnicoMarco César Silva
Diagramação e ArteVitor M. Rodrigues
RevisãoMarcos César Silva
ColunistasAlessandro FerreiraFabiano BelmonteFellipe Capolupo
Luís Alexandre de OliveiraMarcos César SilvaMauro Sant´AnnaVictory Fernandes
Impressão e acabamento:GRILL - Gráfica e EditoraRua São Paulo, nº 447
Cep: 18740-00 - Taquarituba-SPTel. (14) 3762-1345
ReproduçãoA utilização, reprodução, apropriação, armazenamento em banco de dados, sob qualquer forma ou meio, de textos, fotos e outras criações intelectuais em cada publicação da revista “The Club Megazine” são terminantemente proibidos sem autorização escrita dos titulares dos direitos autorais.
Bem-vindo
Delphi é marca registrada da Borland International, as demais marcas citadas são registradas
pelos seus respectivos proprietários.
Marcos Césa Silva - Editor Chefemarcos@theclub.com.br
Neste mês Fabio Câmara esta de volta com o artigo “Uma metodologia ágil – SCRUM - Conceituação sobre metodologias ágeis e SCRUM”, neste artigo ele aborda esta metodologia de desenvolvimento ágil que vem en-trando no Brasil a pouco tempo embora já seja usado na América do norte a alguns anos. Na seção Delphi temos o artigo “Transações com múltiplos ClientDataSets” onde nosso consultor Luis Alexandre aborda um assunto comum no dia-a-dia de suporte, onde exemplos de controles de transações são sempre solicitados por nossos sócios.
Um artigo muito útil publicado este mês é “Considerações sobre de-sempenho de Banco de dados”, onde mostra algumas dicas simples, mas que podem fazer toda a diferença quando se diz respeito à velocidade e performance de consultas SQL em banco de dados, acredito que este artigo seja valido para do programador iniciante ate o mais experiente.
Na seção .Net Fabiano Belmonte continua com sua série de artigo sobre LINQ To SQL, onde neste mês aprofunda-se mais um pouco sobre o assunto falando de LINQ To XML, que é uma ferramenta muito útil para trabalhar com XML facilitando em muito a vida do programador.
Neste mês também tenho um artigo na revista, onde mostro para vocês as novidades que a Embarcadero incluiu na VCL do Delphi 2009, são novos componentes visuais, que podem dar um “toque” especial na aplicação.
Boa leitura a todos e até o próximo mês.
novembro 2008 05
Coluna Fábio Camara
Muitas pessoas equivocadamente enten-dem que agilidade significa falta de estrutura e organização, porém ausência de estrutura e organização significa – na verdade – caos.
Introdução
Das muitas definições sobre agi-lidade que podemos encontrar em livros, revistas e na internet, uma das que mais gosto é: _
“Agilidade é a habilidade de criar e responder a mudanças com respeito ao resultado financeiro do projeto em um turbulento ambiente de negócios. Agilidade é a habilidade de balancear flexibilidade com estabilidade”. (Highsmith, Jim. Agile Project Management, 2002)
Agilidade é uma proposta de desenvolver projetos com uma estrutura e organização “su-ficientes”. Muita estrutura e organização reduz a criatividade e a flexibilidade de suportar mu-danças, pouca estrutura e organização permeia a ineficiência e resulta em esforços maiores que os necessários.
A diferença entre caos e agilidade pode ser
Uma metodologia ágil - SCRUM
Conceituação sobre metodologias ágeis e SCRUM
verificada nos produtos resultantes. Considerando o mesmo cenário turbulento de negócios1 , nas equipes que convivem com o caos verificamos atrasos constantes, baixissíma qualidade dos sistemas, problemas com estimativas e estouro de orçamento. Nas equipes que utilizam-se de métodos ágeis percebemos entregas parciais constantes, interação com clientes para revisão de estimativas e orçamento conjuntamente com antecedência salutar ao projeto e principalmente dois pontos fundamentais: compromisso com a satisfação do cliente e responsabilidade com o resultado financeiro do projeto.
Empresas procuram métodos ágeis
As metodologias ágeis estão disponíveis desde a década passada, porém foi no ano de 2001 que houve a formalização com a assinatura do manifes-to ágil (Manifesto for Agile Software Development - http://agilemanifesto.org/).
Inicialmente houve uma desconfiança geral por parte da indústria de software, certamente impulsionada pelas diferenças aos métodos tradi-cionais e as questões das dificuldades de quebra de paradigmas por parte das pessoas. Nesta
1- O autor entende como cenário turbulento de negócios as demandas oriundas de empresas no qual a neces-sidade de prazos rápidos e a competi-tividade são predominantes como regra de sobrevivência no seu próprio mercado de atuação.
novembro 200806
as empresas de software começaram a estudar uma proposta de metodologia classificada como ágil que propõe novos métodos em substituição aos métodos praticados tradicionalmente. Este critério de escolha, que em minha opinião está suficiente-mente maduro, buscou primeiramente resolver as questões acerca da organização, distribuição e controle das atividades de um projeto de software. Eis a explicação da escolha da metodologia SCRUM pelo mercado de empresas desenvolvedoras de software.
SCRUM, muito simples de usar
A metodologia SCRUM está entrando na moda aqui no Brasil, após já haver conquistados inúmeras empresas da indústria de software na América do Norte.
Particularmente, eu considero o SCRUM uma proposta extremamente prática e honesta. Defino por prática neste contexto a facilidade de compreensão e aplicação em nosso ambiente de desenvolvimento de software. Defino por honesta a fidelidade entre a proposta do método e o resul-tado que podemos obter após aplicá-lo.
SCRUM, nome utilizado inicialmente pelos japoneses Hirotaka Takeuchi e Ikujiro Nonaka, descrevia um tipo de processo de desenvolvimento de produto utilizado no Japão.Também o nome SCRUM foi escolhido pela similaridade entre o jogo de Rugby e o tipo de desenvolvimento de produto comentado. Ambos são adaptativos, rápidos e promovem a auto-organização.
Para explicar SCRUM, utilizarei uma estratégia que foi usada pelo Ken Schwaber3 em seu livro chamado Agile Project Development with SCRUM. Na minha leitura, este é o melhor livro disponível lançado até a presente data.
Iniciando um projeto, há uma formalização de todas as coisas que se pretende fazer ou que
2- O autor define como agressivida-de neste contexto, a quantidade de pro-cedimentos que deveriam ser mudados no caso da adoção plena da metodologia ao invés da adoção de apenas alguns dos métodos propostos pela metodologia.
3- Ken Schwaber junto com Jeff Sutherland foram os formalizadores das primeiras versões de SCRUM como meto-dologia para desenvolvimento de projetos de software. Ken está trabalhando neste projeto desde o início dos anos 90.
época tornou-se bastante famosa a metodologia XP (eXtreme Programming), pois propunha sem hipocrisia uma série de métodos polêmicos, muitos deles questionáveis até hoje como por exemplo a programação em pares e o cliente ao lado do desenvolvedor durante o projeto.
Lentamente, a indústria de software impul-sionada pela necessidade de obter resultados diferentes dos obtidos pelos métodos tradicionais, verificou que pessoas válidas estavam propondo métodos sérios e factíveis. Desta forma, determi-nadas práticas ágeis começaram a ser utilizadas em projetos de software sem a agressividade2 pela adoção plena de uma metodologia ágil.
Alguns destes métodos, compreendidos de forma inadequada, causavam uma dificuldade de percepção dos resultados. Um ótimo exemplo disto é a iteração. A iteração, que em tradução simples quer dizer repetição, foi confundida com “interação” em alguns casos, e pela tradução simples definida como repetição. Na verdadeira definição ágil, iteração está mais para processos confiáveis do que processos repetíveis. Na lingua inglesa também verificamos este desentendimento quando estudamos em textos ágeis as palavras “repeatable” e “reliable”.
A confusão entre confiável e repetível acontece porque muitos gestores de empresas gostam de formalizar processos muito estruturados e preci-sos (repetíveis) no lugar de formalizar processos suficientemente estruturados e flexíveis (confiá-veis). Processos repetíveis focam na entrada das atividades, processos confiáveis focam no resultado das atividades.
Outros métodos, por oferecerem propostas mais simples de compreensão e apuração de resul-tado, começaram a chamar a atenção positivamen-te da indústria de software. Face a isso, iniciou-se um movimento liderado pelas universidades no Brasil (hoje sou consultor de metodologias ágeis da USP) que objetiva esclarecer os métodos e gerar conteúdos práticos que facilitem a implantação de tais propostas metodológicas.
Certificadas de que estes métodos funcionam,
novembro 2008 07
se precisar construir no projeto. Cada item desta lista representa um requisito funcional, ou requi-sito não funcional, ou questão de tecnologia / infra-estrutura. Esta lista é denominada Product Backlog.
Podemos traduzir Product Backlog como uma lista de todos os requisitos de um produto prioriza-dos, ou, em outras palavras, é qualquer coisa que represente um trabalho que precisa ser feito para o produto. Os itens com maior prioridade nesta lista são os requisitos mais desejados pelo produto. No projeto real, o Product Backlog nunca é finalizado. Existe uma natural evolução e maturidade dos requisitos nesta lista. Requisitos novos podem aparecer, requisitos existentes podem perder prioridade e podem até serem eliminados. Apesar de se permitir que áreas usuárias manifestem seus pedidos nesta lista, somente o Product Owner pode priorizar o Backlog.
O Product Owner possui a responsabilidade de definir a ordem que os requisitos serão produzidos pela equipe de desenvolvimento. Esta equipe deve ser pequena, multi-disciplinar e capaz de desenvol-ver todos os requisitos. Esta equipe recebe o nome de SCRUM Teams. A preparação dos trabalhos é denominada SPRINT Planning.
SPRINT Planning é composta dos seguintes ingredientes: Product Backlog, a capacidade de de-senvolvimento da equipe, as condições e exigências do negócio, as características da tecnologia a ser usada e o comprometimento em entregar produtos executáveis incrementais. A mistura são revisões, administração e organização. Os resultados são SPRINT Goal e SPRINT.
O SCRUM Team deve desenvolver os itens se-parados pelo Product Owner em um determinado prazo previamente combinado. Este prazo é defi-nido como Time Box e o trabalho de desenvolver os itens separados neste time box é denominado SPRINT. Estes itens separados do Product Backlog fazem parte de uma nova lista. Esta lista, chamada SPRINT Backlog, será de total responsabilidade do SCRUM Team que deverá mantê-la e organizá-la de tal forma a atender os objetivos do específico SPRINT.
É permitido ter mais de um SCRUM Team tra-balhando no mesmo Product Backlog, por isso os requisitos são devidamente separados em SPRINT Backlog distintos por equipe.
A liderança destas equipes é exercida por um papel denominado SCRUM Master. O SCRUM Master é um facilitador da gestão dos requisitos e direcionador da gestão das equipes. Este papel deve garantir a correta utilização das práticas de
SCRUM, deve ajudar a equipe a tomar decisões e apoiar a equipe para adquirir os recursos necessá-rios para o desenvolvimento do produto.
Este método de liderança é exercido através de 3 recorrentes tipos de reunião: SCRUM Daily Mee-ting, SPRINT Review e Retrospective. Começando pelo SPRINT Review que é a reunião típica de final de SPRINT (alguns SCRUM Team também a fazem no meio do SPRINT) para validar o produto execu-tável que a equipe conseguiu incrementar.
Explicando a Retrospective, é uma reunião que também acontece ao final do SPRINT com o objeti-vo de fortalecer a unidade de ação da equipe. Três perguntas deverão ser respondidas com seriedade por todos os membros do SCRUM Team:
1- O que você fez e gostou neste SPRINT?
2- O que você fez e não gostou neste SPRINT?
3- O que você vai fazer diferente no próxi-mo SPRINT?
O desenvolvimento de projetos de software é um desafio constante, é uma atividade complexa. Todo processo complexo exige uma intensa co-municação entre todos os membros do projeto. SCRUM Daily Meeting é a resposta para promover a comunicação da equipe.
Todos os dias, obrigatoriamente, todo o SCRUM Team irá se reunir por 15 minutos apro-ximadamente para responder a 3 importantes perguntas. Sugerimos que está reunião seja de
pé, pois temos verificado bons resultados em nossas práticas.
As perguntas são:
1- O que eu fiz desde a última SCRUM Daily Meeting até agora?
2- O que eu vou fazer hoje?3- O que pode me impedir?
Adicionalmente as técnicas apresentadas neste artigo, temos observado que a utilização de KANBAN (ver figura abaixo) ajuda a maximizar o compromentimento da equipe e a comunicação de todos os comprometidos e envolvidos com o projeto.
Observe a Figura 1 – Nossa implementação
de KANBAN na empresa REPOM dirigida pelo SCRUM Master Marcelo Martins. As cores amarela e laranja representam diferentes complexidades das atividades. A cor pink representa atividades não planejadas no SPRINT que foram incluídas por motivo de força maior.
Por se tratar de um extenso assunto, aborda-remos detalhes explicativos sobre o que é KANBAN e como se utiliza em projetos de software no nosso próximo artigo técnico.
Para saber mais recomendamos os livros:
- Agile Project Management by Jim Highs-
Figura 1
novembro 200808
Sobre o autor
mith.- Agile Software Development with SCRUM by
Ken Schwaber e Mike Beedle.- Agile Project Management with SCRUM by
Ken Schwaber. - Treinamento MSF Agile + SCRUM + Agile
Methods em http://www.fcamara.com.br
Considerações Finais
Nós, praticantes das metodologias ágeis, acreditamos que todos os projetos são diferentes. A tecnologia destes projetos são diferentes. As pessoas, os requisitos idem. Nós não queremos ser indivíduos críticos do que existe há muito tempo na engenharia de software, nós queremos sugerir, proporcionar e fundamentar alternativas novas para resolver problemas antigos.
Na grande maioria das consultorias que minis-tro sob a titulação de “coaching” para fins de cresci-mento dos resultados qualitativos e produtivos de equipes de desenvolvimento de software, encontro
Fábio Câmara (fabio.camara@vstsrocks.com.br): é consultor e implanta metodologias, processos para equipes de desenvolvimento e ferramentas para automação de ciclo de vida de desenvolvimento de software. Seus tra-balhos podem ser verificados no site http://www.fcamara.com.br .Possui o título Micro-soft MVP para a ferramenta Visual Studio Team System e possui os certificados SCRUM Master, MSF Practitioner, ITIL Foundations e MCTS – Team Foundation Server.
4- STV foi um termo criado em uma de minhas reuniões de trabalho com os profissionais da USP, quando queríamos definir aspectos pessoais motivadores para incentivar a adoção de nossas pro-postas de métodos ágeis na instituição de ensino. O slogan ficou: Combata a STV com agilidade no seu dia-a-dia.
5- Defino por adequação mental neste contexto, a responsabilidade com o questionamento de seus próprios paradigmas. É necessária uma mudança de comportamento e uma revisão de valores.
pessoas que utilizando-se de métodos tradicionais ou simplesmente de improviso diário (também denominado “ausência de métodos”) revelam-me uma estranha e frustante sensação – A Síndrome do Trabalho Vazio.
A STV4 é a sensação que ocorre depois de um intenso dia de trabalho repleto de aborrecimentos e de atividades urgentes, quando percebe-se que no final todas as atividades planejadas para aque-le dia não puderam ser implementadas. É uma constatação que se é uma espécie de marionete do tempo, da empresa e dos clientes.
A utilização de métodos ágeis, com a adequa-ção mental5 conforme os princípios estabelecidos pelas metodologias ágeis, mudaram minha vida profissional perante o cenário anteriormente descrito. Eu consigo fazer atividades planejadas, consigo priorizar atividades importantes e tenho um pequeno índice de atividades urgentes no meu dia-a-dia. Eu me sinto protagonista do meu dia.
As metodologias ágeis são uma positiva proposta para as empresas desgastadas com os resultados proporcionados por “waterfall approach to software development” ou pela ausência de métodos. Para iniciantes em metodologias ágeis, eu recomendo o SCRUM. Para praticantes de métodos ágeis que não conhecem o SCRUM, permitam-se mais uma evolução.
Sucesso em seus projetos.
novembro 2008 09
Delphi
Muito dos associados nos tem questio-nado como proceder com transações em firebird.
Antes de tudo, vamos partir para uma abordagem conceitual.
TRANSAÇÃO
É um conjunto de procedimentos que é exe-cutado num banco de dados, que para o usuário é visto como uma única ação.
Exemplo:
• A transferência de fundos de uma conta corrente pra uma conta poupança é uma operação única do ponto de vista do cliente, porém, dentro de sistemas de banco de dados, ela envolve várias operações.
• É essencial que todo o conjunto de operações seja concluído, ou que, no caso de uma falha, nenhuma delas ocorra.
• Essas operações, que formam uma única unidade lógica de trabalho são
Transações com múltiplos
ClientDataSets chamadas de transações.
Portanto Um SGBD precisa:
• Garantir que a execução da transação seja completa;
• Administrar a execução simultânea de várias transações evitando inconsistências;
• Uma transação que calcula o total de dinheiro do cliente poderia trabalhar com o saldo da conta corrente antes do débito feito pela tran-sação de transferência e, também, verificar o saldo da poupança depois do crédito. Com isso, obteria um resultado incorreto.
A integridade de uma transação depende de 4 propriedades:
Atomicidade
Trata o trabalho como parte indivisível (atômi-co). A transação deve ter todas as suas operações executadas em caso de sucesso ou nenhum resulta-do de alguma operação refletido sobre a base de dados em caso de falha. Ou seja, após o término de
uma transação (commit ou abort), a base de dados não deve refletir resultados parciais da transação. Ex: Ou todo o trabalho feito, ou nada é feito.
Consistência
Regras de integridade dos dados são assegu-radas, ou seja, as transações não podem quebrar as regras do Banco de Dados.
Isolamento
Tudo se parece como se o trabalho estivesse isolado. O resultado de uma transação executada concorrentemente a outra deve ser o mesmo que o de sua execução de forma isolada. Operações exteriores a uma dada transação jamais verão esta transação em estados intermediários.
Ex: Duas transações executadas juntas.
Transação Y altera o nome do cliente.Transação X altera o nome do mesmo clien-
te;
novembro 200810
Ao fazer insert, update ou delete enquanto a transação estiver em andamento todos os dados da tabela serão alocados para aquela transação, portanto a transação X só poderá ser executada após a conclusão da transação Y. Esta escolha é feita pelo banco de dados e ele executa primeiro uma transação depois a outra.
Uma transação só pode ser simultânea se elas não alterarem os mesmos dados.
DurabilidadeOs efeitos de uma transação em caso de
sucesso (commit) são permanentes mesmo em presença de falhas.
Operações Adicionais
Uma transação é uma unidade de trabalho atômica que é completada em sua totalidade ou nada dela deve ter efeito. Para tornar isso possível, as seguintes operações são necessárias:
StartTransaction: Denota o início da execução da transação;
Commit (confirma) ou Rollback (cancela): Denota o término de uma transação.
Abordagem prática
Vamos trabalhar com um simples cenário envolvendo as tabelas Clientes- Pedidos- Itens- Produtos. Para implementar a solução utilizei o EMS Interbase & Firebird Manager 3. Observe o script na listagem 1:
Agora vamos criar 2 generator para utilizar-mos como geradores das PKs: Gen_Id_Pedido e Gen_Id_Itens
Figura 1. Layout sugerido formulário Pedidos
Neste formulário adicionei os seguinte com-ponentes da paleta DBExpress:
• TSQLConnection - • Pedidos• TSQLDataSet o Name: sdsPedidos o CommandText: Select P.*, C.NOME
FROM PEDIDOS P LEFT OUTER JOIN CLIENTES C ON (C.ID_CLIENTE=P.ID_CLIENTE)
• TDataSetProvider –o DataSet – sdsPedidos
/* Table: CLIENTES */
CREATE TABLE CLIENTES ( ID_CLIENTE INTEGER NOT NULL, NOME VARCHAR (50) CHARACTER SET NONE COLLATE NONE, ENDERECO VARCHAR (50) CHARACTER SET NONE COLLATE NONE, BAIRRO VARCHAR (30) CHARACTER SET NONE COLLATE NONE, CIDADE VARCHAR (30) CHARACTER SET NONE COLLATE NONE, TELEFONE VARCHAR (15) CHARACTER SET NONE COLLATE NONE);
/* Primary keys definition */
ALTER TABLE CLIENTES ADD CONSTRAINT PK_CLIENTES PRIMARY KEY (ID_CLIENTE);
/* Indices definition */
CREATE UNIQUE INDEX PK_CLIENTES ON CLIENTES (ID_CLIENTE);
SET TERM ^ ;
/* Table: PEDIDOS */
CREATE TABLE PEDIDOS ( ID_PEDIDO INTEGER NOT NULL, DATA DATE, ID_CLIENTE INTEGER);
/* Primary keys definition */
ALTER TABLE PEDIDOS ADD CONSTRAINT PK_PEDIDOS PRIMARY KEY (ID_PEDIDO);
/* Foreign keys definition */
ALTER TABLE PEDIDOS ADD CONSTRAINT FK_PEDIDOS_2 FOREIGN KEY (ID_CLIENTE) REFERENCES CLIENTES (ID_CLIENTE);
/* Indices definition */
CREATE INDEX FK_PEDIDOS_2 ON PEDIDOS (ID_CLIENTE);CREATE UNIQUE INDEX PK_PEDIDOS ON PEDIDOS (ID_PEDIDO);
SET TERM ^ ;listagem 01
novembro 2008 11
o UpdateMode – upWhereKeyOnly• TclientDataSet o Name - cdsPedidoso ProviderName- dspPedidos
Configuração dos providersFlags dos Tfields do sdsPedidos
• ID_Pedido – pfinUpdate, pfinWhere, pfinKey = true . O restante marque como false.
• Data e ID_Cliente – Somente o pfinU-pdate com true, deixando o restante como false
• Nome – Todos Providers flags como false
Faço o mesmo para os providersFlags do cdsPedidos.
• Itens o TDataSource – Name: dsPedido_Itens DataSet: sdsPedidos
• TSQLDataSet o Name: sdsItens o CommandText: SELECT I.*, P.NOME
FROM ITENS I LEFT OUTER JOIN PRODUTOS P ON (P.ID_PRODUTO=I.ID_PRODUTO) WHERE I.ID_PEDIDO=:ID_PEDIDOo DataSource : dsPedido_Itens• TClientDataSet o Name: cdsItenso ProviderName- dspPedidoso DataSetField – cdsPedidossdsItens ( não
se esqueçam de carregar no cdsPedidos o TField o sdsItens para efetuar o relacionamento mestre-detalhe)
Configuração dos providersFlags dos TFields do sdsItens
• ID_Item – pfinUpdate, pfinWhere, pfinKey = true . O restante marque como false.
• ID_PEDIDO,ID_PRODUTO,QUANTIDADE – Somente o pfinUpdate com true, deixando o restante como false
• Nome – Todos Providers flags como false
/* Table: ITENS */
CREATE TABLE ITENS ( ID_ITEM INTEGER NOT NULL, ID_PEDIDO INTEGER, ID_PRODUTO SMALLINT, QUANTIDADE INTEGER);
/* Primary keys definition */
ALTER TABLE ITENS ADD CONSTRAINT PK_ITENS PRIMARY KEY (ID_ITEM);
/* Foreign keys definition */
ALTER TABLE ITENS ADD CONSTRAINT FK_ITENS_2 FOREIGN KEY (ID_PEDIDO) REFERENCES PEDIDOS (ID_PEDIDO);ALTER TABLE ITENS ADD CONSTRAINT FK_ITENS_3 FOREIGN KEY (ID_PRODUTO) REFERENCES PRODUTOS (ID_PRODUTO);
/* Indices definition */
CREATE INDEX FK_ITENS_2 ON ITENS (ID_PEDIDO);CREATE INDEX FK_ITENS_3 ON ITENS (ID_PRODUTO);CREATE UNIQUE INDEX PK_ITENS ON ITENS (ID_ITEM);
SET TERM ^ ;
/* Table: PRODUTOS */
CREATE TABLE PRODUTOS ( ID_PRODUTO INTEGER NOT NULL, NOME VARCHAR (60) CHARACTER SET NONE COLLATE NONE, ESTOQUE INTEGER);
/* Primary keys definition */
ALTER TABLE PRODUTOS ADD CONSTRAINT PK_PRODUTOS PRIMARY KEY (ID_PRODUTO);
/* Indices definition */
CREATE UNIQUE INDEX PK_PRODUTOS ON PRODUTOS (ID_PRODUTO);
listagem 01
novembro 200812
Faço o mesmo para os providersFlags do cdsItens.
• Produtos • TSQLDataSet o Name: sdsProdutos o CommandText: SELECT * FROM PRODU-
TOS• TDataSetProvider –o DataSet – dspProdutoso UpdateMode – upWhereKeyOnly• TclientDataSet o Name - cdsProdutoso ProviderName- dspProdutos
Configuração dos providersFlags dos Tfields do sdsProdutos
• ID_Produto – pfinUpdate, pfinWhere, pfinKey = true . O restante marque como false.
• Nome – Somente o pfinUpdate com true, deixando o restante como false
Faço o mesmo para os providersFlags do cdsProdutos
Faça a conexão do DBGrid_Itens com o dsI-tens.
Adicione uma variável global TD: TTran-sactionDesc; // descreve uma transação
Vamos buscar o cliente pelo código. Observem a listagem 2
Gerando numeração automática de campos
Na edição dos mês de outubro de 2005 tem um artigo que aborda como gerar numeração automática pelo dbexpress.
Observe a função na listagem 3.
Figura 1
procedure TfrmPedidos.DBEdit2Exit(Sender: TObject);var Consulta: TSQLDataSet;begin if cdsPedidos.State in [dsInsert, dsEdit] then begin Consulta := TSQLDataSet.Create(Application); Consulta.SQLConnection := Conexao; Consulta.Close; Consulta.CommandText := Format(‘select NOME from clientes where ID_CLIENTE = %d’, [StrToInt(DBEdit2.Text)]); Consulta.Open; cdsPedidosNOME.AsString := Consulta.Fields[0].AsString; end;end;
function TfrmPedidos.AutoInc(Generator: string; conexao: TSQLConnection): Integer;var SQLGen: TSQLDataSet; begin SQLGen := TSQLDataSet.Create(Application); try SQLGen.SQLConnection :=Conexao; SQLGen.CommandText := ‘Select Cast(Gen_Id(‘ + Generator + ‘,1) as Integer) as Codigo From Rdb$Database’; SQLGen.Open; Result := SQLGen.FieldByName(‘Codigo’).AsInteger; SQLGen.Close; finally SQLGen.Free; end; end;
listagem 02
listagem 03
novembro 2008 13
Crie um procedimento para fazer as opera-ções no banco de dados e um procedimento para controle dos botões na listagem 4.
No botão incluir chamamos o procedimento “Manutenção” . Listagem 5
procedure TfrmPedidos.Manutencao(Botao: Integer; DataSet: TClientDataSet);begin case Botao of 1 : begin DataSet.Append; DBEdit2.SetFocus; end; 2 : begin DataSet.Edit; DBEdit2.SetFocus; end; 3 : if MessageDlg(‘Confirma a exclusão?’, mtConfirmation, [mbYes, mbNo], 0) = mrYes then DataSet.Delete;
4 : begin if MessageDlg(‘Confirma a gravação?’, mtConfirmation, [mbYes, mbNo], 0) = mrYes then DataSet.Post; end; 5 : if MessageDlg(‘Cancelar a edição?’ , mtConfirmation, [mbYes, mbNo], 0) = mrYes then DataSet.Cancel; 7 : Close; end;
end;
procedure TfrmPedidos.dsPedidoStateChange(Sender: TObject);begin BT_Inclui.Enabled := not (dsPedido.State in [DSINSERT,DSEDIT]); BT_Alterar.Enabled := not (dsPedido.State in [DSINSERT,DSEDIT]); BT_Excluir.Enabled := not (dsPedido.State in [DSINSERT,DSEDIT]); BT_Grava.Enabled := dsPedido.State in [DSINSERT,DSEDIT]; BT_Cancela.Enabled := dsPedido.State in [DSINSERT,DSEDIT]; BT_Pesquisa.Enabled := not (dsPedido.State in [DSINSERT,DSEDIT]); BT_Sair.Enabled := not (dsPedido.State in [DSINSERT,DSEDIT]);end; listagem 04
procedure TfrmPedidos.bt_incluiClick(Sender: TObject);begin Manutencao((Sender as TSpeedButton).Tag, cdsPedidos);end; listagem 05
novembro 200814
Figura 2
Vamos criar um form para o usuário selecionar o produto e definir a quantidade. Figura 2
No evento onExit do edtCodigo fiz a se-guinte rotina para busca o produto pelo código. Listagem 6
O DataSource (dsItens) da figura 2 está ligado com o frmPedidos.cdsItens.
O DBtext1 e o DBEdit1 está ligado com o DataSource(dsItens) da figura 2.
No botão Incluir do formulário Pedidos adi-cione o seguinte script(listagem 7)
Observem que é neste momento efetuaremos a baixa no estoque
procedure TfrmItens. edtCodigo Exit(Sender: TObject);var Consulta: TSQLDataSet;begin Consulta:=TSQLDataSet.Create(Application); Consulta.SQLConnection:=frmPedidos.Conexao; Consulta.Close; Consulta.CommandText:= Format(‘select NOME from PRODUTOS where ID_PRODUTO = %d’,[StrToInt(Edit1.Text)]); Consulta.Open; frmPedidos.cdsItensNOME.AsString:=Consulta.Fields[0].AsString;end;
listagem 06
procedure TfrmPedidos.btnIncluirClick(Sender: TObject);Var Estoque:Integer;aWhere:String;aSql:String;begin frmItens := TfrmItens.Create(Self); cdsItens.Insert; if frmItens.ShowModal = mrOk then begin cdsItensQUANTIDADE.AsInteger:=strtoInt(frmItens.Edit1.text); asql:= ‘select * from Produtos’; aWhere:= format(‘ where ID_PRODUTO= %d’,[cdsItensID_PRODUTO.AsInteger]); cdsProdutos.Close; cdsProdutos.CommandText:= aSql + awhere; cdsProdutos.Open; Estoque:=cdsProdutosESTOQUE.AsInteger - cdsItensQUANTIDADE.AsInteger; cdsProdutos.Edit; cdsProdutosESTOQUE.AsInteger:=Estoque; cdsProdutos.Post; cdsItens.post; end else cdsItens.Cancel; frmItens.Free; listagem 07
novembro 2008 15
Nos eventos BeforePost dos CdsPedidos e CdsI-tens adicionem respectivamente(Listagem 8)
Para finalizar, vamos proceder a tratamento de transação explícita com múltiplos clientDataSet
No evento AfterPost do cdsPedidos . Lista-gem9
Conclusão
Vimos nesse artigo como é tranqüilo tratar transações com múltiplos ClientDatasets.
Até a próxima
procedure TfrmPedidos.cdsPedidosBeforePost(DataSet: TDataSet);begin if DataSet.State = dsInsert then DataSet.FieldByName(‘ID_PEDIDO’).AsInteger := AutoInc(‘GEN_ID_PEDIDO’, CONEXAO);end;
procedure TfrmPedidos.cdsItensBeforePost(DataSet: TDataSet);begin if DataSet.State = dsInsert then DataSet.FieldByName(‘ID_ITEM’).AsInteger := AutoInc(‘GEN_ID_ITEM’, CONEXAO);end; listagem 08
procedure TfrmPedidos.cdsPedidosAfterPost(DataSet: TDataSet);begin
try{ **** Iniciando a transação **** } TD.TransactionID := 1; // valor para transação TD.IsolationLevel:= xilReadCommitted;// Mudanças podem ser vistas por outras transações somente quando efetuadas (comitadas, commited) Conexao.StartTransaction(TD); if cdsPedidos.ApplyUpdates(0) = 0 then if cdsProdutos;ApplyUpdates(0)= 0 then Conexao.Commit(TD) except Conexao.Rollback(TD); ShowMessage(‘Erro na gravação’); end;
listagem 09
Sobre o autor
Luís Alexandre de Oliveira é Téc-nologo em Processamento de Dados ,graduado pela Faculdade de Técnologia de Sorocaba, Consultor técnico do The Club
Docente do curso técnico informática - Etec de Avaré e do curso Tecnologia em Redes de Computadores - Fatec Eduvale – Avaré
novembro 200816
Para aqueles que não tiveram a oportu-nidade de ter contato com a nova versão do Delphi, neste arquivo levo até vocês algumas das novidades na VCL do Delphi 2009, que são novos componentes visuais com recursos bas-tante interessantes e úteis no nosso dia-a-dia. Veremos agora algumas destas novidades:
TCategoryPanelGroup
O TCategoryPanelGroup é um componente com características similar a barra de ferramentas do Microsoft Outlook, neste compo-
nente incluído na paleta Additional temos panels que podem conter qualquer tipos de componente visual, ou seja este componente é uma coleção de painéis tem a principal características de ocultar e mostrar cada um de seus painéis. Este foi um recursos tão desejado e comentado a anos atrás que até foi tema de artigo do The Club em Maio de 2002, onde publicamos o artigo “Criando uma barra de ferramentas no estilo do Outlook”, http://www.theclub.com.br/REVISTA/CRIA0502B.ASPX. Agora
com este recurso incluído na paleta de componen-tes do Delphi, implementar o visual do Microsoft Outlook na sua aplicação ficou absurdamente sim-ples. Dentre os diversos recursos, podemos alterar a cor de cada panel , incluir imagens no “cabeçalho” dos painéis. Veja a imagem 1.
TButtonedEdit
O TButtonedEdit é um Edit da paleta Addi-tional que permite incluir 2 botões, um a direita e outra a esquerda do texto, aonde associado a um ImageList os botões ficam associados a cada imagem desejada. Neste componente cada um dos botões possuem o evento de clique distinto, o OnRightButtonClick e o OnLeftButtonClick. Veja imagem 2.
Imagem 2 Imagem 1
novembro 2008 17
TLinkLabel
O componente TLinkLabel da paleta Addi-tional, é um label com o recurso de incluir “tags” HTML, onde por exemplo se na propriedade cap-tion do componente colocarmos a seguinte tag HTML, teremos o efeito da imagem 3.
LinkLabel1.Caption := ‘O maior clube de programadores do Brasil: <a href="http://www.theclub.com.br">The Club</a>’;
Podemos também usar o evento OnLinkClick para chamar o navegador com o link que foi clicado, veja o código 01:
TCustomHint e TBalloonHint
A propriedade CustomHint inclusos em todos os controles da VCL, permite que cada controle
Imagem 3
implementation
uses ShellApi;
{$R *.dfm}
procedure TForm1.LinkLabel1LinkClick(Sender: TObject; const Link: string; LinkType: TSysLinkType);begin ShellExecute(Handle, ‘Open’, Pchar(link), nil, nil, sw_shownormal);end;
end.
Código 01
novembro 200818
se associe ao componente TBallonHint, que nada mais é do que um componente que permite inserir características visuais mais elaboradas ao Hint dos controle, neste caso exibindo Hint em formato de balão, veja imagem 4. Da mesma forma que o TBallonHint é herdado da classe TCustomHint, o de-senvolvedor poderá criar seu próprio componente Hint e associá-lo aos controles uma vez herdando seu componente da classe TCustomHint.
Para exibirmos imagem no balão do hint liga-remos a propriedade BalloonHint1.Images a um ImageList1 com as imagens definidas, no controle Edit por exemplo ligaremos a propriedade Edit1.CustomHint ao component e BalloonHint1, e na propriedade hint agora teremos as 3 informações, a primeira que é o título do hint, a segunda a men-sagem propriamente dita e por ultimo o índex da imagem do ImageList ligado ao BalloonHint1, veja exemplo abaixo.
Edit1.Hint := ‘Compromisso|Digite seu compromisso|2’;
Veja a Imagem 4
Imagem 4
Conclusão
Vimos apenas algumas das novidades do Delphi 2009, embora neste artigo tenhamos vis-to poucos controles, observamos a iniciativa da Embarcadero de inovar nesta nova versão. Para aqueles desejem ver de perto estas novidades sugiro que faça o download da versão Trial no site da Embarcadero o link http://cc.codegear.com/Free.aspx?id=25876.
Um grande abraço a todos.
Sobre o autor
Marcos César Silva, Consultor de Sistemas na consultoria de sistemas DataSmart e Consultor Técnico do The Club, Bacharel em Ciência da Computação, MBA em Gestão Empre-sarial, Certificações MCAD (Microsoft Certified Application Developer) e MCSD.NET (Microsoft Certified Solution Developer .NET)
novembro 2008 19
No nosso dia a dia, nos deparamos com a necessidade constante da utilização de ins-truções SQL´s, e quase sempre há necessidade de realizarmos consultas muitas vezes com-plexas, daí a necessidade de nos atentarmos quanto ao desempenho das mesmas.
Neste contexto, vamos mencionar neste arti-go, algumas cláusulas e operadores que devemos evitar seu uso, são eles:
• Operador LIKE e os coringas• Operador OR• Evitar Procedures Armazenadas (Stored
Procedures)• Clausula HAVING• Evitar Operações de classificações gran-
des
Operador LIKE e uso de Coringas
O operador LIKE é um opção extremamente útil e principalmente pela sua flexibilidade. Os Coringas são úteis na utilização de consultas para retorno de dados similares.
Assim vamos observar isto na prática:
Vamos construir três Consultas:
Considerações sobre Desempenho de Banco de Dados
Consulta 1
SELECT ID_PRODUTO, PRODUTO FROM PRODUTOSWHERE PRODUTO LIKE ‘%P%;
Consulta 2
SELECT ID_PRODUTO, PRODUTOFROM PRODUTOSWHERE PRODUTO LIKE ‘%PARAF%’;
Consulta 3
SELECT ID_PRODUTO, PRODUTOFROM PRODUTOSWHERE PRODUTO ‘PAR%’;
Veremos que as consultas retornarão resulta-dos diferentes. A primeira consulta retornará um numero muito maior de registros, assim as consul-tas numero 2 e 3, por serem mais específicas com certeza retornaram menos dados que a consulta numero 1, acelerando em muito a velocidade e filtro dos dados desejados.
Na consulta numero 3, realizamos um filtro buscando pelas três primeiras strings, assim efetuará o retorno dos dados de maneira mais
rápida e eficaz.
OPERADOR OR
Sempre que possível na construção de ins-truções SQL, devemos substituir a utilização do operador OR pelo IN, pois haverá substancial aumento na velocidade do retorno dos dados em uma query.
Vejamos um exemplo:
Consulta utilizando OR:
SELECT ID_PRODUTO, PRODUTO, TIPOFROM PRODUTOSWHERE TIPO = ‘ELETRICO’ OR TIPO = ‘HIDRAULICO’ OR TIPO = ‘ACABAMENTO’;
Realizando a mesma consulta utilizando o operador IN:
SELECT ID_PRODUTO, PRODUTO, TIPOFROM PRODUTOSWHERE TIPO IN (‘ELETRICO’ , ’HIDRAULICO’ , ’ACABAMENTO’);
novembro 200820
PROCEDURES ARMAZENADAS
Procedures Armazenadas ou simplesmente STORED PROCEDURES, somente devem ser criadas para instruções SQL´s que são executadas regular-mente, para transações ou consultas grandes.
CLAUSULA HAVING
A clausula HAVING, também é um recurso extramamente útil, mas o seu uso implica no com-prometimento no tempo de retorno de dados.
Vejamos um exemplo de utilização de HA-VING:
SELECT ID_FUNCIONARIO, FUNCIONARIO, CIDADE, SALARIOFROM FUNCIONARIOSWHERE CIDADE = ‘CAMPINAS’HAVING AVG(SALARIO) > 5000;
OPERAÇÕES DE CLASSIFICAÇÃO GRAN-DES
Grandes operações de classificação requerem
o uso de GROUP BY, ORDER BY e HAVING, assim devemos nos atentar quanto ao uso destas clau-sulas pois afetam significativamente o tempo de reposta de dados.
VARREDURAS EM TABELAS
A varredura deve ser evitada em tabelas gran-des, assim um índice é absolutamente relevante em grandes tabelas.
Assim as colunas a serem indexadas são:
• COLUNAS COM CHAVES PRIMÁRIAS (PRIMARY KEY)
• COLUNAS COM CHAVES ESTRANGEIRAS (FOREIGN KEY)
• COLUNAS COM ALTA PORCENTAGEM DE VALORES ÚNICOS
• COLUNAS UTILIZADAS PARA UNIR TA-BELAS
USO ADEQUADO DO CLAUSULA FROM NA TABELA
A alocação das tabelas na clausula FROM, pode significar um aumento considerável no desempe-nho de uma instrução SQL.
Assim listar as tabelas menores e depois as
tabelas maiores mostra-se muito mais eficiente.Exemplo:
SELECT <CAMPOS>FROM <TABELA MENOR>, <TABELA MAIOR>WHERE <CONDIÇÕES>
Salientamos que, quando falamos em desem-penho, temos que levar em conta a configuração do equipamento (Hardware) utilizado, como também o volume de registros armazenados em uma base.
Embora não seja recomendado o uso de certos
operadores e clausulas em instruções SQL, há situ-ações que infelizmente seu uso é inevitável face a situações impostas, assim neste caso teremos que sacrificarmos o desempenho.
Sobre o autor
Marco Antonio ArmandoConsultor Técnico The club
novembro 2008 21
Olá pessoal como tinha dito vamos fazer uma serie de artigos falando de LINQ, mês passado falei sobre sua teoria geral e nos aprofundamos mais no LINQ To SQL, este mês vamos falar mais sobre o LINQ To XML que uma ferramenta muito útil para trabalhar com XML, pra que já manipulou XML seja no Asp 3.0, ou ate mesmo nas versões anteriores do .NET vai notar o quando esta ferramenta facilita nossa vida.
O LINQ TO XML
O LINQ to XML é um provedor de dados LINQ que é implementado no namespace System.Xml.LINQ a partir da versão 3.5 da plataforma
.NET. Ele fornece um modelo de programação que permite ler, construir e escrever dados XML. Você
LINQ To XML
pode usar LINQ To XML para realizar consultas LINQ sobre dados no formato XML que podem ser retor-nados do arquivo de sistemas, de uma URL HTTP remota, de um web service ou partir de qualquer XML em memória existente.
O LINQ To XML fornece mais recursos e facilida-des para tratar com XML do que a API presente no namespace System.XML(XmlReader/XmlWriter) da versão anterior da plataforma .NET, sendo também mais eficiente, por usar menos memória, que a API DOM do XmlDocument fornece.
O conceito de documento XML é fundamental no DOM e os nós XML são criados no contexto do documento XML, se você desejar usar um elemen-to através de múltiplos documentos vai precisar importar os nós através do documento. O LINQ To XML simplifica essa abordagem.
No LINQ to XML você pode criar elementos XML diretamente: Ex:
XElement documentoXml = new XElement(“Clientes”);
Criando documentos XML
Para criar um arquivo XML vamos utilizar a classe XElement .Todos os atributos e elementos serão criados com os métodos SetAttributeValue e SetElementValue, para salvar o arquivo a classe disponibiliza o método Save.
Conforme o código fonte 01 adicione o método CriaXML
Veja Código Fonte 01 e 2.
Como e simples criar um arquivo XML e salva-lo no disco, note que não precisamos de nenhum outro namespace fizemos tudo pelo System.Xml.LINQ
novembro 200822
Código Fonte 01.
Código Fonte 02.
Código Fonte 03.<?XML?>
private void CriaXML() {
XElement xml = new XElement(“Clientes”, new XElement(“Cliente”, new XAttribute(“CliID”, “1”), new XElement(“Nome”, “Fabiano Belmonte”), new XElement(“Email”, “fbelmonte@etniax.com.br”) ), new XElement(“Cliente”, new XAttribute(“CliID”, “2”), new XElement(“Nome”, “Juca das Neves”), new XElement(“Email”, “juca@bol.com.br”) ) );
xml.Save(“c:\\xmlClientes.xml”); }
<?xml version=”1.0” encoding=”utf-8”?><Clientes> <Cliente CliID=”1”> <Nome>Fabiano Belmonte</Nome> <Email>fbelmonte@etniax.com.br</Email> </Cliente> <Cliente CliID=”2”> <Nome>Juca das Neves</Nome> <Email>juca@bol.com.br</Email> </Cliente></Clientes>
Veja o Resultado:
private void CarregaXml() { XElement xml = XElement.Load(“c:\\xmlClientes.xml”, LoadOptions.SetBaseUri | LoadOptions.SetLineInfo);
//Mostra o caminho base. Response.Write(“Caminho :” + xml.BaseUri);
//Mostra informações de linha IXmlLineInfo lineInfo = xml as IXmlLineInfo; Response.Write(“ <br> LineNumber “ + lineInfo.LineNumber + “e LinePosition: “ + lineInfo.LinePosition);
Carregar arquivo XML
Para carregar e selecionar valores utilizando Linq to XML podemos utilizar a classe XElement. Método Load: carregar conteúdo XML de um arqui-vo ou da memórias, em uma de suas sobrecargas podemos passar o caminho do arquivo XML , as ou-tras sobrecargas recebe como parâmetros um ob-jeto TextReader ou XmlReader.Você também pode definir opções à partir do enum LoadOptions.
O LoadOption possui quatro opções . None : todas as linhas desnecessárias,linhas em branco e linhas de informações, do arquivo XML não serão carregadas. PreserveWhitespace: essa opção defi-ne que todas as linhas em branco do arquivo XML serão preservadas. SetBaseUri : essa opção define o preenchimento da propriedade BaseUri. SetLi-neInfo: essa opção habilita o preenchimento da das informações de linha, essa informações pode ser recuperadas através da interface IXmlLineInfo.
Conforme código fonte 03 adicione o método CarregaXml
Veja Código Fonte 03.
novembro 2008 23
Código Fonte 03.
Código Fonte 04.
LIN
QAlterando valores
Para isso utilizamos todo o poder do Linq para selecionar o atributo ou elemento que desejamos alterar.
Conforme o código fonte 04 adicione o método AlterandoValores
Excluindo Valores
Agora vamos excluir um elemento de dentro de um XML, utilizaremos o mesmo conceito onde retiramos um elemento que possua o atributo passado veja como e simples.
private void AlterandoValores() { XElement xml = XElement.Load(“c:\\xmlClientes.xml”, LoadOptions.SetBaseUri | LoadOptions.SetLineInfo); IEnumerable<XElement> elements = xml.Elements();
foreach (var item in elements.Elements(“Nome”).Where(e => e.Value == “Fabiano Belmonte”)) item.Value = “Adriano Jose”;
foreach (var item in elements.Attributes(“CliID”).Where(e => e.Value == “1”)) item.Value = “12”;
//Salva Alterações xml.Save(“c:\\xmlClientes.xml”); }
//Carrega todos os elementos dentro do elemento root IEnumerable<XElement> enumerable = xml.Elements();
//Mostra todos os elementos dentro do elemento root Response.Write(“<br> Mostra todos os elementos dentro do elemento root <br>”); foreach (var item in enumerable) Response.Write(item + “<br>”);
//Mostra todos os atributos nome do elento Cliente Response.Write(“<br> Mostra todos os atributos nome do elento Cliente <br>”); foreach (var item in enumerable.Attributes(“CliID”)) Response.Write(item + “<br>”);
//Mostra todos os elementos CPF dentro do elemento Cliente Response.Write(“ <br> Mostra todos os elementos Email dentro do elemento Cliente <br> “); foreach (var item in enumerable.Elements(“Email”)) Response.Write(item + “<br>”); }
novembro 200824
Sobre o autor
Código Fonte 05.
Código Fonte 06.
Fabiano BelmonteSenior Architect da InfoMoney.com, especialista em aplicações e-Business com larga experiência em
B2B (Submarino.Com e Saraiva.Com). Trabalha há 5 anos com a tecnologia .Net, aplicando conhecimentos nas diversas áreas: instituições financeiras (sistema SPB), e-Commerce, gerenciamento logístico entre outras. Trabalhando com Visual Studio desde suas primeiras versões, responsável pela implementação de uma Metodologia de trabalho e melhoras significativas no resultados e na qualidade do time de Desen-volvimento de muitas empresas por onde passou como (Saraiva.Com) e ferramentas como TFS (Team Foundation Server).
Foi palestrante em eventos como Codificando. NET 2008 e outros eventos sobre Tecnologia .NET.Instrutor da e-TNIAX Group especialista em C#, ASP.NET e Silverlight. www.etniax.com.br
private void ExcluindoValores() { XElement xml = XElement.Load(“c:\\xmlClientes.xml”, LoadOptions.SetBaseUri | LoadOptions.SetLineInfo); IEnumerable<XElement> elements = xml.Elements();
elements.AncestorsAndSelf(“Cliente”).Where(e => e.Attribute(“CliID”).Value == “2”).Remove();
//Salva Alterações xml.Save(“c:\\xmlClientes.xml”); }
private void InsereElemento() {
XElement xml = XElement.Load(“c:\\xmlClientes.xml”, LoadOptions.SetBaseUri | LoadOptions.SetLineInfo);
XElement Newxml = new XElement( new XElement(“Cliente”, new XAttribute(“CliID”, “2”), new XElement(“Nome”, “Juca das Neves”), new XElement(“Email”, “juca@bol.com.br”) ) );
xml.Add(Newxml);
xml.Save(“c:\\xmlClientes.xml”);
}
Conforme o código fonte 05 adicione o método ExcluindoValores
Inserindo Elementos
Para inserir elementos em um XML, também e muito simples precisamos primeiramente fazer o load no XML, em seguida criar um novo elemento e adicionar no XML Conforme o código fonte 06 adicione o método InsereElemento
E isso pessoal com estes exemplos realizamos quase todas operações básicas com o LINQ.XML, com isso conseguimos ter uma idéia de o quanto e simples e fácil trabalhar com este novo elemento da FrameWork 3.5.
Espero ter ajudado.
Bons Códigos...
novembro 2008 25
Dicas DELPHI
Arquivo – Lista os arquivos e seus atributos
procedure TForm1.Button1Click(Sender: TObject);var SearchRec:TSearchRec; Result:Integer; Atributo: string;
begin Memo1.Clear; Result:=FindFirst(‘A:\*.*’, faAnyFile, SearchRec); while Result=0 do
begin case SearchRec.Attr of faReadOnly : Atributo := ‘Somente para leitura’; faHidden : Atributo := ‘Arquivo Oculto’; faSysFile : Atributo := ‘Arquivo de sistema’; faVolumeID : Atributo := ‘Identificar de volume’; faDirectory: Atributo := ‘Diretório’; faArchive : Atributo := ‘Arquivo’; faAnyFile : Atributo := ‘Qualquer arquivo’; end; Memo1.Lines.Add(SearchRec.Name+ ‘ ‘+ Atributo); if SearchRec.Attr = faHidden then
begin SearchRec.ExcludeAttr := 0; DeleteFile(‘A:\’+SearchRec.Name);
end; Result:=FindNext(SearchRec); end;end;
Arredondamento – Valores Extensos
function Decimais(nValor : Extended; Casas : Integer) : Extended;Var I, nDivisor : Integer; nFracao : Extended;Begin nDivisor := 10; if Casas > 1 then for I := 2 to Casas do nDivisor := nDivisor * 10; nFracao := Frac(nValor); nValor := Int(nValor)+Round(nFracao*nDivisor)/nDivisor; Result := nValor;end;
BDE – Retorna a quantidade Total de Registros mesmo com a tabela filtrada.
procedure TForm1.Button1Click(Sender: TObject);var Qtde : Integer;begin Check(DBIGetRecordCount(Table1.Handle,Qtde)); Caption := IntTostr(Table1.Recordcount)+’ / ‘+IntTostr(Qtde);end;
Componente – Saber qual componente recebeu foco
procedure TForm1.ProcessaMsg(var Msg: TMsg; var Handled: Boolean);var
novembro 200826
Controle : TWinControl;begin if Msg.message = WM_MOUSEMOVE then begin
Controle := FindControl(mSG.hwnd); if Controle <> nil then Caption := Controle.Name; end;end;
No Evento OnCreate do seu form utilize a rotina abaixo:procedure TForm1.FormCreate(Sender: TObject);begin Application.OnMessage := ProcessaMsg;end;
DBChart – Salvando o conteúdo em uma Imagem JPEG/BMP
Procedure TrRelGrafico04.BitBtn4Click(Sender: TObject);Var tmpW, tmpH : LongInt; B : TBitmap; J : TJPegImage; Tmp : String;Begin With SaveDialog1 do Begin FileName := ‘Grafico_Comparativo’; If Execute then With TBitmap.Create do Try Tmp := ChangeFileExt(FileName, ‘.bmp’); TmpW := DBChart1.Width; TmpH := DBChart1.Height; Width := 2 * tmpW; // width do TBitmap; Height:= 2 * tmpH; // Heigth do TBitmap;
DBChart1.BufferedDisplay:=False; // Desenhando o dbchart dentro do bitmap. DBChart1.Draw(Canvas,Rect(0,0,Width,Height)); DBChart1.BufferedDisplay:=True; SaveToFile(ChangeFileExt(FileName, ‘.bmp’)); Finally B.Free; End; If UpperCase(ExtractFileExt(SaveDialog1.FileName)) = ‘.JPG’ then Begin Try B := TBitmap.Create; B.LoadFromFile(ChangeFileExt(FileName, ‘.bmp’)); J := TJPegImage.Create; J.CompressionQuality := 100; // Qualidade: 100% J.Assign(B); //Convertendo o BMP pra JPG J.SaveToFile(FileName); Finally DeleteFile(ChangeFileExt(FileName, ‘.bmp’)); b.Free; J.Free; End; End; End;End;
DBGrid - Colocando um CheckBox em uma coluna lógica
procedure TForm1.grdExemploDrawColumnCell(Sender: TObject; const Rect: TRect; DataCol: Integer; Column: TColumn; State: TGridDrawState);
novembro 2008 27
Anuncie
conosco
Solicite um orçamento:
Skype: theclub_cadastro
E-mail: cadastro@theclub.com.br
Fone: (14) 3732-1529
Anuncie na revista e ganhe um
banner publicitário no site do The Club
begin { Desenha CheckBox } if Column.FieldName = ‘Situacao’ then begin grdExemplo.Canvas.FillRect(Rect); Imagens.Draw(grdExemplo.Canvas, Rect.Left+10, Rect.Top+1, 0); if not cdsExemploSituacao.IsNull then if cdsExemploSituacao.AsBoolean then Imagens.Draw(grdExemplo.Canvas, Rect.Left+10, Rect.Top+1, 2) else Imagens.Draw(grdExemplo.Canvas, Rect.Left+10, Rect.Top+1, 1); end;end; procedure TForm1.grdExemploCellClick(Column: TColumn);begin { Quando clicar, alterna o valor True/False } if Column.FieldName = ‘Situacao’ then begin if cdsExemplo.State = dsBrowse then cdsExemplo.Edit; cdsExemploSituacao.AsBoolean := not cdsExemploSituacao.AsBoolean; end;end; procedure TForm1.grdExemploEnter(Sender: TObject);begin { Não permite edição na célula do CheckBox } with grdExemplo do begin if SelectedField = cdsExemploSituacao then Options := Options - [dgEditing] else Options := Options + [dgEditing]; end;end;
procedure TForm1.cdsExemploNewRecord(DataSet: TDataSet);begin cdsExemploSituacao.AsBoolean := True;end;
Delphi – Verifica se a tecla foi pressionada
function GetToggleState(Key: integer): boolean;begin Result := Odd(GetKeyState(Key));end;
procedure TForm1.FormClick(Sender: TObject);begin if GetToggleState(16) then showmessage(‘Shift pressionado!’) else showmessage(‘Shift não pressionado!’);end;
novembro 200828
Dicas ASP.NET
Como Utilizar Left Join em Consultas LINQ to SQL
Ultimamente tenho recebido nos treinamentos varios alunos tem me perguntado se e possivel fazer LEFT JOIN em consultas LINQ estão resolvi escrever este pequeno artigo com um exemplo de como fazer. Espero poder abrir um caminho que os levara a consultas LINQ cada vez mais otmizadas e inteligente.
Vamos ao exemplo:
Para isso vou utilizar as tabelas de Customers e de Orders ( Clientes e Pe-didos) no Banco de Dados Northwind, adcionei um novo Cliente sem nenhum pedido, vou criar um SELECT com LEFT JOIN que me retorne todos os clientes que o nome comece com a letra(“F”) mesmo que eles não tenham registros na tabela de pedido.
NorthwindDataContext db= new NorthwindDataContext(); var query= from c in db.Customers where c.CustomerID.StartsWith("F") join o in db.Orders on c.CustomerID equals o.CustomerID into sr from x in sr.DefaultIfEmpty() select new {CustomerID= c.CustomerID, ContactName=c.ContactName, OrderID = x.OrderID == null ? -1 : x.OrderID};
Veja que eu usei o operador join into na Query o que resultou em um LEFT JOIN, Eu adcionei meu filtro no final da clausula WHERE, e retornei um tipo anonimo que contem CustomerID, ContactName, e OrderID onde -1 corresponde os clientes que não tem nenhum pedido e os que tem pedido retornamos o ID do pedido.
Veja a string SQL correspondente:
SELECT [t0].[CustomerID], [t0].[ContactName], (CASE WHEN [t1].[OrderID] IS NULL
THEN @p1 ELSE [t1].[OrderID] END) AS [value]FROM [dbo].[Customers] AS [t0]LEFT JOIN [dbo].[Orders] AS [t1] ON [t0].[CustomerID] = [t1].[CustomerID]WHERE [t0].[CustomerID] LIKE @p0
Observe como o LEFT JOIN aparece, perceba como o case reflete IF/ELSE que eu adicionei na Query acima.
Abrindo um arquivo existem através da aplicação
private void button3_Click(object sender, EventArgs e){ System.Diagnostics.Process proc = new System.Diagnostics.Process(); proc.StartInfo.FileName = “Notepad”; proc.StartInfo.Arguments = “C:\\Theclub.txt”; proc.Start(); proc.WaitForExit();}
Formatando valores numéricos com máscara
private void button1_Click(object sender, System.EventArgs e){ double Valor = 1500; label1.Text = Valor.ToString(“#,##0.00”);}
novembro 2008 29
novembro 200830
novembro 2008
novembro 2008