Как сделать флешку как брелок

Как сделать флешку как брелок

2004 г.

Проблемы отчетов в ACCESS

Сергей Гущенко, Издательский Дом "КОМИЗДАТ"

Важным элементом программ работы с базами данных является механизм "отчетов". Так как структура баз может быть достаточно сложной, для реализации таких программ недостаточно знать основные возможности "конструктора отчетов". Может потребоваться знание ряда слабо документированных функций и технологических приемов

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

Рассмотрим пример. Допустим, есть таблица "TELEFKOD" телефонных кодов с 528-ю записями, начало которой имеет следующий вид:

NPP GOROD KOD_TEL OBLAST 1 Авдеевка 06236 Донецкая 2 Акимовка 06131 Запорожская 3 Александрия 05235 Кировоградская 4 Александровка 06269 Донецкая 5 Александровка 05269 Кировоградская 6 Алушта 06560 Крым
Рис. 1. Вид отчета в Конструкторе

Причем поле "NPP" имеет тип Счетчик (Длинное целое), особенность которого состоит в следующем: при удалении записи в этом поле удаляется и значение, которое больше повторяться не будет. В результате перечень порядковых номеров может не совпасть с перечнем значений в этом поле.

В качестве выходного документа для этой таблицы подготовлен несложный отчет, вид которого в Конструкторе представлен на рис. 1.

Рис. 2. Вид окна свойств Примечания отчета

В этом отчете названия колонок (шапка таблицы) размещены в верхнем колонтитуле, в качестве номера по порядку используется поле "NPP", в нижнем колонтитуле указывается номер страницы и добавлено Примечание отчета с количеством выводимых записей и примером подписей. Модуль класса пустой (то есть никаких программных кодов на языке VBA нет). Распечатывается такой отчет без проблем. Но могут возникнуть претензии к размещению Примечания. По умолчанию его свойство Не разрывать имеет значение "Да". (рис. 2).

Это означает: если всё Примечание не помещается на последней странице строк с данными, то оно будет целиком перенесено на следующую. Но не всегда такое решение допустимо - особенно если печатается финансовый документ. Поэтому можно поменять значение этого свойства на "Нет" - тогда Примечание будет начинаться сразу после вывода последней записи. Это решает рассматриваемую проблему, но не до конца. Может возникнуть ситуация, когда одна подпись (например, Директора) окажется на одной странице (последней с данными), а другая перенесется на следующую,- тоже плохо. Более приемлемым решением в этом случае - с небольшой высотой Примечания - было бы его размещение полностью на отдельной странице, но так, чтобы к нему сверху автоматически добавлялись несколько последних строк с данными. И вот тут без обращения к 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 приводит к прекращению печати отчета.

Рис. 3. Размещение элемента управления Конец страницы в Области данных

Во-вторых, в Области данных установлен элемент управления Конец страницы (рис. 3), действие которого контролируется в модуле класса.

При форматировании каждой новой страницы его "видимость" отключается (Me![EndStr1]. Visible = False). Включается же при форматировании Области данных - при наступлении определенного условия, которое состоит из двух частей. Первая контролирует область листа, на котором Примечание уже не может разместиться полностью. В данном отчете опытным путем определено, что такой момент возникает после печати 39-й строки (If I1 > 39 Then). Целочисленной переменной, в которой учитывается номер печатаемой строки, является I1. Рис. 4. Пример вывода Примечания отчета на новой странице вместе с несколькими (двумя) последними строками данных При форматировании верхнего колонтитула она обнуляется, а при форматировании каждой новой строки данных ее значение увеличивается на 1. Но этого мало - требуется еще определить, что выводятся последние строки. Это делается через две другие переменные: KolZ, в которую заносится номер текущей записи в печатаемой таблице (KolZ = Me. CurrentRecord) и KolZap, в которой хранится общее количество записей, рассчитываемое при открытии отчета (KolZap = zap. RecordCount). В конечном итоге, если возникает ситуация печати последних двух записей в зоне листа, где уже не может полностью разместиться Примечание, то они печатаются вместе с ним на следующей странице (рис. 4).

