При работе с конфигурацией 1С:Управление производственным предприятием (УПП) разработчики часто сталкиваются с загадочным поведением платформы во время проведения документов. Типичный пример: вы открываете документ Реализация товаров и услуг (РТУ), запускаете отладчик, ставите точку останова в обработчике проведения или в модуле набора записей регистра бухгалтерии ПередЗаписью и видите только две проводки. Однако, когда документ завершает проведение, в движениях по регистру Хозрасчетный волшебным образом появляются три проводки.
В этой статье мы подробно разберем, почему так происходит, как устроена архитектура проведения документов в 1С:УПП, почему стандартный отладчик «теряет» часть движений и как гарантированно перехватить формирование скрытой третьей проводки.
---
Для того чтобы понять суть происходящего, проанализируем внутренние механизмы проведения документов в УПП. В отличие от более простых конфигураций, в УПП процесс формирования движений по регламентированному учету разделен на несколько независимых этапов.
Рассмотрим, какие именно проводки обычно формирует документ Реализация товаров и услуг:
ОбработкаПроведения. Именно их вы и наблюдаете при первой остановке в отладчике.
УправлениеЗапасамиПартионныйУчет.
Схема проведения выглядит следующим образом: сначала документ записывает первичные проводки (первый вызов ПередЗаписью набора записей), затем управление передается в общий модуль партионного учета. Этот модуль выполняет сложные расчеты, определяет стоимость списываемых партий, формирует третью проводку, добавляет её в тот же набор записей и выполняет повторную запись в регистр бухгалтерии Хозрасчетный (второй вызов ПередЗаписью).
---
Если система делает повторную запись, то точка останова в процедуре ПередЗаписью модуля набора записей регистра должна срабатывать дважды. Если у вас она срабатывает только один раз, на то есть три технические причины.
Это самая распространенная ошибка среди начинающих разработчиков. Тот факт, что вы работаете в Толстом клиенте и ваш отладчик подключен по протоколу TCP/IP, никак не влияет на режим работы сервера 1С. Общие модули партионного учета в УПП имеют свойство Сервер, и код расчета себестоимости выполняется непосредственно на стороне сервера приложений 1С.
Если служба сервера 1С:Предприятия запущена без специального ключа отладки, то любые точки останова в серверных модулях (а также в процедурах, вызванных из серверного контекста) будут игнорироваться системой. На клиенте отладчик сработает (вы увидите первые 2 проводки), а при переходе выполнения на сервер отладка просто «пролетит» мимо.
В настройках параметров учета УПП может быть установлен флаг «Выполнять проведение по партиям в фоновом режиме». В этом случае при проведении РТУ система формирует только проводки по выручке и НДС. Сама же себестоимость рассчитывается фоновым заданием, которое запускается асинхронно.
По умолчанию конфигуратор не подключается к фоновым заданиям, поэтому отладчик не может перехватить момент работы этого фонового потока.
В некоторых случаях при формировании партионных движений разработчики используют программную перезапись набора с установленным свойством ОбменДанными.Загрузка = Истина. При такой записи стандартные платформенные обработчики событий (такие как ПередЗаписью и ПриЗаписи в модуле набора) могут игнорироваться платформой, чтобы ускорить процесс записи данных.
---
Проанализируем последовательность действий, которая позволит вам гарантированно перехватить управление в момент расчета и записи себестоимости.
Выясним, как правильно включить отладку на сервере 1С. Способ зависит от операционной системы, под управлением которой работает ваш сервер приложений.
Для ОС Windows:
Win + R, введите regedit и нажмите Enter).HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\1C:Enterprise 8.3 Server Agent... (название ветки зависит от версии платформы).ImagePath.-debug.
Пример исходной строки:
"C:\Program Files\1cv8\8.3.22.1709\bin\ragent.exe" -srvc -agent
Пример измененной строки:
"C:\Program Files\1cv8\8.3.22.1709\bin\ragent.exe" -srvc -agent -debug
services.msc) и перезапустите службу сервера 1С:Предприятия.Для ОС Linux:
/etc/sysconfig/srv1cv83 или /etc/default/srv1cv83.SRV1CV8_DEBUG и установите ее значение в 1:
SRV1CV8_DEBUG=1
systemctl restart srv1cv83
После активации серверной отладки нам необходимо подготовить сам Конфигуратор к перехвату фоновых процессов:
Теперь рассмотрим структуру вызовов. Основной расчет партий и себестоимости в УПП происходит в общем модуле УправлениеЗапасамиПартионныйУчет. Нам интересны процедуры, выполняющие запись наборов.
Типичная упрощенная схема вызовов при проведении документа выглядит так:
// В модуле документа РеализацияТоваровУслуг
Процедура ОбработкаПроведения(Отказ, РежимПроведения)
// 1. Формируются стандартные движения (Выручка, НДС)
Движения.Хозрасчетный.Записать();
// 2. Подготовка параметров для проведения по партиям
ПараметрыПроведения = ПодготовитьПараметрыПартионногоУчета();
// 3. Вызов серверного общего модуля для расчета партий и себестоимости
УправлениеЗапасамиПартионныйУчет.ДвиженияПоУчетуНоменклатуры(Ссылка, ПараметрыПроведения);
КонецПроцедуры
Внутри серверного общего модуля происходит выборка списанных товаров и расчет их себестоимости. Код добавления проводки по списанию себестоимости выглядит следующим образом:
// Внутри общего модуля УправлениеЗапасамиПартионныйУчет
Процедура ДобавитьПроводкуПоСебестоимости(ТаблицаПартий, НаборЗаписейХозрасчетный)
Для Каждого СтрокаПартии Из ТаблицаПартий Цикл
НоваяПроводка = НаборЗаписейХозрасчетный.Добавить();
НоваяПроводка.Период = СтрокаПартии.Период;
НоваяПроводка.СчетДт = ПланыСчетов.Хозрасчетный.Продажи_Себестоимость; // 90.02.1
НоваяПроводка.СчетКт = СтрокаПартии.СчетУчета; // Например, 41.01
// Заполнение субконто и измерений
БухгалтерскийУчет.УстановитьСубконто(НоваяПроводка.СчетДт, НоваяПроводка.СубконтоДт, ...);
НоваяПроводка.Сумма = СтрокаПартии.Стоимость;
НоваяПроводка.КоличествоКт = СтрокаПартии.Количество;
КонецЦикла;
// Запись модифицированного набора проводок обратно в базу данных
НаборЗаписейХозрасчетный.Записать();
КонецПроцедуры
Чтобы детально проанализировать процесс формирования проводки:
Хозрасчетный.ПередЗаписью(Отказ, Замещение) и установите на нее точку останова.ПередЗаписью. Посмотрите в табло переменную ЭтотОбъект. В ней будет только 2 строки (Выручка и НДС). Нажмите F5 (Продолжить).ПередЗаписью. Теперь в коллекции записей вы увидите 3 строки — добавилась проводка списания себестоимости.УправлениеЗапасамиПартионныйУчет, которые привели к формированию этой проводки. Дважды кликнув по строке стека, вы переместитесь непосредственно к коду, сгенерировавшему проводку.Важное примечание по режимам учета в УПП: Описанный выше алгоритм актуален, если в вашей базе УПП используется традиционный партионный учет. Если же в настройках параметров учета включен Режим расширенной аналитики учета затрат (РАУЗ), то себестоимость при проведении документов вообще не рассчитывается в реальном времени. В режиме РАУЗ проводки по дебету 90.02 и кредиту 41/43 будут сформированы только в конце месяца при проведении регламентного документа Расчет себестоимости выпуска.