konto usunięte

Temat: DAO recordset - liczenie rekordów

Jak sie powinno liczyć rekordy ?

.recordcount wbrew nazwie nie zwraca ilośći rekordów tylko indeks bieżącego, czyli trzeba zrobić .movelast żeby działało. Movelast z kolei wykrzacza się jeżeli nie ma łekołdów. Wiem ze to wszystko pikuś do przeskoczenia, ale czy zaprawdę nie ma prostszego sposobu ? Dlaczego to wszystko jest takie po%@ane ?

Obiekty excela to przy tym dziadostwie szczyt elegancji i intuicyjności.

konto usunięte

Temat: DAO recordset - liczenie rekordów

A czy nie aby przypadkiem .Properties.Count ?

EDIT: co ja chrzanie, toż to liczy propertiesy po prostu...
Jednak dawno do vba nie zaglądałem :)Piotr S. edytował(a) ten post dnia 03.11.09 o godzinie 16:45
Bartek Borczyk

Bartek Borczyk Operator liczb i
słów

Temat: DAO recordset - liczenie rekordów

Maciek Głuszak:
Jak sie powinno liczyć rekordy ?

.recordcount wbrew nazwie nie zwraca ilośći rekordów tylko indeks bieżącego, czyli trzeba zrobić .movelast żeby działało. Movelast z kolei wykrzacza się jeżeli nie ma łekołdów. Wiem ze to wszystko pikuś do przeskoczenia, ale czy zaprawdę nie ma prostszego sposobu ? Dlaczego to wszystko jest takie po%@ane ?

Obiekty excela to przy tym dziadostwie szczyt elegancji i intuicyjności.

Ta, strasznie irytuje.

Ja to zawsze tak, ale ty chyba też.


Sub IlośćRekordów()
Dim dbsBieżąca As DAO.Database
Dim strTabela_Nazwa As String
Dim rcsTabela As DAO.Recordset
Dim lngIlość As Long

Set dbsBieżąca = CurrentDb
Set rcsTabela = dbsBieżąca.TableDefs(strTabela_Nazwa).OpenRecordset(dbOpenTable)

With rcsTabela
If Not .EOF Then
.MoveLast
lngIlość = .RecordCount
.MoveFirst
End If
.Close
End With

MsgBox "Liczba rekordów: " & lngIlość

Set rcsTabela = Nothing
Set dbsBieżąca = Nothing
End Sub

konto usunięte

Temat: DAO recordset - liczenie rekordów

No to chyba nie ma innego wyjścia rzeczywiście..
Karol Wojda

Karol Wojda Student,
Politechnika
Świętokrzyska w
Kielcach

Temat: DAO recordset - liczenie rekordów

A jakie polecenie jest do zliczenia kolumn z tabeli? Muszę wczytać do tablicy dane, które są poziomo a nie pionowo. Chciałbym, żeby wczytywanie było dynamiczne jeżeli ktoś np. doda lub usunie kolumnę. W poniższej procedurze na sztywno deklaruje wielkość tablicy i późniejszą pętlę For ....

Sub test()
Dim tablica() As Single
Dim i As Integer
Dim rs As New ADODB.Recordset
rs.Open "Select * From tblRoczniki where rok=2006", CurrentProject.Connection, adOpenKeyset, adLockOptimistic

ReDim tablica(12)
For i = 0 To 11
tablica(i) = rs.Fields(i + 1)
Debug.Print tablica(i)
Next i
rs.Close
Set rs = Nothing
End Sub

Temat: DAO recordset - liczenie rekordów

nie mam jak sprawdzić, ale chyba .fields.count
Michał Dziubek

Michał Dziubek Programista,
INFORM\'1

Temat: DAO recordset - liczenie rekordów

Możesz to zrobić pętlą for each
np tak
i=1
for each fld in rst.Fields
redim preserve tablica(i)
tablica(i)=fld.value
i=i+1
next
Tomasz Gryzio

Tomasz Gryzio Dyrektor
zarządzający/Trener/
Konsultant - It
School

