Что такое событийная процедура
Перейти к содержимому

Что такое событийная процедура

Процедуры и функции Sub-процедуры

Процедуры – это, как правило, маленькие подпрограммы, которые можно вызывать из других мест программы.

Событийные процедуры

Обработчики событий в VisualBasicреализуются как процедуры. Такие процедуры вVBвсегда привязаны как к совершаемому событию, так и к объекту, над которым это событие совершается. Это отражается в том, что имя процедуры, которое в этом случае формируетVB, складывается из имени объекта и названия события. Фактически весь программный код состоит из некоторого набора таких процедур-событий.

Private Sub Commandl_Click()

end Sub

Событийные процедуры вызываются системой при появлении соответствующего события. Если необходимое событие не произойдет, событийная процедура, связанная с этим событием не выполнится ни разу.

Процедуры пользователя

Можно создавать и собственные процедуры не связанные с объектами на форме, если в вашем приложении есть часто повторяющаяся последовательность кодов, — это существенно сократит время набора команды и упростит алгоритм. Для создания собственной процедуры необходимо в общей части кода программы (General/Declaration) ввестиSub, затем задать имя и нажать клавишуEnter. В полученной конструкции набрать свой код программы.

Такие процедуры называют еще пользовательскимиилиглавнымипроцедурами.

Вызов процедур

В создаваемых процедурах могут использоваться и аргументы. Они просто помещаются в скобках в заголовке процедуры с указанием, при необходимости, типа данных. Аргументы могут быть как формальными (используемыми в теле процедуры), так фактическими (передаваемыми в процедуру при ее вызове).

Для вызова собственной процедуры, необходимо воспользоваться оператором

Call имя процедуры

или просто записав ее имя, перечислив ее фактические параметры через запятую без скобок.

1) Вычислить сумму гдеf=<5;-3;1;2>.

Сначала в разделе Generalсоздается процедура вычисления произведения любого количества любых сомножителей из элементов массива.

Dim i as integer

Здесь k- количество сомножителей,z- имя массива, элементы которого перемножаются,p– параметр, в котором будет храниться значение вычисленного произведения.

Затем в событийной процедуре, например, Command1_Click, создается программный код, в котором используется созданная процедура.

Private Sub Command1_click()

Dim F(4), F1(4), S,p,p1 as single

Dim i as integer

Print “Сумма произведений равна”; s

Здесь после ввода в память массивов fиf1дважды вызывается процедураproizv. При этом первый раз в нее передаются фактические значения для формальных параметровkиz, соответственно равны4иf, а результат сохраняется как значение переменнойp1. Во второй раз – значения параметровkиz, соответственно равны3иf1, а результат сохраняется как значение переменнойp2.

Процедура с нулевым списком параметров должна очистить форму и установить размер выводимых на форму символов в 30 пунктов и тип символов курсив.

Обращение к процедуре

Обращение к процедуре

Private Sub Form_Load()

Print “Пример процедуры”

Private sub form_click()

Переменные, объявленные внутри процедуры, называются локальными, они доступны только в этой процедуре. Если они объявлены оператором Dim, то они существуют пока выполняется процедура, после чего память освобождается. Есть возможность сохранять значение локальной переменной до следующего вызова процедуры. Для этого ее нужно объявить как статическую, с ключевым словомStatic. В этом случае переменная недоступна в других процедурах, но ее значения сохраняются от вызова к вызову. Глобальные переменные (объявленные со словомPublic), доступны всему приложению.

Событийно-ориентированное программирование

  Шаблон:  Просмотр • англ.  event-driven programming ; в дальнейшем СОП) — парадигма программирования, в которой выполнение программы определяется событиями — действиями пользователя (клавиатура, мышь), сообщениями других программ и потоков, событиями операционной системы (например, поступлением сетевого пакета).

СОП можно также определить как способ построения компьютерной программы, при котором в коде (как правило, в головной функции программы) явным образом выделяется главный цикл приложения, тело которого состоит из двух частей: выборки события и обработки события.

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

Содержание

Сфера применения

Событийно-ориентированное программирование, как правило, применяется в трех случаях:

  1. при построении пользовательских интерфейсов (в том числе графических);
  2. при создании серверных приложений в случае, если по тем или иным причинам нежелательно порождение обслуживающих процессов;
  3. при программировании игр, в которых осуществляется управление множеством объектов.

Применение в серверных приложениях

Событийно-ориентированное программирование применяется в серверных приложениях для решения проблемы масштабирования на 10000 одновременных соединений и более.

В серверах, построенных по модели «один поток на соединение», проблемы с масштабируемостью возникают по следующим причинам:

  • слишком велики накладные расходы на структуры данных операционной системы, необходимые для описания одной задачи (сегмент состояния задачи, стек);
  • слишком велики накладные расходы на переключение контекстов.

