Seções iMasters
.NET + Linguagens

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

Para exemplificar a utilização prática do controle TreeView, veremos neste artigo 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 três 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 diferentes: root, tabelas e colunas.

Para isso, utilize a janela do Images Collection Editor e clicando no botão Add, inclua três 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 quatro controles Buttons, um controle Label e um controle OpenFileDialog no formulário fom1.vb :

  • btnPopular – Preenche o controle TreeView com os dados;
  • btnRetrair – Retrai todos os nós da árvore;
  • btnExpandir – Expande todos os nós da árvore;
  • btnSair – Encerra a aplicação;
  • OpenFileDialog – name= ofd1 – Exibe a caixa de diálogo “abrir arquivo” para selecionar o arquivo .mdb;
  • Label = lblTabelas – Exibe a quantidade de tabelas no banco de dados.

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 popular Treeview 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 arquivo a ser carregado 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. O 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 :

  • Colunas;
  • Chaves externas;
  • Índices;
  • Chaves primárias;
  • Tabelas;
  • Modos de exibição.

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

Qual a sua opinião?