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!
O Excel tem algumas de funções de pesquisa muito utilizadas, como é o caso do VLOOKUP(), HLOOKUP(), INDEX(), etc. Estas funções permitem pesquisar por um valor e, em alguns casos, retornar um resultado de uma coluna adjacente.
Por exemplo a função VLOOKUP() funciona da seguinte forma:
=VLOOKUP(«valor a procurar»;«área a procurar»;«coluna retorno»;«busca parcial»)

Como podem ver na imagem, a tabela de valores vai de A2 a B11. Se colocarmos o valor “1” em A14 (que será o valor a pesquisar) e a formula =VLOOKUP(A14;A2:B11;2;FALSE) na célula B14, teremos o seguinte resultado: “um”.
Isto é o funcionamento desta formula, que vai procurar um valor a uma área e retorna o valor de uma determinada coluna, da linha encontrada.
No entanto, podemos querer tornar esta função mais poderosa e com isso indicar vários valores e retornar vários resultados. Para isso podemos criar uma função personalizada (UDF - User Defined Function), que neste caso foi designada por xLookup().
Public Function xVLOOKUP(ByVal str As String) As String
Dim searchValues() As String
Dim rng As Range, searchID As Range
Dim x As Integer, columnIndex As Integer
Dim result As String
' Define o area de pesquisa
Set rng = [a2:b11]
' Define qual a coluna onde estão os resultados
columnIndex = 2
' Separa os ID's que se encontram separados por
' ponto e virgula ao array criado
searchValues = Split(str, ";")
' Ciclo nos ID's encontrados
For x = 0 To UBound(searchValues)
' Pesquisa o ID na area definida(limpando também espaços)
searchID = rng.Find(What:=Trim(searchValues(x)), SearchFormat:=False)
' Caso encontra colocar o resultado da linha encontrada
' e de acordo com a coluna, caso contrário um texto geral
If Not searchID Is Nothing Then
result = result & Cells(searchID.Row, columnIndex).Value & ";"
Else
result = result & "Não Encontrado;"
End If
Next
' Atribui o resultado à função, removendo o ";" final
If Len(result) > 1 Then
xVLOOKUP = Mid(result, 1, Len(result) - 1)
Else
xVLOOKUP = result
End If
End Function
Neste caso, o que a função faz, é separar o valor de uma célula para uma array e depois pesquisar valor a valor, construindo o resultado.

Como podem na imagem, se colocarmos “1;2;3;1” na célula A17, e a formula =xVLOOKUP(A17) em B17, obtemos o resultado “um;dois;três;um”
É mais um exemplo de uma UDF e de como podemos criar novas formulas, para além das inúmeras que já que temos disponíveis. Mostra também como fazer uma pesquisa numa área definida e de como utilizar os resultados dessa pesquisa.
NOTA: Estas são aplicações práticas colocadas em fóruns, newsgroups, blogs, etc, e como mostram algum código e poderem ser utilizadas em outros contextos, são aqui publicadas.
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!