Как в запросе 1С объединить строки с характеристиками и без для сопоставления цен покупки и продажи?

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

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

Проблема группировки записей с пустыми характеристиками

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

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


ВЫБРАТЬ
    ТестДокументТовары.Номенклатура КАК Номенклатура,
    ТестДокументТовары.Характеристика КАК Характеристика,
    СУММА(ТестДокументТовары.Количество) КАК Количество
ИЗ
    Документ.ТестДокумент.Товары КАК ТестДокументТовары
СГРУППИРОВАТЬ ПО
    ТестДокументТовары.Номенклатура,
    ТестДокументТовары.Характеристика

Чтобы объединить эти данные в одну строку с общей суммой, проанализируем поведение агрегатных функций. Функция МАКСИМУМ для ссылочных типов работает таким образом, что любое заполненное значение всегда «больше», чем ПустаяСсылка. Следовательно, если мы сгруппируем данные только по номенклатуре, а для характеристики выберем максимум, мы получим желаемое объединение.

Решение через агрегатную функцию МАКСИМУМ

Разберем, как изменить структуру запроса, чтобы добиться схлопывания строк. Основная идея заключается в том, чтобы убрать Характеристика из блока СГРУППИРОВАТЬ ПО и перенести её в список выбора с использованием агрегатной функции.


ВЫБРАТЬ
    ТестДокументТовары.Номенклатура КАК Номенклатура,
    МАКСИМУМ(ТестДокументТовары.Характеристика) КАК Характеристика,
    СУММА(ТестДокументТовары.Количество) КАК Количество
ИЗ
    Документ.ТестДокумент.Товары КАК ТестДокументТовары
СГРУППИРОВАТЬ ПО
    ТестДокументТовары.Номенклатура

В этом случае, если для «банки» есть строки с характеристикой «зеленая» и пустой ссылкой, в результат попадет «зеленая» и общая сумма 10 (5+5). Рассмотрим подробнее ограничения этого метода: он корректно работает только в том случае, если для одной номенклатуры в рамках выборки существует не более одной заполненной характеристики. Если характеристик будет две (например, «красная» и «зеленая»), функция выберет одну из них согласно внутреннему порядку ссылок в базе данных, что может привести к потере аналитики.

Прикладная задача: Сопоставление себестоимости и выручки

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

Проблема заключается в том, что в типовых конфигурациях (например, «1С:Бухгалтерия») эти данные фиксируются разными проводками:

  1. Себестоимость: Дебет 90.02.1 — Кредит 41.01 (здесь мы видим сумму списания).
  2. Выручка: Дебет 62.01 — Кредит 90.01.1 (здесь мы видим сумму реализации).

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

Шаг 1: Получение данных о себестоимости

Выясним причину списания и стоимость товара. Для этого обратимся к оборотам по счету 90.02.


ВЫБРАТЬ
    ХозрасчетныйОбороты.Регистратор КАК Регистратор,
    ХозрасчетныйОбороты.Субконто1 КАК Номенклатура,
    ХозрасчетныйОбороты.СуммаОборот КАК СуммаСебестоимость,
    ХозрасчетныйОбороты.КоличествоОборот КАК Количество
ПОМЕСТИТЬ втСебестоимость
ИЗ
    РегистрБухгалтерии.Хозрасчетный.Обороты(&НачалоПериода, &КонецПериода, Регистратор, Счет = ЗНАЧЕНИЕ(ПланСчетов.Хозрасчетный.СебестоимостьПродаж), , , , ) КАК ХозрасчетныйОбороты

Шаг 2: Получение данных о выручке

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


ВЫБРАТЬ
    ХозрасчетныйОбороты.Регистратор КАК Регистратор,
    ХозрасчетныйОбороты.Субконто1 КАК Номенклатура,
    ХозрасчетныйОбороты.СуммаОборот КАК СуммаВыручка
ПОМЕСТИТЬ втВыручка
ИЗ
    РегистрБухгалтерии.Хозрасчетный.Обороты(&НачалоПериода, &КонецПериода, Регистратор, Счет = ЗНАЧЕНИЕ(ПланСчетов.Хозрасчетный.Выручка), , , , ) КАК ХозрасчетныйОбороты

Шаг 3: Финальное соединение и расчет цен

Теперь объединим временные таблицы. Чтобы рассчитать цену за единицу, разделим сумму на количество. Используем ЕСТЬNULL, чтобы избежать ошибок при отсутствии данных в одной из таблиц.


ВЫБРАТЬ
    втСебестоимость.Номенклатура КАК Номенклатура,
    втСебестоимость.СуммаСебестоимость / втСебестоимость.Количество КАК ЦенаПокупки,
    втВыручка.СуммаВыручка / втСебестоимость.Количество КАК ЦенаПродажи,
    втСебестоимость.Регистратор КАК ДокументПродажи
ИЗ
    втСебестоимость КАК втСебестоимость
ЛЕВОЕ СОЕДИНЕНИЕ втВыручка КАК втВыручка
    ПО втСебестоимость.Регистратор = втВыручка.Регистратор
    И втСебестоимость.Номенклатура = втВыручка.Номенклатура

Важные технические нюансы

При реализации подобных запросов следует учитывать специфику настроек учета в конкретной базе 1С:

  1. Аналитика на счетах 90.01 и 90.02: По умолчанию на этих счетах в бухгалтерии используется субконто «Номенклатурные группы». Если учет по конкретной номенклатуре на 90-х счетах не включен в настройках параметров учета, получить данные напрямую из регистра бухгалтерии не удастся. В этом случае придется обращаться к документам РеализацияТоваровУслуг или регистру Продажи (в управленческих конфигурациях).
  2. Партионный учет: Если необходимо вытащить «Документ покупки» (партию), следует анализировать субконто счета 41 в проводке списания. Обычно это третье субконто, если включен партионный учет.
  3. Характеристики в бухгалтерии: Стандартно счет 41 не имеет разреза по характеристикам. Если характеристики добавлены как дополнительные реквизиты или дополнительные субконто, условия соединения в запросе должны учитывать это.
  4. Средняя стоимость: Помните, что если в учетной политике установлено списание «По средней», то цена покупки будет одинаковой для всех реализаций в периоде, независимо от того, из какой конкретно поставки пришел товар.

Использование временных таблиц и функции МАКСИМУМ для «схлопывания» аналитики — это мощный инструмент, который позволяет сделать отчеты более читаемыми и точными, избегая дублирования строк из-за пустых значений характеристик.

← На главную