При работе с типовыми конфигурациями 1С часто возникает потребность в небольших доработках, которые значительно улучшают удобство использования для конечных пользователей. Однако прямые изменения в конфигурации влекут за собой сложности при дальнейших обновлениях, вынуждая нас либо отказываться от поддержки, либо постоянно переносить свои доработки. В этой статье мы рассмотрим, как решить подобную задачу, а именно — добавить интерактивный вопрос при закрытии формы обработки, не вмешиваясь в основной код конфигурации и сохраняя ее на типовой поддержке.
Представим ситуацию: у нас есть обработка, которая включена в конфигурацию. Ее разрабатывают и обновляют сторонние специалисты, руководствуясь своим техническим заданием. Наши же пользователи хотели бы внести небольшие изменения, например, добавить вопрос "Вы точно хотите закрыть окно и потерять нафиг 20 минут работы?" при нажатии клавиши Esc. Сохранить обработку в виде отдельного файла и дописать ее – не выход, так как при следующем обновлении конфигурации наши изменения будут утеряны. Как быть в такой ситуации?
Прежде чем перейти к решению, давайте проясним один важный момент, который часто вызывает путаницу. Автор исходного вопроса использовал фразу "внешняя обработка, которая включена в конфигурацию". Это может ввести в заблуждение.
Понимание этой разницы критически важно, так как решение, которое мы будем использовать, применимо именно к объектам, являющимся частью конфигурации.
Для решения нашей задачи мы будем использовать мощный и гибкий инструмент платформы 1С:Предприятие 8.3 — механизм расширений конфигурации. Расширения позволяют нам изменять или дополнять функциональность типовой конфигурации, не внося изменений в ее основной код. Это означает, что мы сохраняем возможность легкого обновления типовой конфигурации поставщиком, а наши доработки остаются работоспособными.
Таким образом, расширения являются идеальным инструментом для нашей задачи, позволяя нам модифицировать поведение формы обработки, не опасаясь потерять изменения при следующем обновлении.
Давайте разберем, как именно мы можем добавить вопрос при закрытии формы обработки, используя расширения.
Прежде всего, нам необходимо создать новое расширение конфигурации. Это первый шаг к изоляции наших доработок от типового кода.
Для того чтобы модифицировать форму обработки, нам необходимо "заимствовать" ее в наше расширение. Это не копирование объекта, а создание ссылки на него в расширении, которая позволяет нам вносить изменения, не затрагивая оригинал.
Обратите внимание, что мы заимствуем только те объекты, которые планируем изменять. В данном случае это сама обработка (как контейнер для формы) и конкретная форма этой обработки.
Теперь, когда форма обработки находится в нашем расширении, мы можем открыть ее модуль и добавить необходимую логику. Наша задача — добавить вопрос при закрытии формы. Для этого мы будем использовать событие формы ПередЗакрытием.
Событие ПередЗакрытием вызывается платформой перед тем, как форма будет закрыта. Оно имеет параметр Отказ, который мы можем установить в Истина, чтобы отменить закрытие формы. Также есть параметр СтандартнаяОбработка, который позволяет управлять вызовом стандартного обработчика (если он есть). Для добавления нашего вопроса мы используем аннотацию &Перед.
Аннотации &Перед, &После, &Вместо:
&Перед("ИмяПроцедурыВБазе"): Выполняет ваш код до кода оригинальной процедуры или функции. Если ваша процедура устанавливает параметр Отказ = Истина или СтандартнаяОбработка = Ложь, то оригинальная процедура может быть не вызвана.&После("ИмяПроцедурыВБазе"): Выполняет ваш код после кода оригинальной процедуры или функции.&Вместо("ИмяПроцедурыВБазе"): Выполняет ваш код вместо кода оригинальной процедуры или функции, полностью заменяя ее логику. Это наиболее рискованная аннотация, так как она может нарушить стандартное поведение.В нашем случае, если мы хотим добавить вопрос ДО того, как форма закроется, и, возможно, предотвратить ее закрытие, нам идеально подходит &Перед.
// В модуле формы, заимствованной в расширение,
// мы можем добавить обработчик события ПередЗакрытием.
// Если в базовой конфигурации уже есть процедура ПередЗакрытием,
// мы можем перехватить ее с помощью аннотации &Перед,
// чтобы добавить нашу логику до выполнения типовой.
&Перед("ПередЗакрытием")
Процедура ПередЗакрытиемРасширение(Отказ, СтандартнаяОбработка)
// Этот код будет выполнен перед тем, как будет вызван типовой обработчик
// ПередЗакрытием (если он есть) и перед закрытием формы.
// Нажатие Esc часто приводит к вызову события ПередЗакрытием формы.
// Выводим диалог с вопросом
Ответ = Вопрос("Вы точно хотите закрыть окно и потерять нафиг 20 минут работы?", РежимДиалогаВопрос.ДаНет, , КодВозвратаДиалога.Нет);
// Если пользователь ответил "Нет", то отменяем закрытие формы
Если Ответ = КодВозвратаДиалога.Нет Тогда
Отказ = Истина; // Устанавливаем Отказ в Истина, чтобы предотвратить закрытие формы
СтандартнаяОбработка = Ложь; // Подавляем вызов оригинального обработчика ПередЗакрытием
// (если он существует), так как мы уже приняли решение.
КонецЕсли;
// Если Отказ не установлен в Истина, форма продолжит закрываться,
// и, если СтандартнаяОбработка не Ложь, будет вызван типовой обработчик ПередЗакрытием.
КонецПроцедуры
Пояснения к коду:
ПередЗакрытиемРасширение, но применили к ней аннотацию &Перед("ПередЗакрытием"). Это означает, что наша процедура будет выполняться перед вызовом оригинальной процедуры ПередЗакрытием из базовой конфигурации.Вопрос(...): Это стандартная функция 1С для вывода диалогового окна с вопросом.РежимДиалогаВопрос.ДаНет: Мы предлагаем пользователю выбрать "Да" или "Нет".КодВозвратаДиалога.Нет: Устанавливаем "Нет" в качестве значения по умолчанию.Отказ = Истина. Это ключевой момент, который отменяет закрытие формы.СтандартнаяОбработка = Ложь: Этот параметр передается в процедуру. Если мы устанавливаем его в Ложь в своей процедуре с аннотацией &Перед, мы предотвращаем вызов оригинального обработчика ПередЗакрытием (если он был) и дальнейшую стандартную обработку закрытия. Это полезно, если мы сами полностью управляем логикой и не хотим, чтобы типовой код продолжал работу после нашего решения об отмене.После того как мы внесли все необходимые изменения в расширение, нам необходимо убедиться, что оно корректно подключено к базе данных и активно.
Платформа 1С различает три типа расширений, которые применяются в определенном порядке. Понимание этих типов поможет нам более грамотно подходить к разработке доработок:
В нашем случае добавление вопроса при закрытии формы является примером Адаптации.
Хотя расширения являются мощным инструментом, их использование требует внимательности и соблюдения определенных правил, чтобы избежать проблем в будущем. Об этом нас предупреждали и коллеги на форуме.
&Вместо, которая полностью заменяет типовую логику. Если типовая логика сильно изменится, ваше &Вместо может оказаться неактуальным или привести к ошибкам. Аннотации &Перед и &После менее конфликтны, но также требуют контроля.&Перед или &После без должного понимания, как они взаимодействуют с типовым кодом, существует риск, что некие важные действия, которые разработчики основной конфигурации делают при закрытии формы, будут выполняться дважды или трижды. Всегда анализируйте типовой код, чтобы понять, что он делает, и как ваша доработка в него встроится.Использование механизма расширений в 1С:Предприятии 8.3 — это современный и предпочтительный способ адаптации типовых конфигураций. Он позволяет нам гибко и безопасно вносить изменения, такие как добавление диалогового окна при закрытии формы, не теряя при этом возможность обновлять основную конфигурацию. Однако, как и любой мощный инструмент, расширения требуют от нас глубокого понимания их работы, внимательности к потенциальным конфликтам и соблюдения рекомендаций по разработке. Всегда стремитесь к чистому и поддерживаемому коду, и по возможности, к конструктивному диалогу с основными разработчиками.