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