Почему в 1С:УНФ расходные накладные не списывают остатки со склада после переноса данных

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

При переходе с устаревших систем, таких как 1С:Торговля и Склад 7.7, на современные конфигурации вроде 1С:Управление нашей фирмой (УНФ) 1.6, пользователи часто сталкиваются с «фантомными» ошибками. Одна из самых неприятных — когда документ Расходная накладная проводится без ошибок, но фактически не списывает товар с регистра Запасы на складах. При этом проблема проявляется выборочно: в одной накладной всё хорошо, а в другой часть позиций игнорируется системой.

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

Анализируем симптомы проблемы

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

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

Выясняем причину: магия единиц измерения и коэффициентов

Давайте проанализируем внутреннюю логику работы 1С:УНФ. Когда документ делает движения по регистрам остатков, он всегда пересчитывает количество из «единицы хранения», указанной в документе, в «базовую единицу» (если они различаются). Для этого используется коэффициент пересчета.

Если при переносе данных из 7.7 ссылка на единицу измерения в табличной части документа или во вспомогательных регистрах оказалась «битой» (неопределено или пустая ссылка), то система при проведении сталкивается со следующей логикой:

  1. Программа обращается к объекту единицы измерения для получения коэффициента.
  2. Если единица не определена, коэффициент считается равным нулю.
  3. Количество в документе умножается на нулевой коэффициент.
  4. В регистр записывается результат: 0 (или пусто).

Рассмотрим ситуацию глубже. Почему визуально в документе единица измерения видна, а движения все равно пустые? Это происходит потому, что в УНФ 1.6 механизм подстановки данных работает через цепочку регистров.

Регистр «Цены номенклатуры» как скрытый источник ошибок

Одной из ключевых находок при решении данной проблемы является анализ регистра сведений Цены номенклатуры. В 1С:УНФ при выборе товара в накладную система пытается автоматически подставить цену. Вместе с ценой из регистра подтягивается и единица измерения, для которой эта цена была установлена.

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

Пошаговый план диагностики:

  1. Перейдем в настройки программы и временно включим функциональную опцию Использовать несколько единиц измерения.
  2. Откроем справочник Номенклатура и проверим вкладку с ценами или перейдем непосредственно в регистр сведений Цены номенклатуры через «Все функции» (или «Функции для технического специалиста»).
  3. Посмотрим на колонку Единица измерения. Если в ней пусто или стоит «Объект не найден», мы нашли причину.

Проблема «чужого» владельца

Еще один важный момент, который стоит рассмотреть — это соответствие владельца единицы измерения. В системе 1С каждая единица измерения (упаковка) жестко привязана к конкретной карточке номенклатуры (поле Владелец).

При некорректном программном переносе может возникнуть ситуация, когда в табличную часть Запасы подставляется единица измерения, которая принадлежит другому товару (например, дублю номенклатуры). Визуально названия могут совпадать (например, «шт»), но внутренние идентификаторы (GUID) будут разными. В этом случае программный код проведения может просто игнорировать такие строки, так как проверка Единица.Владелец = Номенклатура не проходит.

Как исправить ошибку массово

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

Нам необходимо выполнить два действия: исправить записи в регистре цен и обновить данные в самих накладных.

Шаг 1: Исправление регистра цен

Проанализируем ситуацию в консоли запросов или через групповую обработку. Нам нужно найти все записи регистра Цены номенклатуры, где ЕдиницаИзмерения не заполнена.

Пример логики для обработки:


Выборка = РегистрыСведений.ЦеныНоменклатуры.Выбрать();
Пока Выборка.Следующий() Цикл
    Если НЕ ЗначениеЗаполнено(Выборка.ЕдиницаИзмерения) Тогда
        Запись = Выборка.ПолучитьОбъект();
        // Устанавливаем единицу хранения из карточки номенклатуры
        Запись.ЕдиницаИзмерения = Выборка.Номенклатура.ЕдиницаИзмерения;
        Запись.Записать();
    КонецЕсли;
КонецЦикла;

Шаг 2: Групповое обновление документов

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

Рассмотрим пример кода, который можно запустить в обработке Групповое изменение реквизитов (используя возможность выполнения произвольного алгоритма):


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

Профилактика: установка проверок

Чтобы подобные ошибки не появлялись в будущем (например, при новых загрузках данных), мы рекомендуем добавить небольшую проверку в модуль объекта документа РасходнаяНакладная в процедуру ПередЗаписью.

Разберем, какой код поможет локализовать ошибку до того, как документ будет проведен:


Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
    Если РежимПроведения = РежимПроведенияДокумента.Проведение Тогда
        Для Каждого Стр Из ЭтотОбъект.Запасы Цикл
            Если НЕ ЗначениеЗаполнено(Стр.ЕдиницаИзмерения) Тогда
                Сообщить("В строке № " + Стр.НомерСтроки + " не заполнена единица измерения! Списание невозможно.");
                Отказ = Истина;
            КонецЕсли;
        КонецЦикла;
    КонецЕсли;
КонецПроцедуры

Почему не помогло ТиИ (Тестирование и исправление)

Многие системные администраторы первым делом запускают ТиИ или chkdbfl.exe. В данной ситуации они бесполезны. Проанализируем почему: ТиИ ищет физическую целостность (битые ссылки на несуществующие в базе объекты). В нашем случае ссылки физически существуют (это либо NULL, либо пустая ссылка типа СправочникСсылка.ЕдиницыИзмерения), но они логически неверны для бизнес-логики УНФ. База данных считает, что всё в порядке, в то время как алгоритм проведения «спотыкается» об отсутствие значения.

Резюме

Проблема пустого количества в движениях 1С:УНФ 1.6 чаще всего кроется в незаполненных единицах измерения в регистре цен или несоответствии владельца упаковки. При переносе из 7.7 всегда проверяйте не только справочники, но и связанные регистры сведений. Используйте групповые обработки для восстановления связей, и ваши складские остатки всегда будут в порядке.

← На главную