VB 2005 - Trabalhando com o objeto DataTable


Na versão anterior da ADO.NET , os objetos DataTable eram originalmente membros dos objetos DataSets. Com o advento da ADO.NET 2.0 isso mudou. A nova versão permite que você crie DataTables mais 'leves' que compartilham muitos métodos antes somente existentes no DataSet. Agora os Datatables suportam os métodos : ReadXml, ReadXmlSchema, WriteXml e WriteXmlSchema , Load(DataReader) e o objeto DataTableReader. Você pode também atribuir um namespace e um prefixo namespace ao DataTable.

Este artigo tem o objetivo de mostrar como você pode usar os novos recursos do objeto DataTable, dentre eles:

O projeto exemplo deste artigo usa o VB 2005 Express e o SQL Server 2005 Express. O banco de dados de exemplo que será acessado será o banco de dados Cadastro.mdf e a tabela Clientes ambos criados no SQL Server 2005 Express via VB 2005.

O projeto DataTables : criando a base de dados no SQL Server 2005 Express

- Abra o VB 2005 Express Edition e crie um novo projeto chamado DataTables.

- Se a janela Data Sources não estiver visível Ative-a no menu Data->Show Data Sources.

- Clique no link Add New Data Source e na janela Data Source Configuration Wizard selecione DataBase.

Nota:  Poderíamos criar a base de dados clicando o botão direito do mouse sobre o nome do projeto e selecione Add->New Item  e na janela de templates selecionar o item SQL Database informando o nome cadastro.mdf para a base de dados a ser criada.

Clique no botão Next> na caixa de combinação selecione a conexão com a base cadastro.mdf. Expandindo a Connection String você verá a string de conexão que será usada para a conexão.

Ao clicar no botão Next> irá surgir a seguinte mensagem de aviso. Ela pergunta se você deseja copiar o arquivo da base de dados cadastro.mdf para o seu projeto. Clique em Não(No) para não salvar o arquivo no seu projeto usando assim o local original onde o mesmo foi criado.

Nota: Veja artigo VB.NET  2005 -  TableAdapater não atualiza os dados  para maiores detalhes sobre o assunto.

Clicando no botão Next> o próximo passo será salvar a string de conexão no arquivo de configuração da aplicação.(Você pode ver o valor clicando em My Project ->Settings)

Neste ponto você deve clicar no botão Cancel para cancelar a operação pois não vamos criar um Data Source. Fizemos os passos acima somente para criar a base de dados e obter a string de conexão.

A string de conexão com o banco de dados usada será armazenada usando o recurso My.Settings conforme os seguintes passos:

  1. Clique com o botão direito sobre My Project na janela Solution Explorer e selecione Open.
  2. Na janela a seguir selecione Settings e informe um nome para a string de conexão e para a string SQL na coluna Name. Eu usei os nomes connSQL. Salve a operação. Pronto ! já podemos recuperar esta informação a partir de My.Settings em tempo de execução.

Criando a tabela Clientes

A próxima etapa será criar uma nova tabela chamada Clientes na base de dados cadastro.mdf.

- Abra a janela do DataBase Explorer e expanda os objetos para a conexão Cadastro.mdf.

- Selecione a opção Table e clique com o botão direito do mouse selecionando a opção Add New Table

 

A seguir informe, conforme a figura abaixo, os nomes dos campos e o tipo de dados. Ao terminar, salve o trabalho. Retornando a janela DataBase Explorer veremos a tabela Clientes e seus respectivos campos criados.

Se desejar pode incluir valores diretamente na tabela. Para isto clique sobre a tabela Clientes e selecione a opção Show Data Table e digite alguns valores conforme abaixo:

Incluindo a coluna para armazenar a imagem

Vamos incluir na tabela Clientes um campo para poder armazenar a imagem.

Clique com o botão direito do mouse sobre o nome da tabela no DataBase Explorer e selecione Open Table Definition

A seguir inclua uma nova coluna com o nome Foto e o data type igual a image

Altere o nome do formulário padrão form1.vb para DataTables.vb e inclua os seguintes controles no formulário:

O leiaute do projeto é exibido na figura abaixo:

A primeira coisa a fazer é definir os namespaces usados e o ambiente do VB 2005. Para isto inclua o seguinte código no inicio do formulário :

Option Explicit On
Option
Strict On
Imports
System.Data
Imports
System.Data.SqlClient
Imports
System.IO

A seguir vamos definir as variáveis objetos usadas no projeto. Na primeira linha de código após a declaração do formulário digite:

