Проблеми звітів в ACCESS, MS Office, Програмні керівництва, статті

Важливим елементом програм роботи з базами даних є механізм “звітів”. Так як структура баз може бути досить складною, для реалізації таких програм недостатньо знати основні можливості “конструктора звітів “. Може знадобитися знання ряду слабо документованих функцій і технологічних прийомів.

Вихідні документи в СУБД проектуються за допомогою механізму звітів. У MS Access цей механізм має масу можливостей, що дозволяють створювати вихідні документи без звернення до програмування на вбудованому мовою VBA. Однак не всі завдання можна вирішити таким шляхом.


Розглянемо приклад. Припустимо, є таблиця “TELEFKOD” телефонних кодів з 528-ю записами, початок якої має наступний вигляд:







































NPP

GOROD

KOD_TEL

OBLAST


1


Авдіївка


06236


Донецька


2


Якимівка


06131


Запорізька


3


Олександрія


05235


Кіровоградська


4


Олександрівка


06269


Донецька


5


Олександрівка


05269


Кіровоградська


6


Алушта


06560


Крим


Причому поле “NPP” має тип Лічильник (Довге ціле), особливість якого полягає в наступному: при видаленні запису в цьому полі віддаляється і значення, яке більше повторюватися не буде. У результаті перелік порядкових номерів може не збігтися з переліком значень в цьому полі.


У цьому звіті назви колонок (шапка таблиці) розміщені у верхньому колонтитулі, в якості номера по порядку використовується поле “NPP”, в нижньому колонтитулі вказується номер сторінки і додано Примітка звіту з кількістю виведених записів і прикладом підписів. Модуль класу порожній (тобто ніяких програмних кодів на мові VBA немає). Роздруковується такий звіт без проблем. Але можуть виникнути претензії до розміщення Примітки. За замовчуванням його властивість Не розривати має значення “Так”.


Це означає: якщо все Примітка не поміщається на останній сторінці рядків з даними, то воно буде цілком перенесено на наступну. Але не завжди таке рішення допустимо – особливо якщо друкується фінансовий документ. Тому можна поміняти значення цієї властивості на “Ні” – тоді Примітка буде починатися відразу після виведення останнього запису. Це вирішує дану проблему, але не до кінця. Може виникнути ситуація, коли один підпис (наприклад, Директора) виявиться на одній сторінці (останньої з даними), а інша перенесеться на наступний, – теж погано. Більш прийнятним рішенням у цьому випадку – з невеликою висотою Примітки – було б його розміщення повністю на окремій сторінці, але так, щоб до нього зверху автоматично додавалися кілька останніх рядків з даними. І ось тут без звернення до VBA вже не обійтися. Варіантом вирішення цього завдання може виявитися наступний текст Модуля класу з кодами обробки подій:






Option Compare Database
Option Explicit
Dim I1 As Integer, KolZap As Integer, KolZ As Integer
Dim dd As Database, zap As Recordset,
 
Private Sub Report_NoData (Cancel As Integer)
MsgBox (“А нету записів!”)
Cancel = True
End Sub
 
Private Sub Report_Open (Cancel As Integer)
Set dd = CurrentDb
Set zap = dd. OpenRecordset (” TELEFKOD”, dbOpenDynaset)
If Not zap. BOF Then
zap. MoveLast
KolZap = zap. RecordCount
End If
zap. Close
KolZ = 0
End Sub
 
Private Sub ВерхнійКолонтітул_Format (Cancel As Integer, FormatCount As Integer)
Me![EndStr1]. Visible = False
I1 = 0
End Sub
 
Private Sub ОбластьДанних_Format (Cancel As Integer, FormatCount As Integer)
I1 = I1 + 1
KolZ = Me. CurrentRecord
If I1 > 39 Then
If KolZap – KolZ < 3 Then
Me![EndStr1]. Visible = True
End If
End If
End Sub
 
 

По-перше, тут по ходу справи задіяно цікава властивість Report_NoData – обробка ситуації, коли в таблиці-джерелі даних немає записів. Текст процедури майже стандартний, рядок Cancel = True призводить до припинення друку звіту.


По-друге, в Області даних встановлено елемент управління Кінець сторінки, дія якого контролюється в модулі класу.


При форматуванні кожної нової сторінки його “видимість” відключається (Me! [EndStr1]. Visible = False). Включається ж при форматуванні Області даних – при настанні певної умови, яка складається з двох частин. Перша контролює область листа, на якому Примітка вже не може розміститися повністю. У даному звіті дослідним шляхом визначено, що такий момент виникає після друку 39-го рядка (If I1> 39 Then). Цілочисельний змінної, в якій враховується номер друкується рядки, є I1. При форматуванні заголовка вона обнуляється, а при форматуванні кожної нової рядки даних її значення збільшується на 1. Але цього мало – потрібно ще визначити, що виводяться останні рядки. Це робиться через дві інші змінні: KolZ, в яку заноситься номер поточного запису в печатаемой таблиці (KolZ = Me. CurrentRecord) і KolZap, в якій зберігається загальна кількість записів, розраховується при відкритті звіту (KolZap = zap. RecordCount). В кінцевому підсумку, якщо виникає ситуація друку останніх двох записів в зоні листа, де вже не може повністю розміститися Примітка, то вони друкуються разом з ним на наступній сторінці.


