Как обновить форму открытого документа из внешней обработки 1С

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

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

Разбор ситуации: почему форма не обновляется сама?

Для начала проанализируем, как работает управляемая форма 1С. Форма — это клиентский объект, который хранит данные в реквизите Объект. Когда внешняя обработка меняет данные самого документа в базе данных (на сервере), клиентское приложение об этом «не знает». Данные на форме и данные в таблицах базы данных рассинхронизируются. Чтобы их объединить, нам нужно дать команду форме актуализировать свое состояние.

Способ 1. Использование метода Прочитать()

Это самый простой и часто используемый способ, который был найден в ходе обсуждения. Метод Прочитать() расширения управляемой формы для документа полностью перезагружает данные из базы данных в реквизит формы Объект.

Рассмотрим пример кода, который позволяет найти форму и вызвать этот метод:


// В контексте внешней обработки
Ключ = Новый Структура("Ключ", СсылкаНаДокумент);
ФормаДокумента = ПолучитьФорму("Документ.ПересчетТоваров.Форма.ФормаДокумента", Ключ);     
ФормаДокумента.Прочитать();

Важные нюансы этого метода:

  1. Запись обязательна: Метод Прочитать() загружает данные именно из базы. Это значит, что перед его вызовом ваша внешняя обработка должна обязательно выполнить ЭтотОбъект.Записать(). Если вы изменили данные в памяти, но не сохранили их, вызов Прочитать() просто сотрет ваши изменения, вернув форму к исходному состоянию.
  2. Потеря несохраненных данных пользователя: Если пользователь перед запуском обработки что-то ввел в документ вручную и не сохранил, вызов Прочитать() уничтожит эти правки.

Способ 2. Правильный доступ к форме через параметры БСП

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

В процедуру ВыполнитьКоманду на клиенте передается структура ПараметрыВыполнения. Рассмотрим, как правильно использовать это свойство:


&НаКлиенте
Процедура ВыполнитьКоманду(ИдентификаторКоманды, ОбъектыНазначения, ПараметрыВыполнения)
    // ПараметрыВыполнения.ЭтаФорма — это и есть форма документа-владельца
    ТекущаяФормаДокумента = ПараметрыВыполнения.ЭтаФорма;
    
    // После выполнения серверного кода по заполнению
    ВыполнитьЗаполнениеНаСервере(ОбъектыНазначения);
    
    // Обновляем форму
    ТекущаяФормаДокумента.Прочитать();
КонецПроцедуры

Использование ПараметрыВыполнения.ЭтаФорма гарантирует, что мы работаем именно с тем окном, из которого пользователь нажал кнопку заполнения.

Способ 3. Обновление данных в памяти без записи в БД

Иногда требуется заполнить табличную часть документа так, чтобы пользователь мог проверить результат и решить, сохранять документ или нет. В этом случае метод Прочитать() нам не подходит. Нам нужно передать данные напрямую в реквизиты формы.

Для этого используется метод КопироватьДанныеФормы. Проанализируем схему работы:

  1. Передаем объект на сервер.
  2. Заполняем его (не записывая!).
  3. Возвращаем заполненный объект обратно на клиент.
  4. Копируем данные в форму.

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

Способ 4. Система оповещений (ОповеститьОбИзменении)

Если ваша обработка выполняется асинхронно или вы хотите обновить не только форму документа, но и все динамические списки (например, список документов), где фигурирует этот объект, следует использовать глобальные методы оповещения.

Вызов ОповеститьОбИзменении(Ссылка) заставляет платформу проверить все открытые формы. Если форма отображает данные этого объекта, она будет обновлена. Это наиболее «чистый» способ с точки зрения архитектуры платформы 1С.


// После записи объекта в базе данных
ОповеститьОбИзменении(СсылкаНаДокумент);

Выясним причины возможных ошибок

Проанализируем ситуации, когда обновление может не сработать:

Подведение итогов

Для эффективного обновления формы из внешней обработки выберем подходящий алгоритм:

  1. Если документ нужно записать в базе: используем ПараметрыВыполнения.ЭтаФорма.Прочитать() или ОповеститьОбИзменении(Ссылка).
  2. Если документ нужно оставить открытым для редактирования без записи: используем КопироватьДанныеФормы и устанавливаем Модифицированность = Истина.
  3. Всегда отдаем предпочтение обращению через ПараметрыВыполнения, чтобы избежать ошибок при работе с несколькими открытыми окнами одного и того же типа документа.

Применяя эти методы, мы обеспечим комфортную и корректную работу пользователя с внешними инструментами заполнения данных в 1С.

← На главную