Private dtbClientes As DataTable
Private dtSchema As DataTable
Private strPath As String
Private
strArquivoIE As String = "D:\Arquivos de programas\Internet Explorer\Iexplore.exe"
Private blnIsCarregando As Boolean
Private
intRows As Integer

No evento Load do formulário inclua o seguinte código:  

'****************************************

'Carregando DataTable e Exibindo rotinas

'****************************************


Private
Sub frmDataTables_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
 

'Carrega e exibe o DataTable padrão

strPath = Application.StartupPath + "\"

carregaDoDB(False)

salvaArquivosXML(False)
 

'Verifica a localização do IE

If File.Exists(strArquivoIE) Then

   btnExibirDados.Visible = True

   btnExibirDataSet.Visible = True

   btnExibirDiffGram.Visible = True

End If

End Sub

 

No código acima estamos usando a rotina carregaDoDB() que possui o seguinte código:

Private Sub carregaDoDB(ByVal blnWithNamespace As Boolean)
        'Carrega e exibe o DataTable com ou sem uma tabela namespace
        Dim strConn As String = My.Settings.connSQL
        Dim cnnCadastro As SqlConnection = New SqlConnection(strConn)
        Try
            Dim cmdClientes As SqlCommand = cnnCadastro.CreateCommand
            With cmdClientes
                .CommandType = CommandType.Text
                .CommandText = "SELECT * FROM Clientes"
            End With
            cnnCadastro.Open()
            Dim drClientes As SqlDataReader = cmdClientes.ExecuteReader(CommandBehavior.KeyInfo)
            dtbClientes = New DataTable
            dtSchema = drClientes.GetSchemaTable
            With dtbClientes
                .TableName = "Clientes"
                If blnWithNamespace Then
                    .Namespace = "http://www.macoratti.net/schemas/Clientes"
                End If

                'Carrega os dados e aceita as alterações
                .Load(drClientes)
                .AcceptChanges()

                If .PrimaryKey.Length = 0 Then
                    'Define a chave primaria se estiver faltando
                    Dim acolKeys(1) As DataColumn
                    acolKeys(0) = .Columns(0)
                    .PrimaryKey = acolKeys
                End If

                'Testa a propriedade DataSet
                If Not .DataSet Is Nothing Then
                    Dim strNome As String = .DataSet.DataSetName
                    MsgBox(strNome)
                End If
            End With
            drClientes.Close()

            'Testa o DataTableReader
            Dim dtrClientes As New DataTableReader(dtbClientes)
            intRows = 0
            While dtrClientes.Read
                intRows += 1
            End While
            dtrClientes.Close()
            carregaDataGridViews()
        Catch excDT As Exception
            MsgBox(excDT.Message + excDT.StackTrace, , "erro ao carregar o DataTable")
        Finally
            cnnCadastro.Close()
        End Try
    End Sub

O código acima carrega o DataTable a partir da tabela Clientes , inclui um namespace e prefixo opcional , designa a coluna para a chave primária , cria um esquema da DataTable, e interage a DataTable com o DataTableReader e chama a rotina carregaDataGridViews para exibir o conteúdo da tabela e o esquema. O resultado pode ser visto na figura abaixo:

O código da rotina carregaDataGridViews  é o seguinte :

 Private Sub carregaDataGridViews()
        'Carrega e e formata os dados
        blnIsCarregando = True
        With dgvClientes
            .DataSource = dtbClientes
            .AutoGenerateColumns = True
            .AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.DisplayedCells
            .Columns(0).Width = 70
            .Columns(7).Width = 70
            .RowHeadersWidth = 25
            .BorderStyle = BorderStyle.None
        End With
        'Carrega e formata o  schema
        With dgvSchema
            .DataSource = dtSchema
            .AutoGenerateColumns = True
            .AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.DisplayedCells
            .RowHeadersVisible = False
            .BorderStyle = BorderStyle.None
        End With
        blnIsCarregando = False
    End Sub

O DataTable que foi carregado a partir do DataReader são atualizáveis e você pode persistir os dados como um documento XML no formato DataSet ou DiffGram. A rotina salvarArquivosXML gera documentos XML de dados e esquema  e persiste o conteúdo do DataTable em um formato DataSet. A rotina salva todas as alterações feitas no DataGridView como um arquivo diffgram.

