Почему поле Регистратор или Ордер выводится пустым в отчете СКД по остаткам

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

При разработке отчетов на системе компоновки данных (СКД) программисты часто сталкиваются с ситуацией, когда при использовании виртуальной таблицы ОстаткиИОбороты поля Регистратор, ДокументДвижения или связанные с ними данные (например, Ордер) приходят пустыми (NULL). Это вызывает недоумение, особенно когда в параметрах виртуальной таблицы указана периодичность Регистратор.

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

Разбор технической причины: Почему Регистратор пустой?

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

Основная проблема заключается в непонимании того, что такое Остаток в терминах базы данных. Рассмотрим по шагам:

  1. Агрегация данных: Регистры накопления остатков хранят итоги. Конечный остаток на определенную дату — это сумма всех приходов минус все расходы с момента начала учета. Это число. У этого числа не может быть одного «Регистратора», так как оно сформировано сотнями или тысячами документов.
  2. Периодичность виртуальной таблицы: Когда мы устанавливаем периодичность Авто или Регистратор, платформа 1С пытается разбить итоги по периодам. Если в выбранном периоде (между датой начала и датой окончания) не было движений конкретным регистратором по конкретной номенклатуре, то в строке с остатком поле Регистратор будет содержать значение NULL.
  3. Особенности СКД: Система компоновки данных накладывает свои роли на поля периодов. Если поле Регистратор не выбрано как обязательное в настройках ролей или если итоговый запрос СКД сворачивает данные до группировки по Номенклатуре, информация о регистраторе теряется на этапе компоновки макета.

Архитектурные ограничения УТ 11 и регистра Товары на складах

Проанализируем конкретный пример из конфигурации УТ 11. Автор вопроса использует регистр накопления ТоварыНаСкладах. В этой конфигурации реализовано четкое разделение на складской (логистический) и финансовый учет:

Регистр Товары на складах — это оперативный складской учет. Его задача — быстро ответить на вопрос: «Сколько штук товара сейчас лежит на полке?». Он хранит остатки в разрезе складов, номенклатуры и серий. В нем нет аналитики по партиям или документам поступления. Как только товар поступил по Приходному ордеру, он «растворяется» в общем остатке склада.

Если вы пытаетесь вытащить «Ордер» из этого регистра, вы совершаете логическую ошибку: регистр не знает, из какого ордера пришла та единственная штука, которая осталась на складе после десяти продаж.

Решение №1: Использование регистров партионного учета

Если перед нами стоит задача увидеть остатки в разрезе документов поступления (узнать, по какому документу пришел товар), необходимо использовать регистры, поддерживающие партионный учет. В УТ 11 это:

В этих регистрах есть измерение АналитикаУчетаНоменклатуры и, что более важно, ДокументПоступления (или поле Партия). Рассмотрим пример запроса к регистру партий:


ВЫБРАТЬ
    ПартииТоваров.ДокументПоступления КАК Ордер,
    ПартииТоваров.Номенклатура,
    ПартииТоваров.КоличествоОстаток КАК Количество
ИЗ
    РегистрНакопления.ПартииТоваровОрганизаций.Остатки(&ДатаКон, ) КАК ПартииТоваров

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

Решение №2: Метод обратного хронологического анализа (FIFO вручную)

Что делать, если партионный учет выключен, а отчет «Остатки по документам прихода» все равно нужен? В этом случае применяется сложный алгоритм «восстановления» последовательности. Разберем логику:

  1. Получаем текущий общий остаток товара на складе (например, 10 штук).
  2. Выбираем все приходы по этому товару, отсортированные по дате убывания (от новых к старым).
  3. Бежим по списку приходов и «наполняем» наш остаток.
    • Последний приход был на 6 штук — значит, все 6 штук из этого документа входят в текущий остаток.
    • Предпоследний приход был на 10 штук — но нам нужно всего 4 штуки (10 - 6), чтобы покрыть остаток. Значит, из этого документа в остатке только 4 штуки.
  4. Все документы прихода, которые были раньше, в текущий остаток не входят (они уже проданы).

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

Решение №3: Правильная настройка виртуальной таблицы в СКД

Если вам все же необходимо использовать таблицу ОстаткиИОбороты и вы хотите видеть регистраторы движений (а не остатков), убедитесь, что вы правильно настроили параметры:

Проанализируем параметры виртуальной таблицы:

РегистрНакопления.ТоварыНаСкладах.ОстаткиИОбороты(&НачалоПериода, &КонецПериода, Регистратор, , )

Важные моменты:

Практические рекомендации

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


ЛЕВОЕ СОЕДИНЕНИЕ Документ.ПриходныйОрдерНаТовары.Товары КАК ПриходныйОрдерНаТоварыТовары
ПО ТоварыНаСкладахОстаткиИОбороты.Регистратор = ПриходныйОрдерНаТоварыТовары.Ссылка
И ТоварыНаСкладахОстаткиИОбороты.Номенклатура = ПриходныйОрдерНаТоварыТовары.Номенклатура

Почему это не работает эффективно?

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

Во-вторых, если в регистр ТоварыНаСкладах делает запись не ПриходныйОрдер, а, например, ПеремещениеТоваров или СписаниеНедостач, то ваше левое соединение с таблицей ПриходныйОрдерНаТовары.Товары не найдет соответствия, и поле Ордер останется пустым.

Как сделать правильно:

  1. Выясните, включен ли в системе партионный учет. Если да — забудьте о регистре ТоварыНаСкладах для этой задачи и используйте ПартииТоваровОрганизаций.
  2. Если нужно видеть именно складской документ (Ордер), используйте Серии номенклатуры. Если настроить политику учета серий «Учет себестоимости по сериям», то Серия фактически станет идентификатором каждой партии поступления. Тогда вы сможете вытащить информацию о приходе через серию.
  3. Если задача стоит «показать документы, которыми двигался товар в периоде», используйте таблицу Обороты, а не ОстаткиИОбороты. Она работает быстрее и поле Регистратор там заполняется естественным образом для каждой строки прихода или расхода.

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

← На главную