Как синхронизировать комментарии и значения флажков между двумя разными формами и документами в 1С

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

В процессе разработки в среде 1С часто возникает задача обеспечения идентичности данных в разных объектах. Например, когда пользователь вводит комментарий или устанавливает флажок в одной форме, эти изменения должны автоматически отобразиться в другом документе или форме. Ситуация осложняется, если прямой ссылки между документами в метаданных не существует. Разберем подробно, как реализовать такую синхронизацию, используя различные механизмы платформы.

Вариант 1. Использование регистра сведений для хранения общих данных

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

Создадим непериодический РегистрСведений, назовем его, например, ОбщиеКомментарииКДокументам. В качестве измерений можно использовать ключевые поля, по которым система поймет, что документы относятся к одной «группе» (например, Контрагент и Дата, или какой-то уникальный строковый идентификатор связи). В ресурсы добавим Комментарий и Флажок.

Теперь в модуле формы каждого документа нам нужно реализовать чтение и запись в этот регистр. Посмотрим на пример кода записи при изменении данных на форме:


&НаСервере
Процедура ЗаписатьОбщийКомментарийНаСервере(ЗначениеКомментария, КлючСвязи)
    МенеджерЗаписи = РегистрыСведений.ОбщиеКомментарииКДокументам.СоздатьМенеджерЗаписи();
    МенеджерЗаписи.КлючСвязи = КлючСвязи;
    МенеджерЗаписи.Комментарий = ЗначениеКомментария;
    МенеджерЗаписи.Записать();
КонецПроцедуры

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

Вариант 2. Синхронизация через подписку на события (уровень базы данных)

Выясним причину, по которой иногда неудобно использовать регистры: если данные все же должны дублироваться в реквизитах самих документов. В этом случае нам поможет объект метаданных ПодпискаНаСобытие. Это позволит автоматически обновлять второй документ в момент записи первого.

Создадим подписку на событие ПриЗаписи для первого типа документа. В обработчике нам необходимо найти «парный» документ и обновить его. Рассмотрим пример логики поиска и обновления:


Процедура СинхронизироватьКомментарийПриЗаписи(Источник, Отказ) Экспорт
    // Проверяем, что запись инициирована пользователем, а не обменом данных
    Если Источник.ОбменДанными.Загрузка Тогда
        Возврат;
    КонецЕсли;

    // Логика поиска связанного документа (например, по реквизиту или коду)
    ДокументОбъект2 = НайтиСвязанныйДокумент(Источник); 
    
    Если ДокументОбъект2 <> Неопределено Тогда
        // Проверяем, не заблокирован ли объект
        Попытка
            ДокументОбъект2.Заблокировать();
            ДокументОбъект2.Комментарий = Источник.Комментарий;
            ДокументОбъект2.Галка = Источник.Галка;
            // Важно установить ОбменДанными.Загрузка, чтобы не вызвать бесконечную рекурсию
            ДокументОбъект2.ОбменДанными.Загрузка = Истина;
            ДокументОбъект2.Записать();
        Исключение
            // Сообщить пользователю о невозможности синхронизации
        КонецПопытки;
    КонецЕсли;
КонецПроцедуры

Важный момент: использование свойства ОбменДанными.Загрузка = Истина критически важно для предотвращения зацикливания, если для второго документа настроена аналогичная подписка.

Вариант 3. Оперативное обновление через механизм оповещений (уровень интерфейса)

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

В первой форме (где вводят текст) добавим обработчик события ПриИзменении для поля комментария:


&НаКлиенте
Процедура КомментарийПриИзменении(Элемент)
    СтруктураДанных = Новый Структура;
    СтруктураДанных.Вставить("Текст", Объект.Комментарий);
    СтруктураДанных.Вставить("Флажок", Объект.Галка);
    
    Оповестить("ОбновлениеСвязанныхДанных", СтруктураДанных, ЭтаФорма);
КонецПроцедуры

Во второй форме в процедуре ОбработкаОповещения мы принимаем этот сигнал:


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

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

Вариант 4. Обновление через «ОповеститьОбИзменении»

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

Сравнительный анализ решений

Выберем оптимальный путь в зависимости от задачи:

  1. Если данные должны храниться вечно и документы не связаны — используем Регистр сведений.
  2. Если нужно жесткое дублирование в реквизитах объектов — используем Подписку на событие.
  3. Если важна визуальная синхронизация в открытых окнах — используем Механизм оповещений.

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

Таким образом, комбинируя подписку на событие (для надежности хранения в БД) и механизм оповещений (для удобства интерфейса), мы получаем полноценное решение задачи синхронизации данных.

← На главную