Але в цьому прикладі є і помилка – підсумкове поле для підрахунку кількості записів в Примітці звіту нарахувало 528 записів. А останній Номер по порядку значиться як “529”. Така ситуація можлива у випадку, якщо як номера по порядку виводиться поле, що має тип Лічильник, а в процесі заповнення таблиці були виконані видалення записів (у прикладі була видалена один запис). Тому як поля порядкового номера в звіті краще використовувати вільне поле, не пов’язане з вихідною таблицею. В якості даних для такого поля треба встановити значення “= 1” і вказати варіант Для всього в параметрі Сума з нагромадженням .


Може виникнути необхідність нумерації не тільки в межах всього звіту, але і посторінково. Це також робиться через вільне поле, але його заповнення виконується в модулі класу. Під нього оголошується нова змінна, наприклад: Dim NStrP As Integer. Вона повинна обнулятиметься при форматуванні заголовка і заповнюватися при форматуванні області даних, наприклад:



 






Private Sub ВерхнійКолонтітул_Format (Cancel As Integer, FormatCount As Integer)
…..
NStrP = 0
End Sub
 
Private Sub ОбластьДанних_Format (Cancel As Integer, FormatCount As Integer)
…..
NStrP = NStrP + 1
Me![NSTR1] = NStrP
End Sub
 

Останнім варіантом обліку рядків розглянемо нумерацію в групі. Access дозволяє сортувати і групувати дані прямо при виведенні. Ці настройки виконуються в Конструкторі через діалогове вікно Сортування і угруповання (викликається по команді меню Вид). Для створення угруповання з якого-небудь полю цього вікна, його (поле) треба вибрати в списку (у прикладі – поле OBLAST) і вказати “Так” у параметрі Тема групи. Тут же можна встановити сортування для інших полів без групування за ним (у прикладі – по полю GOROD). Висновок порядкового номера в групі проводиться в “вільному” поле, в параметрі Дані якого зазначено “= 1”, але Сума з нагромадженням встановлена ​​Для групи.


Наступною проблемою може виявитися розміщення в нижньому колонтитулі проміжних сум по якомусь полю. Така ситуація часто виникає у фінансових документах – наприклад, при роздруківці відомості на зарплату. На перший погляд, зробити це можна за технологією, розглянутої раніше: оголошується змінна, обнуляється при форматуванні заголовка і заповнюється при форматуванні області даних. Але оскільки результат повинен бути занесений в “вільне” поле, розміщене в іншому розділі (в Нижньому колонтитулі), сума виявиться неправильною – адже процес форматування деяких розділів “звітів” в Access може повторюватися! Це є особливістю технології підготовки “звітів” – потрібно пам’ятати про це при програмуванні. Зокрема, в розглянутому прикладі заповнення змінної для проміжної суми (SumStr) можна виконувати не при форматуванні області даних, а при відпрацюванні властивості друку області даних (ОбластьДанних_Print), в якій можна проконтролювати ситуацію – буде друкуватися лист з цими даними чи ні. І саме в залежності від результатів контролю має бути заповнено поле, розташоване в нижньому колонтитулі. Припустимо, воно має ім’я SumS, а змінна, в якій накопичується значення на сторінці, – SumStr. Тоді текст коду подібної процедури буде мати наступний вигляд:






Private Sub ОбластьДанних_Print (Cancel As Integer, PrintCount As Integer)
“PrintCount = 0 – сторінка не друкується, = 1 – буде друкуватися
 
SumStr = SumStr + NStrP
If PrintCount = 1 Then Me![SumS] = SumStr
End Sub
 
 

Подібна ж ситуація може виникнути при спробі використовувати Підлеглий звіт, який найчастіше вставляється в Примітка звіту або в Примітка групи. Якщо в ньому потрібно вказувати якесь розрахункове значення (наприклад, той же номер на сторінці), то воно може виявитися неправильним, тому що такий звіт буде форматуватися кілька разів.


Для вирішення проблеми команду заповнення поля № рядка на сторінці Підлеглого звіту треба перемістити з обробки події Форматування в обробку події Друк розділу Область даних, наприклад:






Private Sub ОбластьДанних_Print (Cancel As Integer, PrintCount As Integer)
NStrP = NStrP + 1
Me![NSTR1] = NStrP
SumStr = SumStr + NStrP
If PrintCount = 1 Then Me![SumS] = SumStr
End Sub
 

Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*