Как обновить форму списка документов при их программном создании на сервере в 1С?

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

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

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

Анализ архитектурной ошибки: создание документов при проведении

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

  1. Транзакции и дедлоки (взаимные блокировки). Проведение любого документа всегда выполняется внутри транзакции базы данных. Если внутри этой транзакции мы начинаем записывать и проводить другие связанные документы, СУБД накладывает избыточные блокировки на таблицы базы данных. В многопользовательской базе это неизбежно приведет к ошибкам взаимных блокировок.
  2. Целостность данных. При возникновении любой ошибки во время создания связанного документа вся транзакция проведения основного документа будет отменена. Это делает систему нестабильной и усложняет поиск ошибок.
  3. Отсутствие связи с клиентом. Находясь внутри транзакции проведения на сервере, платформа физически не может передать сигнал на клиентское приложение для обновления формы списка. Механизмы оповещения в транзакции не работают.

Правильное решение: Логику автоматического создания связанных документов необходимо полностью выносить за рамки транзакции проведения. Оптимальный вариант — выполнять генерацию документов на клиенте сразу после успешной записи и проведения основного документа. Для этого отлично подходят обработчики событий формы ПослеЗаписи или ПослеЗаписиНаСервере.

Способ 1. Использование механизма Динамического списка (Автоматическое обновление)

Если форма списка, которую вам нужно обновить, построена на стандартном элементе управления Динамический список, платформа 1С может обновить её автоматически. Но для этого необходимо соблюдение двух строгих условий:

  1. У динамического списка в конфигураторе обязательно должно быть заполнено свойство «Основная таблица» (например, Документ.ЗаданиеУчасток). Если список использует произвольный запрос без указания основной таблицы, платформа не сможет отследить изменения данных в СУБД, и автоматического обновления списка не произойдет.
  2. Транзакция записи создаваемого документа на сервере должна быть полностью завершена и зафиксирована в базе данных.

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

Способ 2. Возврат управления на клиент и вызов Оповещения (Рекомендуемый метод)

Если автоматическое обновление не сработало (или список построен на базе произвольного запроса без основной таблицы), правильным архитектурным подходом будет передача управления с сервера обратно на клиент и последующий вызов метода ОповеститьОбИзменении().

Давайте разберем по шагам, как должна выглядеть эта цепочка вызовов:

  1. Пользователь совершает действие на клиенте (например, нажимает кнопку проведения или закрытия).
  2. Клиентский код вызывает серверную функцию общего модуля, которая выполняет создание документов.
  3. Серверная функция возвращает на клиент результат работы — массив ссылок на созданные документы.
  4. На клиенте, получив массив ссылок, мы вызываем метод ОповеститьОбИзменении() для каждой новой ссылки.

Рассмотрим пример реализации кода. Начнем с серверной функции в общем модуле, которая создает документы:


Функция СоздатьДокументыНаСервере(СтруктураПараметров) Экспорт
    МассивСозданныхДокументов = Новый Массив;
    
    НовыйДокумент = Документы.ЗаданиеУчасток.СоздатьДокумент();
    НовыйДокумент.Дата = ТекущаяДата();
    НовыйДокумент.Номенклатура = СтруктураПараметров.Номенклатура;
    НовыйДокумент.Количество = СтруктураПараметров.Количество;
    
    Попытка
        НовыйДокумент.Записать(РежимЗаписиДокумента.Запись);
        МассивСозданныхДокументов.Добавить(НовыйДокумент.Ссылка);
    Исключение
        ВызватьИсключение "Не удалось записать документ Задание на участок: " + ОписаниеОшибки();
    КонецПопытки;
    
    Возврат МассивСозданныхДокументов;
КонецФункции

Теперь рассмотрим клиентскую часть в модуле формы, откуда инициируется создание:


&НаКлиенте
Процедура ВыполнитьСозданиеИОбновление(Команда)
    ПараметрыЗаказа = Новый Структура;
    ПараметрыЗаказа.Вставить("Номенклатура", Объект.Номенклатура);
    ПараметрыЗаказа.Вставить("Количество", Объект.Количество);
    
    // Вызываем серверный метод через серверный контекст формы
    СозданныеДокументы = ВыполнитьСозданиеНаСервере(ПараметрыЗаказа);
    
    // Оповещаем открытые формы об изменениях
    Если СозданныеДокументы.Количество() > 0 Тогда
        Для Каждого СсылкаДок Из СозданныеДокументы Цикл
            ОповеститьОбИзменении(СсылкаДок);
        КонецЦикла;
    КонецЕсли;
КонецПроцедуры
    
&НаСервере
Функция ВыполнитьСозданиеНаСервере(ПараметрыЗаказа)
    // Вызов функции из общего модуля
    Возврат ОбщийМодульДокументы.СоздатьДокументыНаСервере(ПараметрыЗаказа);
КонецФункции

Использование метода ОповеститьОбИзменении() — это наиболее производительный и правильный способ взаимодействия в управляемом приложении. Он посылает сигнал всем открытым формам списков данного типа перечитать данные из базы данных.

Способ 3. Система взаимодействия (Push-уведомления для сложных сценариев)

Иногда возникают ситуации, когда документ создается в фоновом задании, другим пользователем или через внешнее API (HTTP-сервис). В этом случае стандартная цепочка клиент-серверного вызова у текущего пользователя отсутствует. Для таких задач в платформе 1С предусмотрена Система взаимодействия.

Принцип реализации выглядит следующим образом:

  1. На сервере в момент записи документа отправляется push-сообщение в интеграционный канал Системы взаимодействия.
  2. На клиенте, при открытии формы списка документов, мы подписываемся на этот канал.
  3. При получении сообщения на клиенте срабатывает обработчик, который принудительно вызывает метод Элементы.Список.Обновить().

Этот подход позволяет реализовать мгновенный обмен событиями между сессиями разных пользователей без лишней нагрузки на СУБД.

Способ 4. Включение автообновления динамического списка по таймеру

Если все предыдущие варианты по какой-то причине не подходят, можно настроить автоматическое периодическое обновление формы списка средствами самой платформы. Для этого выполните следующие действия:

  1. Откройте форму списка нужного документа в конфигураторе.
  2. Выберите элемент формы «Список» (динамический список).
  3. В панели свойств найдите флаг «Автообновление» и установите его.
  4. В поле «Период автообновления» укажите интервал в секундах (например, 15 или 20 секунд).

После этого платформа будет самостоятельно опрашивать базу данных и обновлять список документов на экране пользователя. Однако помните, что данный способ создает дополнительную постоянную фоновую нагрузку на сервер СУБД. Применять его для тяжелых списков со сложными запросами не рекомендуется.

← На главную