Философской предпосылкой для отказа от потоковой модели серверов может служить высказывание Алана Кокса: «Компьютер — это конечный автомат. Потоковое программирование нужно тем, кто не умеет программировать конечные автоматы» [1] .

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

Мультиплексирование

Для мультиплексирования соединений могут быть использованы следующие средства операционной системы:

  • select (большинство UNIX систем). Плохо масштабируется, из-за того, что список дескрипторов представлен в виде битовой карты;
  • poll и epoll (Linux); (FreeBSD);
  • /dev/poll (Solaris);
  • IO completion port (Windows);
  • POSIX AIO на текущий момент только для операций дискового ввода-вывода;
  • io submit и eventfd для операций дискового ввода-вывода.

Примеры реализаций

  • Веб-серверы:

Применение в настольных приложениях

В современных языках программирования события и обработчики событий являются центральным звеном реализации графического интерфейса пользователя. Рассмотрим, к примеру, взаимодействие программы с событиями от мыши. Нажатие правой клавиши мыши вызывает системное прерывание, запускающее определенную процедуру внутри операционной системы. В этой процедуре происходит поиск окна, находящегося под курсором мыши. Если окно найдено, то данное событие посылается в очередь обработки сообщений этого окна. Далее, в зависимости от типа окна, могут генерироваться дополнительные события. Например, если окно является кнопкой (в Windows все графические элементы являются окнами), то дополнительно генерируется событие нажатия на кнопку. Отличие последнего события в том, что оно более абстрактно, а именно, не содержит координат курсора, а говорит просто о том, что было произведено нажатие на данную кнопку.

Обработчик события может выглядеть следующим образом (на примере C#):

Здесь обработчик события представляет собой процедуру, в которую передается параметр sender, как правило содержащий указатель на источник события. Это позволяет использовать одну и ту же процедуру для обработки событий от нескольких кнопок, различая их по этому параметру.

Языки программирования

В языке C# события реализованы как элемент языка и являются членами классов. Механизм событий здесь реализует шаблон проектирования Publisher/Subscriber. Пример объявления события:

Здесь EventHandler — делегат, определяющий тип процедуры обработчика событий. Подписка на событие производится следующим образом:

Здесь myClass — экземпляр класса MyClass, Handler — процедура-обработчик. Событие может иметь неограниченное количество обработчиков. При добавлении обработчика события он добавляется в специальный стек, а при возникновении события вызываются все обработчики по их порядку в стеке. Отписка от события, то есть удаление обработчика производится аналогично, но с использованием оператора «-=».

Разные языки программирования поддерживают СОП в разной степени. Наиболее полной поддержкой событий обладают следующие языки (неполный список):

    (события и демоны DAEMON , и их приоритеты PRIO ), [2] , , , (события event ) [3] .

Остальные языки, в большей их части, поддерживают события как обработку исключительных ситуаций.

Инструменты и библиотеки

    , событийно-ориентированный I/Oфреймворк на JavaScript движке V8 & Objective-C, рефлексивный объектно-ориентированный язык программирования, добавляющий сообщения в стиле Smalltalk в язык Си.
  • Gui4Cli[4] , событийно-ориентированный язык программирования для Windows   (англ.) русск.
  • libevent
  • libasync, часть библиотек sfs и sfslite [5] , эффективная событийная библиотека для C++   (англ.) русск.   (англ.) русск. , компонентный событийно-ориентированный инструмент для Web-программирования на PHP 5 , Python , кроссплатформенная библиотека виджетов для C++, основанная на модели управления событиями. Существует сокращённая версия, называемая Qt/Console, из которой исключён, код поддержки виджетов, и представляющий собой управляемый событиями фреймвок, в который также включены некоторые дополнительные средства, вроде кроссплатформенной работы с сетью, многопоточности и работы с XML.
  • QP — семейство открытых событийно-ориентированных окружений для встроенных систем реального времени [6]
  • Simple Unix Events a.k.a. SUE[7] , простая объектно-ориентированная библиотека для построения событийно-ориентированных программ под Unix на языке C++.

См. также

Англоязычные источники

    из Portland Pattern Repository  — учебное пособие Стефана Ферга (Stephen Ferg) учебное пособие Алана Голда (Alan Gauld) by Tim Boudreau
  • Event-driven programming and SOA: Jack van Hoof. How EDA extends SOA and why it is important;;
  • Пример с открытым кодом: Distributed Publish/Subscribe Event System
  • Событийно-ориентированное программирование на языке Java: Rex Youung. Jsasb

Материалы на русском

  • Н. Н. Непейвода 13. Лекция: Событийное программирование // Стили и методы программирования. курс лекций. учебное пособие. — М .: Интернет-университет информационных технологий, 2005. — С. 213—222. — 316 с. — ISBN 5-9556-0023-X
  • С.В. Зыков Лекции №15 и №16 // Введение в теорию программирования. Объектно-ориентированный подход. — Интернет-университет информационных технологий.
  • О. В. АнуфриевО методике обучения основам событийного программирования]   (рус.) . Новосибирский государственый педагогический университет. Архивировано из первоисточника 3 марта 2012.Проверено 29 октября 2010.