O código da rotina salvarArquivosXML  é dado a seguir :

    'Rotinas para Salvar e carregar XML
    Private Sub salvaArquivosXML(ByVal blnShowMessage As Boolean)
        'Deleta e re-salva os dados, schema, e (se houve mudanças) os arquivos diffgram
        deletaArquivosXML()
        With dtbClientes
            .WriteXml(strPath + "Data.xml", System.Data.XmlWriteMode.IgnoreSchema)
            .WriteXml(strPath + "DataSet.xml", System.Data.XmlWriteMode.WriteSchema)
            .WriteXmlSchema(strPath + "Schema.xsd")
        End With
        btnExibirDados.Enabled = True
        btnExibirDataSet.Enabled = True
        btnExibirEsquema.Enabled = True
        'A propriedade HasChanges esta faltando
        Dim dtMudancas As New DataTable
        dtMudancas = dtbClientes.GetChanges
        Dim strMsg As String
        If dtMudancas Is Nothing Then
            strMsg = "Dados e esquema para " + intRows.ToString + " linhas escrita para '" + strPath + "' pasta."
            btnExibirDiffGram.Enabled = False
        Else
            dtMudancas.WriteXml(strPath + "Diffgram.xml", System.Data.XmlWriteMode.DiffGram)
            strMsg = "Dados para " + intRows.ToString + " linhas, schema, e alterações no diffgram escritas para '" + strPath + _
 "' pasta e alterações aceitas."
            dtbClientes.AcceptChanges()
            btnExibirDiffGram.Enabled = True
        End If
        If blnShowMessage Then
            MsgBox(strMsg, , "Arquivos XMl Salvos")
        End If
        btnlerXML.Enabled = True
    End Sub

 

Você sabe o que é um DiffGram ?

Um DiffGram é um formato XML que é usado para identificar versões atuais e originais de elementos de dados. O DataSet usa o formato DiffGram para carregar e persistir o seu conteúdo e serializar o conteúdo para o transporte através da rede. Quando um DataSet é escrito como um DiffGram, ele preenche o DiffGram com toda a informação necessária para recriar os elementos.

A rotina para ler o arquivo XML é dada a seguir:

Private Sub btnLerXML_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnlerXML.Click
        'Carrega ou tenta carregar o DataTable do DataSet salvo
        btnExibirDiffGram.Enabled = False
        Try
            dtbClientes = New DataTable
            With dtbClientes
                .ReadXml(strPath + "DataSet.xml")
                If File.Exists(strPath + "Diffgram.xml") Then
                    'aplica as alterações
                    .ReadXml(strPath + "Diffgram.xml")
                End If
                .AcceptChanges()
            End With

            'Testa o DataTableReader
            Dim dtrClientes As New DataTableReader(dtbClientes)
            dtSchema = dtrClientes.GetSchemaTable
            intRows = 0
            While dtrClientes.Read
                intRows += 1
            End While
            dtrClientes.Close()
            carregaDataGridViews()
        Catch excXML As Exception
            MsgBox(excXML.Message + excXML.StackTrace, , "Erro na leitura do DataTable : ReadXml")
        End Try
    End Sub

Os arquivos XML são exibidos usando o Internet Explorer. As rotinas usadas para este objetivo estão relacionadas com os botões de comando Exibir Dados. A seguir as rotinas para cada um dos botões:

'****************************************

'Exibe o tratamento de evento dos botäes

'*****************************************

Private Sub btnExibirDados_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnExibirDados.Click

  exibirNoIE(strPath + "Data.xml")

End Sub
 

Private Sub btnExibirDataSet_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnExibirDataSet.Click

  exibirNoIE(strPath + "DataSet.xml")

End Sub
 

Private Sub btnExibirEsquema_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnExibirEsquema.Click

  exibirNoIE(strPath + "Schema.xsd")

End Sub
 

Private Sub btnExibirDiffGram_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnExibirDiffGram.Click

  exibirNoIE(strPath + "DiffGram.xml")

End Sub
 

Private Sub exibirNoIE(ByVal strArquivo As String)

   'System.Diagnostics.Process.Start(strArquivo)

   Shell("" + strArquivoIE + "" + strArquivo, AppWinStyle.NormalFocus)

End Sub

 

Nota: O comando Shell usado para executar o Internet Explorer existe como forma de compatibilidade através do namespace Microsoft.VisualBasic.Compatibility . O namespace System.Diagnostics fornece a class Process que você pode usar para executar programas externos e é nativa da plataforma .NET.

A seguir temos um exemplo onde é exibido o XML DiffGram de um arquivo deletado no DataGridView:

Pegue o código completo do projeto aqui : dataTables.zip

Até o próximo artigo VB.NET 2005.


José Carlos Macoratti