Temat: DAO recordset - liczenie rekordów

@Bartosz Borczyk

Kod Kolegi Bartosza oczywiście działa i jest dokładnie tym co w takich sytuacjach jest potrzebne.

Pozwolę sobie dodać od siebie, że tak kod:

Sub test()
Dim dbsBieżąca As DAO.Database
Dim strTabela_Nazwa As String
Dim rcsTabela As DAO.Recordset
Dim lngIlość As Long

Set dbsBieżąca = CurrentDb
Set rcsTabela = dbsBieżąca.OpenRecordset("select count(1) from employees")

Debug.Print "Liczba rekordów: " & rcsTabela.Fields(0)

Set rcsTabela = Nothing
Set dbsBieżąca = Nothing
End Sub

jest krótszy, zwraca wartość ilości rekordów i potrafi działać duuużo szybciej (w zależności od wielkości recordseta - pamiętajmy o movelast!) oraz działa również w przypadku gdy z jakichś przyczyn jesteśmy zmuszeni do używania recordsetów ActiveX Data Objects (ADO) w wersji 2.0 lub nowszej, gdy typu kursora jest adOpenForwardonly lub adOpenDynamic:

Sub test()
Dim rcsTabela As New ADODB.Recordset
rcsTabela.Open "select count(1) from employees", CurrentProject.Connection, adOpenForwardonly , adLockOptimistic
Debug.Print rcsTabela.RecordCount 'zwraca -1
Debug.Print rcsTabela.Fields(0) 'zwraca 107
Set rcsTabela = Nothing
Set dbsBieżąca = Nothing
End Sub

w przypadku innych kursorów RecordCount zwraca prawidłowe wyniki.

Pozdrawiam Tomasz Gryzio
Tomasz Gryzio

Tomasz Gryzio Dyrektor
zarządzający/Trener/
Konsultant - It
School

Temat: DAO recordset - liczenie rekordów

@Karol Wojda

Oczywiście jest sposób na policzenie zwróconych kolumn w recordsecie ADO:

Sub test()
Dim rcsTabela As New ADODB.Recordset
rcsTabela.Open "select * from employees", CurrentProject.Connection, adOpenForwardonly , adLockOptimistic
Debug.Print rcsTabela.Fields.Count 'zwraca 11
Set rcsTabela = Nothing
Set dbsBieżąca = Nothing
End Sub

Przy wykorzystaniu zwróconej wartości jesteś w stanie zbudować tabelę o dynamicznej w wielkości:

Sub test()
Dim tabela() As Variant
Dim k As Currency
Dim l As Currency

Dim tabela
Dim rcsTabela As New ADODB.Recordset
rcsTabela.Open "select * from employees", CurrentProject.Connection, adOpenDynamic, adLockOptimistic
k = rcsTabela.Fields.Count
l = rcsTabela.RecordCount
Set rcsTabela = Nothing
Set dbsBieżąca = Nothing
ReDim tabela(0 To l, 0 To k) As String
(...)

End Sub
i zainicjalizować jej wartości podwójną pętlą, ale ja osobiści poleciłbym funkcję getrows(rows,start,fields) - zwraca tabelę (array) budowaną na podstawie recordsetu ADO [dla recordsetu DAO również jest funkcja getrows, ale posiada inną składnię]

Sub test()

Dim tabela() As Variant

Dim rcsTabela As New ADODB.Recordset
rcsTabela.Open "select * from employees", CurrentProject.Connection, adOpenDynamic, adLockOptimistic
tabela = rcsTabela.GetRows()

Debug.Print tabela(1, 100) 'zwraca Jennifer - prawidłowo

Set rcsTabela = Nothing
Set dbsBieżąca = Nothing

End Sub

Pozdrawiam Tomasz Gryzio
Karol Wojda

Karol Wojda Student,
Politechnika
Świętokrzyska w
Kielcach

Temat: DAO recordset - liczenie rekordów

