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