Проблеми звітів у ACCESS - Програмні продукти
p align="justify"> Важливим елементом програм роботи з базами даних є механізм "звітів". Так як структура баз може бути досить складною, для реалізації таких програм мало знати основні можливості "конструктора звітів". Може знадобитися ряду слабо документованих функцій та технологічних прийомів.
Вихідні документи до СУБД проектуються за допомогою механізму звітів. У MS Access цей механізм має багато можливостей, що дозволяють створювати вихідні документи без звернення до програмування вбудованою мовою VBA. Проте чи всі завдання можна вирішити таким шляхом.
Причому поле "NPP" має тип Лічильник (Довге ціле), особливість якого полягає в наступному: при видаленні запису в цьому полі видаляється значення, яке більше повторюватися не буде. В результаті перелік порядкових номерів може не збігатися з переліком значень цього поля.
У цьому звіті назви колонок (шапка таблиці) розміщені у верхньому колонтитулі, як номер по порядку використовується поле "NPP", у нижньому колонтитулі вказується номер сторінки і додано Примітку звіту з кількістю записів, що виводяться, і прикладом підписів. Модуль класу порожній (тобто, ніяких програмних кодів на мові VBA немає). Роздруковується такий звіт без проблем. Але можуть виникнути претензії щодо розміщення Примітки. За промовчанням його властивість Не розривати має значення "Так".
Це означає: якщо все Примітка не міститься на останній сторінці рядків з даними, вона буде повністю перенесена на наступну. Але не завжди таке рішення допустиме – особливо якщо друкується фінансовий документ. Тому можна змінити значення цієї властивості на "Ні" - тоді Примітка почнеться відразу після виведення останнього запису. Це вирішує розглянутупроблему, але не до кінця. Може виникнути ситуація, коли один підпис (наприклад, Директора) опиниться на одній сторінці (останній з даними), а інший перенесеться на наступний, теж погано. Більш прийнятним рішенням у цьому випадку - з невеликою висотою Примітки - було б його розміщення повністю на окремій сторінці, але так, щоб зверху до нього автоматично додавалися кілька останніх рядків з даними. І тут без звернення до VBA вже не обійтися. Варіантом розв'язання цього завдання може бути наступний текст Модуля класу з кодами обробки подій:
По-перше, тут у процесі справи задіяна цікава властивість 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. Вона повинна обнулятися при форматуванні верхнього колонтитула і заповнюватися при форматуванні області даних, наприклад:
Останнім варіантом обліку рядків розглянемо нумерацію групи. Access дозволяє сортувати та групувати дані прямо при виведенні. Ці налаштування виконуються у Конструкторі через діалогове вікно Сортування та групування (викликається за командою меню Вигляд) . Для створення угруповання по якомусь полі цього вікна, його (поле) треба вибрати в списку (у прикладі - поле OBLAST) і вказати "Так" у параметрі Заголовок групи. Тут же можна встановитисортування для інших полів без угруповання за ними (у прикладі – по полю GOROD). Виведення порядкового номера в групі здійснюється у "вільному" полі, у параметрі Дані якого вказано "=1", але Сума з накопиченням встановлена Для групи.
Наступною проблемою може бути розміщення в нижньому колонтитул проміжних сум по якому-небудь полю. Така ситуація часто виникає у фінансових документах – наприклад, під час роздрукування відомості на зарплату. На перший погляд, зробити це можна за технологією, розглянутою раніше: оголошується змінна, обнулюється при форматуванні верхнього колонтитулу та заповнюється при форматуванні області даних. Але оскільки результат має бути занесений у "вільне" поле, розміщене в іншому розділі (у Нижньому колонтитулі), сума виявиться неправильною – адже процес форматування деяких розділів "звітів" у Access може повторюватися. Це є особливістю технології підготовки "звітів" - треба пам'ятати про це під час програмування. Зокрема, у прикладі заповнення змінної для проміжної суми (SumStr) можна виконувати не при форматуванні області даних, а при відпрацюванні властивості друку області даних (ОбластьДанних_Print), в якій можна проконтролювати ситуацію - буде друкуватись лист з цими даними чи ні. І саме залежно від результатів контролю має бути заповнене поле, розташоване у нижньому колонтитулі. Допустимо, воно має ім'я SumS, а змінна, в якій накопичується значення на сторінці, - SumStr. Тоді текст коду подібної процедури матиме такий вигляд:
Така ж ситуація може виникнути при спробі використовувати Підпорядкований звіт, який найчастіше вставляється до Примітки звіту або до Примітки групи. Якщо в ньому потрібно вказувати якесь розрахункове значення(наприклад, той же номер на сторінці), то воно може виявитися неправильним, оскільки такий звіт форматуватиметься кілька разів.
Для вирішення проблеми команду заповнення поля № рядка на сторінці Підпорядкованого звіту треба перемістити з обробки події Форматування для обробки події Друк розділу Область даних, наприклад: