|
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.
|
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. |