Visual Basic em Português

Página pessoal de Jorge Paulino sobre o Visual Basic (VB.NET, ASP.NET, VB6, VBA) e algumas noticias de tecnologia

Mostrar mensagens com a etiqueta Visual Studio 2008. Mostrar todas as mensagens
Mostrar mensagens com a etiqueta Visual Studio 2008. Mostrar todas as mensagens

Microsoft All-In-One Code Framework

A Microsoft All-In-One Code Framework é uma biblioteca de exemplos gratuitos de aplicações .NET (VB.NET, C# e C++), categorizados em diversas áreas de desenvolvimento, para as versões do Visual Studio 2008 e 2010.

Existem diversos exemplos de áreas como ASP.NET, Silverlight, Windows Azure, Office, Windows 7, Windows Forms, WPF, XML, Segurança, entre muitas outras.

A Microsoft Community Team recolhe informação de necessidades frequentes e prepara exemplos com as melhores praticas de desenvolvimento. Todos podem contribuir com pedidos de exemplos ou votando nos pedidos já efectuados.

Está disponível ainda um ficheiro *.docx com os Coding Standards utilizados nos exemplos, com algumas boas referências e bases a seguir nas aplicações.

Mais informação e downloads: http://1code.codeplex.com/
Para acompanhar as novidades pode seguir o blog: http://blogs.msdn.com/b/codefx/


VB.NET: Namespace Microsoft.VisualBasic

O Visual Basic.NET (VB.NET) é uma sucessão do Visual Basic 6.0 (VB6) e por uma questão de compatibilidade, e facilidade de migração dos programadores e das aplicações, muitas das funções e objectos, que estavam disponíveis no VB6, estão também disponíveis no VB.NET.

Estas funções e objectos estão agrupadas no namespace Microsoft.VisualBasic e fazem parte do conjunto de referências base de cada projecto, ou seja, quando é criado um novo projecto, já existe uma referência a este namespace, que poderá ser utilizado em todo o projecto.

Existem no entanto alternativas para essas funções e objectos, que estão disponíveis em alguns namespaces da plataforma .NET.

Por uma questão de boas práticas de programação é bom utilizar as funções e objectos mais recentes, pois estas são as que irão prevalecer (nunca se sabe se as outras serão descontinuadas e removidas de edições futuras).

Para desactivar esta referência do projecto e obrigar desta forma à utilização dos novos métodos (pessoalmente recomendo que se faça), pode-se fazer o seguinte:

1 - Duplo clique em My Project ou menu Project – Properties
2 - Seleccionar a TAB References. Aqui estão as referências que estão adicionadas ao projecto.

Podemos ainda, e dentro das referências, clicar em “Unused References” para verificarmos que referências não estão a ser utilizadas no nosso projecto. Isto não irá reduzir o tamanho do ficheiro mas reduzirá o número de dependências do projecto.

3 - Finalmente, nos namespaces importados para o projecto, retiramos a selecção do namespace Microsoft.VisualBasic.

Isto irá obrigar a usar as novas funções no projecto!

Além disso existem funções que estão disponíveis em diferentes namespaces e que poderão provocar alguns problemas, como é o caso de Left(), Len(), etc.

 
Alguns exemplos de conversão funções de VB6 para VB.NET

Formatar números:

        ' VB6
        Dim num As Integer = 12345
        Debug.WriteLine(Format(num, "#,00"))

        ' VB.NET
        Dim num As Integer = 12345
        Debug.WriteLine(num.ToString("#,00"))

Retirar X caracteres à esquerda:

        ' VB6
        Dim num As Integer = 12345
        Debug.WriteLine(Microsoft.VisualBasic.Left(num, 2))

        ' VB.NET
        Dim num As Integer = 12345
        Debug.WriteLine(num.ToString.Substring(0, 2))

Retirar X caracteres do meio de uma string:

        ' VB6
        Dim num As Integer = 12345
        Debug.WriteLine(Microsoft.VisualBasic.Mid(num, 1, 1))

        ' VB.NET
        Dim num As Integer = 12345
        Debug.WriteLine(num.ToString.Substring(0, 1))

Verifica qual o código ascii de um caracter:

        ' VB6
        Debug.WriteLine(Asc("A"))

        ' VB.NET
        Debug.WriteLine(Convert.ToByte("A"c))

Converte um código ascii no seu caracter:

        ' VB6
        Debug.WriteLine(Chr(65))

        ' VB.NET
        Debug.WriteLine(Convert.ToChar(65))

Mostra a data/hora actual:

        ' VB6
        Debug.WriteLine(Now.ToString)

        ' VB.NET
        Debug.WriteLine(DateTime.Now.ToString)

Mostra uma mensagem no ecrã:

        ' VB6
        MsgBox("teste!")

        ' VB.NET
        MessageBox.Show("teste!")

Converte para Inteiro:

        ' VB6
        Debug.WriteLine(CInt("123"))

        ' VB.NET
        Debug.WriteLine(Integer.Parse("123"))

Converte para String:

        ' VB6
        Dim num As Integer = 12345
        Debug.WriteLine(CStr(num))

        ' VB.NET
        Dim num As Integer = 12345
        Debug.WriteLine(num.ToString)

Verifica se uma expressão é numérica:

        ' VB6
        Dim num As String = "12345"
        If IsNumeric(num) Then
            ' verdadeiro
        End If

        ' VB.NET
        Dim num As String = "12345"
        Dim result As Integer
        If Integer.TryParse(num, result) Then
            ' verdadeiro e a variável result
            ' fica com o resultado em inteiro
        End If

Verifica se uma expressão é uma data válida:

        ' VB6
        Dim data As String = "5-2-2010"
        If IsDate(data) Then
            ' verdadeiro
        End If

        ' VB.NET
        Dim data As String = "5-2-2010"
        Dim dt As DateTime
        If DateTime.TryParse(data, dt) Then

            ' verdadeiro e a variável dt
            ' fica com o resultado como DateTime
        End If

Existem muitos mais exemplos, mas estes servem para mostrar algumas das formas de como podemos substituir as antigas funções do VB6 e começar a programar à “.NET way”

Espero que ajude!


VB.NET: Classe SqlBulkCopy

A plataforma .NET permite implementar de uma forma muito simples um BULK INSERT em uma base de dados SQL, ou seja, importar dados de uma fonte de dados (base de dados, arquivo de texto, XML, etc) e gravar numa tabela SQL. Este método é muito prático e com ganhos significativos em termos de eficiência para diversas operações como a migração de dados, inserção de muita informação, etc. Esta operação também é possível de se fazer, e para não é familiar com o termo BULK INSERT, utilizando comandos Transact-SQL.

Para mostrar como utilizar a classe SqlBulkCopy, e como pode ser útil, será mostrado um pequeno exemplo de migração de dados de Access para SQL.

Deve-se verificar se o mapeamento entre colunas está correcto (podem-se utilizar os nomes da colunas em vez do seu índice) e se o tipo de dados das colunas de origem é ser suportado nas colunas de destino (não gravar strings em integers por exemplo). Podem ser utilizadas apenas algumas colunas.

O que o seguinte código faz é ler a informação de uma tabela de Access para um DataSet (que ficará numa DataTable) e depois, usando o SqlBulkCopy, gravar essa informação na tabela de destino no SQL.

Lê a informação do Access, da tabela tblOrigem:

        Dim connStringAccess As String = _
            "Provider=Microsoft.Jet.OLEDB.4.0;" & _
            "Data Source=c:\DadosOrigem.mdb;" & _
            "Jet OLEDB:Database Password=teste;"

        ' Lê a informação da tabela do Access para um DataSet
        Dim ds As New DataSet
        Dim SQL As String = "SELECT * FROM tblOrigem"
        Using da As New OleDb.OleDbDataAdapter(SQL, connStringAccess)
            da.Fill(ds)
        End Using

Grava no SQL, na tabela tblDestino, com base na informação anterior:

        Dim connStringSQL As String = _
            "Data Source=<Servidor>;" & _
            "Integrated Security=False;" & _
            "User ID=teste;Password=teste"

        ' Cria uma ligação ao servidor SQL
        Using conn As New SqlClient.SqlConnection(connStringSQL)
            conn.Open()

            Using copy As New SqlClient.SqlBulkCopy(conn)

                ' Irá mostrar o total de registos copiados
                AddHandler copy.SqlRowsCopied, AddressOf SqlRowsCopiedEvent

                ' Faz o mapeamento das tabelas em que, por  
                ' exemplo, a coluna 2 da tabela de origem irá   
                ' ser escrita na coluna 3 da tabela de destino
                copy.ColumnMappings.Add(0, 0)
                copy.ColumnMappings.Add(1, 1)
                copy.ColumnMappings.Add(2, 3)
                copy.ColumnMappings.Add(3, 2)

                ' Indica a tabela de destino
                copy.DestinationTableName = "tblDestino"

                Try

                    ' Escreve no SQL
                    copy.WriteToServer(ds.Tables(0))

                Catch ex As Exception
                    MessageBox.Show(ex.Message)
                End Try

            End Using
        End Using

Finalmente a informação do total de registos copiados:

    Sub SqlRowsCopiedEvent(ByVal sender As Object, _
                       ByVal e As System.Data.SqlClient.SqlRowsCopiedEventArgs)

        MessageBox.Show("Registos copiados: " & e.RowsCopied.ToString)

    End Sub

Neste caso o número de registo que irá mostrar será o total, porque não foi definido um BatchSize (que indica o número de registos que irá copiar). Definindo um BatchSize (por exemplo copy.BatchSize = 100), poder-se-ia utilizar este evento para animar uma ProgressBar e mostrar a evolução do processo, sendo obviamente, o processo um pouco mais lento desta forma.

Nota: Como curiosidade, e numa migração recente em que utilizei este método, a migração de uma tabela de Access com 260.000 registo para SQL, demorou aproximadamente 6 segundos.

Mas esta classe pode ter mais aplicação, como por exemplo, inserir no SQL um grande número de registo. Pode-se criar uma tabela, carregar os dados e finalmente inserir todos os registos de uma vez (sem várias chamadas à base de dados).

Por exemplo:

        Dim dt As New DataTable("Origem")
        dt.Columns.Add("ID", GetType(Integer)).AutoIncrement = True
        dt.Columns.Add("numero", GetType(Integer))
        dt.Columns.Add("nome", GetType(String))
        dt.Columns.Add("data", GetType(DateTime))

        Dim dr As DataRow = dt.NewRow
        dr.Item("numero") = 1
        dr.Item("nome") = "Jorge Paulino"
        dr.Item("data") = DateTime.Now
        dt.Rows.Add(dr)

        Dim ds As New DataSet
        ds.Tables.Add(dt)


E depois repetir o mapeamento e a inserção usando a classe SqlBulkCopy.

Espero que ajude!


VB.NET: Utilizando o controlo Treeview

O controlo Treeview permite mostrar diversos nodes (nós) hierarquicamente, como acontece com o explorador do sistema operativo, e com isso permitir ao utilizador uma forma simples de visualizar ou seleccionar qualquer node.

Para adicionar nodes a uma Treeview, pode-se fazer em design time (utilizando o wizard) ou em run-time (utilizando código). Um exemplo simples de adicionar alguns nodes usando código é o seguinte:


    Dim node1 As TreeNode = Me.TreeView1.Nodes.Add("Fruta")
    node1.Nodes.Add("Laranja")
    node1.Nodes.Add("Maça")
    node1.Nodes.Add("Pessego")

    Dim node2 As TreeNode = Me.TreeView1.Nodes.Add("Bebidas")
    node2.Nodes.Add("Whiskey")
    node2.Nodes.Add("Moscatel")
    node2.Nodes.Add("Vodka")

Isto irá adicionar dois nodes principais (“Fruta” e “Bebidas”), e dentro desses nodes, outros subnodes (designado por child nodes). O resultado será o seguinte:

Mas quando se tem mais informação, não se pode inserir todos os nodes desta forma. É preciso guarda a informação em uma base de dados, ou em outro recurso qualquer, sendo necessário primeiro definir uma estrutura que seja adequada.

Este exemplo de estrutura é a forma mais usada e mais prática de o fazer. Um campo “ID” que é a chave-primária e com auto-numeração (Identity), uma campo designado como “dependencia” que irá fazer referência ao “ID” que queremos, e, finalmente, uma campo para a descrição.

Como se pode ver nos dados, os campos que vão aparecer na raiz têm no campo “dependencia” um 0 (zero). Os outros fazem referência ao ID base.

Mas podemos criar mais níveis hierárquicos na árvore, bastando para isso fazer referência a um “ID” qualquer e esse registo será um child node do ID indicado. Neste caso iremos adicionar algumas marcas de Whiskey.

Para finalizar o código!

É fundamental criar um método recursivo, que irá percorrer todos os itens na lista, e preencher a Treeview.

Eis um exemplo de como se pode fazer:


  Private Const connString As String = _
      "Data Source=.\SQLEXPRESS;AttachDbFilename='C:\myDB.mdf';" & _
      "Integrated Security=True;User Instance=True"

  ''' <summary>
  ''' Preenche recursivamente uma Treeview com  
  ''' informação de uma base de dados SQL
  ''' </summary>
  ''' <param name="dependenciaID">ID do node base</param>
  ''' <param name="childNode">Node anterior</param>
  Sub FillTreeViewNodes(ByVal dependenciaID As Integer, ByVal childNode As TreeNode)

    Try

      Dim SQL As String = _
          "SELECT * FROM produtos WHERE dependencia=@id ORDER BY descricao;"

      ' Ligação à base de dados (SQL)
      Using conn As New SqlConnection(connString)
        conn.Open()

        ' Define o comando e o parameter
        Using command As New SqlCommand(SQL, conn)
          command.Parameters.Add("@id", SqlDbType.Int).Value = dependenciaID

          ' Lê os dados para um SqlDataReader
          Using reader As SqlDataReader = command.ExecuteReader()

            ' Caso tenha resultados
            If reader.HasRows Then
              While reader.Read()

                Dim newNode As TreeNode = Nothing
                Dim desc As String = reader.Item("descricao").ToString()
                Dim actualID As Integer = Integer.Parse(reader.Item("ID").ToString())

                ' Verifica se é o primeiro node
                If childNode Is Nothing Then
                  newNode = New TreeNode(desc)
                  Me.TreeView1.Nodes.Add(newNode)
                Else
                  newNode = childNode.Nodes.Add(desc)
                End If

                ' Chama recursivamente o método com o ID actual
                Call FillTreeViewNodes(actualID, newNode)

              End While
            End If

          End Using 'reader

        End Using 'command

      End Using 'conn

    Catch ex As Exception
      Throw New Exception(ex.Message)
    End Try

  End Sub

Finalmente, para chamar o método criado:


    ' Preenche a Treeview, iniciando nos nodes da raiz
    Call FillTreeViewNodes(0, Nothing)

E este será o resultado:

Este artigo pretende mostrar de uma forma simples como preencher uma Treeview, através de uma função recursiva, e como criar uma estrutura numa base de dados para guardar a informação.

Espero que ajude!


VB.NET: Microsoft Reports – Formatações

Os Microsoft Reports permitem formatar diversas propriedades através da criação de expressões. Estas propriedades têm de ser alteradas desta forma, caso os resultados sejam dinâmicos, uma vez que não é possíveis de o fazer através do código. São diversas propriedades como BackgroundColor, ForeColor, BorderColor, FontFamily, FontStyle, TextAlign, etc, etc.

Tudo junto, e com algum bom gosto, podem-se criar relatórios bastante profissionais e de uma forma relativamente simples.

Quando seleccionamos algumas dessas propriedades, está disponível uma opção para construir uma expressão. Isso indica que é possível alterar essa propriedade de acordo com o resultado de um campo, com o número da linha, ou com outra condição qualquer. O resultado da expressão é uma String.

Depois, no Expression Editor, existem algumas constantes especificas para a propriedade, que escolhemos definir através de uma expressão. Neste caso a propriedade Color.

Finalmente, na expressão, podemos utilizar condições simples ou complexas. Este é um exemplo que verifica se o campo “ID1” tem o valor “AAA” e coloca a cor Gainsboro caso esta expressão seja verdadeira, e White caso seja falsa.

=IIF(Fields!ID1.Value="AAA","Gainsboro", “White")


Com algumas condições e manipulando diferentes propriedades, podemos obter resultados com este, onde um plano anual, tem diferentes cores para diferentes códigos.

Outro exemplo, e também para um plano anual, usando um objecto Table, pode-se seleccionar a TableRow e definir a seguinte expressão:

=IIF(RowNumber(Nothing) MOD 2 = 0,"White","LightBlue")

Isto fará com que as linhas tenham cores alternadas para uma mais fácil distinção.

São alguns exemplos de formatação em Microsoft Reports, que espero que ajudem a melhorar o resultado final dos relatórios.


VB.NET: Comentário numa DataGridViewCell

O Microsoft Excel permite colocar comentários nas células, de modo a guardar informações não visíveis(escondidas), mas que quando o ponteiro do rato está sobre a respectiva célula, o comentário é exibido sobre a forma de Tooltip.

Este comentário é representado por um pequeno triângulo, de cor vermelha, ao canto superior direito da célula.

A DataGridView é um controlo muito semelhante às células do Microsoft Excel, mas como é natural, esta possibilidade não está contemplada. A DataGridView não é uma folha de calculo!

No entanto, poderá ser útil, reproduzir esta funcionalidade em uma DataGridView, para guardar alguns comentários, notas pessoais, etc.

Para implementarmos este tipo de funcionalidade, podemos criar um novo tipo de coluna – DataGridViewColumnComment - e um novo tipo de célula -DataGridViewCellComment. Depois, no evento Paint(), criamos o triângulo ao canto superior direito da respectiva célula.

O resultado, será uma classe como esta:


''' <summary>
''' Cria um novo tipo de coluna
''' </summary>
<System.Diagnostics.DebuggerStepThrough()> _
Public Class DataGridViewColumnComment
    Inherits DataGridViewColumn

    Public Sub New()
        MyBase.New(New DataGridViewCellComment())
    End Sub

End Class

''' <summary>
''' Cria uma nova TextBoxCell que irá permitir
''' adicionar comentários e mostrar como ToolTipText
''' </summary>
<System.Diagnostics.DebuggerStepThrough()> _
Public Class DataGridViewCellComment
    Inherits DataGridViewTextBoxCell

    Private m_Comment As String

    ''' <summary>
    ''' Guarda a informação dos comentários
    ''' </summary>
    Public Property Comment() As String
        Get
            Return m_Comment
        End Get
        Set(ByVal value As String)
            m_Comment = value

            ' Define o texto para a tooltip
            If m_Comment IsNot Nothing AndAlso m_Comment.Length <> 0 Then
                Me.ToolTipText = m_Comment
            Else
                Me.ToolTipText = String.Empty
            End If

        End Set
    End Property


    Protected Overrides Sub Paint(ByVal graphics As System.Drawing.Graphics, _
          ByVal clipBounds As System.Drawing.Rectangle, _
          ByVal cellBounds As System.Drawing.Rectangle, _
          ByVal rowIndex As Integer, _
          ByVal cellState As System.Windows.Forms.DataGridViewElementStates, _
          ByVal value As Object, _
          ByVal formattedValue As Object, _
          ByVal errorText As String, _
          ByVal cellStyle As System.Windows.Forms.DataGridViewCellStyle, _
          ByVal advancedBorderStyle As  _
                System.Windows.Forms.DataGridViewAdvancedBorderStyle, _
          ByVal paintParts As System.Windows.Forms.DataGridViewPaintParts)

        ' Desenha a célula (processo normal)
        MyBase.Paint(graphics, clipBounds, cellBounds, rowIndex, _
                    cellState, value, formattedValue, errorText, _
                    cellStyle, advancedBorderStyle, paintParts)

        ' Caso tenha algum comentário, desenha o triângulo
        If Me.Comment IsNot Nothing AndAlso Me.Comment.Length <> 0 Then

            Dim rect As Rectangle = cellBounds
            Dim points As New List(Of Point)
            points.Add(New Point(rect.Right - 8, rect.Top))
            points.Add(New Point(rect.Right, rect.Top + 8))
            points.Add(New Point(rect.Right, rect.Top))

            graphics.FillPolygon(Brushes.Red, points.ToArray)

        End If

    End Sub

End Class

Depois, para adicionar colunas à DataGridView:

        Dim col As New DataGridViewColumnComment
        col.Name = "Nova Coluna"
        col.HeaderText = "Nova Coluna"
        Me.DataGridView1.Columns.Add(col)


Finalmente, para inserir ou remover comentários, é apenas necessário altera a propriedade Comment. Colocando qualquer String, o comentário é definido, caso contrário, é removido.

        ' Posição na DataGridView
        Dim row As Integer = 0
        Dim col As Integer = 0

        ' Converte a célula para o tipo criado
        Dim cell As DataGridViewCellComment = _
            DirectCast(Me.DataGridView1(col, row), DataGridViewCellComment)

        ' Define um comentário para a célula. Para remover era necessário
        ' apenas definir como String.Empty ou ""
        cell.Comment = "http://vbtuga.blogspot.com/"

        ' Obriga a célula, agora com comentário, a actualizar
        Me.DataGridView1.InvalidateCell(cell)


Um exemplo simples, que mostra como colocar um comentário numa célula, mas acima de tudo como podemos criar células personalizadas, e adiciona-las à DataGridView.


VB.NET: XML Literals - Parte IV (Modificar, Inserir e Eliminar)

Este é o último artigo, por agora, sobre XML Literals. Os artigos anteriores mostraram diversas coisas importantes, como por exemplo, criar um ficheiro XML, ler e pesquisar informação (usando LINQ e Lambda Expressions), mas até agora ainda não foram referidos alguns pontos essenciais para a manipulação deste tipo de ficheiros: modificação, inserção e eliminação.

Neste artigo será mostrado como fazer estas operações com base no seguinte ficheiro XML, que terá o nome “myFile.xml”

<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<!--Lista de livros e revistas>
<
library
     <
books
         <
book name="Crepúsculo"author="Stephenie Meyer" /> 
         <
book name="Equador"author="Miguel S. Tavares" /> 
         <
book name="O Sétimo Selo"author="José R. dos Santos" /> 
    </
books
    <
magazine
        <
magazineName>MSDN Magazine</magazineName>  
        <
magazineName>Code Magazine</magazineName>
     </
magazine>
</
library>

Modificar

Para modificar um ficheiro XML, depois de o ler, é apenas necessário escolher o elemento a modificar e atribuir um novo valor. De acordo com o ficheiro base, e para alterar no grupo “Magazine” de “MSDN Magazine” para outro valor, podíamos fazer:

Dim xmlFile = XDocument.Load(strFileName)
xmlFile...<magazineName>.Value = "Novo Valor"

Isto irá modificar o primeiro elemento que encontrar, uma vez que utilizamos a propriedade descendantes, que neste caso é a que pretendemos. Para modificar um elemento especifico, podemos uma vez mais recorrer a Lambda ou LINQ, e seleccionar apenas esse, como por exemplo, modificar um atributo no grupo “books”

Dim xmlFile = XDocument.Load(strFileName)
Dim element = xmlFile.<library>.<books>.<book>.Where(Function(f) _
                                                                             f.@name = "Equador")
element.@author = "Jorge Paulino"

Este exemplo indica o caminho completo, mas podemos, uma vez mais, usar a propriedade descendantes, simplificando o código (apenas em duas linhas):

Dim xmlFile = XDocument.Load(strFileName)
xmlFile...<book>.Where(Function(f) _
                                 f.@name = "Equador").@author = "Jorge Paulino"


Inserir

Para inserirmos um novo elemento no ficheiro XML, é necessário “construir” o novo XElement, e depois adiciona-lo à posição correcta. Podemos fazer isto pelo menos de duas formas: criando um XElement e os respectivos(caso existam) XAtributes:

Dim xmlFile = XDocument.Load(strFileName)
Dim element = New XElement("book", _
                                  New XAttribute("name", "XML Literals"), _
                                 New XAttribute("author", "Jorge Paulino"))
Dim parent = xmlFile...<books>.FirstOrDefault()
parent.Add(element)

Ou directamente no código:

Dim xmlFile = XDocument.Load(strFileName)
Dim element = <book name="XML Literals" author="Jorge Paulino"/>
Dim parent = xmlFile...<books>.FirstOrDefault()
parent.Add(element)

Neste segundo exemplo, e caso queiramos substituir o valor dos atributos por uma variável, podemos usar Embedded Expressions, utilizando as tags <%= %>, como já explicado num artigo anterior.

Eliminar

Eliminar um elemento é bastante simples e semelhante à modificação.

Dim xmlFile = XDocument.Load(strFileName)
xmlFile...<magazineName>.Remove()

Este exemplo mostra como remover os elementos com a tag “magazineName”. Mas atenção, este exemplo elimina todos os elementos com a tag indicada. Para apagarmos apenas um elemento especifico, temos de indicar qual.

Dim xmlFile = XDocument.Load(strFileName)
xmlFile...<book>.Where(Function(f) f.@author = "Stephenie Meyer").Remove()

 

Em todos os exemplos mostrados, é necessário gravar as alterações efectuadas, usando simplemente:

xmlFile.Save(strFileName)


E para já é tudo!

Espero que estes exemplos de XML Literals, em conjunto com Lambda e LINQ, tenham ajudado a uma mais fácil utilização de ficheiros XML.


VB.NET: XML Literals - Parte III (Ler dados)

Um dos benefícios do uso de XML Literals é a facilidade de ler informação e com isso melhorar o código e reduzir o tempo de desenvolvimento. Existem algumas formas de ler informação, como por exemplo LINQ ou Lambda Expressions, e como num artigo anterior já foi referido alguma coisa sobre LINQ, neste artigo será apenas utilizado Lambda.

Estes métodos de pesquisa serão a base para modificar dados, apagar ou inserir novos elementos, mas isto, será mostrado brevemente.

Ficheiro: “myFile.xml”

<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<!--
Lista de livros e revistas –>
<library>
  <books>
     <
book name="Crepúsculo"author="Stephenie Meyer" />
     <
book name="Equador"author="Miguel S. Tavares" />
     <
book name="O Sétimo Selo"author="José R. dos Santos" />
  </
books>
  <magazine>
     <
magazineName>MSDN Magazine</magazineName>
     <magazineName>Code Magazine</magazineName>
</magazine>
</
library>

A leitura de um ficheiro, começa sempre pela sua leitura para uma variável, e para isso utilizamos um XDocument. Depois, mediante o tipo de informação que queremos pesquisar/ler, utilizam-se diferentes métodos.

Nota: O nome do ficheiro está guardado na variável strFileName

Dim strFileName As String = "d:\myFile.xml"


Uma leitura simples de um elemento, por exemplo “magazineName”, será feito da seguinte forma:

Dim xmlFile = XDocument.Load(strFileName)
Debug.WriteLine(xmlFile...<magazineName>.Value)

Tão simples com isto! Este método utiliza a propriedade descendants, que irá procurar todos os elementos que tenham a tag indicada.

O resultado, na Immediate Window será “MSDN Magazine”, ou seja, o primeiro elemento que encontrar. Mas podemos também procurar por um valor nos elementos com a mesma tag, neste caso 2, utilizando, por exemplo, Lambda.

Dim xmlFile = XDocument.Load(strFileName)
Debug.WriteLine(xmlFile...<magazineName>.Where(Function(f) _  
                                                          f.Value = "Code Magazine").Value)

Para mostrar um atributo da categoria <Books> o método é semelhante. Desta vez, como se trata de um atributo, é usado a “@”, seguido do nome do atributo.

Dim xmlFile = XDocument.Load(strFileName)
Debug.WriteLine(xmlFile...<book>.@author)

Mas isto irá mostrar apenas o primeiro autor, do primeiro elemento. E se quisermos o nome do autor do livro “Equador” ? Podemos utilizar uma vez mais Lambda.

Dim xmlFile = XDocument.Load(strFileName)
Debug.WriteLine(xmlFile...<book>.Where(Function(f) _ 
                                                                 f.@name = "Equador").@author)

Desta forma, pesquisamos o elemento cujo atributo name é igual a “Equador”, e mostramos o nome do author.


Estes são mais alguns exemplos que mostram como é simples ler informação de um ficheiro XML, usando XML Literals.


VB.NET: XML Literals - Parte II (Embedded Expressions)

As Embedded Expressions não são mais do que expressões que podemos utilizar embebidas nos código, colocando a expressão entre as tags <%= expressão %>, que é o mesmo sintaxe que é utilizado em ASP.NET.

Desta forma, é muito simples com base numa lista, DataTable, DataSet, etc., criar um ficheiro XML com a estrutura pretendida.

Um exemplo simples, utilizando um Func Delegate (Lambda Expressions) que soma dois valores:

' Define a Lambda Expression
Dim f As Func(Of Integer, Integer, Integer) = Function(x, y) x + y

Dim exemplo = _
    <teste>
        <
valor><%= f(125, 125).ToString() %></valor>
    </
teste>

O resultado será:

<teste>
  <
valor>250</valor>
</
teste>

Mas podemos incluir o cabeçalho de um ficheiro XML, e usando o LINQ, preencher o ficheiro de uma forma bastante simples com base numa lista, neste exemplo, List(Of T)

   ' Cria uma lista com alguns livros 
  
Dim bookList As New List(Of String
   bookList.AddRange(New String() {"Crepúsculo", "Equador", "O Sétimo Selo"}) 

   ' Gera o XML e grava para o disco. 
  
Dim newBookList1 = _ 
       <?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
       <
library
           <
books
              
<%= From b In bookList Select <book><%= b %></book> %> 
           </books
       </
library

  
newBookList1.Save("c:\result.xml")

Neste exemplo, o resultado será:

<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
  <
library>
      <
books>
           <
book>Crepúsculo</book>
           <
book>Equador</book>
           <
book>O Sétimo Selo</book>
     </
books>
</
library>

Usando o método DataTable.WriteXml() ou Datset.WriteXml() é muito simples gravar o conteúdo de uma base de dados ou de uma tabela para um ficheiro XML. No entanto, não permite criar com o formato especifico ou usar apenas alguns campos.

Desta forma, e usando Embedded Expressions, podemos formatar o resultado final, como se pode ver no seguinte exemplo:

      ' Neste exemplo tudo é criado manualmente, mas os dados poderiam 
      ' ser preenchidos de uma tabela SQL ou outra base de dados qualquer 
   
Dim dt As New DataTable("Livros"
    dt.Columns.Add("Livro", GetType(String)) 
    dt.Columns.Add("Autor", GetType(String)) 

    dt.Rows.Add("Crepúsculo", "Stephenie Meyer"
    dt.Rows.Add("Equador", "Miguel S. Tavares"
    dt.Rows.Add("O Sétimo Selo", "José R. dos Santos"

     Dim ds As New DataSet 
     ds.Tables.Add(dt) 


     ' Gera o XML, definindo 2 atributos: "name" e "author" 
     
Dim newBookList2 = _ 
         <?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
         <!--
Isto é apenas um comentário –
          <
library
              <
books
                 
<%= From b In ds.Tables("Livros") Select
                               <book name=<%= b.Item("Livro") %> 
                                              author=<%= b.Item("Autor") %>/> %>    
              </books
         </
library

    
' Grava para o disco 
   
newBookList2.Save("c:\result.xml")

Finalmente o resultado: 

<?xml version="1.0" encoding="utf-8" standalone="yes" ?> 
<
library>
         <
books>
              <
book name="Crepúsculo"author="Stephenie Meyer" />
              <
book name="Equador"author="Miguel S. Tavares" />
              <
book name="O Sétimo Selo"author="José R. dos Santos" />
        </
books>
</
library>

Como podem ver, usando Embedded Expressions e XML Literals, consegue-se fácilmente criar ficheiros XML e com a estrutura do ficheiro definida no código.

Espero que ajude!


VB.NET: XML Literals - Parte I

Antes de falar propriamente nos XML Literals, e porque nunca aqui foi referido e será utilizado neste exemplo, vou falar um pouco sobre a declaração Option Infer.

Option Infer

A declaração Option Infer On permite que não se indique o tipo de variável, sendo esta identificada efectuada automaticamente pelo compilador.

Isto é bastante útil para LINQ ou para Lambda Expressions e pode ser activado ou desactivado a nível do projecto (Tools - Options - Projects and Solutions - VB Defaults) ou a nível do documento, através da declaração "Option Infer On" ou "Option Infer Off". Por defeito está definido para "On".

Vejamos estas declarações:

Dim str = "Exemplo"
Dim int = 123
Dim dbl = 12.3
Dim list = New List(Of Integer)

Nestes exemplos, e caso esteja definido Option Infer On, as variáveis serão definidas como str = String, int = Integer, dbl = Double e list as System.Collections.Generics.List(of T).

É o mesmo que fazer:

Dim str As String = "Exemplo"
Dim int As Integer = 123
Dim dbl As Double = 12.3
Dim list As New List(Of Integer)

Caso estivesse definido como Option Infer Off, todas as variáveis ficariam definidas como Object, e não o tipo desejado.

XML Literals

Passando ao tema principal deste artigo, este pretende mostrar como os XML Literals permitem incorporar o XML directamente no código e com isso, conseguir manipular muito facilmente este tipo de ficheiros. Os XML Literals estão disponíveis a partir do Visual Studio 2008, suportando a maioria da especificação Extensible Markup Language (XML) 1.0.

Este exemplo cria, em modo runtime, a estrutura de um ficheiro XML, com alguns dados, estando disponível intellissence e auto-indenting do texto:

Dim bookList = _
    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <!--
Lista de livros e revistas -->
    <
library>
        <
books>
            <
book name="Crepúsculo" author="Stephenie Meyer"/>
            <
book name="Equador" author="Miguel S. Tavares"/>
            <
book name="O Sétimo Selo" author="José R. dos Santos"/>
        </
books>
        <
magazine>
            <
magazineName>"MSDN Magazine"</magazineName>
            <
magazineName>"Code Magazine"</magazineName>
        </
magazine>
    </
library>

 
Com base no ficheiro criado, e para listar todas as revistas, indicando o caminho da estrutura XML até ao elemento pretendido, podemos criar um ciclo For Each:

For Each m In From element In _
                                        bookList.<library>.<magazine>.<magazineName>
  
Debug.WriteLine(m.Value)
Next

Este é um método mais prático de o fazer, sem ser necessário indicar o caminho para o elemento pretendido, utilizando a propriedade Descendants, que irá retornar todos os elementos descendentes que encontre na descrição especificada entre as chavetas <>:

For Each m In From element In bookList...<magazineName>
   
Debug.WriteLine(m.Value)
Next


Para listar os livros, o processo é semelhante, mas desta vez como o Nome e o Autor estão como atributos, utiliza-se o caracter "@" para indicar qual o atributo a ler:

For Each book In From element In bookList...<book>
   
Debug.WriteLine("Livro: " & book.@name.ToString)
    Debug.WriteLine("Autor: " & book.@author.ToString)

    ' Linha de separação
   
Debug.WriteLine(New String("-"c, 40))
Next

 
Para um pesquisa de informação podemos utilizar LINQ to XML. Neste caso, para procurar todos os registo que com a palavra "Selo":

Dim bookSearch = From b In bookList...<book>_
                 Where b.@name.ToString.Contains("Selo") _
                 Select b.@name, b.@author

For Each book In From element In bookSearch
    Debug.WriteLine("Livro: "& book.name)
    Debug.WriteLine("Autor: " & book.author)

    ' Linha de separação
   
Debug.WriteLine(New String("-"c, 40))
Next

 
Finalmente, podemos gravar para o disco, o XML que se encontra em memória

bookList.Save("d:\LivrosRevistas.xml")

 
É um exemplo simples de como ler informação utilizando XML Literals e LINQ to XML, que mostra que nunca foi tão fácil trabalhar com ficheiro XML.

Para breve mais exemplos sobre XML Literals!




Microsoft Office Especialist

Membro da Comunidade
Experts-Exchange


Administ. da Comunidade
Portugal-a-Programar



Twitter

Artigos no CodeProject

Artigos no CodeProject

Subscrever Novidades

Endereço de Email:

Delivered by FeedBurner

Seguidores

Histórico