Dicas do OsmarJr

Como saber o número de registros em um recordset?


Muitas vezes desejamos saber alguma coisa sobre o número de registros com os quais estamos trabalhando. Normalmente desejamos saber ou se temos algum registro ou a quantidade de registros.

Autor:Por JasonM. Texto original.
Tradução: Osmar José Correia Júnior


Temos um método geral no VBA, usando a propriedade RecordCount do objeto DAO.RecordSet(1) que pode ser usado com qualquer conjunto de registros. Isto inclui tabelas e formulários (ou subformulários) vinculados.

Antes de entrarmos nos exemplos é necessário entender como funciona o recordCount. Ele não diz o número de registros em um recordset. Na verdade ele informa a quantidade de registros acessados no Recordset. Esses números podem ou não significar a mesma coisa.

Para ter certeza de que sejam a mesma coisa é necessário acessar todos os registros. A forma mais fácil de fazer isso é usar MoveLast para ir até o último registro. Após isso, RecordCount vai refletir o número real de registros no recordset.

Mais um ponto: o MoveLast pode ser bastante dispendioso e só precisamos dele para obter o número real de registros. Se precisamos saber apenas se o recordset tem registros, podemos usar a propriedade EOF.

Vamos aos exemplos. Vamos, primeiramente, examinar as tabelas, já que vanos trabalhar com conjuntos de registros. Todas as amostras, entretanto, serão similares. Então vamos ver eses casos detalhadamente.

UMA TABELA

Veja este exemplo de código:
Public Function Tabela_RecordCount(sTabela As String) As Long
Dim RS As DAO.Recordset

    Set RS = CurrentDb.OpenRecordset(sTabela)
    If Not (RS.EOF) Then
        RS.MoveLast
        Tabela_RecordCount = RS.RecordCount
    End If
    Set RS = Nothing
End Function


Na janela imediata:
?Tabela_RecordCount("TabelaVazia")
0
?Tabela_RecordCount("TabelaNãoVazia")
6


Dois pontos de interesse aqui:

Note que verificamos o EOF antes de tentar o MoveLast. Sem isso teriamos um erro em um recordset vazio.

O que aconteceria se verificasemos o RecordCount sem o MoveLast?

Como exemplo, em uma tabela local, com 6 registros, obtemos um resultado igual a 6 (correto). Em uma tabela vinculada, com 7.832 registros, recebemos um resultado igual a 1 (errado). O RecordCount deveria responder sempre com um valor diferente de zero se o recordset contiver registros mas, como podemos ver, sem o MoveLast, não podemos ter certeza de que estamos recebendo o resultado correto.

Vamos expandir um pouco mais este segundo ponto. Algumas vezes vemos (ou tentamos) algo semelhante a isto:

If (rs.RecordCount > 0) Then
    Debug.Print "Tem registros"
Else
    Debug.Print "Não tem registros"
End If

Nem sempre isso vai dar o resultado esperado. Existem circunstâncias em que RecordCount devolve -1 quando existem registros(2). Novamente, se desejamos verificar se existem registros, devemos usar EOF. A única coisa que podemos ter certeza quando usamos RecordCount sem um MoveLast anterior é que o resultado será diferente de zero se houver registros e 0 se não houver.

Existem outros métodos para obter o número de registros em tabelas, em SQL, e não utilizam o objeto Recordset. esses métodos não são cobertos neste artigo.

UM FORMULÁRIO
Agora que já sabemos como obter o número de registros de um recordset, precisamos saber como "pegar" o recordset desejado.

Para um formulário é bastante simples:
Private Sub cmdShowRecordCount_Click()
Dim rs As DAO.Recordset
Dim lRecordCount As Long
    Set rs = Me.RecordsetClone
    If Not (rs.EOF) Then
        rs.MoveLast
    End If
    lRecordCount = rs.RecordCount
    MsgBox lRecordCount & " registro(s)"
    Set rs = Nothing
End Sub


Note-se que usamos a propriedade RecordsetClone do formulário. Não queremos executar um MoveLast no conjunto de registros do formulário, já que isso reposicionaria o formulário no último registro. Para evitar isso, usamos RecordsetClone.

Entretanto, se apenas desejamos saber se temos registros, podemos usar o recordset do formulário, já que não haverá referência a registro.
Private Sub Form_Open(Cancel As Integer)
    If (Me.Recordset.EOF) Then
        MsgBox "Formulário sem registros"
    End If
End Sub


O RecordsetClone também poderia ser usado no código acima, sem problemas.

Para formulários devemos ter em mente, sempre, a diferença entre recordset e RecordsetClone.

UM SUBFORMULÁRIO
Subformulários derrubam muita gente e uma das razões está na necessidade de entender como referenciá-los. (Como referenciar campos em formulários).

Para obter a contagem de registros do recordset de um subformulário necessitamos referenciar a propriedade Form do controle subformulário (o subformulário, dentro de um formulário principal, é um controle como os outros - caixa de texto, caixa de combinação, etc).
vejamos um exemplo que apresenta uma caixa de mensagens que mostra o número de registros do formulário principal e do subformulário.
Private Sub cmdRecordCount_Click()
Dim rs As DAO.Recordset
Dim sMsg As String
Dim lRecordCount As Long

' Formulário principal
    rs = Me.RecordsetClone
    If Not (rs.EOF) Then
        rs.MoveLast
    End If l
    RecordCount = rs.RecordCount
    sMsg = "Formulário principal: " & lRecordCount & " registro(s)"

' Subformulário
    Set rs = Me.fsub.Form.RecordsetClone
    If Not (rs.EOF) Then
        rs.MoveLast
    End If
    lRecordCount = rs.RecordCount
    sMsg = sMsg & vbCrLf & "Subformulário: " & lRecordCount & " registro(s)"
    MsgBox sMsg
    Set rs = Nothing
End Sub

Em resumo:

1) Se desejamos saber se existem registros, podemos usar Recordset e verificar EOF.

2) Se desejamos saber quantos registros existem, usamos RecordsetClone, MoveLast e, então, RecordCount.

Uma nota que pode ser de interesse

Quando abrimos um recordset pela primeira vez, também podemos verificar o BOF para determinar se ela contém registros. Ou seja, se o conjunto de registros estiver vazio (sem registros), tanto EOF quanto [BOF[/i] serão verdadeiros.

Prefiro verificar EOF porque podemos criar loops como:
Do While Not rs.EOF
    ' Faz alguma coisa com cada registro
Loop


Isto combina a verificação de um recordset vazio e a estrutura de laço. Não dá para fazer o mesmo com BOF.

Não esqueça do [b]BOF[/i] pois podemos encontrar estruturas como:
    If (rs.EOF) Or (rs.BOF) Then
        'Sem registros
    End If


1) Mantive o foco em recordsets DAO já que os recordsets de formulários sempre são DAO, mesmo no Access 2000 e posteriores.

2) Normalmente com um objeto TableDef vinculado, não um Recordset, mas é mais fácil, para ser consistente.
Home

Contato | Copyright©Osmar José Correia Júnior | 09-Mar-2006 17:10