Selecionando registro de um Recordset usando GetRows
Selecionar uma determinada quantidade de registros de um base de dados é uma das tarefas mais frequentes em aplicações usando banco de dados. E pode ser o gargalo da sua aplicação se não for bem planejada. A esta altura já cabe a pergunta : Como você faz para extrair registros de um base de dados ? Qual o método frequentemente utilizado ? Vamos analisar...
Selecionado registros da tabela Authors da base de dados Biblio.mdb
1-) Creio que muitos usam o seguinte código para tal tarefa:
Dim codigo as integer
Dim autor as string
Dim ano as integer
Set db = DBEngine.Workspaces(0).OpenDatabase(app.path & "\blibio.mdb")
Set rs = db.OpenRecordset("Authors", dbOpenTable)
Do Until tabela.EOF
codigo = rs("Au_Id")
autor = rs("Author")
ano = rs("Year_Born")
rs.movenext
....
aqui voce realiza o seu processsamento
Loop
rs.close
set rs=nothing
|
Ou seja, você vai percorrendo (movenext) o Recordset , extraindo os registros e fazendo o processamento. Funciona ! voce pode dizer . Tudo bem , funciona , mas você já pensou no fato de que se o Recordset possuir 1000 registros e você está selecionando três campos vai ter 3000 requisições de leitura a sua base de dados ? E se a base de dados possuir 10.000 registros e você estiver selecionando 10 campos ? serão 100.000 requisições de leitura.
Para preencher um grid com os registros selecionados também enfrentamos o mesmo problema. Como os controles vinculados oneram demais o processamento, geralmente usamos o modo não vinculado(sem usar um controle de dados) dos grids (DBGrid) . Para preencher um grid no modo não vinculado precisamos conhecer dois parâmetros: quantas linhas e quantas colunas irão compor o grid. O número de linhas é o total de registros que estaremos selecionando do recordset e o número de colunas são os campos que selecionamos do recordset. Aqui começam os problemas...
Para conhecermos o número de campos do recordset é simples , usamos a propriedade Count do objeto Recordset, assim:
| Dim icampos as integer Set db = DBEngine.Workspaces(0).OpenDatabase(app.path & "\blibio.mdb") Set rs = db.OpenRecordset("Authors", dbOpenTable) icampos = rs.fields.Count |
E para determinar a quantidade de registros selecionados ? Geralmente os métodos mais usados são:
1-) Usando a propriedade RecordCount
| dim registros Set db = DBEngine.Workspaces(0).OpenDatabase(app.path & "\blibio.mdb") Set rs = db.OpenRecordset("Authors", dbOpenTable) rs.movelast rs.movefirst registros = rs.Recordcount.... |
Ou seja você percorrendo todo o Recordset até o final e volta depois ao início para saber quantos registros vai ter o grid. Acho que nem preciso dizer que este método não é aconselhável .
2-) Usando a função agregada Count da SQL
| dim registros Set db = DBEngine.Workspaces(0).OpenDatabase(app.path & "\blibio.mdb") Set rs = db.OpenRecordset("Authors", dbOpenTable) set rstmp=db.OpenRecordset("SELECT
Count(*) as Registros From Authors") |
Este método pode ser mais rápido que o anterior mas você vai precisar criar dois recordsets : um para preencher o grid e outro para obter a quantidade de registros.
Existe uma forma melhor de fazer o serviço ? Sim existe , usando o método GetRows, vejamos então...
O método GetRows foi introduzido ainda nos tempos da DAO 3.0 e RDO 1.0 , mas apresentava problemas de implementação . Com o advento da ADO o método voltou aperfeiçoado e funcionando perfeitamente.
O objetivo em usar o método GetRows é selecionar múltiplos registros de um recordset e armazená-los em um vetor bidimensional. Nosso foco será o método GetRows da ADO 2.0.
A sintaxe na utilização de GetRows é a seguinte:
Nome_do_Vetor = Recordset.GetRows (Linhas , Inicio, Campos )
GetRows é usado para copiar registro de um Recordset para um vetor bidimensional. O primeiro item do vetor identifica os campos (colunas) e o segundo item identifica os registros.
A variável associada ao vetor tem o seu tamanho alocado dinamicamente quando da seleção dos registros.
Se não for informado o valor do argumento Linhas , GetRows retorna todos os registros do recordset e se for solicitado mais registros do que o disponível , GetRows retorna somente a quantidade existente.
Para restringir os campos selecionados, voce pode passar como argumento o nome do campo ou o seu número ou ainda passar como argumento um vetores de campos/números . Após GetRows retornar os registros do Recordset o próximo registro não lido se torna o registro atual, ou se não há mais registros , a propriedade EOF é definida como True.
Vejamos então o código para selecionar registros de um recordset usando GetRows:
Dim codigo as integer
Dim autor as string
Dim ano as integer
Dim contador as integer
Dim dbvetor as variant
Set db = DBEngine.Workspaces(0).OpenDatabase(app.path & "\blibio.mdb")
Set rs = db.OpenRecordset("Authors", dbOpenTable)
dbvetor= rs.GetRows
rs.close
set rs=nothing
db.close
numero_de_colunas = Ubound(dbvetor,1)
numero_de_registros = Ubound(dbvetor,2)
for contador=0 to numero_de_registros
codigo = dbvetor(contador,1)
autor = dbvetor(contador,2)
ano = dbvetor(contador,3)
....
aqui voce realiza o seu processsamento
next
|
Vamos entender o código acima:
Ela retorna o valor maior para o indice do vetor na dimensão indicada. Assim se temos um vetor tridimensional definido como:
Dim A(1 To 100, 0 To 3, -3 To 4)
| Instrução | Valor Retornado |
UBound(A, 1) |
100 |
UBound(A, 2) |
3 |
UBound(A, 3) |
4 |
Assim quando fizemos:
numero_de_colunas = Ubound(dbvetor,1) numero_de_registros = Ubound(dbvetor,2)
Estamos retornando em numero_de_colunas o maior valor do índice para a primeira dimensão: Ora este é o valor relacionado a quantidade de campos selecionado e estamos retornando em numero_de_registros o maior valor para índice da segunda dimensão que é o valor relacionado com a quantidade de registros.
for contador=0 to numero_de_registros codigo = dbvetor(contador,1) autor = dbvetor(contador,2) ano = dbvetor(contador,3) .... aqui voce realiza o seu processsamento next |
Para encerrar abaixo temos um exemplo simples e prático de preenchimento de um MSFlexgrid usando o GetRows:
Private Sub Command1_Click()
Dim cnn As New ADODB.Connection
Dim rst As New ADODB.Recordset
Dim fld As ADODB.Field
Dim avarData() As Variant
Dim introws As Integer
Dim i As Integer
Dim j As Integer
Dim linha As String
'Ábre o Recordset
cnn.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\teste\nwind.mdb;"
'Open the forward-only, read-only recordset
rst.Open "Select * from Customers", cnn, adOpenForwardOnly, adLockReadOnly
'Seleciona todos os registros e armazena no vetor avarData
avarData = rst.GetRows
'fecha o recordset
rst.Close
Set rst = Nothing
'verifica se há registros selecionados
If introws > UBound(avarData, 2) Then
MsgBox "Não ha registros para selecionar ...", vbAbortRetryIgnore, "JcmSoft"
Exit Sub
End If
'calcula o total de campos e registros selecionados
colunas = UBound(avarData, 1)
registros = UBound(avarData, 2)
'define o numero de colunas do grid
Grid1.Cols = colunas
'defina as linhas e colunas fixas
Grid1.FixedCols = 0
Grid1.FixedRows = 1
'Preenche o grid
For i = 0 To registros
For j = 0 To colunas
linha = linha & avarData(j, i) & Chr(9)
Next j
Grid1.AddItem linha
linha = ""
Next i
End Sub
Private Sub Command2_Click()
Unload Me
End Sub
|
Ao executar o projeto inicialmente você verá a tela1 abaixo e , após clicar no botão Preencher Grid terá a figura 2.0 :
![]() |
![]() |
Bem... espero que façam bom proveito ....