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