Рис. 5. Настройка в "Конструкторе" поля для отображения порядкового номераРис. 6. Результат отображения "Отчета" (рис. 5) при просмотре

Но в этом примере есть и ошибка - итоговое поле для подсчета количества записей в Примечании отчета насчитало 528 записей. А последний Номер по порядку значится как "529". Такая ситуация возможна в случае, если в качестве номера по порядку выводится поле, имеющее тип Счетчик, а в процессе заполнения таблицы были выполнены удаления записей (в примере была удалена одна запись). Поэтому в качестве поля порядкового номера в отчете лучше использовать свободное поле, не связанное с исходной таблицей. В качестве данных для такого поля надо установить значение "=1" и указать вариант Для всего в параметре Сумма с накоплением (рис. 5 - вид в Конструкторе и рис. 6 - при предварительном просмотре).

Рис. 7. Добавление поля порядкового номера на странице (в Конструкторе)

Может возникнуть необходимость нумерации не только в границах всего отчета, но и постранично. Это также делается через свободное поле (рис. 7), но его заполнение выполняется в модуле класса. Под него объявляется новая переменная, например: 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 Рис. 8. Вид диалогового окна Сортировка и группировкаРис. 9. Вид Отчета с группировкой по областям и с сортировкой по городам внутри "группы"

Последним вариантом учета строк рассмотрим нумерацию в группе. Access позволяет сортировать и группировать данные прямо при выводе. Эти настройки выполняются в Конструкторе через диалоговое окно Сортировка и группировка (вызывается по команде меню Вид) - рис. 8. Для создания группировки по какому-либо полю этого окна, его (поле) надо выбрать в списке (в примере - поле OBLAST) и указать "Да" в параметре Заголовок группы. Здесь же можно установить сортировку для других полей без группировки по ним (в примере - по полю GOROD). Вывод порядкового номера в группе производится в "свободном" поле, в параметре Данные которого указано "=1", но Сумма с накоплением установлена Для группы. Фрагмент результата показан на рис. 9.

Следующей проблемой может оказаться размещение в нижнем колонтитуле промежуточных сумм по какому-либо полю. Такая ситуация часто возникает в финансовых документах - например, при распечатке ведомости на зарплату. На первый взгляд, сделать это можно по технологии, рассмотренной ранее: объявляется переменная, обнуляется при форматировании верхнего колонтитула и заполняется при форматировании области данных. Но поскольку результат должен быть занесен в "свободное" поле, размещенное в другом разделе (в Нижнем колонтитуле), сумма окажется неправильной - ведь процесс форматирования некоторых разделов "отчетов" в 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 Рис. 10. Пример вывода Отчета с Подчиненным отчетом в разделе Примечания отчета (и с неправильным заполнением поля № строки на странице в Подчиненном отчете - значения "55, 56 и т.д.")

Подобная же ситуация может возникнуть при попытке использовать Подчиненный отчет, который чаще всего вставляется в Примечание отчета или в Примечание группы. Если в нем требуется указывать какое-то расчетное значение (например, тот же номер на странице), то оно может оказаться неправильным, так как такой отчет будет форматироваться несколько раз (рис. 10).

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

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
Как сделать флешку как брелок 399
Как сделать флешку как брелок 571
Открытка на английском языке Английский онлайн
Как сделать флешку как брелок 299
Что
Как сделать флешку как брелок 30
Как сделать флешку как брелок 17
Как сделать флешку как брелок 50
Как сделать флешку как брелок 70
Как сделать флешку как брелок 19
Как сделать флешку как брелок 82
Как сделать флешку как брелок 19
Как сделать флешку как брелок 25
Как сделать флешку как брелок 4