NET Populando o controle TreeView com tabelas e colunas do
SQL Server 27 de janeiro de 2012 por Jos Carlos Macoratti Em meu artigo VB.NET Populando o controle TreeView com tabelas e colunas do MS Access, eu mostrei como preencher o controle TreeView com tabelas e colunas de um banco de dados MS Access. Chegou a hora de fazer a mesma coisa com o SQL Server. Eu sugiro duas opes para realizar esta tarefa: uma usando uma consulta SQL, e a outra obtendo as informaes de um arquivo XML atravs da classe XMLDataDocument. Abra o Visual Basic 2010 Express Edition, clique em New Project e selecione o template Windows Forms Application, informando o nome Tvw_SQLServer, e clique em OK:
No formulrio 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 trs imagens que sero usadas para diferenciar os nveis dos ns do controle TreeView, visto que teremos trs nveis de ns (nodes): root, tabelas e colunas. Para isso, utilize a janela do Images Collection Editor, e clicando no boto Add, inclua trs imagens a seu gosto, conforme a figura abaixo:
A seguir, no controle TreeView, atribua propriedade ImageList o nome Imgl do controle acima. Vamos incluir, tambm, quatro controles Buttons, um Label e um OpenFileDialog no formulrio fom1.vb: btnPopular Preenche o controle TreeView com os dados; btnRetrair Retrai todos os ns da rvore; btnExpandir Expande todos os ns da rvore; btnSair Encerra a aplicao; OpenFileDialog name= ofd1 Exibe a caixa de dilogo Abrir arquivo para selecionar o arquivo .mdf; Label = lblTabelas Exibe a quantidade de tabelas no banco de dados. Conforme o leiaute da figura abaixo:
Definindo o cdigo do projeto 1. O namespace usado no formulrio para acessar as classes do provedor para o SQL Server Imports System.Data.SqlClient. No incio do formulrio, vamos definir a varivel nomeArquivo, que ir receber o nome do arquivo SQL Server: Dim nomeArquivo As String. 2. Cdigo do evento Click do boto Exibir: Private Sub btnPopular_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnPopular.Click
Dim arquivoSQLServer As OpenFileDialog = New OpenFileDialog() arquivoSQLServer.InitialDirectory = "c:\dados\" Dim caminho As DialogResult Dim caminhoArquivo As String
If caminhoArquivo = Nothing Then MessageBox.Show("Arquivo Invalido", "Abrir Arquivo", MessageBoxButtons.OK) Else nomeArquivo = Path.GetFileName(caminhoArquivo) popularTreeView(nomeArquivo.Replace(".MDF", "")) btnRetrair.Enabled = True btnExpandir.Enabled = True End If End Sub O cdigo define algumas propriedades do controle OpenFIleDialog e chama a rotina popularTreeview, passando o caminho do arquivo selecionado. InitialDirectory Representa o diretrio a ser exibido quando a janela de dilogo aparecer pela primeira vez; Title Usada para definir ou atribuir um ttulo a janela de dilogo; Filter Representa o filtro da janela de dilogo que ser usado para filtrar o tipo de arquivos que sero carregados durante a localizao; FileName Representa o nome do arquivo selecionado na janela de dilogo. Naturalmente, voc ter que pedir permisso para acessar o SQL Server. O cdigo da rotina popularTreeView() mostrado a seguir: Private Sub popularTreeView(ByVal DBSQLServer As String)
'define os objetos ADO .NET para acessar o SQL Server Dim conexaoSQLServer As SqlConnection = Nothing Dim cmd As SqlCommand Dim da As New SqlDataAdapter Dim ds As New DataSet
'define a string de conexo Dim strCon As String = "Data Source= .\SQLEXPRESS;Initial Catalog=" & DBSQLServer & ";Integrated Security=True"
'define a consulta para obter as tabelas e suas colunas Dim sqlConsulta As String = "SELECT TABLE_NAME, COLUMN_NAME " + "FROM information_schema.columns " + "ORDER BY TABLE_NAME, COLUMN_NAME"
'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 nomePrincipal As String = String.Empty Dim nomeFilho As String = String.Empty Dim BancoDados As String = DBSQLServer
Try 'define e abre a conexo com o SQL Server conexaoSQLServer = New SqlConnection(strCon) conexaoSQLServer.Open()
'atribui o comando usado na conexo cmd = New SqlCommand(sqlConsulta, conexaoSQLServer) da.SelectCommand = cmd
Dim contaTabelas as Integer For Each row As DataRow In ds.Tables("Dados_Sistema").Rows
If nomePrincipal <> row(0).ToString Then NoPrincipal = NoRaiz.Nodes.Add(key:="Table", text:=row(0).ToString, imageIndex:=1, selectedImageIndex:=1) nomePrincipal = row(0).ToString contaTabelas += 1 End If 'define os ns filhos NoFilho = NoPrincipal.Nodes.Add(key:="Column", text:=row(1).ToString, imageIndex:=2, selectedImageIndex:=2)
Next
lblTabelas.Text = contaTabelas.ToString & " Tabelas no arquivo"
tvwDados.Nodes(0).EnsureVisible()
Catch ex As Exception MessageBox.Show("Erro ao realizar a operao com o arquivo : " & ex.Message) Exit Sub Finally 'libera os recursos da conexo usada conexaoSQLServer.Close() conexaoSQLServer.Dispose() conexaoSQLServer = Nothing End Try
End Sub A consulta SQL usada para retornar as tabelas e suas colunas usa a view INFORMATION_SCHEMA.COLUMNS para obter o nome das tabelas e colunas do SQL Server. Essa view contm uma linha para cada coluna acessvel para o atual usurio no banco de dados atual. A view INFORMATION_SCHEMA.COLUMNS baseada nas tabelas do sistema nosysobjects, type_info spt_data, systypes, syscolumns, syscomments, sysconfigures e syscharsets. Abaixo vemos o resultado da consulta executada no SQL Server Management Studio:
Vamos usar essa view para obter as tabelas e as consultas do banco de dados. O cdigo do evento Click do boto Expandir: Private Sub btnExpandir_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnExpandir.Click 'expande todos os ns tvwDados.ExpandAll() End Sub O mtodo ExpandAll() expande todos os nodes. O cdigo do evento Click do boto Retrair: Private Sub btnRetrair_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnRetrair.Click 'retrai todos os ns tvwDados.CollapseAll() End Sub O mtodo CollapseAll() retrai todos os nodes. O cdigo do evento Click do boto 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 aplicao ?", _ "Encerrar", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2)
If resultado = DialogResult.Yes Then Application.Exit() End If
End Sub Executando o projeto ao clicar no boto Exibir, teremos a caixa de dilogo Abrir arquivo aberta para selecionarmos o arquivo SQL Server:
Aps selecionar o arquivo, o controle preenchido com os nomes das tabelas e suas colunas:
Para obter o n selecionado no controle TreeView, ns usamos o evento AfterSelect, pois o evento Click do controle retorna apenas o n anterior selecionado. No cdigo 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 = nomeArquivo 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_SQLServer.zip
VB .NET - Vinculando um DataTable a um TreeView
Volto a falar sobre o controle TreeView, um controle importante e que oferece recursos para disponibilizar uma visualizao hierrquica de dados. Tentarei no me repetir apresentando aspectos ainda no abordados sobre este controle. O controle TreeView permite uma apresentao intuitiva da informao dispostas em ns facilitando a visualizao e a seleo da mesma. O exemplo mais conhecido onde este tipo de visualizao usada o Explorer do Microsoft Windows que exibe informaes sobre o sistema operacional:
Para entender como o TreeView funciona temos que saber que: - Cada n representa uma informao ; - Ns filhos esto contidos nos ns pais ; - O n raiz contm todos os ns; Obs: importante sempre conhecer o n pai para qualquer n que estamos consultando ou incluindo. Algumas caractersticas bsicas do TreeView: Cada Item em um TreeView esta encapsulado dentro de um objeto TreeNode; Cada TreeNode pode ter zero , um ou muitos ns filhos; A propriedade Nodes do treeview representa a coleo de objetos TreeNode que se relacionam com o n raiz ou o n superior na hierarquia; Cada N possui sua prpria coleo Nodes que contm todos os Ns filhos; Voc pode interagir via cdigo atravs de cada uma destas colees; Voc pode selecionar somente um nico N por vez; Voc pode selecionar um N clicando nele com o mouse ou usando o teclado; Para selecionar um N via cdigo definimos a propriedade TreeView.SelectedNode e o N atualmente selecionado pode ser obtido pelo valor desta mesma propriedade; Use a propriedade FullPath do N selecionado para determinar a hierarquia completa para o N; No VB.NET geralmente usamos o controle TreeView para exibir dados hierrquicos. Podemos fazer isso em tempo de execuo ou em tempo de projeto. Vamos supor que voc precisa exibir uma informao que esta no banco de dados em um rvore hierrquica usando o controle TreeView. Uma situao propcia a este cenrio quando temos duas tabelas relacionadas. Para este exemplo eu vou usar um banco de dados Access e duas tabelas : Funcionarios e Cargos. Para criar o banco de dados e as tabelas eu vou usar o aplicativo VISDATA que vem junto com o Visual Basic 5 ou 6. (tnel do tempo...). O aplicativo pode ser executado a partir do IDE do VB ou como um programa a parte. Nota: Veja nas referncias como usar o VISDATA para criar o banco de dados MSAccess.(.mdb) Veja abaixo o banco de dados Empresa.mdb e as tabelas Funcionarios e Cargos exibindo a sua estrutura:
Perceba que temos a seguinte hierarquia no relacionamento entre as tabelas: --- Cargo |------- Funcionario Nosso objetivo ser obter os dados das duas tabelas e exibir em um controle TreeView. Uma das muitas formas de resolver este problema usar o objeto DataTable criando um datatable para cada uma das tabelas e verificando o relacionamento e incluindo Ns pais e ns filhos no TreeView via cdigo. Abra o Visual Studio 2010 beta 2 ou o VS 2008 ou o VB 2008 Express Edition e crie um novo projeto do tipo Windows Forms Application; No formulrio padro form1.vb inclua um controle TreeView (tvEmpresa) e um boto de comando btnPreencherTV conforme o leiaute abaixo:
Agora defina o namespace para usar o banco de dados Microsoft Access: Imports System.Data.OleDb No evento Click do boto de comando vamos fazer a chamada da rotina para preencher o controle TreeView: Private Sub btnPreencherTV_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnPreencherTV.Click vinculaDadosTreeView() End Sub A seguir defina o cdigo da rotina vinculaDadosTreeView() conforme abaixo: Sub vinculaDadosTreeView() Dim pkp(0), pke(0) As DataColumn Dim dtbCargos As New DataTable Dim dtbFuncionarios As New DataTable
Dim strconn As String = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\dados\Empresa.mdb" Dim conn As OleDbConnection Dim da As OleDbDataAdapter
Dim i As Integer Dim j As Integer
Try 'inicia a conexo conn = New OleDbConnection(strconn)
' Vincula os cargos do DataTable dtbCargos da = New OleDbDataAdapter("Select * from Cargos", conn)
'limpa e preenche o datatable e define a chave primaria dtbCargos.Clear() da.Fill(dtbCargos) pke(0) = dtbCargos.Columns("cargoid") dtbCargos.PrimaryKey = pke
' Vincula os funcionarios do DataTable dtbFuncionarios da = New OleDbDataAdapter("Select * from Funcionarios", conn) dtbFuncionarios.Clear() da.Fill(dtbFuncionarios) pke(0) = dtbFuncionarios.Columns("id") dtbFuncionarios.PrimaryKey = pke
'fecha a conexao conn.Close()
' percorre a posio do dtbCargos For i = 0 To dtbCargos.Rows.Count - 1 'Inclui um No pai tvEmpresa.Nodes.Add(dtbCargos.Rows(i).Item("cargo")) ' percorre o datatable dtbFuncionarios For j = 0 To dtbFuncionarios.Rows.Count - 1 ' Verifica se o funcionario pertence ao cargo If dtbCargos.Rows(i).Item("cargoid") = dtbFuncionarios.Rows(j).Item("cargoid") Then 'Inclui o funcionario no N pai
tvEmpresa.Nodes(i).Nodes.Add(dtbFuncionarios.Rows(j).Item("Nome")) End If Next Next Catch ex As Exception MsgBox("Erro : " & ex.Message) End Try End Sub Executando o projeto iremos obter:
Veja se o cdigo abaixo lhe ajuda. Private Sub btnLocalizar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnLocalizar.Click Dim text As String = String.Empty text = txtNome.Text Dim b As Boolean = True If text <> String.Empty Then Try Dim tn As TreeNode() = TreeView1.Nodes.Find(text, b) For i = 0 To tn.Length - 1 TreeView1.SelectedNode = tn(i) TreeView1.SelectedNode.BackColor = Color.Blue Next Catch ex As Exception MessageBox.Show(ex.Message) End Try Else MessageBox.Show("Favor inserir um nome para pesquisar.") End If End Sub