VB .NET - Populando o controle TreeView com tabelas e colunas do MS Access


Para exemplificar a utilização prática do controle TreeView, neste tutorial veremos como popular o controle com todas as tabelas e suas colunas a partir de um banco de dados MS Access usando a linguagem VB .NET.

Abra o Visual Basic 2010 Express Edition e clique em New Project e selecione o template Windows Forms Application informando o nome Tvw_MsAccess e clique em OK;

No formulário form1.vb do projeto inclua a partir da ToolBox um controle TreeView (name=tvwDados) e um controle ImageList (name= Imgl);

A seguir no controle ImageList clique na propriedade Images e inclua 3 imagens que serão usadas para diferenciar níveis dos nós do controle TreeView visto que teremos três níveis de nós (nodes) : root, tabelas e colunas

Para isso utilize a janela do Images Collection Editor e clicando no botão Add inclua 3 imagens a seu gosto conforme a figura abaixo:

A seguir no controle TreeView atribua à propriedade ImageList o nome Imgl do controle acima;

Vamos incluir também 4 controles controles Buttons, 1 controle Label e um controle OpenFileDialog no formulário fom1.vb :

Conforme o leiaute da figura abaixo:

Definindo o código do projeto

1- O namespace usado no formulário para acessar as classes do provedor para o Microsoft Access

Imports System.Data.OleDb

2- Código do evento Click do botão Exibir:

 Private Sub btnExibir_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnExibir.Click

        Dim arquivoMDB As OpenFileDialog = New OpenFileDialog()
        arquivoMDB.InitialDirectory = "c:\dados"
        Dim caminho As DialogResult
        Dim caminhoArquivo As String

        arquivoMDB.Title = "Escolher Arquivo"
        arquivoMDB.FileName = "Nome Arquivo"
        arquivoMDB.Filter = "Arquivos MsAccess (*.mdb)|*.mdb"
        caminho = arquivoMDB.ShowDialog
        caminhoArquivo = arquivoMDB.FileName

        If caminhoArquivo = Nothing Then
            MessageBox.Show("Arquivo Invalido", "Abrir Arquivo", MessageBoxButtons.OK)
        Else
            popularTreeView(caminhoArquivo)
            btnRetrair.Enabled = True
            btnExpandir.Enabled = True
        End If
    End Sub

O código define algumas propriedades do controle OpenFIleDialog e chama a rotina popularTreeview passando o caminho do arquivo selecionado.

- InitialDirectory - Representa o diretório a ser exibido quando a janela de diálogo aparecer pela primeira vez.
- Title - Usada para definir ou atribuir um título a janela de diálogo;
- Filter - Representa o filtro da janela de diálogo que será usado para filtrar o tipo de arquivos a serem carregados durante a localização.
- FileName - Representa o nome do arquivo selecionado na janela de diálogo.

O código da rotina popularTreeView() é mostrada a seguir:

Private Sub popularTreeView(ByVal arquivo As String)
        Dim strCon As String
        strCon = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & arquivo & ";User Id=admin;Password=;"

        'define os nodes que iremos usar no treeview
        Dim NoRaiz As TreeNode = Nothing
        Dim NoPrincipal As TreeNode = Nothing
        Dim NoFilho As TreeNode = Nothing

        'define algumas constanes e variaveis usadas
        Dim DataBase As String = arquivo
        Dim conexaoMDB As OleDbConnection = Nothing
        Dim nomePrincipal As String = String.Empty
        Dim nomeFilho As String = String.Empty

        Try
            'define a string de conexão e abre a conexão com o arquivo escolhido
            conexaoMDB = New OleDbConnection(connectionString:=strCon)
            conexaoMDB.Open()

            'retorna as tabelas do esquema
            Dim esquemaTabela As DataTable = conexaoMDB.GetOleDbSchemaTable(schema:=Data.OleDb.OleDbSchemaGuid.Tables, _ 
restrictions:=New Object() {Nothing, Nothing, Nothing, "Table"})
            tvwDados.Nodes.Clear()
            'inclui o node raiz
            NoRaiz = tvwDados.Nodes.Add(key:="Root", text:=DataBase, imageIndex:=0, selectedImageIndex:=0)

            'exibe quantidade de tabelas do banco de dados na label
            lblTabelas.Text = esquemaTabela.Rows.Count & " Tabelas no arquivo"

            'percorre cada tabela do banco de dados
            For contaTabelas As Integer = 0 To esquemaTabela.Rows.Count - 1
                'pega o nome da tabela
                Dim nomeTabela As String = esquemaTabela.Rows(index:=contaTabelas)!TABLE_NAME.ToString
                'verifica se o nome da tabela ja existe na coleção de nós
                If nomePrincipal <> nomeTabela Then
                    NoPrincipal = NoRaiz.Nodes.Add(key:="Table", text:=nomeTabela, imageIndex:=1, selectedImageIndex:=1)
                    nomePrincipal = nomeTabela
                End If

                'pega o nome das colunas na tabela
                Dim esquemaColuna = conexaoMDB.GetOleDbSchemaTable(schema:=OleDbSchemaGuid.Columns, _ 
restrictions:=New Object() {Nothing, Nothing, nomeTabela, Nothing})

                'inclui cada coluna como um nó filho
                For contaColunas As Integer = 0 To esquemaColuna.Rows.Count - 1
                    nomeFilho = esquemaColuna.Rows(index:=contaColunas)!COLUMN_NAME.ToString
                    NoFilho = NoPrincipal.Nodes.Add(key:="Column", text:=nomeFilho, imageIndex:=2, selectedImageIndex:=2)
                Next

                'certifica que o nó seja visível
                tvwDados.Nodes(0).EnsureVisible()

            Next

        Catch ex As Exception
            MessageBox.Show("Erro ao realizar a operação com o arquivo : " & ex.Message)
            Exit Sub
        Finally
            'libera os recursos da conexão usada
            conexaoMDB.Close()
            conexaoMDB.Dispose()
            conexaoMDB = Nothing
        End Try
    End Sub

