В процессе кастомизации системы 1С:ERP 2.2 программисты часто сталкиваются с необходимостью изменить стандартную логику проведения документов. Одной из таких задач является доработка алгоритма формирования движений в регистре накопления СебестоимостьТоваров. Рассмотрим ситуацию, когда документ ДвижениеПродукцииИМатериалов после доработки начинает делать записи в разные периоды (например, часть движений в июне, а часть — в июле). На первый взгляд, платформа 1С позволяет это делать, однако при попытке выполнить регламентную операцию «Закрытие месяца» пользователь обнаруживает, что часть записей бесследно исчезает. Разберемся, почему так происходит, и как работает внутренний механизм системы.
Проанализируем поведение системы в момент запуска обработки «Расчет себестоимости товаров». В типовых решениях на базе 1С:ERP (и Комплексной автоматизации 2) этап формирования движений по партиям и себестоимости работает не по принципу инкрементальных правок, а по принципу полного замещения. Это критически важный момент для понимания проблемы.
Когда мы запускаем расчет за июнь, программный код (обычно это модули, связанные с обработкой РасчетСебестоимостиПрикладныеОбъекты) выполняет следующие действия:
СебестоимостьТоваров.Проблема заключается в том, что типовой алгоритм очистки зачастую ориентирован на дату самого документа. Если документ датирован июнем, система ожидает, что и все его «законные» движения находятся в июне. Записи, сделанные этим же документом в июле, воспринимаются алгоритмом как некорректные или избыточные (оставшиеся от предыдущих манипуляций), и они удаляются для обеспечения целостности данных периода.
Разберем ситуацию с точки зрения методологии учета. Расчет себестоимости в 1С:ERP — это не просто суммирование цифр, а решение сложной системы линейных уравнений. Программа строит дерево (граф) распределения затрат, где узлами являются аналитики учета, а ребрами — движения товаров и материалов.
Если один и тот же первичный документ ДвижениеПродукцииИМатериалов влияет на разные отчетные периоды (месяцы), это создает следующие проблемы для математического ядра системы:
Выясним причину удаления записей через анализ структуры регистра СебестоимостьТоваров. В этом регистре, помимо измерений (Номенклатура, Склад), огромную роль играют реквизиты:
РазделУчетаВидЗапасовАналитикаУчетаНоменклатурыОрганизацияПри закрытии месяца система проверяет соответствие этих реквизитов данным других регистров (например, ВыручкаИСебестоимостьПродаж). Если при доработке алгоритма проведения вы программно создали запись, но не заполнили специфические для ERP служебные поля (которые обычно заполняются в общих модулях при вызове процедур проведения), система сочтет такие записи «мусорными». В момент регламентного расчета происходит «причесывание» базы, и все записи, не прошедшие проверку на логическую целостность, удаляются.
Рассмотрим пример кода, который часто становится причиной ошибок при попытке ручного формирования движений:
// ОПАСНО: Ручное формирование движений без учета логики закрытия месяца
Движение = Движения.СебестоимостьТоваров.Добавить();
Движение.Период = ДатаБудущегоМесяца; // Ошибка: Период отличается от даты документа
Движение.Регистратор = ЭтотОбъект.Ссылка;
Движение.Организация = Организация;
// Пропуск заполнения ВидаЗапасов и Аналитики приведет к удалению строки при закрытии месяца
Если в вашей конфигурации включен партионный учет 2.2, ситуация усугубляется. Партионный учет строится на жесткой последовательности. Когда фоновое задание по расчету партий анализирует цепочку товародвижения, оно ожидает строгой хронологии. Движения «будущим числом» от документа из «прошлого» создают логические разрывы. Механизм автоматической корректировки партий просто отсекает такие записи, так как не может подобрать для них корректную партию поступления, которая еще не была передана в следующий период штатным образом.
Если перед вами стоит задача отразить движения в разных периодах, мы рекомендуем отказаться от идеи «один документ — движения в разных месяцах». Вместо этого рассмотрим следующие варианты:
ДвижениеПродукцииИМатериалов — один концом июня, второй началом июля. Это гарантирует, что закрытие месяца отработает штатно.РасчетСебестоимостиПрикладныеОбъекты или ПроведениеСервер, чтобы расширить границы поиска движений для удаления. Однако мы настоятельно не рекомендуем этот путь, так как это сделает вашу систему необновляемой и может привести к непредсказуемым ошибкам в финансовом результате.Проанализируем ситуацию: если вы все же решили оставить доработку в текущем виде, вам необходимо убедиться, что в процедуре проведения документа все движения (независимо от их даты) имеют полностью заполненную аналитику, идентичную той, что используется в текущем месяце. Но помните, что при пересчете июня система все равно будет пытаться синхронизировать движения документа с его датой.
Резюме: Удаление записей — это защитный механизм 1С:ERP, предотвращающий порчу финансовой отчетности. Система жестко связывает период регистрации затрат с периодом документа-регистратора. Любые отклонения воспринимаются алгоритмом закрытия месяца как ошибка, подлежащая исправлению через удаление «неправильных» строк.