Как из внешней обработки заполнения получить доступ к управляемой форме документа и обновить ее элементы

Программист 1С v8.3 (Управляемые формы) 1С:Зарплата и Управление Персоналом IT и автоматизация бизнеса
← На главную

При разработке дополнительных обработок заполнения по стандарту БСП часто возникает задача: дать пользователю возможность выбрать внешний файл через диалоговое окно на клиенте, загрузить данные в текущий документ, а затем обновить элементы управляемой формы (например, скрыть или показать определенные колонки табличной части, как это происходит при изменении периода в документе «Табель»).

Однако при реализации такого сценария разработчики сталкиваются с архитектурным тупиком. Разберем суть проблемы, выясним причины ограничений платформы «1С:Предприятие 8.3» и рассмотрим работающие варианты решения поставленной задачи без снятия конфигурации с поддержки.

В чем заключается проблема и архитектурные ограничения

Проанализируем стандартные варианты подключения дополнительных обработок БСП и возникающие при этом сложности:

  1. Режим «ВызовСерверногоМетода»: контекст формы документа доступен на сервере через свойство ПараметрыВыполнения.ЭтаФорма. В этом случае мы можем напрямую передать форму в типовые серверные процедуры общих модулей. Однако в этом режиме невозможно интерактивно взаимодействовать с пользователем на клиенте — открыть диалог выбора файла или форму параметров нельзя.
  2. Режим «ОткрытиеФормы»: пользователю открывается собственная форма обработки, где доступен диалог выбора файлов. Через свойство ЭтаФорма.ВладелецФормы на клиенте доступна ссылка на форму документа. Однако передать форму-владельца на сервер в типовой общий модуль нельзя — платформа вызовет исключение «Передача мутабельного значения на сервер», так как объект типа УправляемаяФорма не сериализуется и привязан исключительно к клиентскому контексту.
  3. Программное изменение данных: изменение реквизитов объекта или формы из внешнего программного кода не вызывает штатные события элементов управления ПриИзменении, поэтому автоматического пересчета видимости колонок типовыми механизмами конфигурации не происходит.

Посмотрим на пример типового серверного вызова, к которому часто требуется обратиться (например, при заполнении табеля учета рабочего времени):


&НаСервере
Процедура ПериодРегистрацииПриИзменении()
    УчетРабочегоВремениРасширенныйФормы.ТабельПериодРегистрацииПриИзменении(ЭтаФорма);
КонецПроцедуры

Поскольку серверный контекст формы документа изолирован внутри самого модуля формы документа, вызвать такую контекстную серверную процедуру из внешней формы напрямую невозможно. Разберем доступные и корректные пути решения.

Вариант 1. Управление видимостью элементов формы напрямую на клиенте

Проанализируем назначение типовых серверных процедур управления формой. В большинстве случаев они рассчитывают условия видимости и обращаются к коллекции элементов интерфейса. При этом свойства Видимость, Доступность и ТолькоПросмотр элементов формы полностью доступны для чтения и модификации в клиентском контексте.

Поэтому самым чистым решением без изменения конфигурации является перенос логики переключения видимости колонок на клиент:

  1. На сервере внешней обработки считываем файлы, формируем структуру загружаемых данных и определяем список колонок, которые должны остаться видимыми.
  2. Возвращаем результат на клиент в форму обработки или в процедуру завершения.
  3. Заполняем реквизиты документа через ВладелецФормы.
  4. Напрямую обходим элементы формы-владельца на клиенте и переключаем их свойство Видимость.

Рассмотрим пример кода на клиенте формы обработки после завершения загрузки:


&НаКлиенте
Процедура ЗавершитьЗагрузкуИНастроитьФорму(ИменаВидимыхКолонок)
    ФормаДокумента = ЭтаФорма.ВладелецФормы;
    
    // Перебираем колонки табличной части документа
    Для НомерДня = 1 По 31 Цикл
        ИмяКолонки = "Дни" + Строка(НомерДня);
        ЭлементКолонка = ФормаДокумента.Элементы.Найти(ИмяКолонки);
        
        Если ЭлементКолонка <> Неопределено Тогда
            ЭлементКолонка.Видимость = (ИменаВидимыхКолонок.Найти(ИмяКолонки) <> Неопределено);
        КонецЕсли;
    КонецЦикла;
КонецПроцедуры

Вариант 2. Команда «ВызовКлиентскогоМетода» с асинхронной загрузкой файлов

Если для загрузки не требуется сложный интерфейс настройки, а нужен только выбор файлов на диске, можно отказаться от открытия отдельной формы обработки и зарегистрировать команду БСП с типом ВызовКлиентскогоМетода.

Разберем по шагам эту схему:

  1. В модуле обработки на клиенте в процедуре ВыполнитьКоманду через параметр ПараметрыВыполнения.ЭтаФорма мы получаем доступ к исходной форме документа.
  2. Вызываем асинхронный диалог выбора файлов с помощью метода ПоместитьФайлыНаСервер() без открытия промежуточных окон.
  3. После помещения файлов во временное хранилище на клиенте формы документа остаются доступны все ее элементы для модификации.

Вариант 3. Использование механизма оповещений формы

Проанализируем модуль формы документа в конфигураторе. Нередко в типовых формах реализован предопределенный обработчик ОбработкаОповещения, который отслеживает определенные события и запускает внутри формы требуемые серверные процедуры перерисовки интерфейса.

Если в форме документа есть такой обработчик, из формы обработки на клиенте достаточно отправить системное оповещение:


&НаКлиенте
Процедура ПослеЗагрузкиДанных()
    // Отправляем оповещение, на которое подписана форма документа
    Оповестить("ОбновитьФормуПослеЗаполнения", Новый Структура("Ключ", Значение), ВладелецФормы);
КонецПроцедуры

Форма документа, поймав оповещение в своем контексте, самостоятельно выполнит вызов серверных процедур с передачей собственного контекста ЭтаФорма.

Вариант 4. Реализация через расширение конфигурации

Если вызывать штатную серверную процедуру документа обязательно и логика управления элементами слишком сложна для дублирования на клиенте, наиболее правильным архитектурным решением будет использование механизма расширений (без снятия основной базы с поддержки):

  1. Добавляем форму документа в расширение конфигурации.
  2. Объявляем в форме экспортную процедуру с директивой &НаСервере или перехватываем обработчик события с помощью аннотации &После.
  3. Из внешней обработки вызываем эту процедуру формы-владельца, либо полностью переносим механизм заполнения и чтения файлов в само расширение.
← На главную