Как найти и программно обработать счет в 1С, созданный при синхронизации из Битрикс24

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

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

Проблема поиска «последнего» счета

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

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

Настройка подписки на событие

Чтобы выполнить код в момент записи счета, перейдем в Конфигуратор и создадим новый объект метаданных ПодпискаНаСобытие. Настроим ее следующим образом:

  1. Источник: Укажем тип объекта ДокументОбъект.СчетНаОплатуПокупателю.
  2. Событие: Выберем ПриЗаписи. Это событие срабатывает, когда данные уже проверены, но транзакция еще не завершена.
  3. Обработчик: Создадим процедуру в общем модуле (модуль должен иметь флаг «Сервер»).

Разберем структуру обработчика. В процедуру первым параметром всегда передается Источник — это и есть тот самый объект (счет), который записывается в данный момент.


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

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

КонецПроцедуры

Как отличить обмен от ручного ввода

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

Проанализируем ситуацию, когда флаг Загрузка не установлен, но нам все равно нужно понять, что это объект из CRM. В этом случае мы можем проверить наличие идентификатора Битрикс24 в дополнительных реквизитах.

Поиск идентификатора Битрикс24 в документе

Обычно модуль интеграции записывает ID сделки или счета из CRM в дополнительные реквизиты. Чтобы программно его достать, обратимся к табличной части ДополнительныеРеквизиты. Рассмотрим пример функции для получения этого значения:


Функция ПолучитьIDБитрикс(СчетОбъект)
    
    Результат = "";
    Для Каждого СтрокаДопРеквизита Из СчетОбъект.ДополнительныеРеквизиты Цикл
        // Имя реквизита зависит от настроек вашей интеграции
        Если СтрокаДопРеквизита.Свойство.Наименование = "ID внешнего объекта" Тогда
            Результат = СтрокаДопРеквизита.Значение;
            Прервать;
        КонецЕсли;
    КонецЦикла;
    
    Возврат Результат;

КонецФункции

Корректировка суммы документа

Теперь разберем самую сложную часть: изменение итоговой суммы. В конфигурации Бухгалтерия предприятия сумма документа — это агрегатное значение, которое складывается из сумм строк табличной части Товары. Если мы просто напишем Источник.СуммаДокумента = 1000, при открытии или пересчете документа 1С вернет сумму, равную итогу по строкам.

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


Процедура УстановитьНужнуюСумму(СчетОбъект, НужнаяСумма)
    
    ТекущийИтог = СчетОбъект.Товары.Итог("Сумма");
    Разница = НужнаяСумма - ТекущийИтог;
    
    Если Разница <> 0 И СчетОбъект.Товары.Количество() > 0 Тогда
        // Находим последнюю строку и добавляем к ней разницу
        ПоследняяСтрока = СчетОбъект.Товары[СчетОбъект.Товары.Количество() - 1];
        ПоследняяСтрока.Сумма = ПоследняяСтрока.Сумма + Разница;
        
        // Пересчитываем НДС для этой строки, если нужно
        // СтавкаНДС = ПоследняяСтрока.СтавкаНДС; 
        // ПоследняяСтрока.СуммаНДС = ... (расчет налога)
    КонецЕсли;
    
КонецПроцедуры

Важные ограничения и риски

Рассмотрим важные технические нюансы, которые уберегут вашу базу от ошибок:

  1. Рекурсия при записи: Внутри подписки на событие ПриЗаписи категорически нельзя вызывать метод Источник.Записать(). Это приведет к бесконечному циклу, так как вызов записи снова спровоцирует выполнение этой же подписки. Платформа сама запишет все изменения, которые вы внесли в поля Источник, после завершения вашей процедуры.
  2. Затирание данных: Помните, что синхронизация работает в обе стороны. Если вы изменили сумму в 1С, но не передали ее обратно в Битрикс24, при следующем сеансе обмена Битрикс может прислать старую сумму и «затереть» ваши исправления. Убедитесь, что логика синхронизации настроена на приоритет данных 1С или что изменения фиксируются в обеих системах.
  3. Целостность данных: Изменение суммы без изменения количества или цены товара может привести к вопросам со стороны налоговой или бухгалтерии, так как печатная форма счета будет содержать строки, сумма которых не сходится с ценой, умноженной на количество. Рекомендуется корректировать именно Цена, чтобы произведение давало нужный результат.

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

← На главную