Как узнать, откуда записывается документ в 1С: из формы, программно или через обмен данными?

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

В процессе разработки и поддержки конфигураций на платформе «1С:Предприятие 8» программисты часто сталкиваются с необходимостью разделения логики при записи документов. Бизнес-требования могут отличаться в зависимости от того, как именно записывается объект: вводится ли он вручную пользователем через форму, создается ли программно с помощью обработки, или же загружается в автоматическом режиме через каналы обмена данными. Например, при интерактивном вводе нужно запустить строгие проверки заполнения, а при программной загрузке из другой системы — принять данные «как есть». Для точечной миграции объектов между базами с сопоставлением по произвольным полям используется обработка для переноса данных между похожими конфигурациями 1С.

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

1. Как отличить интерактивную запись (из формы) от программной записи

Для решения этой задачи в платформе предусмотрен штатный инструмент — свойство ДополнительныеСвойства, доступное у любого прикладного объекта. Это структура, которая существует только в оперативной памяти в рамках текущего сеанса и транзакции записи объекта. Данные из нее не сохраняются в базу данных, что делает её идеальным контейнером для передачи временных параметров (маркеров контекста) из формы в модуль объекта.

Давайте разберем по шагам, как настроить передачу такого маркера:

Шаг 1. Передаем признак из модуля формы документа

В модуле управляемой формы документа найдем или создадим предопределенный серверный обработчик ПередЗаписьюНаСервере. В этот момент у нас есть одновременный доступ как к контексту формы, так и к самому записываемому объекту через параметр ТекущийОбъект. Пропишем в нем установку специального флага:


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

Шаг 2. Анализируем маркер в модуле объекта

Теперь перейдем в модуль самого документа. В обработчике события ПередЗаписью (или ПриЗаписи) мы можем считать этот параметр и выполнить соответствующую логику:


Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
    
    // По умолчанию считаем запись программной
    ИнтерактивнаяЗапись = Ложь;
    
    // Проверяем наличие нашего флага в структуре дополнительных свойств
    Если ЭтотОбъект.ДополнительныеСвойства.Свойство("ИнтерактивнаяЗапись", ИнтерактивнаяЗапись) 
        И ИнтерактивнаяЗапись Тогда
        
        // Сюда пишем код, который должен выполняться ТОЛЬКО при записи пользователем из формы
        // Например: интерактивные проверки заполнения реквизитов, специфические диалоги и т.д.
        
    Иначе
        
        // Этот блок сработает при программной записи (из внешних обработок, группового перепроведения)
        // Здесь структура ДополнительныеСвойства будет пустой
        
    КонецЕсли;
    
КонецПроцедуры

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

2. Как определить, что документ записывается в процессе обмена данными

Если в вашей системе настроена синхронизация данных с другими информационными базами (например, УТ – БП или ERP – ЗУП), то документы могут загружаться автоматически. При этом крайне важно отключать локальные бизнес-проверки модуля объекта, чтобы не заблокировать перенос корректных данных из другой базы. Чтобы проконтролировать корректность загруженных данных и выявить возможные расхождения после переноса, используется программа автоматической сверки проводок между базами 1С.

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

Проанализируем правильный шаблон написания обработчиков в модуле объекта с учетом этого механизма:


Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
    
    // Это должно быть ПЕРВОЙ строкой любого обработчика событий записи
    Если ОбменДанными.Загрузка Тогда
        Возврат; // Полностью пропускаем локальные проверки, так как данные пришли из доверенного источника
    КонецЕсли;
    
    // Ниже идет стандартная бизнес-логика для ручной или программной записи внутри этой базы
    // ...
    
КонецПроцедуры

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

3. Как выяснить, участвовал ли документ в обмене ранее

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

Способ А. Проверка регистрации изменений на узлах планов обмена

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


// Проверим, зарегистрированы ли изменения по документу для конкретного узла обмена
Зарегистрирован = ПланыОбмена.ИзменениеЗарегистрировано(СсылкаНаУзел, СсылкаНаДокумент);
Если Зарегистрирован Тогда
    // Документ ожидает отправки при следующем сеансе обмена
КонецЕсли;

Способ Б. Анализ регистров Библиотеки стандартных подсистем (БСП)

В современных конфигурациях, использующих БСП, факт успешного обмена фиксируется в специализированных регистрах сведений. Наиболее информативным является регистр СоответствияОбъектовИнформационныхБаз. В нем хранится связь между уникальным идентификатором (UUID) объекта в текущей базе и его UUID в базе-приемнике.

Напишем запрос для проверки наличия записи по нашему документу в этом регистре:


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	Соответствия.СобственнаяСсылка КАК СобственнаяСсылка
    |ИЗ
    |	РегистрСведений.СоответствияОбъектовИнформационныхБаз КАК Соответствия
    |ГДЕ
    |	Соответствия.СобственнаяСсылка = &ДокументСсылка";

Запрос.УстановитьПараметр("ДокументСсылка", СсылкаНаДокумент);
РезультатЗапроса = Запрос.Выполнить();

Если НЕ РезультатЗапроса.Пустой() Тогда
    // Документ гарантированно участвовал в обмене и имеет сопоставленный объект во внешней базе
КонецЕсли;

4. Определение контекста через анализ сеансов системы

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

Рассмотрим пример анализа сеанса в модуле объекта:


ТекущийСеанс = ПолучитьТекущийСеансИнформационнойБазы();

// 1. Проверяем, запущена ли запись из фонового задания (регламентные задания, фоновые обмены)
Если ТекущийСеанс.ИмяПриложения = "BackgroundJob" Тогда
    // Запись инициирована фоновым процессом
    
// 2. Проверяем обращение через Web или HTTP-сервисы (интеграция сторонних систем в реальном времени)
ИначеЕсли ТекущийСеанс.ИмяПриложения = "WebService" ИЛИ ТекущийСеанс.ИмяПриложения = "HTTPService" Тогда
    // Запись происходит через программный интерфейс API
    
// 3. Проверяем имя пользователя, под которым выполняется транзакция
КонецЕсли;

ТекущийПользователь = ПользователиИнформационнойБазы.ТекущийПользователь();
Если Найти(ВРег(ТекущийПользователь.Имя), "EXCHANGE") > 0 Тогда
    // Запись выполняется под специализированной учетной записью обмена данными
КонецЕсли;

5. Ретроспективный анализ: Журнал регистрации и Версионирование

Если перед вами стоит задача расследовать инцидент из прошлого (например: «Кто изменил этот документ вчера в 18:00 — пользователь или робот?»), то написание кода в модулях уже не поможет. В этом случае мы должны использовать административные инструменты системы.

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

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

← На главную