Wstęp
Do napisania tego posta skłoniła mnie prośba o pomoc na jednym z forów. Bezpośrednią przyczyną było jednak to, że nie udało mi się opublikować wypowiedzi z powodu silnika tegoż…
Problem
Tutaj jak mogę się domyślać chcemy mieć raport który “imituje” wersje papierową dokumentu, i chcemy niezależnie od ilości danych, aby na stronie była jakaś określona liczba rekordów. Przyjmimy że 20. Pierwsza moja myśl to było połączenie kwerendy źródłowej z jakąś tabelą i wymuszenie jej odpowiednie liczby np. tak:
Select top 20 * from (select 0 as s ,tekst from tabelaxrodlowa union all select 1 as s ,"" as tekst from tabelatymczasowa) as dt order by s
Jednak rozwiązanie niesie za sobą sporo problemów, bo nie weimy cz tych rekordow =< 20, a co jak będzie 21 itd.
Więc troszkę przypomniałem sobie działanie raportów i doszedłem do takiego rozwiązania:
Umieszczamy na stronie 20 rekordów, jeżeli jest mniej to dopisuje te co pozostały.
Żeby tego dokonać to musimy znać 3 rzeczy:
- liczbę rekordów w źródle
- liczbę rekordów na stronie
- numer bieżącego rekordu
ad.1
Liczbę rekordów poznamy poprzez dodanie w sekcji nagłówka raportu niezwiązanego pola o nazwie txtRC i właściwości źródło ustawionej na =Policz(*)
ad.2
To najprościej poprzez deklaracje zmiennej publicznej w module raportu.
ad.3
Dodanie niezwiązanego pola tekstowego w sekcji szczegóły ze źródłem = =1 i właściwością sumy bieżącej: wszędzie
Sprawa jest prosta: w momencie odpalenia raportu ustawiamy zmienną na ilość rekordów którą chcemy mieć na stronie, co 20 rekordów wymuszamy nową stronę, jeżeli jesteśmy w ostatnim rekordzie sprawdzamy ile nam pozostało do 20 i je dopisujemy.
Wykonanie
Wymuszenie strony co n elementów:
Trzeba dodać kontrolkę “podział strony” na raport w sekcji szczegóły i wymuszać nowa stronę poprzez ustawienie jej właściwości visible na true.
Łatwo to zrobić poprzez sprawdzenie reszty dzielenia, aktualnego rekordu przez liczbę rekordów na stronie:
Me.nowastrona.Visible = (Me.txtLP Mod ile = 0)
Dorysowanie pustych linii:
Tu jest trochę inaczej, jeżeli jesteśmy w ostatnim rekordzie i nie jest to rekord który powinien być ostatni, wtedy, zatrzymujemy przejście do następnego rekordu, i tak tyle razy ile mamy tych rekordów do zrobienia.
Jedyny myk jaki trzeba zastosować to to, że jeżeli pokazujemy dane z jednego pola w tabeli np. tekst, to na raporcie musimy mieć dwie lustrzane kontrolki:
1. txtTekst ze źródlem tekst
2. txtTekstPusty ze źródłem =””
chodzi o to że nie możemy zmienić źródła kontrolki podczas generowania raportu, więc w zależności od potrzeby ukrywamy ją lub nie.
Można nie mieć takiej kontrolki, ale wtedy linie tabeli nie opieramy na właściwości obramowania pola tekstowego, a na własnoręcznym rysowaniu linii w szczegółach.
Kod który to realizuje:
Private Sub Szczegóły_Format(Cancel As Integer, FormatCount As Integer) If Me.txtLP = Me.txtRC And Me.txtLP Mod ile <> 0 Then If pozostalo = -1 Then pozostalo = ile - (Me.txtLP Mod ile) Me.NextRecord = False pozostalo = pozostalo - 1 Me.tekst.Visible = True Me.tekstPusty.Visible = False ElseIf pozostalo > 0 Then Me.NextRecord = False pozostalo = pozostalo - 1 Me.tekst.Visible = False Me.tekstPusty.Visible = True End If Else Me.nowastrona.Visible = (Me.txtLP Mod ile = 0) Me.tekst.Visible = True Me.tekstPusty.Visible = False Me.nowastrona.Visible = (Me.txtLP Mod ile = 0) End If End Sub
Podsumowanie
To w zasadzie tyle, ciężko się to opisuje ale dla zainteresowanych przykładowa baza z raportem,
zachęcam do debugowania i zmieniania ilości rekordów na stronie.
0 Comments.