VB - Usando DBGrid no modo não vinculado (Unbound mode)
O controle DBGrid pode ser usado no modo vinculado (Unbound) e no modo não vinculado(DataMode=1). O modo vinculado é o mais utilizado , neste modo o controle é conectado a uma fonte de dados geralmente a conexão feita com um controle de dados vinculados de onde se obtêm a fonte de dados. (Definimos a propriedade DataSource do DBGrid para um objeto de dados vinculados como um Data Control).
O modo não vinculado é pouco usado e não muito documentado. Neste modo não existe uma conexão do controle a uma fonte de dados. E se você decidir usar este modo terá que fornecer via código todo o tratamento e manutenção dos dados. Para usar o DBGrid no modo não vinculado definimos a propriedade DataMode igual a 1.
Embora de mais trabalho ao programador o DBGrid no modo vinculado é uma ferramenta muito útil para tratar dados dinâmicos de uma maneira mais eficiente e rápida que no modo vinculado.
No artigo - Trabalhando com o DBGrid no modo Desvinculado - já dei umas pinceladas sobre o assunto. Hoje vamos ir mais fundo...
Neste artigo vou mostrar como usar o controle DBGrid no modo não vinculado através de um exemplo simples onde iremos usar um arquivo texto a partir do qual os dados serão lidos e gravados . Este arquivo será a nossa fonte de dados. Lembre-se que ao encerrar sua aplicação e fechar o Grid os dados que estão na memória serão perdidos se não forem gravados. Iremos usar um vetor para carregar os dados do arquivo texto e a seguir preencher o DBGrid com os dados. talvez este não seja o melhor caminho a escolher dependendo da quantidade de dados que você tenha que manter. Se você pretende preencher um grid com 1.000.000 de linhas e outras 5.000 colunas provavelmente você terá problemas de memória com sua aplicação. (Geralmente usa-se um banco de dados para armazenar as informações mas por questão de simplicidade irei usar um arquivo texto.)
Para poder trabalhar com o DBGrid no modo não vinculado você terá que conhecer os eventos que deverá tratar via código. Os principais eventos são :
Vejamos o método UnBoundReadData em mais detalhes : Sua sintaxe é :
Private Sub
DBGrid1_UnboundReadData(ByVal RowBuf As MSDBGrid.RowBuffer,
StartLocation As Variant, ByVal ReadPriorRows As Boolean)
End Sub
- RowBuffer - é um objeto OLE definido pelo Grid e usado para trocar dados entre o grid e os eventos de dados não vinculados. A seguir veremos suas propriedades que você pode visualizar através do Object Browser (Menu View - Object Browser ou F2)
DBGrid - Métodos do modo não vinculado | RowBuffer - Membros da classe RowBuffer |
- RowCount - Long - retorna o número de linhas que
o evento espera processar.
- ColumnCount
- Integer - retorna o
número de colunas no buffer. Este propriedade é somente leitura
- ColumnName(Col) String - retorna o nome da coluna do
grid indicada pelo parâmetro Col. Este propriedade é somente
leitura
- Bookmark Variant - define e/ou retorna o bookmark
para a linha especificada no buffer. A linha RowBuffer row é
passada como argumento.
- Value(Row,
Col) Variant - usada para
especiricar o valor do dado associado com a linha e a coluna
RowBuffer.
No evento UnBoundReadData , o objeto RowBuffer é criado pelo grid com valores e bookmarks definidos como Null. RowBuf é passado para o evento com a expectativa de que o evento definirá os valores e bookmarks necessários.
Nos eventos UnboundAddData e UnboundWriteData , os dados que o usuário alterou é tratado em RowBuf.Value(0,Col). Qualquer coluna com dados não alterados tera RowBuf.Value(0,Col) igual a Null. O programador salva os valores alterados (não Null) na fonte de dados (geralmente em um vetor). Somente valores não nulos indica alteração de dados.
- StartLocation - variant - define a linha 'antes' dos dados desejados. O valor depende do argumento : ReadPriorRows.
- ReadPriorRows - boolean - indica a direção na qual o grid esta requisitando os dados. Se o grid determinar um StartLocation para a linha 46 , um RowCount igual 5 e se a propriedade ReadPriorRows for definida como True, então o evento UnboundReadData irá retornar a seguinte informação no RowBuffer:
RowBuf.Value(0, col) = dados para a linha 45 RowBuf.Value(1, col) = dados para a linha 44 RowBuf.Value(2, col) = dados para a linha 43 RowBuf.Value(3, col) = dados para a linha 42 RowBuf.Value(4, col) = dados para a linha 41
Se o valor de ReadPriorRows no entanto for definido como false, então o evento irá retornar os seguintes valores para RowBuffer
RowBuf.Value(0,
col) = dados para a linha 47
RowBuf.Value(1, col) = dados para a linha 48
RowBuf.Value(2, col) = dados para a linha 49
RowBuf.Value(3, col) = dados para a linha 50
RowBuf.Value(4, col) = dados para a linha 51
Nota: O que é um bookmark no modo não vinculado ? São
dados do tipo variant usados pelo grid para identificar de forma
única uma linha dentro dos dados a serem exibidos. Geralmente
eles são fornecidos pelos eventos UnboundReadData and
UnboundAddData e são passados para o grid e a partir do grid. O
grid trata os bookmarks como pacotes de informação binárias
que não podem ser interpretadas. Para o Grid um bookmark é um
pedaço de dados que contém um número específico em uma dada
ordem.
Usando o DBGrid no modo não vinculado ( Unbound mode)
Nosso objetivo será ler os dados de um arquivo texto chamado livros.txt e exibir estes dados em um DBGrid usando o modo não vinculaod. Vamos implementar as seguintes funcionalidades em nosso projeto:
Inicie um novo projeto no VB e inclua o componente DBGrid no seu projeto. A seguir inclua no formulário padrão um controle DBGrid , dois botões de comando e três caixas de texto, conforme layout abaixo:
O conteúdo do arquivo texto a ser exibido contém dados de livros e seus autores: Titulo ,ISBN e URL. O arquivo livros.txt é exibido abaixo:
4 "ASP , ADO , Banco de dados na Internet","85-85943-96-3","www.macoratti.net" "Visual Basic Total","85-7001-735-9","www.editoracampus.com.br" "Visual Basic Banco de dados","85-373-794-5","www.macoratti.net" "Oracle e Visual Basic","85-789-345-67","www.oracle.com" "VB e MySQL","85-471-24268-3","www.mysql.com" |
Ao executar a aplicação teremos o seguinte resultado:
Para incluir um registro no arquivo e exibir no grid basta digitar as informações nas caixas de texto e clicar em - Incluir registro. Os registros serão salvos quando o usuário sair da aplicação.
Vejamos a seguir o código comentado do projeto:
- Na seção General Declarations do formulário form1.frm temos as definições das variáveis e tipos que serão usados no projeto:
Option
Explicit 'define o tipo de dados que vamos ler Private Type LivroInfo Titulo As String ISBN As String URL As String End Type 'define o total de linhas no arquivo a ler Private TotalLivros As Integer ' define o vetor como do tipo LivroInfo Private LivrosInfo() As LivroInfo |
- A seguir nos eventos do formulário - form1.frm:
Private
Sub Form_Activate() txtTitulo.SetFocus End Sub '
carrega os dados |
A rotina CarregaDados é mostrada abaixo: Ela abre o arquivo livros.txt e preenche o vetor com os dados.
'carrega os dados do arquivo Private Sub CarregaDados() Dim fnum As Integer Dim fnome As String Dim i As Integer fnum = FreeFile 'abre o arquivo texto com os dados a exibir no grid fnome = App.Path & "\livros.txt" Open fnome For Input As #fnum Input #fnum, TotalLivros 'redimensiona o vetor com o total de linhas encontrados no arquivo texto ReDim LivrosInfo(0 To TotalLivros) 'preenche o vetor com os dados do arquivo texto For i = 0 To TotalLivros With LivrosInfo(i) Input #fnum, .Titulo, .ISBN, .URL End With Next i 'fecha o arquivo texto lido Close #fnum End Sub |
O código associado ao evento Click do botão - Incluir registro - é dado a seguir. Ele redimensiona o vetor usado para conter o dado.
' inclui um novo registro no arquivo Private Sub cmdInclui_Click() TotalLivros = TotalLivros + 1 'redimensiona o vetor com o novo total de linhas do arquivo ReDim Preserve LivrosInfo(0 To TotalLivros) 'escreve no arquivo texto o registro With LivrosInfo(TotalLivros) .Titulo = txtTitulo.Text .ISBN = txtISBN.Text .URL = txtURL.Text End With 'atualiza o grid com exibição dos novos dados DBGrid1.Refresh End Sub |
Agora o evento UnboundReadData que lê os dados para exibição no grid.
' Carrega
os dados no controle dbgrid Private Sub DBGrid1_UnboundReadData(ByVal RowBuf As MSDBGrid.RowBuffer, PosicaoInicial As Variant, ByVal LeLinha As Boolean) Dim dr As Integer Dim linha_num As Integer Dim r As Integer Dim linhas_retornadas As Integer ' verifica qual a direção da leitura If LeLinha Then dr = -1 Else dr = 1 End If ' verifica se a PosicaoInicial é nulo If IsNull(PosicaoInicial) Then ' Le do fim ou do inicio dos dados If LeLinha Then ' le de a partir do final linha_num = RowBuf.RowCount - 1 Else ' le a partir do inicio linha_num = 0 End If Else ' verifica onde comecamos a leitura linha_num = CLng(PosicaoInicial) + dr End If ' copia os dados do vetor para dentro do buffer = RowBuf. linhas_retornadas = 0 For r = 0 To RowBuf.RowCount - 1 ' nao le além do final dos dados If linha_num < 0 Or linha_num > TotalLivros Then Exit For ' copia os dados para o buffer da linha With LivrosInfo(linha_num) RowBuf.Value(r, 0) = .Titulo RowBuf.Value(r, 1) = .ISBN RowBuf.Value(r, 2) = .URL End With ' usa linha_num como um bookmark. RowBuf.Bookmark(r) = linha_num linha_num = linha_num + dr linhas_retornadas = linhas_retornadas + 1 Next r ' define o numero de linhas retornardo RowBuf.RowCount = linhas_retornadas End Sub |
agora o código do evento UnboundAddData que inclui uma linha no arquivo.
' Inclui uma nova entrada Private Sub DBGrid1_UnboundAddData(ByVal RowBuf As MSDBGrid.RowBuffer, NewRowBookmark As Variant) ' atualiza o total de linhas e define o novo tamanho do vetor TotalLivros = TotalLivros + 1 ReDim Preserve LivrosInfo(0 To TotalLivros) ' define o bookmark para a nova entrada NewRowBookmark = TotalLivros ' Salva os novos dados With LivrosInfo(TotalLivros) If Not IsNull(RowBuf.Value(0, 0)) Then .Titulo = RowBuf.Value(0, 0) Else .Titulo = DBGrid1.Columns(0).DefaultValue End If If Not IsNull(RowBuf.Value(0, 1)) Then .ISBN = RowBuf.Value(0, 1) Else .ISBN = DBGrid1.Columns(1).DefaultValue End If If Not IsNull(RowBuf.Value(0, 2)) Then .URL = RowBuf.Value(0, 2) Else .URL = DBGrid1.Columns(2).DefaultValue End If End With End Sub
|
o código do evento UnboundDeleteRow que exclui uma linha do arquivo.
' exclui a entrada Private Sub DBGrid1_UnboundDeleteRow(Bookmark As Variant) Dim r As Integer ' preenche a linha excluida. For r = Bookmark + 1 To TotalLivros LivrosInfo(r - 1) = LivrosInfo(r) Next r 'atualiza o novo valor total de linhas do arquivo texto TotalLivros = TotalLivros - 1 End Sub |
a rotina do evento UnboundWriteData que escreve os dados no grid.
' salva os dados atualizados pelo controle Private Sub DBGrid1_UnboundWriteData(ByVal RowBuf As MSDBGrid.RowBuffer, WriteLocation As Variant) ' atualiza somente os valores que foram alterados With LivrosInfo(CInt(WriteLocation)) If Not IsNull(RowBuf.Value(0, 0)) Then .Titulo = RowBuf.Value(0, 0) If Not IsNull(RowBuf.Value(0, 1)) Then .ISBN = RowBuf.Value(0, 1) If Not IsNull(RowBuf.Value(0, 2)) Then .URL = RowBuf.Value(0, 2) End With End Sub |
O código associado ao evento Unload do formulário. Este código será acionado quando o usuário fechar o formulário o clicar no botão Sair. Ele dispara a rotina SalvaDados que irá gravar no arquivo textos os dados incluídos.
' Salva os dados Private Sub Form_Unload(Cancel As Integer) If (MsgBox("Deseja Salvar dados !", vbYesNo, "Salva dados") = vbYes) Then SalvaDados End If End Sub |
Finalmente o código da rotina SalvaDados que grava os dados no arquivo texto livros.txt.
' Salva os dados no arquivo Private Sub SalvaDados() Dim fnum As Integer Dim fnome As String Dim i As Integer 'abre o arquivo texto fnum = FreeFile fnome = App.Path & "\livros.txt" Open fnome For Output As #fnum 'escreve o novo total de linhas do arquivo Write #fnum, TotalLivros 'escreve os dados no arquivo texto For i = 0 To TotalLivros With LivrosInfo(i) Write #fnum, .Titulo, .ISBN, .URL End With Next i 'fecha o arquivo Close #fnum End Sub
|
Com isto terminamos este artigo , nele você aprendeu a como usar o DBGrid no modo não vinculado.
Baixe aqui o projeto completo : DBGridUB.zip
Para saber mais sobre o assunto visite:
- FILE: DBGRIDUB.EXE Uses DBGRID in an Unbound Mode
- www.vb-helper.com
- Baixe o exemplo da microsoft sobre DBGrid não vinculado em :DBGRIDUB.EXE
Até a próxima dica VB...
José Carlos Macoratti