Ссылки

  1. Linux-Kernel Archive: Re: Alan Cox quote? (was: Re: accounting
  2. Н. Н. Непейвода 13. Лекция: Событийное программирование // Стили и методы программирования. курс лекций. учебное пособие. — М .: Интернет-университет информационных технологий, 2005. — С. 213—222. — 316 с. — ISBN 5-9556-0023-X
  3. С.В. Зыков Лекции №15 и №16 // Введение в теорию программирования. Объектно-ориентированный подход. — Интернет-университет информационных технологий.
  4. Gui4Cli Home page
  5. sfslite:overview
  6. Download from Quantum Leaps
  7. The Simple Unix Events (SUE) library homepage
  • Парадигмы программирования

Wikimedia Foundation . 2010 .

Полезное

Смотреть что такое «Событийно-ориентированное программирование» в других словарях:

Событийно-управляемое программирование — объектно ориентированное программирование, при котором задаются реакции программы на различные события. См. также: Объектно ориентированное программирование Финансовый словарь Финам … Финансовый словарь

Объектно-ориентированное программирование — Эта статья во многом или полностью опирается на неавторитетные источники. Информация из таких источников не соответствует требованию проверяемости представленной информации, и такие ссылки не показывают значимость темы статьи. Статью можно… … Википедия

Аспектно-ориентированное программирование — Парадигмы программирования Агентно ориентированная Компонентно ориентированная Конкатенативная Декларативная (контрастирует с Императивной) Ограничениями Функциональная Потоком данных Таблично ориентированная (электронные таблицы) Реактивная … Википедия

Субъектно-ориентированное программирование — Парадигмы программирования Агентно ориентированная Компонентно ориентированная Конкатенативная Декларативная (контрастирует с Императивной) Ограничениями Функциональная Потоком данных Таблично ориентированная (электронные таблицы) Реактивная … Википедия

Компонентно-ориентированное программирование — Парадигмы программирования Агентно ориентированная Компонентно ориентированная Конкатенативная Декларативная (контрастирует с Императивной) Ограничениями Функциональная Потоком данных Таблично ориентированная (электронные таблицы) Реактивная … Википедия

Событийно-ориентированная архитектура — Архитектура, управляемая событиями (Event driven architecture  EDA) является шаблоном архитектуры программного обеспечения, позволяющим создание, определение, потребление и реакцию на события. Событие можно определить как «существенное… … Википедия

Парадигма (программирование) — Парадигма программирования это совокупность идей и понятий, определяющая стиль написания программ. Парадигма, в первую очередь, определяется базовой программной единицей и самим принципом достижения модульности программы. В качестве этой единицы … Википедия

Автоматное программирование — Автоматное программирование  это парадигма программирования, при использовании которой программа или её фрагмент осмысливается как модель какого либо формального автомата. В зависимости от конкретной задачи в автоматном программировании… … Википедия

Отражение (программирование) — У этого термина существуют и другие значения, см. Отражение. Для улучшения этой статьи желательно?: Перевести текст с иностранного языка на русский. Н … Википедия

Структурное программирование — Эта статья или раздел нуждается в переработке. Пожалуйста, улучшите статью в соответствии с правилами написания статей … Википедия

Что такое событийная процедура

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

• Познакомимся с элементом управления поле со списком, которое будем использовать при вводе информации о поставщике, сотруднике и категории товара. Это позволит, во-первых, избежать ошибок при вводе с клавиатуры, а, во-вторых, ускорить ввод информации. В нашем случае для списков будем использовать в качестве источника строк информацию из другой таблицы. Кроме того, запретим ввод информации, не содержащейся в списках. • Воспользуемся масками для ввода дат. Маска гарантирует правильность ввода и дает возможность не вводить вручную необязательные символы (разделители). • Познакомимся с простейшими событийными процедурами, которые будут использоваться, в частности, для автоматического заполнения даты приема товара и вычисления розничной цены по известной наценке.

Создадим сначала форму, взяв в качестве источника данных таблицу Товары. При этом можно воспользоваться Мастером форм. Выберем все поля таблицы кроме поля Код_товара, которое имеет тип данных счетчик; при добавлении новой записи уникальное значение в этом поле определяется автоматически и не несет никакой информации. Выберем ленточный тип для этой формы и разместим поля таким образом, как показано на рисунке. Поля Поставщик, Сотрудник, Дата_поступления перенесены в область заголовка формы, т.к. при оформлении нескольких товаров данные в этих полях будут иметь одно и то же значение для каждой строки и, следовательно, будут дублироваться, если разместить их в области данных ленточной формы. Кроме того, горизонтальную протяженность формы в этом случае можно будет уменьшить, и при работе с ней не придется выполнять прокрутку окна.

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

Краткая справка 1. Чтобы переместить элемент управления на форме, необходимо выделить его и перетащить при помощи мыши в соответствующее место. Изменить размеры элемента управления можно при помощи маркеров выделения, расположенных по периметру элемента. 2. Если область заголовка (примечания) формы отсутствует в окне конструктора, выберите команду Вид\Заголовок/примечание формы. 3. Некоторые элементы управления (поля, списки) имеют присоединенную надпись, которая перемещается вместе с самим элементом. Чтобы перемещать их независимо друг от друга, используются маркеры в верхнем левом углу каждого элемента. 4. Для удаления элемента его нужно выделить и нажать клавишу Delete. 5. Изменение взаимного расположения элементов управления и согласование их размеров весьма эффективно можно выполнить при помощи команд в подменю Выровнять, Размер, Интервал по горизонтали/вертикали меню Формат. Для этого необходимо предварительно выделить группу соответствующих элементов управления. Существует несколько приемов выделения группы: последовательные щелчки мышью при нажатой клавише SHIFT; щелчок и протяжка в области линеек окна конструктора; охват элементов посредством протяжки мыши.

Как видно из вышеприведенного рисунка, поля внешних ключей таблицы Товары содержат коды соответствующих записей из таблиц Поставщик, Сотрудник и Категория товара. Пользоваться такой формой весьма неудобно, поскольку для этого нужно помнить все соответствующие коды, особенно при вводе новой информации. К счастью, в этом нет необходимости. Мы можем заменить эти поля — полями со списком, которые будут содержать текстовую информацию из соответствующих таблиц (например, ФИО_поставщика из таблицы Поставщик). Между тем, при выборе элемента списка в соответствующее поле таблицы Товары будет записываться нужный код. Чтобы понять, как это делается, познакомимся сначала с элементом управления Поле со списком, и рассмотрим его основные свойства на примере одного из полей нашей формы.

Нам нужно вместо трех вышеуказанных полей поместить на форму поля со списком. Для этого нет необходимости удалять старые элементы управления и помещать на форму другие новые. В MS Access есть возможность преобразования элементов. Для этого следует выполнить соответствующую команду из подменю Преобразовать элемент в. Это подменю можно найти в меню Формат или в контекстном меню. Естественно, можно преобразовывать элементы друг в друга только в том случае, если они совместимы по типам; в частности, можно преобразовать поле в надпись, список или поле со списком, но нельзя его преобразовать в изображение или переключатель.

Поле со списком

Этот элемент управления представляет ниспадающий список с текстовым полем . При выборе элемента из списка, последний попадает в текстовое поле, а список сворачивается и занимает на форме столько же места, что и поле. Текстовое поле позволяет редактировать выведенный в него текст, а также автоматически подставлять элементы из списка по мере ввода символов с клавиатуры, которые совпадают с первыми символами элемента списка.

Рассмотрим основные свойства поля со списком, взяв для примера элемент управления Поставщик_, используемый для выбора поставщика из списка на форме приема товаров. На рисунке изображено Окно свойств, в котором выбрана вкладка Все. На этой вкладке перечислены все без исключения свойства выделенного элемента управления формы.

Свойство Данные указывает, какие данные выводятся в элементе управления. В нашем случае выводятся данные из поля Поставщик таблицы Товары, являющейся источником данных рассматриваемой формы.

Свойство Тип источника строк указывает тип источника строк, в то время сам источник строк задается ниже следующим свойством Источник строк. Возможными вариантами типов, которые выбираются из списка, являются: Таблица/запрос, Список значений и Список полей.

Значения свойства Источник строк, в зависимости от значения свойства Тип источника строк, перечислены ниже в таблице.

Тип источника строк Источник строк
Таблица/запрос Имя таблицы или запроса (выбирается из списка имеющихся в базе данных таблиц или запросов) или инструкция SQL. Элементами списка в этом случае являются записи из указанной таблицы, сохраненного в базе данных запроса или запроса, написанного на языке SQL. В последнем случае можно воспользоваться конструктором запросов.
Список значений Список элементов, разделяемых точкой с запятой (;).
Список полей Имя таблицы, запроса или инструкция SQL. Элементами списка в этом случае является список полей указанной таблицы или запроса.

В нашем случае источником строк следует выбрать таблицу Поставщик, содержащую необходимую информацию в полях Код_поставщика и ФИО_поставщика.

Свойством Число столбцов задается число столбцов списка. В нашем случае это 2 — первые два поля из таблицы Поставщик, которыми как раз и являются Код_поставщика и ФИО_поставщика. Значения из первого поля нужны нам для связи с таблицей Товары, поскольку при выборе элемента списка именно код поставщика должен записываться в соответствующее поле этой таблицы.

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

Свойство Ширина столбцов задает ширину каждого столбца в сантиметрах; значения в этом поле перечисляются через точку с запятой. Если не указать ширину столбца, то она будет приниматься по умолчанию, например, если вообще оставить это поле пустым, ширина каждого столбца будет одинаковой и в сумме равняться ширине списка. Важным является нулевое значение ширины столбца, которое делает столбец невидимым на экране. Поскольку при выборе элемента из списка существенным при оформлении приема товаров является только имя поставщика, поле кода поставщика делается невидимым. В результате мы будем выбирать поставщика по имени, а в таблицу Товары будет заноситься его код, хотя этот столбец и не выводится на экран.

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

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

Наконец, свойство Автоподстановка (допустимые значения свойства — Да/Нет) определяет, должен ли выполняться автоматический ввод в текстовое поле значения из списка, совпадающего по первым символам с символами, вводимыми в это поле с клавиатуры.

Краткая справка 1. Чтобы при размещении поля таблицы на форме с помощью окна списка полей использовался нужный элемент управления, следует для соответствующего поля таблицы задать свойства подстановки. На рисунке приведен пример использования подстановки для поля Прод_возвр в таблице Продажи. Как видно, источником строк поля со списком в данном случае является список значений. Если бы мы определили аналогичную подстановку для требуемых полей из таблицы Товары до создания формы, то нам не пришлось бы преобразовывать поля на форме ни сейчас, ни в дальнейшем.

При более внимательном анализе и практической работе с формой Прием товаров становятся очевидными следующие недостатки:

• При оформлении партии товара приходится многократно вводить повторяющуюся информацию: дату приема, имя поставщика и имя сотрудника, оформляющего прием. • Случайный выбор из списков других элементов для ранее введенной записи приводит к потере информации, т.к. можно по ошибке приписать товар другому поставщику и.т.д. • При вводе дат желательно воспользоваться масками ввода для ускорения ввода и защиты от ошибок. • Розничную цену лучше не вводить с клавиатуры, а вычислять по известной наценке; это предохранит от ошибок, которые могут привести к установке розничной цены ниже закупочной. • Поскольку, как правило, датой приема является текущая дата, можно воспользоваться этим фактом для автоматического заполнения соответствующего поля.

Устранение этих недостатков должно сделать работу с формой более удобной. Ниже мы покажем, как это сделать и обсудим используемые для этого средства.

Сначала обеспечим маски ввода для полей на форме, содержащих дату приема и срок реализации. Для этого можно выделить сразу оба поля, чтобы задать одну и ту же маску для обоих полей. Затем на вкладке данные в окне свойств выберем поле Маска ввода и нажмем кнопку построителя , после чего выберем краткий формат даты и нажмем кнопку Готово.

Чтобы устранить другие недостатки разрабатываемой формы, имеющихся средств оказывается недостаточно, поэтому нам понадобится незначительное программирование.

Понятие событийной процедуры

Событийная процедура представляет собой последовательность операций, которая выполняется при наступлении некоторого события. Таким событием может быть, например, щелчок кнопкой мыши. События могут генерироваться пользователем (щелчок, протяжка, нажатие клавиши на клавиатуре), системой (события таймера) или сигналами, поступившими от внешних устройств. Таким образом, мы можем определить некоторые действия, которые будут выполняться всякий раз, когда будет происходить то или иное событие. Эти действия в MS Access должны записываться на языке VBA (Visual Basic For Applications) непосредственным вводом с клавиатуры или с помощью мастеров, реализующих наиболее характерные операции при работе с базами данных.

Мы уже, кстати говоря, написали одну событийную процедуру при помощи мастера, когда поместили кнопку Выход на форму Категории товара. Здесь мы рассмотрим процесс создания событийной процедуры «вручную» на примере использования кнопки Вставить текущую дату, которая будет обеспечивать вставку текущей даты в поле даты приема.

Мастер кнопки здесь ничем не сможет нам помочь, поскольку такая специфическая задача не попадает в круг его возможностей. Поэтому следует либо отключить кнопку Мастера на панели элементов перед выбором кнопки, либо сразу после запуска Мастера нажать кнопку Отмена. Теперь выделим созданную кнопку и в окне свойств перейдем на вкладку События. Нужное нам событие называется Нажатие кнопки. Это событие наступает, когда мы щелкаем мышью по элементу управления Кнопка. Из списка в этом поле свойства можно выбрать один из макросов, имеющихся в базе данных, или строку Процедура обработки событий. Макросы – это объекты базы данных, представляющие собой комбинацию макрокоманд, каждая из которых выполняет предопределенное действие. Таких макрокоманд в MS Access имеется несколько десятков; они выполняют наиболее характерные для работы с базами данных действия.

Процедура обработки событий означает, что обработка события будет выполняться кодом VBA. Чтобы попасть в редактор VBA, нужно нажать расположенную справа кнопку

Окно редактора кодов уже будет содержать заголовок и окончание событийной процедуры. Операторы, описывающие действия, которые должны выполняться в ответ на событие (в нашем примере — нажатие кнопки), записываются между этими двумя строками. Как правило, каждый оператор записывается на отдельной строке, строки же выполняются последовательно. Заголовок процедуры, помимо служебных слов Private Sub (что означает локальная процедура) включает имя процедуры, которое формируется автоматически.

Если мы захотим написать другую событийную процедуру для текущей формы, можно закрыть окно редактора и повторить операцию. Однако в этом нет необходимости. Чтобы перейти к другому элементу управления текущей формы, достаточно в левом списке ниже заголовка окна кодов выбрать имя этого элемента управления; а чтобы обработать другое событие, нужно в правом списке выбрать название этого события.

Внимание Чтобы работать с кодовым окном было удобнее, рекомендуется давать элементам управления смысловые имена; иначе, имена будут выглядеть так: Кнопка26, Надпись33 и т.д., что видно на нашем примере. Краткая справка 1. Для обозначения самой формы используется имя Form. 2. Форма также является элементом управления. Работа с мышью вызывает события для формы, если при этом не затрагиваются другие элементы управления, т.к. они находятся как бы над формой. Т.е. если щелкнуть на кнопке, расположенной на форме, то выполнится событийная процедура щелчка по кнопке, а не событийная процедура щелчка на форме, которая вообще не будет в этом случае отрабатывать. 3. Форма имеет и специфичные для нее события, например, загрузка и открытие, которые выполняются, когда форма открывается в режиме «форма». 4. События именуются по-английски. К сожалению, после версии MS Access 97 справка по языку программирования не русифицировалась для локализованной версии MS Office. Тем не менее, чтобы получить справку по конкретному событию, достаточно выделить название события, скажем, слово Click в заголовке процедуры и нажать клавишу F1. В этом случае появится справка по данному событию.

Вернемся к нашей событийной процедуре нажатия кнопки. Фактически нам нужно записать один оператор – оператор присваивания, который можно записать следующим образом

Здесь в левой части оператора присваивания стоит имя поля (формы! Не путать с именем столбца в таблице) Дата_поступления, служащее для ввода и отображения соответствующей информации. В правой части оператора присваивания используется встроенная функция Date, которая возвращает системную дату. В результате выполнения этого оператора в поле Дата_поступления будет занесена системная (текущая) дата. Напомним, что сохранение записи происходит автоматически при переходе к другой записи. Поэтому указанный оператор пока только изменил содержимое поля на форме, но не в источнике данных. Об этом говорит значок карандаша в области выделения формы, который сменяется на треугольник после сохранения записи. Чтобы принудительно сохранить запись, нужно выполнить команду Записи\Сохранить запись. Если изменение сделано ошибочно, то до сохранения записи можно нажать клавишу ESC, чтобы отменить сделанное изменение содержимого элемента управления.

Однако,мы не ограничились одной этой строкой. Причина состоит в том, что эта событийная процедура будет менять любую имеющуюся дату на системную. Это может стать причиной ошибки при случайном нажатии на кнопку. Поэтому поступим следующим образом. Будем вводить в поле даты приема системную дату только в том случае, если мы добавляем новую запись, т.е. тогда, когда это поле пусто. В языке VBA есть встроенная функция IsNull, которая возвращает значение Истина (True), если ее аргумент содержит значение Null – отсутствие информации в элементе управления или отсутствие значения переменной. Поэтому мы сначала проверяем, заполнено ли поле даты приема на форме и, в случае, если нет, заносим в него системную дату.

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

Forms(“Прием товаров”)!Дата_поступления где символ «!» разделяет имя формы и имя элемента управления.

Если элементы управления, находящиеся на разных формах, имеют одинаковые имена (а это допускается), то для обращения к элементу управления на текущей форме может использоваться служебное слово Me (но это не обязательно, поскольку, как было сказано выше, обращение к текущей форме происходит по умолчанию, если явно не указана другая форма), что облегчает чтение кода:

Поскольку наша событийная процедура будет исполняться только при нажатии кнопки на форме Прием товаров, данная форма и будет текущей в момент выполнения процедуры.

Перейдем к определению розничной цены. Здесь нам потребуется не только кнопка, но и поле, в которое мы будем вводить значение наценки, используемой при расчете розничной цены. Поэтому разместим на форме поле, которое назовем Наценка, а также при включенной кнопке Мастера на панели элементов поместим на форму кнопку с именем Определить розн.цену. В качестве действия, выполняемого при нажатии кнопки (событие щелчка выбирается по умолчанию для нажимной кнопки), можно выбрать сохранение записи. Т.е. при нажатии данной кнопки будет сохраняться текущая запись. Строка сохранения записи, записанная мастером выглядит так

DoCmd.DoMenuItem acFormBar, acRecordsMenu, acSaveRecord, , acMenuVer70

Фактически здесь указывается, какую команду меню выполнить. К слову, аналогичным образом мы можем выполнять программно любые команды из меню Access.

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

Цена_розн = Цена_опт * (1 + Наценка/100).

Удобно вводить наценку в процентах; именно поэтому она делится на 100 в вышеприведенной формуле. Вычисление выполняется следующим образом. Сначала вычисляется выражение в круглых скобках, после чего полученный коэффициент умножается (символ «*») на значение оптовой цены товара (поле на форме — = Цена_опт) для текущей записи. Наконец, результат заносится в поле Цена_розн для той же текущей записи. Следует иметь это в виду, нажимая на кнопку.

Теперь, если написать вышеприведенный оператор перед оператором сохранения, то после изменения розничной цены соответствующие изменения текущей записи будут автоматически сохраняться.

Чтобы нельзя было ввести в поле Наценка нечислового значения, выберем значение Фиксированный в свойстве Формат поля для этого элемента управления (вкладка Макет).

Добавим в событийную процедуру для кнопки Определить розн.цену проверку условия (наценка > 0), чтобы нельзя было назначить розничную цену меньше оптовой. При нарушении этого условия будет появляться сообщение об ошибке, которое выводит встроенная процедура MsgBox, использующая в качестве параметра текст сообщения. В результате все тело процедуры примет вид

Как правило, есть некоторое фиксированное значение наценки, которое применяется для большинства товаров. Поэтому будет естественным, если это значение будет автоматически вводиться в поле Наценка на форме. Для этого мы воспользуемся событием загрузки формы.

Событие Загрузка (Load) возникает при открытии формы и выводе на экран ее записей. Если написать следующую процедуру загрузки формы «Прием товаров» Private Sub Form_Load() Наценка = 25 End Sub то в поле Наценка при загрузке формы будет введено значение 25. Если потребуется использовать какое-либо другое значение наценки, ничто не мешает нам изменить вручную значение в этом поле.

Использование вычисляемого поля на форме продемонстрируем на примере расчета предполагаемой прибыли, которая представляет собой просуммированную для всех товаров разность между розничной и оптовой ценой. Оптовая стоимость всей партии одного (текущего) товара представляется формулой

Розничную стоимость мы получим, если в приведенной выше формуле заменим поле Цена_опт на поле Цена_розн. Встроенная статистическая функция Sum вычисляет суммарное значение для всех записей источника данных. Поэтому, если мы разместим в области заголовка или примечания формы вычисляемое поле с формулой

=Sum(([Цена_розн] — [Цена_опт])*[Кол_во_в_упак]*[Кол_во_упак]) то получим требуемый результат. Для этого поместим в область заголовка свободное поле и введем вышеприведенную формулу в поле свойства Данные. При этом, во избежание ошибок, можно воспользоваться Построителем выражений. Заметим, что знак равенства «=» является обязательным атрибутом вычисляемого поля. Чтобы результат выводился в денежных единицах, на вкладке Макет нужно выбрать формат Денежный для этого поля. Внимание При применении фильтра (смотри главу 10) суммироваться будут значения только для отфильтрованных записей.

При оформлении каждой очередной поставки с помощью формы Прием товаров для каждого наименования товара приходится выбирать из соответствующих списков сотрудника, поставщика и категорию товара. При оформлении большой партии товара это отнимет много времени. Было бы удобно при добавлении новой записи автоматически заполнять эти поля. При этом должна использоваться информация из перечисленных полей, введенная в предыдущей записи.

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

Поскольку значения вспомогательных переменных используются в двух различных процедурах, их следует описать в разделе Описания (Declarations) в Общей области (Ganeral) модуля формы.

Для описания переменных используется служебное слово Dim, после которого через запятую перечисляются переменные. Таких строк может быть несколько в каждой процедуре.

Итак, мы описали три переменных Пост, Сотр и Катег, которые будут использованы для хранения текущих значений списков. Переименуем списки таким образом, чтобы не путать их имена с именами полей источника записей. Используя свойство Имя на вкладке Другие, назовем эти списки Поставщик_, Сотрудник_ и Категория_ соответственно. Воспользуемся теперь событийной процедурой После вставки, чтобы сохранить значения этих полей при добавлении новой записи.

Private Sub Form_AfterInsert() ‘ Сохранение значений из списка в переменных Пост, Сотр, Катег Пост = Поставщик_ Сотр = Сотрудник_ Катег = Категория_ End Sub

Теперь воспользуемся событием Текущая запись, чтобы автоматически вводить в списки сохраненные значения. Однако это следует делать только при переходе к новой записи, поэтому сначала проверим, что эта запись – новая. Есть несколько способов такой проверки. Наша проверка состоит в том, что значения всех трех нужных нам элементов управления являются нулевыми. Дело в том, что при добавлении новой записи в таблицу Товары по умолчанию используются нулевые значения для полей Поставщик, Сотрудник и Категория_товара, связанных с рассматриваемыми элементами управления на форме. В результате получим следующую процедуру

Private Sub Form_Current() ‘ Проверка того, что мы перешли к новой записи If (Поставщик_ = 0) And (Сотрудник_ = 0) And (Категория_ = 0) Then ‘ Заполнение полей значениями переменных Поставщик_ = Пост Сотрудник_ = Сотр Категория_ = Катег End If End Sub

Последний отмеченный выше недостаток, связанный с непреднамеренным ошибочным выбором элемента списка для имеющейся записи, можно устранить, если открывать форму Прием товаров в разных режимах: в режиме редактирования, в режиме просмотра или в режиме добавления новых записей. Рассмотрим этот вопрос позже при создании главной формы, которая и будет служить нам для управления работой всего приложения (глава 10).

Сделаем небольшое отступление, чтобы познакомиться с некоторыми важными средствами MS Access, которые на этом этапе разработки приложения уже могут оказаться полезными.

Сжатие базы данных

Эта утилита позволяет значительно уменьшить размер .mdb файла. В силу специфичной структуры файла базы данных, его размер значительно увеличивается в процессе работы над созданием приложения. Увеличение в несколько раз не является здесь чем-то исключительным, особенно при конструировании форм, отчетов и других объектов базы данных. Кроме того, работа с данными приводит к увеличению размера файла. Это связано с тем, что при удалении и добавлении записей дисковые страницы (блоки) оказываются сильно фрагментированными, и их количество может быть уменьшено при устранении свободного пространства на страницах. Помимо экономии объема внешней памяти, процедура сжатия будет способствовать повышению быстродействия системы, т.к. при уменьшении числа дисковых страниц, занимаемых данными, будет уменьшаться и число обращений к диску для поиска нужных данных при выполнении запросов. Поэтому рекомендуется периодически выполнять сжатие базы данных.

Заметим, что сжатие базы данных имеет мало общего с программами-архиваторами типа WinZip или WinRar. При использовании последних файл записывается в одном из сжатых форматов, что не позволяет работать с ним непосредственно с помощью приложения, в котором файл создавался. Таким образом, чтобы продолжить работу со сжатым файлом, нужно предварительно выполнить операцию извлечения из архива. Сжатие же базы данных по существу лишь устраняет фрагментацию страниц за счет более компактного размещения записей, оставляя файл в рабочем состоянии.

Чтобы выполнить сжатие текущего файла базы данных, нужно выполнить команду Сервис\Служебные программы\Сжать и восстановить базу данных. . При этом файл .mdb будет перезаписан под тем же именем.

Чтобы сжать базу данных в файл с другим именем или в файл, который не является текущей базой данных, необходимо закрыть базу данных, не выходя из программы Access, и выполнить ту же команду. Закрыть базу данных можно с помощью команды Файл\Закрыть или же простым закрытием окна базы данных. Однако теперь при выполнении команды сжатия нужно будет сначала указать (выбрать в диалоговом окне), какой файл требуется сжать, а затем ввести имя, под которым будет сохранен сжатый файл. Если при этом выбрать имя существующего файла, то он будет заменен сжатым файлом после подтверждения выполнения операции.

Восстановление базы данных

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

В некоторых случаях Microsoft Access определяет, что база данных повреждена, при попытке открыть, закодировать или раскодировать ее, и предоставляет пользователю возможность восстановить базу данных. В остальных случаях операцию восстановления следует проделать самостоятельно.

В ранних версиях до Access 2000 имелось две разных команды — Сжать базу данных и Восстановить базу данных. Теперь эти две операции выполняются одной командой Сжать и восстановить базу данных. Поэтому для восстановления базы данных следует проделать процедуру, аналогичную процедуре сжатия, описанной выше.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *