Visual Basic 6 - Paginando registros em um DataGrid 


Você já deve estar cansado de saber que os controles de grade (MSFlexGrid ,MSHFlexGrid, DataGrid ,etc.) presentes no VB6 são ótimos para exibição de dados na forma de tabela com linhas e colunas. Mas quando a quantidade de registros é muito grande além de sobrecarregar o sistema , a navegação pelos registros pode se tornar um pesadelo.

Como resolver este problema ? Chamar o 'Chapolin Colorado' ? Não precisamos exagerar !!! A solução é mais simples do que pode parecer. Na verdade se você ler meu artigo : ADO - Paginando através de um Recordset já vai perceber uma luz no fim do túnel.

A idéia é até bem simples : basta exibir em uma página apenas uma quantidade pequena de registros e permitir ao usuário paginar o recordset carregando em cada página a mesma quantidade de registro. Com isto matamos dois coelhos com uma cajadada só : a carga do grid é rápida e a navegação do usuário pelos registros também.

Neste artigo vou mostrar como fazer isto usando um controle DataGrid (presente somente no VB6) exibindo os dados da tabela - Pedidos - do banco de dados Northwind.mdb presentes no diretório c:\teste (na minha máquina). Vou usar a técnica de carregar os recordsets desconectados definindo o tamanho de uma página de dados que será exibida a cada acesso aos dados.

