Разработчики в 1С часто сталкиваются с задачей: в зависимости от значения определенного реквизита документа (например, вида операции или статуса) открыть пользователю ту или иную форму. При попытке реализовать это через обработчик события выбора в динамическом списке списка документов возникает неприятная проблема — открываются сразу две формы (и стандартная, и специализированная), несмотря на то, что в коде явно прописано СтандартнаяОбработка = Ложь;.
В этой статье мы подробно разберем причины такого поведения платформы «1С:Предприятие», научимся правильно переопределять стандартное событие выбора в форме списка, а также рассмотрим более элегантное и архитектурно верное решение через модуль менеджера.
Проанализируем ситуацию на конкретном примере. Допустим, у нас есть документ ИнвентаризацияТоваровНаСкладе. Если у документа вид операции равен «Спецодежда», нам необходимо открыть специализированную форму ФормаСпецодежды, во всех остальных случаях — стандартную ФормаДокумента.
Основная причина, по которой установленное свойство СтандартнаяОбработка = Ложь игнорируется платформой — это неправильное количество параметров в объявлении процедуры-обработчика.
Типичная ошибка разработчика выглядит следующим образом:
&НаКлиенте
Процедура СписокВыбор(Элемент, ВыбранноеЗначение, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
ТекущиеДанные = Элемент.ТекущиеДанные;
СтруктураПараметров = Новый Структура;
СтруктураПараметров.Вставить("Ключ", ТекущиеДанные.Ссылка);
Если ТекущиеДанные.ВидОперации = ПредопределенноеЗначение("Перечисление.ВидыОперацийИнвентаризацияТоваров.Спецодежда") Тогда
ОткрытьФорму("Документ.ИнвентаризацияТоваровНаСкладе.Форма.ФормаСпецодежды", СтруктураПараметров);
Иначе
ОткрытьФорму("Документ.ИнвентаризацияТоваровНаСкладе.Форма.ФормаДокумента", СтруктураПараметров);
КонецЕсли;
КонецПроцедуры
Обратим внимание на сигнатуру процедуры СписокВыбор. Здесь объявлено всего три параметра. Однако системное событие таблицы динамического списка Выбор требует строго четыре параметра:
Выбор(Элемент, ВыбраннаяСтрока, Поле, СтандартнаяОбработка)
Платформа 1С передает параметры по порядку их следования. При трех параметрах в коде происходит следующее:
Элемент передается сама таблица формы.ВыбранноеЗначение передается идентификатор выбранной строки.СтандартнаяОбработка, передается объект ПолеФормы (по которому кликнул пользователь).Таким образом, строка кода СтандартнаяОбработка = Ложь; всего лишь перезаписывает локальную переменную, содержащую ссылку на поле формы, а реальный четвертый параметр, управляющий стандартной обработкой события на уровне платформы, остается незадействованным. Платформа считает, что стандартную обработку никто не отменял (флаг равен Истина), и параллельно с вашей формой открывает стандартную форму объекта.
Самый быстрый способ решить проблему непосредственно в форме списка — привести сигнатуру процедуры в соответствие со стандартами платформы, добавив пропущенный параметр Поле.
Рассмотрим исправленный вариант кода:
&НаКлиенте
Процедура СписокВыбор(Элемент, ВыбраннаяСтрока, Поле, СтандартнаяОбработка)
// Теперь этот параметр действительно отменяет стандартное открытие формы
СтандартнаяОбработка = Ложь;
ТекущиеДанные = Элемент.ТекущиеДанные;
Если ТекущиеДанные = Неопределено Тогда
Возврат;
КонецЕсли;
СтруктураПараметров = Новый Структура;
СтруктураПараметров.Вставить("Ключ", ТекущиеДанные.Ссылка);
// Проверяем условие и открываем соответствующую форму
Если ТекущиеДанные.ВидОперации = ПредопределенноеЗначение("Перечисление.ВидыОперацийИнвентаризацияТоваров.Спецодежда") Тогда
ОткрытьФорму("Документ.ИнвентаризацияТоваровНаСкладе.Форма.ФормаСпецодежды", СтруктураПараметров);
Иначе
ОткрытьФорму("Документ.ИнвентаризацияТоваровНаСкладе.Форма.ФормаДокумента", СтруктураПараметров);
КонецЕсли;
КонецПроцедуры
Важное примечание: При двойном клике по строке списка у таблицы также может срабатывать событие ПередНачаломИзменения. Если вы хотите полностью заблокировать стандартное поведение изменения строки, убедитесь, что в свойствах таблицы на это событие не завязана логика, способная вызвать открытие стандартного окна, или обработайте его, установив параметр Отказ = Истина.
Переопределение открытия формы в обработчике списка решает задачу локально — только в этой конкретной форме списка. Если пользователь откроет документ по ссылке из отчета, из другого документа или через глобальный поиск, то откроется основная форма, а не нужная по условию.
Чтобы избежать дублирования кода и сделать решение глобальным, в платформе 1С:Предприятие реализован механизм переопределения получаемой формы на уровне модуля менеджера объекта с помощью процедуры ОбработкаПолученияФормы.
Выполним следующие шаги для реализации этого подхода:
ИнвентаризацияТоваровНаСкладе.ОбработкаПолученияФормы.Разберем пример реализации кода:
Процедура ОбработкаПолученияФормы(ВидФормы, Параметры, ВыбраннаяФорма, ДополнительнаяИнформация, СтандартнаяОбработка)
// Нас интересует переопределение только основной формы существующего объекта
Если ВидФормы = "ФормаОбъекта" И Параметры.Свойство("Ключ") Тогда
// Получаем значение реквизита быстрым запросом без загрузки всего объекта в память
ВидОперацииДокумента = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(Параметры.Ключ, "ВидОперации");
Если ВидОперацииДокумента = ПредопределенноеЗначение("Перечисление.ВидыОперацийИнвентаризацияТоваров.Спецодежда") Тогда
ВыбраннаяФорма = "Документ.ИнвентаризацияТоваровНаСкладе.Форма.ФормаСпецодежды";
СтандартнаяОбработка = Ложь; // Отменяем стандартный выбор формы платформой
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Преимущества использования модуля менеджера:
Выбор в форме списка, форме выбора и других списках, где отображается наш документ.Важные нюансы при работе с ОбработкаПолученияФормы:
Параметры.Ключ) крайне важно использовать легкие функции получения данных (например, функцию ОбщегоНазначения.ЗначениеРеквизитаОбъекта или прямой запрос), чтобы не считывать весь объект базы данных целиком. Это критично для производительности интерфейса.Ключ будет отсутствовать в структуре параметров. Если вам нужно разделять формы также при создании нового документа, анализируйте параметры заполнения, переданные в структуре Параметры.