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