Почему запрос к регистру цен в 1С выдает неверную сумму и как это исправить?

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

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

Анализ проблемы: почему данные не сходятся?

Представим, что мы пишем запрос для получения суммы списанных материалов. Мы соединяем табличную часть документа с виртуальной таблицей РегистрСведений.ЦеныНоменклатуры.СрезПоследних. Однако на выходе получаем странные цифры. В чем же кроется причина?

Основная причина заключается в структуре регистра цен. В большинстве конфигураций 1С регистр ЦеныНоменклатуры содержит не только измерение Номенклатура, но и обязательное измерение ТипЦен. Когда мы обращаемся к виртуальной таблице СрезПоследних без указания конкретного типа цен, система возвращает нам все записи, актуальные на указанную дату по всем существующим в базе типам цен (например, закупочные, розничные, оптовые).

В результате при соединении таблиц в запросе для одной позиции номенклатуры может «подтянуться» сразу несколько записей с разными ценами. Если мы используем агрегатную функцию СУММА(), происходит некорректное суммирование или умножение количества на все найденные цены сразу, что приводит к многократному завышению или искажению итогового результата.

Шаг 1: Диагностика запроса

Чтобы понять, что именно идет не так, не торопитесь исправлять код. Сначала необходимо увидеть детальные данные, которые попадают в выборку. Поступим следующим образом:

  1. Уберем на время из запроса группировку СГРУППИРОВАТЬ ПО.
  2. Удалим агрегатную функцию СУММА().
  3. Выполним запрос в консоли и проанализируем каждую строку результата.

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

Шаг 2: Исправление запроса

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

Добавим параметр &ТипЦен в условие виртуальной таблицы. В конфигураторе это будет выглядеть так:


ВЫБРАТЬ
    СписаниеМатериаловСоСкладаМатериалы.Ссылка КАК Ссылка,
    СУММА(СписаниеМатериаловСоСкладаМатериалы.Количество * ЦеныНоменклатурыСрезПоследних.Цена) КАК Сумма
ИЗ
    Документ.СписаниеМатериаловСоСклада.Материалы КАК СписаниеМатериаловСоСкладаМатериалы
    ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры.СрезПоследних(&КонДата, ТипЦен = &ТипЦен) КАК ЦеныНоменклатурыСрезПоследних
    ПО СписаниеМатериаловСоСкладаМатериалы.Номенклатура = ЦеныНоменклатурыСрезПоследних.Номенклатура
ГДЕ
    СписаниеМатериаловСоСкладаМатериалы.Ссылка.Проведен = ИСТИНА
СГРУППИРОВАТЬ ПО
    СписаниеМатериаловСоСкладаМатериалы.Ссылка

Почему важно указывать ТипЦен?

Если в базе данных по какой-то номенклатуре заведено несколько цен (например, мы когда-то использовали «Закупочную», а сейчас перешли на «Основную»), то запрос без параметра вернет не одну запись, а столько, сколько типов цен найдет. Если вы не указываете фильтр, 1С не может «угадать», какую именно цену вы хотите использовать для расчета себестоимости списания.

Рекомендации по отладке

Чтобы избежать подобных проблем в будущем, возьмите на вооружение эти советы:

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

← На главную