Para atingir este objetivo vou usar algumas propriedades do objeto Recordset ADO :

  1. PageSize - Indica o número de registros que uma página possui no Recordset.( O valor padrão é 10 registros)
  2. PageCount - Indica quantas páginas de dados um objeto Recordset possui.
  3. AbsolutePage - Define em qual página o registro atual esta localizado. Pode retornar os seguintes valores:
    1. adPosUnknown - O recordset esta vazio ( empty) a posição do registro atual é desconhecida.
    2. adPosBOF - O registro atual esta definido como BOF. (O valor numérico é -2)
    3. adPosEOF - O registro atual esta definido como EOF. (O valor numérico é -3)
  4. RecordCount - Define o número total de registros de um recordset ADO. (
  5. AbsolutePosition - recupera a posição atual do cursor do recordset. (o cursor deve suportar a propriedade)

Definindo Páginas

A técnica de paginar através de um recordset permite  definir  páginas do recordset com um certo número de registros; cada página possui então um número e uma certa quantidade de registros. Para mover-se para uma página e exibir seus registros basta especificar o número da página e ler todos os registros desta página no recordset. As etapas podem ser resumidas assim :

  1. Definimos um número de registros em uma página do recordset atribuindo um valor para a propriedade PageSize ( 10 é o valor padrão )
  2. Para ir para uma determinada página especificamos o número da página usando a propriedade AbsolutePage
  3. Para sabermos quantas páginas possui o recordset usamos a propriedade PageCount
Usando um Recordset Desconectado

Eu já tratei deste assunto no artigo - ADO - Trabalhando com Recordsets sem uma base de dados - por isto não vou me aprofundar no tema.(Dê uma olhada no artigo...). Só quero fazer uma pequena ressalva ; para criar um recordset desconectado eu não preciso necessariamente usar um cursor do lado do cliente (client-side) e um bloqueio em lote do tipo otimista ( batch optimistic locking type).

Quer saber por que ? Bem se não houver uma conexão com o servidor o cursor será implicitamente do lado do cliente e neste caso o VB assume automaticamente o bloqueio em lote do tipo otimista ; portanto basta definirmos a variável objeto e instancia-la.

Eu não preciso fazer assim :

rst.LockType = adLockBatchOptimistic

rst.CursorLocation = adUseClient

Posso fazer assim :
Dim rst As ADODB.Recordset

Set rst = New ADODB.Recordset

A próxima etapa será adicionar os campos ao construtor ; para isto usamos o método Append da coleção Fields :
rst.Fields.Append "Código", adVarChar

rst.Fields.Append "Nome", adVarChar

Após ter criado o recordset podemos incluir os registros usando método AddNew após abrir o recordset:
rst.Open
rst.AddNew
rst("Código") = "123"
rst("Nome") = "José Carlos Macoratti"
rst.Update
Criando o projeto

- Inicie um novo projeto no VB e no formulário padrão insira um componente DataGrid , quatro botões de comando e dois componentes Label , conforme figura abaixo :

- Na seção General Declarations do formulário vamos definir as variáveis :

Option Explicit
Private conn As ADODB.Connection
Private rst As ADODB.Recordset
Private subRst As ADODB.Recordset
Const PAGE_SIZE = 12
Dim reg As Integer
- conn é a variável objeto para conexão

- rst e subRst são as variáveis objeto do tipo Recordset

- PAGE_SIZE define o tamanho da página

- reg é a variável que armazena o número de registros atual

- No evento Load do formulário insira o código abaixo:

Private Sub Form_Load()
Dim sql As String

Set conn = New ADODB.Connection

With conn
   .Provider = "Microsoft.Jet.OLEDB.4.0"
   .ConnectionString = "Data Source=c:\teste\Northwind.mdb"
   .Open
End With

Set subRst = New ADODB.Recordset
Set rst = New ADODB.Recordset

Command1(2).Caption = "Próximos >" & PAGE_SIZE
Command1(1).Caption = "Anteriores < " & PAGE_SIZE

sql = "SELECT CódigoDoCliente, NomeDoDestinatário, DataDoPedido FROM Pedidos"

With rst
  .CursorLocation = adUseClient
  .PageSize = PAGE_SIZE
  .Properties("Initial Fetch Size") = PAGE_SIZE
  .Open sql, conn, adOpenKeyset, , adAsyncFetchNonBlocking
Set DataGrid1.DataSource = PaginarRecordset(rst)
End With

reg = PAGE_SIZE
lblreg.Caption = reg
End Sub

- No código acima eu estou usando o Provedor ADO OLE DB para o Access versão 4.0 e exibindo os campos :CódigoDoCliente, NomeDoDestinatário, DataDoPedido da tabela Pedidos.

- O código associado aos botões de comando que fazem a paginação pelos registros é dado abaixo :

Private Sub Command1_Click(Index As Integer)

Dim novaPagina As Long

With rst
Select Case Index
  Case 0
     novaPagina = 1
     reg = PAGE_SIZE
     lblreg.Caption = reg
  Case 1
     novaPagina = .AbsolutePage - 1
     reg = reg - PAGE_SIZE
     If reg < PAGE_SIZE Then
       reg = PAGE_SIZE
     End If
     lblreg.Caption = reg
  Case 2
     novaPagina = .AbsolutePage + 1
     reg = reg + PAGE_SIZE
     If reg > rst.RecordCount Then
        reg = rst.RecordCount
     End If
     lblreg.Caption = reg
  Case 3
     novaPagina = .PageCount
     reg = rst.RecordCount
     lblreg.Caption = reg
End Select

If novaPagina < 1 Or novaPagina > .PageCount Then
   Exit Sub
End If

 .AbsolutePage = novaPagina
 Set DataGrid1.DataSource = PaginarRecordset(rst)

End With
End Sub

- O código da função que realiza efetivamente a página é dada a seguir :

Private Function PaginarRecordset(recset As ADODB.Recordset) As ADODB.Recordset

Dim x As Long
Dim fld As Field
Dim origPage As Long

origPage = IIf(recset.AbsolutePage > 0, recset.AbsolutePage, 1)

With subRst
  If .State = adStateOpen Then .Close

  'Cria campos
  For Each fld In recset.Fields
     .Fields.Append fld.Name, fld.Type, fld.DefinedSize, fld.Attributes
  Next fld

  'Inclui registros
  .Open
  For x = 1 To PAGE_SIZE
 
    If recset.EOF Then Exit For
      .AddNew
 
    For Each fld In recset.Fields
      subRst(fld.Name) = fld.Value
    Next fld

    .Update
    recset.MoveNext

  Next x

.MoveFirst
recset.AbsolutePage = origPage

End With

Set PaginarRecordset = subRst

End Function

- Finalmente o código que encerra a aplicação , fecha os objetos e libera a memória.

Private Sub Form_Unload(Cancel As Integer)
subRst.Close
Set subRst = Nothing
rst.Close
Set rst = Nothing
conn.Close
Set conn = Nothing
End Sub

Ao excecutar o projeto teremos o formulário exibido como abaixo:

Até o próxima artigo ... Bye...

Veja os Destaques e novidades do SUPER DVD Visual Basic (sempre atualizado) : clique e confira !

Quer migrar para o VB .NET ?

Quer aprender C# ??

Quer aprender os conceitos da Programação Orientada a objetos ?

Quer aprender o gerar relatórios com o ReportViewer no VS 2013 ?

Quer aprender a criar aplicações Web Dinâmicas usando a ASP .NET MVC 5 ?


  Gostou
?   Compartilhe no Facebook   Compartilhe no Twitter

 

Referências:


José Carlos Macoratti