Почему возникают отрицательные остатки в регистре «Товары организаций» при раздельном учете и как это исправить?

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

При работе в комплексных конфигурациях на платформе 1С (таких как «Управление производственным предприятием 1.3» или «Комплексная автоматизация 1.1») пользователи часто сталкиваются с неприятной ситуацией. При попытке провести документ списания или реализации система выдает ошибку: «Остатка по организации [Имя Организации] недостаточно». При этом отчеты по физическим складам (например, «Ведомость по товарам на складах» или «Партии товаров на складах») показывают, что товар в наличии есть в нужном количестве.

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

---

Выясняем причину: почему двоятся движения по регистру «Товары организаций»?

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

  1. «Товары на складах» — это чисто складской, оперативный учет. Он отвечает на вопрос: «В каком физическом месте (складе) лежит данный товар?». Для этого регистра не важен юридический контекст (какому юрлицу принадлежит товар).
  2. «Товары организаций» — это финансово-юридический учет. Он отвечает на вопрос: «Какому конкретно юридическому лицу принадлежит этот товар на складе?». Этот регистр напрямую связан с механизмом регламентированного (бухгалтерского и налогового) учета и распределением ГТД.

В методологию «1С:УПП» и «1С:КА» заложен принцип: один хозяйственный документ отражает операцию во всех видах учета одновременно. Это значит, что если мы продаем товар, то создаем один документ РеализацияТоваровУслуг, в котором взведены флаги:

В такой штатной ситуации документ проводится один раз и делает ровно одно списание по регистру ТоварыОрганизаций.

Однако на практике многие компании ведут раздельный учет. Например, оперативный (управленческий) учет ведется менеджерами в реальном времени, а бухгалтерские документы создаются или выгружаются позже, зачастую другими сотрудниками. В итоге для одной и той же физической отгрузки в базе создается два разных документа:

  1. Первый документ — с флагом только «Упр. учет».
  2. Второй документ — с флагами только «Бух. учет» и «Налог. учет».

И вот здесь кроется главная проблема: оба этих документа делают движения по регистру «Товары организаций»!

Происходит банальное задвоение списания. Программа видит два документа и дважды списывает одну и ту же позицию по организации, уводя остатки в глубокий минус. Физический склад при этом списывается корректно (так как упр. документ списал складской регистр, а бух. документ складские регистры не трогает), но юридический баланс организации разрушается.

---

Почему типовой код так работает?

Если мы заглянем в модуль проведения документов (например, РеализацияТоваровУслуг), то увидим процедуру ДвиженияПоРегиструТоварыОрганизаций. В ней присутствует проверка следующего вида:


Если НЕ СтруктураШапкиДокумента.ОтражатьВРегламентированномУчете Тогда 
    Возврат; 
КонецЕсли;

Переменная ОтражатьВРегламентированномУчете устанавливается в истину, если в карточке Организации взведен флаг «Отражать в регламентированном учете». Таким образом, даже если в самом документе сняты флажки БУ и НУ, но стоит только флажок УУ, программа все равно видит, что сама организация является регламентированной, игнорирует настройки шапки документа и делает движения по регистру ТоварыОрганизаций. Это методологическая позиция разработчиков 1С, но для раздельного учета она является критической проблемой.

Рассмотрим подробнее три практических способа решения этой проблемы.

---

Решение 1. Изменение кода в общем модуле проведения (быстрый способ)

Если ваша конфигурация находится на поддержке с возможностью изменения, мы можем скорректировать проверку непосредственно в коде документов. Основные документы, которые вызывают проблему: РеализацияТоваровУслуг и ОтчетОРозничныхПродажах.

Давайте найдем в процедуре ДвиженияПоРегиструТоварыОрганизаций условие выхода и перепишем его так, чтобы движения формировались только в том случае, если документ действительно проводится по регламентированному учету (БУ или НУ).

Заменим стандартный блок:


Если НЕ СтруктураШапкиДокумента.ОтражатьВРегламентированномУчете Тогда 
    Возврат; 
КонецЕсли;

На следующий код:


// Проверяем, установлены ли конкретные флаги отражения БУ или НУ в самом документе
Если НЕ (СтруктураШапкиДокумента.ОтражатьВБухгалтерскомУчете ИЛИ СтруктураШапкиДокумента.ОтражатьВНалоговомУчете) 
   ИЛИ НЕ СтруктураШапкиДокумента.ОтражатьВРегламентированномУчете Тогда 
    Возврат; 
КонецЕсли;

Что это нам дает? Теперь, если менеджер проводит документ «Реализация товаров и услуг» с единственной галочкой «Упр. учет», программа не будет делать списания по организации. Эти движения сделает второй (бухгалтерский) документ, у которого будут стоять флаги БУ/НУ. Задвоение полностью исчезнет.

---

Решение 2. Использование подписки на событие перед записью (безопасный способ)

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

Разберем этот процесс по шагам:

  1. Создадим новую Подписку на событие в дереве метаданных.
  2. В качестве источника выберем РегистрНакопленияНаборЗаписей.ТоварыОрганизаций.
  3. Событие выберем как ПередЗаписью.
  4. Создадим обработчик в общем модуле (например, в специально созданном нетиповом модуле _КорректировкаДвиженийПроцедуры).

Напишем следующий программный код для обработчика:


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

Этот метод изящен тем, что он автоматически срабатывает для любых документов, делающих движения по регистру ТоварыОрганизаций. Если документ чисто управленческий — его движения по этому регистру просто стираются перед непосредственной записью в базу данных.

---

Решение 3. Использование концепции «Управленческой организации»

Если вы не хотите вносить изменения в программный код системы, можно воспользоваться чисто методологическим решением, которое в дальнейшем разработчики 1С применили в более современных ERP-системах.

Вы можете создать в справочнике Организации специальный предопределенный элемент — виртуальную организацию, назвав её, к примеру, «Управленческий учет (УУ)». При создании управленческих документов менеджеры будут выбирать в качестве организации именно этот элемент. Для этой организации в настройках не включается признак отражения в регламентированном учете.

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

---

Как выровнять уже накопленные отрицательные остатки в базе?

Устранение причины в коде предотвратит появление новых ошибок в будущем, но что делать с «красотой» в виде огромных минусов, которые копились в базе годами? Перепроводить документы с прошлых лет крайне опасно — это гарантированно разрушит закрытые периоды, изменит себестоимость и «поплывут» декларации по налогу на прибыль и НДС.

Давайте разберем правильный алгоритм исправления исторических остатков:

  1. Выберем дату «точки отсчета» (например, 31 декабря прошлого года, ровно за секунду до конца года — 23:59:59).
  2. Создадим специальный документ «Корректировка записей регистров». Этот документ предназначен именно для ручного или полуавтоматического изменения записей любых регистров в системе без перепроведения первичных документов.
  3. Добавим в таблицу регистров документ корректировки регистр накопления ТоварыОрганизаций.
  4. Напишем небольшую внешнюю обработку (или воспользуемся консолью запросов), чтобы сопоставить остатки на дату корректировки. Запрос должен выбрать разницу между реальными остатками на складе (регистр ТоварыНаСкладах) и остатками по организациям (регистр ТоварыОрганизаций) в разрезе Номенклатуры, Склада, Организации, Характеристик и Серий.
  5. Заполним движения документа Корректировка записей регистров полученной разницей:
    • Если остаток по регистру организаций меньше складского (ушел в минус), мы делаем движение «Приход» на величину разницы.
    • Если остаток по организации больше складского (зависли излишки), мы делаем движение «Расход».
  6. Запишем и проведем документ корректировки.

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

← На главную