MS Access поднять форму событий программно - PullRequest
2 голосов
/ 10 мая 2010

Можно ли вызывать события встроенной формы MS Access программно? у меня есть чувствую, что это не так, но думал, что я проверю. (Я использую Access 2003).

Например, я хочу сделать что-то подобное в частном сабвуфере на форма:

RaiseEvent Delete(Cancel)

и вызвать событие удаления Access.Form - т.е. удаление связанной записи.

Обратите внимание, что мое событие удаления обрабатывается не самой формой, а внешним класс, поэтому я не могу просто вызвать Form_Delete (Отмена).

Ответы [ 2 ]

0 голосов
/ 14 июля 2013

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

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

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

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

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

  1. Если для обработки событий используется модуль класса, то здесь вы можете делать все, вам не нужен код формы.
  2. Если запрос доступен только для чтения и вы хотите удалить запись базовой таблицы, никакая подпрограмма не может вам помочь. Они запускаются, когда пользователь хочет удалить что-то, что он не может сделать, потому что это только для чтения, поэтому DoCmd также не поможет вам.
  3. Как сказал Дэвид в комментарии выше, просто создайте кнопку «Удалить» в любом месте, в котором вы хотите, чтобы затем можно было прочитать идентификатор текущей строки в непрерывной форме и запустить команду «УДАЛИТЬ» SQL, а затем просто запросить непрерывную форму и все готово Вы также можете обработать это в своем стандартном модуле класса, потому что вы можете не только пересылать события формы, вы также можете пересылать события управления таким же образом. Создайте процедуру Init в вашем модуле класса, которая берет все элементы управления из вашей формы, которые вы хотите обработать, с любым, может быть, дополнительным именем базовой таблицы в каждой непрерывной форме, тогда модуль класса может назначить ее стандартному определенному «WithEvents», определенному Например, управляющую переменную типа CommandButton и сохраните имя базовой таблицы в строковую переменную. (Не забудьте установить для события OnClick значение «[Event Process]» в процедуре Init.) В событии Load вашей непрерывной формы, где вы, вероятно, инициализируете свой модуль класса, вы можете затем переслать имя базовой таблицы и элемент управления кнопкой удаления в процедуру Init модуля класса, которая затем может обработать удаление очень общим способом, запустив УДАЛИТЬ запрос к базовой таблице и запросить форму, потому что она уже имеет ссылку на форму. Нет необходимости вызывать процедуру события.

И последнее, но не менее важное: возможно, существуют фреймворки, которые позволяют напрямую вызывать события, но в общем я бы сказал, что создатели таких фреймворков также не понимали цели процедур событий. Если вы когда-либо создавали собственное событие в собственном модуле класса, вы увидите, что они также не могут быть вызваны вне модуля класса. Конечно, вы МОЖЕТЕ создать подпрограмму «RaiseEvent» самостоятельно, чтобы вызывать их извне - и на самом деле, в случае собственных событий это может иметь смысл в некоторых сценариях. В случае событий формы (управления ...) они должны сообщить коду о том, что произошло, и теперь должна быть реакция. Если вы используете события в собственных модулях класса, вы обычно создаете переменную «WithEvents» во внешнем модуле, чтобы получать информацию, когда событие произошло в другом модуле класса. Событие должно сделать объекты модуля независимыми друг от друга. Модуль с событием будет только инициировать событие, и он не знает, слушает ли кто-либо его или реагирует на это событие. Он сообщает «миру», что произошло что-то, что произошло в модуле класса, и ничего больше. Как радиостанция, которая посылает ежедневные новости «в мир», но не знает, слушает ли кто-нибудь ее. Обычно ни один слушатель радиостанции не идет на радиостанцию ​​и не читает свои собственные новости для других слушателей. Только люди на радиостанции решают, что отправлять и когда. Та же история.

0 голосов
/ 11 мая 2010

Я могу понять ваше замешательство - я не объяснил ни одного более крупного контекста. Сожалею.

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

Итак, моей первой мыслью было удаление вне набора записей формы, например. используя запрос на удаление. И я надеялся подключить стандартные события Delete / BeforeDelConfirm / AfterDelConfirm к этой процедуре ручного удаления, вызывая эти события самостоятельно. Но, увы, это невозможно.

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

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

@ Knox , я в принципе не согласен с тем, что возможность самому вызывать «встроенные» события сложно документировать и поддерживать. От этого зависит множество других рамок. На практике Я согласен с вами, поскольку все мы должны работать в рамках ограничений наших инструментов и «лучших практик», которые развиваются вокруг этих ограничений. Благо и проклятие Access - это тесная связь между наборами записей и формами ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...