A jak wyświetlić później chociażby rekordy z tablicy wczytanej z ożyciem funkcji GetRows ?

Sub test5435()

Dim k As Currency
Dim l As Currency
Dim i As Integer
Dim tabela
Dim rcsTabela As New ADODB.Recordset
rcsTabela.Open "Select * From tblRoczniki where Rok = 2006", CurrentProject.Connection, adOpenKeyset, adLockOptimistic

k = rcsTabela.Fields.Count
Debug.Print k 'zwraca 13, pierwsza kolumna to numer roku

ReDim tabela(0 To k) As String
tabela = rcsTabela.GetRows()

For i = 0 To k - 2
Debug.Print tabela(i)
Next i

Set rcsTabela = Nothing
End Sub

Procedura zwraca komunikat Subscript out of range
Tomasz Gryzio

Tomasz Gryzio Dyrektor
zarządzający/Trener/
Konsultant - It
School

Temat: DAO recordset - liczenie rekordów

Poniższy kod działa bez deklarowania wielkości tablicy:

Sub test()

Dim tabela() As Variant ' [b] tutaj deklaruje zmienna tablicową [\b]

Dim rcsTabela As New ADODB.Recordset
rcsTabela.Open "select * from employees", CurrentProject.Connection, adOpenDynamic, adLockOptimistic
tabela = rcsTabela.GetRows()

Debug.Print tabela(1, 100) ' [b] zwraca Jennifer - prawidłowo - tu wyświetlam zawarość tabela(1,100) - pierwszy wymiar reprezentuje kolumny, drugi wiersze, gdzie sam nigdzie nie redim[owalem] tablicy [\b]

Set rcsTabela = Nothing
Set dbsBieżąca = Nothing

End Sub

U Ciebie mogłoby wyglądać to tak:

Sub test5435()

Dim tabela() as Variant
Dim rcsTabela As New ADODB.Recordset
rcsTabela.Open "Select * From tblRoczniki where Rok = 2006", CurrentProject.Connection, adOpenKeyset, adLockOptimistic

tabela = rcsTabela.GetRows()

For i = 0 To Ubound(tabela,2)
for j = 0 to ubound(tabela,1)
Debug.Print tabela(j,i)
Next
Next
Set rcsTabela = Nothing
End Sub

Błędy miałeś w liniach:
1. Dim tabela - to ma być tablica czyli -> Dim tabela()
2. ReDim tabela(0 To k) As String - getrows sobie poradzi z redim[owaniem] tablicy, jeśli zrobisz to niepoprawnie to będzie błąd nr 9
3. Debug.Print tabela(i) - to jest tablica dwuwymiarowa, a odwołujesz się do jednego wymiaru

Pozdrawiam Tomasz Gryzio

Temat: DAO recordset - liczenie rekordów

Witam
Posiadam problem z RecordCount'em
Sub filtruj()

Dim sQL, sQL1 As String, strKryteria As String
Dim i As Integer
Dim rs As DAO.Recordset
Dim db As DAO.Database

Set db = CurrentDb

sQL1 = "SELECT ID_Klienta, chr_Nazwa, chr_NIP, chr_Wojew, chr_Miejscowosc, " _
& "chr_Adres, chr_Os_Kont_Imie, chr_Os_Kont_Nazwisko " _
& "FROM tbl_Klienci " _
& "ORDER BY ID_Klienta;"
If Not IsNull(Me.txtNazwa_Klienta) Then
If IsNothing(strKryteria) Then
strKryteria = strKryteria & "chr_Nazwa Like '*" & Me.txtNazwa_Klienta & "*'"
Else
strKryteria = strKryteria & " AND chr_Nazwa like '*" & Me.txtNazwa_Klienta & "*'"
End If
End If

If Not IsNull(Me.txtNIP) Then
If IsNothing(strKryteria) Then
strKryteria = strKryteria & "chr_NIP = '" & Me.txtNIP & "'"
Else
strKryteria = strKryteria & " AND chr_NIP = '" & Me.txtNIP & "'"
End If
End If

If Not IsNull(Me.txtMiejscowosc) Then
If IsNothing(strKryteria) Then
strKryteria = strKryteria & "chr_Miejscowosc = '" & Me.txtMiejscowosc & "'"
Else
strKryteria = strKryteria & " AND chr_Miejscowosc = '" & Me.txtMiejscowosc & "'"
End If
End If

sQL = "SELECT tbl_Klienci.ID_Klienta, tbl_Klienci.chr_Nazwa, tbl_Klienci.chr_NIP, tbl_Klienci.chr_Wojew," _
& "tbl_Klienci.chr_Miejscowosc, tbl_Klienci.chr_Adres, tbl_Klienci.chr_Os_Kont_Imie, tbl_Klienci.chr_Os_Kont_Nazwisko" _
& " FROM tbl_Klienci" _
& " WHERE " & strKryteria _
& " ORDER BY tbl_Klienci.ID_Klienta;"

Set rs = db.OpenRecordset(sQL)

With rs
If Not .EOF Then
.MoveLast
i = .RecordCount
.MoveFirst
End If
.Close
End With

If i = 0 Then
MsgBox "Brak rekordów do wyświetlenia. Wprowadź ponownie wyrażenie kwerendy!", vbOKOnly
Me.txtMiejscowosc = ""
Me.txtNazwa_Klienta = ""
Me.txtNIP = ""
Me.txtNazwa_Klienta.SetFocus
Me.Lista16.RowSourceType = "Table/Query"
Me.Lista16.RowSource = sQL1
Else
Me.Lista16.RowSourceType = "Table/Query"
Me.Lista16.RowSource = sQL
End If

Set rs = Nothing
Set db = Nothing

End Sub

Chodzi o to że w przypadku wpisania kryterium, które wyszuka rekordy pole list zwraca recordset, natomiast w przypadku wpisania kryterium nomuch, każde kolejne wywolanie procedury generuje msgbox o braku rekordów, pomimo spełnionego kryterium.

konto usunięte

Temat: DAO recordset - liczenie rekordów

Krzysztof B.:
Witam
Posiadam problem z RecordCount'em
Sub filtruj()

Dim sQL, sQL1 As String, strKryteria As String
Dim i As Integer
Dim rs As DAO.Recordset
Dim db As DAO.Database

Set db = CurrentDb

sQL1 = "SELECT ID_Klienta, chr_Nazwa, chr_NIP, chr_Wojew, chr_Miejscowosc, " _
& "chr_Adres, chr_Os_Kont_Imie, chr_Os_Kont_Nazwisko " _
& "FROM tbl_Klienci " _
& "ORDER BY ID_Klienta;"
If Not IsNull(Me.txtNazwa_Klienta) Then
If IsNothing(strKryteria) Then
strKryteria = strKryteria & "chr_Nazwa Like '*" & Me.txtNazwa_Klienta & "*'"
Else
strKryteria = strKryteria & " AND chr_Nazwa like '*" & Me.txtNazwa_Klienta & "*'"
End If
End If

If Not IsNull(Me.txtNIP) Then
If IsNothing(strKryteria) Then
strKryteria = strKryteria & "chr_NIP = '" & Me.txtNIP & "'"
Else
strKryteria = strKryteria & " AND chr_NIP = '" & Me.txtNIP & "'"
End If
End If

If Not IsNull(Me.txtMiejscowosc) Then
If IsNothing(strKryteria) Then
strKryteria = strKryteria & "chr_Miejscowosc = '" & Me.txtMiejscowosc & "'"
Else
strKryteria = strKryteria & " AND chr_Miejscowosc = '" & Me.txtMiejscowosc & "'"
End If
End If

sQL = "SELECT tbl_Klienci.ID_Klienta, tbl_Klienci.chr_Nazwa, tbl_Klienci.chr_NIP, tbl_Klienci.chr_Wojew," _
& "tbl_Klienci.chr_Miejscowosc, tbl_Klienci.chr_Adres, tbl_Klienci.chr_Os_Kont_Imie, tbl_Klienci.chr_Os_Kont_Nazwisko" _
& " FROM tbl_Klienci" _
& " WHERE " & strKryteria _
& " ORDER BY tbl_Klienci.ID_Klienta;"

Set rs = db.OpenRecordset(sQL)

With rs
If Not .EOF Then
.MoveLast
i = .RecordCount
.MoveFirst
End If
.Close
End With

If i = 0 Then
MsgBox "Brak rekordów do wyświetlenia. Wprowadź ponownie wyrażenie kwerendy!", vbOKOnly
Me.txtMiejscowosc = ""
Me.txtNazwa_Klienta = ""
Me.txtNIP = ""
Me.txtNazwa_Klienta.SetFocus
Me.Lista16.RowSourceType = "Table/Query"
Me.Lista16.RowSource = sQL1
Else
Me.Lista16.RowSourceType = "Table/Query"
Me.Lista16.RowSource = sQL
End If

Set rs = Nothing
Set db = Nothing

End Sub

Chodzi o to że w przypadku wpisania kryterium, które wyszuka rekordy pole list zwraca recordset, natomiast w przypadku wpisania kryterium nomuch, każde kolejne wywolanie procedury generuje msgbox o braku rekordów, pomimo spełnionego kryterium.

Obliczyć liczbę rekordów zawsze możesz używając fukcji DCount w VBA, możesz również policzyć rekordy bezpośrednio w stringu kwerendy który napisałeś używając "Select count()". Nie polecam jednak używania ".RecordCount" jako warunku sprawdzenia czy są rekordy aby wykonać jakiś kod, ponieważ jest to funkcja obciążająca wykonanie. Co do filtrowania. Proponuje inne podejście. Zbudować kwerendę i w klauzuli where przy pomocy iif umieścić warunki odnoszące się bezpośrednio do pól w formularzu, jest to bezpieczne i szybkie w wykonaniu rozwiązanie. Możesz podesłać mi próbkę bazy to coś poradzimy.

Temat: DAO recordset - liczenie rekordów

Witam,
Pierwotnie chciałem użyć" DCount" ale uznałem, że RecordSet lepiej sobie z tym poradzi.Jak pokazało doświadczenie - myliłem się.
Co do utworzenia kwerendy dla funkcji filtrującej uznałem, że nie ma sensu generowania kolejnego obiektu (aplikacja jest mocno rozbudowana), jednocześnie procedura użyta jest tylko w jednym form.
Dziękuję za cenną uwagę. Sprawdzę czy w ogóle formularz wyszukiwania jest mi potrzebny do całokształtu aplikacji.
Krzysztof Szurlej

Krzysztof Szurlej aktualnie bezrobotny
:) szukający pracy

Temat: DAO recordset - liczenie rekordów

Witam,
Mam pewien problem, nie jestem informatykiem ale chciałem zrobić taką prostą bazę majątku u mnie w straży. Korzystając z pomocy dostępnych źródeł stworzyłem bazę ale nie mogę sobie poradzić z nadawaniem indeksu. w książce był taki kod do wpisania:
Private Sub Form_AfterUpdate()
On Error GoTo errHandler
Dim rst As New ADODB.Recordset, i As Integer
rst.Open "SELECT * FROM Sygnatury", _
CurrentProject.Connection, adOpenKeyset, _
adLockOptimistic
For i = 1 To CInt(Me.Ile.Text)
rst.AddNew
rst!ID_P = Me.ID_P
rst!Sygnatura = Format(Year(Me.Data_p), "0000") & _
Format(Me.ID_P, "000")
rst!Status = 1
Next i
rst.MovePrevious
rst.Close
Me.Refresh
Exit Sub
errHandler:
MsqBox ErrDescription
End Sub
ale podczas wykonywania tego wyświetla mi błąd. Będę wdzięczny za pomoc :)

Następna dyskusja:

ado a dao




Wyślij zaproszenie do