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