O provedor de dados OLEDB .NET usa o método GetOleDbSchemaTable do objeto OleDbConnection para expor as informações do esquema.

GetOleDbSchemaTable retorna uma DataTable que é preenchida com as informações do esquema.

- O primeiro argumento de GetOleDbSchemaTable é o parâmetro de esquema, um argumento OleDbSchemaGuid que identifica quais informações de esquema para retornar (como tabelas, colunas e chaves primárias).

- O segundo argumento é uma matriz de objeto de restrições para filtrar as linhas que são retornadas no esquema de DataTable (por exemplo, você pode especificar as restrições de nome, tipo, proprietário e/ou esquema da tabela).

OleDbSchemaGuid membros

O argumento OleDbSchemaGuid especifica o tipo do esquema da tabela para o método GetOleDbSchemaTable.

Alguns dos membros OleDbSchemaGuid incluem :

Restrições

As restrições são uma matriz de objeto de valores de filtro, cada um dos quais corresponde a um DataColumn na DataTable resultante. O argumento OleDbSchemaGuid determina as restrições relevantes. Por exemplo, quando você especificar um OleDbSchemaGuid de tabelas, a matriz de restrições será definida assim: {TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME, TABLE_TYPE}

Quando você passa valores na matriz de restrição, inclua a palavra-chave Nothing para elementos da matriz que não contêm valores. Por exemplo, se você desejar recuperar esquemas de tabela, use OleDbSchemaGuid.Tables.

No entanto, se você especificar tabelas, isso também retornará aliases, sinônimos, modos de exibição e outros objetos relacionados. Assim, se você desejar filtrar todos os objetos, exceto tabelas, use uma restrição do TABLE para TABLE_TYPE.

Dessa forma você pode usar Nothing para TABLE_CATALOG TABLE_SCHEMA e TABLE_NAME porque você não está filtrando esses objetos.

DataTable retornada

O DataTable que o método GetOleDbSchemaTable retorna possui uma linha para cada objeto que atenda aos critérios de restrição e o tipo OleDbSchemaGuid. O DataTable possui uma coluna para cada uma das colunas restrição, que é seguido por informações adicionais do esquema com base no campo OleDbSchemaGuid.

As colunas que são retornadas no DataTable são as colunas de restrição (TABLE_CATALOG TABLE_SCHEMA, TABLE_NAME, TABLE_TYPE), que são seguidas pelas colunas adicionais do esquema de TABLE_GUID, descrição, TABLE_PROPID, DATE_CREATED e DATE_MODIFIED.

Para obter essa lista de nomes de coluna (ou seja, os campo descritores, como TABLE_CATALOG, TABLE_SCHEMA e TABLE_NAME), você pode usar a posição ordinal das colunas. Observe que a matriz de colunas é baseado em zero.

O código do evento Click do botão Expandir

Private Sub btnExpandir_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnExpandir.Click
        'expande todos os nós
        tvwDados.ExpandAll()
    End Sub 

O método ExpandAll() expande todos os nodes.

O código do evento Click do botão Retrair

Private Sub btnRetrair_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnRetrair.Click
        'retrai todos os nós
        tvwDados.CollapseAll()
    End Sub

O método CollapseAll() retrai todos os nodes.

O código do evento Click do botão Sair

 Private Sub btnSair_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSair.Click
        Dim resultado As DialogResult = MessageBox.Show("Deseja encerrar a aplicação ?", _
             "Encerrar", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2)

        If resultado = DialogResult.Yes Then
            Application.Exit()
        End If

    End Sub

Executando o projeto ao clicar no botão Exibir teremos a caixa de diálogo Abrir arquivo aberta para selecionarmos o arquivo Access:

Após selecionar o arquivo o controle é preenchido com os nomes das tabelas e suas colunas:

Para obter o nó selecionado no controle TreeView usamos o evento AfterSelect pois o evento Click do controle retorna apenas o nó anterior selecionado.

No código usamos as propriedades e.Node e SelectedNode para obter o nó selecionado.

    Private Sub tvwDados_AfterSelect(ByVal sender As System.Object, ByVal e As System.Windows.Forms.TreeViewEventArgs) Handles tvwDados.AfterSelect

        'obtem o item selecionado
        Dim itemSelecionado As String = tvwDados.SelectedNode.ToString
        'remove a string TreeNode
        itemSelecionado = itemSelecionado.Replace("TreeNode: ", "")

        'verifica se o item é nulo
        If (e.Node.Parent IsNot Nothing) Then
            'verifica o tipo do no
            If (e.Node.Parent.GetType() Is GetType(TreeNode)) Then
                If e.Node.Parent.Text = ofd1.FileName Then
                    'mostra o nome da tabela e da coluna selecionada
                    MessageBox.Show(e.Node.Parent.Text + "." + itemSelecionado)
                Else
                    'mostra so o nome da tabela
                    MessageBox.Show(itemSelecionado)
                End If

            End If
        End If

    End Sub

Executando o projeto e selecionando um nó com o mouse iremos obter :

Pegue projeto completo aqui: Tvw_MsAccess.zip

Mar 11:24 Por isso vos digo que tudo o que pedirdes em oração, crede que o recebereis, e tê-lo-eis.

Referências:


José Carlos Macoratti