Почему в 1С:Управление торговлей 11 не работает распределение дополнительных расходов по объему упаковок?

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

Когда перед нами встает задача распределения транспортно-заготовительных расходов (ТЗР) на себестоимость товаров пропорционально их объему или весу, мы ожидаем, что система 1С:Управление торговлей (УТ 11) выполнит эту операцию автоматически. Мы скрупулезно заполняем весогабаритные характеристики (ВГХ) в справочнике упаковок, указываем эти упаковки в документах поступления, но при попытке распределить услуги в документе ПриобретениеУслугИПрочихАктивов сталкиваемся с неприятным сюрпризом: программа выдает нулевые значения или распределяет суммы некорректно. При этом, если те же самые данные заполнить непосредственно в карточке номенклатуры, расчет проходит успешно.

Выясним причину такого поведения системы, проанализируем архитектурные особенности решений на платформе 1С:Предприятие 8.3 (таких как УТ 11, КА 2 и ERP 2) и разберем практические способы решения этой проблемы — как методические, так и программные.

Почему типовой механизм 1С игнорирует упаковки при распределении?

Для того чтобы понять, почему система игнорирует весогабаритные характеристики упаковок, нам необходимо обратиться к архитектуре регистров накопления и логике проведения документов в конфигурациях ERP-семейства.

Рассмотрим, в каком виде хранятся данные о складских остатках и себестоимости. Любое движение товаров регистрируется в базовых единицах хранения (например, в штуках, килограммах или литрах). Когда мы проводим документ ПриобретениеТоваровУслуг, в котором указана упаковка (например, «Коробка 20 шт.»), система делает записи в регистры накопления (такие как СебестоимостьТоваров или ДвиженияНоменклатураДоходыРасходы), автоматически пересчитывая количество в базовую единицу. Информация о том, что товар физически приехал в коробках или на паллетах, на уровне регистров учета затрат фактически нивелируется.

Когда мы открываем документ ПриобретениеУслугИПрочихАктивов и выбираем вариант распределения «Пропорционально объему» (или «Пропорционально весу»), программа инициирует сложный алгоритм расчета базы распределения. Этот алгоритм работает по следующей схеме:

  1. Определяется список номенклатурных позиций, на которые необходимо распределить расходы (исходя из выбранных документов-оснований поступления).
  2. Для каждой позиции извлекается количество в базовых единицах хранения.
  3. Система обращается к реквизитам Вес и Объем, расположенным непосредственно в справочнике Номенклатура (то есть к свойствам самой карточки товара, соответствующим его базовой единице).
  4. Рассчитывается общий объем по формуле: КоличествоВБазовыхЕдиницах * ОбъемБазовойЕдиницы.

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

Методическое решение: Корректное заполнение карточек товаров

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

Проанализируем этот процесс на конкретном примере:

Мы закупаем товар «Кабель электрический». Базовая единица хранения — «метр». Товар поступает в упаковках — «Бухта 100 метров». Объем одной бухты составляет 0,2 кубических метра ($m^3$).

Чтобы распределение работало корректно, мы должны рассчитать объем одного метра кабеля:

0,2 м³ / 100 метров = 0,002 м³.

Именно это значение — 0,002 — мы должны внести в поле «Объем» в карточке номенклатуры. Когда в документе поступления пользователь укажет 3 бухты (что эквивалентно 300 метрам), алгоритм распределения расходов умножит 300 метров на 0,002 м³ и получит верную базу распределения — 0,6 м³.

Важное ограничение метода: В 1С все стандартные показатели объема хранятся в кубических метрах (м³). Если наш товар очень мелкий (например, флакон лекарства или микросхема), то объем одной единицы в кубических метрах будет представлять собой число со множеством знаков после запятой (например, 0,000005 м³). Из-за ограничений точности представления чисел в стандартных реквизитах конфигурации (обычно это 3 или 4 знака после запятой для объема) программа округлит это значение до нуля. В этом случае методический подход не сработает, и нам придется прибегнуть к программным доработкам.

Программные варианты решения проблемы

Разберем, каким образом программист может кастомизировать систему под требования бизнеса, когда распределение ТЗР должно происходить строго на основании упаковок, указанных в первичных документах поступления.

Вариант А. Использование расширения конфигурации (корректировка запроса распределения)

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

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

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

Посмотрим на пример логики построения такого запроса:


// Пример модифицированного запроса для расчета базы распределения по упаковкам
ВЫБРАТЬ
	ТаблицаТоваров.Номенклатура КАК Номенклатура,
	ТаблицаТоваров.Количество КАК КоличествоВБазовыхЕдиницах,
	ВЫБОР
		КОГДА ТаблицаТоваров.Упаковка <> ЗНАЧЕНИЕ(Справочник.УпаковкиНоменклатуры.ПустаяСсылка)
			ТОГДА ТаблицаТоваров.Упаковка.Объем * (ТаблицаТоваров.Количество / ТаблицаТоваров.Упаковка.Числитель)
		ИНАЧЕ ТаблицаТоваров.Номенклатура.Объем * ТаблицаТоваров.Количество
	КОНЕЦ КАК ИтоговыйОбъем
ИЗ
	Документ.ПриобретениеТоваровУслуг.Товары КАК ТаблицаТоваров
ГДЕ
	ТаблицаТоваров.Ссылка В (&МассивДокументовПоступления)

Этот запрос проверяет: если в документе поступления была указана конкретная упаковка, то система берет объем этой упаковки, делит общее количество базовых единиц на коэффициент упаковки (реквизит Числитель в справочнике УпаковкиНоменклатуры) и умножает на объем упаковки. Если упаковка не указана, система откатывается к стандартному поведению и берет объем из карточки номенклатуры.

Вариант Б. Разработка внешней обработки заполнения табличной части

Если мы хотим избежать вмешательства в код проведения документов и механизмы закрытия месяца, мы можем пойти путем создания внешней обработки заполнения для документа ПриобретениеУслугИПрочихАктивов.

Пользователь будет действовать по следующей схеме:

  1. Создает документ приобретения услуг, выбирает статью расходов с распределением на себестоимость товаров.
  2. Указывает документы-основания (поступления товаров).
  3. Вместо нажатия стандартной кнопки распределения запускает внешнюю обработку заполнения.
  4. Обработка программно считывает все связанные документы поступления, анализирует колонку Упаковка, вычисляет реальные физические объемы строк, рассчитывает коэффициенты распределения и пропорционально заполняет суммы в табличной части документа услуг.

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

Вариант В. Использование дополнительных реквизитов для мелких товаров

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

  1. Создаем дополнительный реквизит для номенклатуры — «Объем в миллилитрах» (тип Число с высокой точностью) или «Вес в граммах».
  2. Внедряем небольшое расширение, которое при расчете распределения обращается к значению этого дополнительного реквизита вместо стандартного реквизита объема.
  3. При расчете программа будет распределять полученную сумму пропорционально этим значениям, избегая ошибок округления до нуля.

Различия в версиях УТ 11.4 и УТ 11.5 / ERP 2.5

Проанализируем, изменилось ли что-то в более новых редакциях программных продуктов 1С. Начиная с версии УТ 11.5.7, разработчики изменили структуру хранения правил распределения расходов. Теперь они настраиваются в рамках отдельного справочника «Правила распределения и показатели».

Тем не менее, сама концепция осталась неизменной: показатели «Объем товаров» и «Вес товаров» по-прежнему собираются на основе характеристик базовой единицы из карточки номенклатуры. Штатной возможности переключить логику распределения на «ВГХ фактически указанных в документах упаковок» разработчики 1С так и не добавили. Поэтому все описанные выше архитектурные выводы и методы решения остаются на 100% актуальными как для УТ 11.4, так и для УТ 11.5, КА 2.5 и ERP 2.5.

← На главную