Как правильно вывести последнюю цену закупки в отчете на СКД

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

При разработке отчетов в системе 1С:Управление нашей фирмой часто возникает задача отображения актуальной информации о себестоимости или ценах поставщиков. Одной из наиболее частых задач является добавление колонки «Последняя цена закупки» в отчет по продажам. Давайте разберем, как реализовать это эффективно и без ошибок.

Основные подходы к решению задачи

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

Использование виртуальной таблицы СрезПоследних

Самый очевидный способ — использование регистра сведений ЦеныНоменклатурыКонтрагентов. Однако при работе с СКД необходимо учитывать особенности передачи параметров. Если мы попробуем просто соединить данные в одном запросе, мы можем столкнуться с ошибкой несоответствия типов. Чтобы избежать этого, рекомендуем использовать разделение наборов данных.

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


ВЫБРАТЬ 
    &Период1 КАК Период1, 
    Цены.Номенклатура КАК Номенклатура, 
    Цены.Цена КАК ЦенаПокупки 
ИЗ 
    РегистрСведений.ЦеныНоменклатурыКонтрагентов.СрезПоследних(&Период1, ) КАК Цены

Шаг 2: На вкладке «Связи наборов данных» свяжите основной набор (продажи) со вторым набором по полю Номенклатура (и Характеристика, если ведется учет в разрезе характеристик).

Шаг 3: Обязательно используйте функцию ЕСТЬNULL в вычисляемых полях или в самом запросе, чтобы избежать пустых значений в отчете:

ЕСТЬNULL(Цены.Цена, 0) КАК ЦенаПокупки

Оптимизация производительности через пакетные запросы

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


ВЫБРАТЬ 
    Т.Номенклатура, 
    Т.Характеристика, 
    Т.Период, 
    ВЫБОР 
        КОГДА Т.Количество = 0 ТОГДА 0 
        ИНАЧЕ Т.Сумма / Т.Количество 
    КОНЕЦ КАК Цена 
ПОМЕСТИТЬ ТПриход 
ИЗ РегистрНакопления.Закупки КАК Т 
ГДЕ Т.Регистратор ССЫЛКА Документ.ПриходнаяНакладная 
И Т.Период <= &Дата;

ВЫБРАТЬ 
    ТПриход.Номенклатура, 
    МАКСИМУМ(ТПриход.Период) КАК Период 
ПОМЕСТИТЬ ТМакс 
ИЗ ТПриход КАК ТПриход 
СГРУППИРОВАТЬ ПО ТПриход.Номенклатура;

ВЫБРАТЬ 
    ТПриход.Номенклатура, 
    ТПриход.Цена 
ИЗ ТПриход 
ВНУТРЕННЕЕ СОЕДИНЕНИЕ ТМакс 
ПО ТПриход.Номенклатура = ТМакс.Номенклатура 
И ТПриход.Период = ТМакс.Период;

Важные замечания и рекомендации

  1. Характеристики: Всегда учитывайте Характеристику в связях. Если забыть про этот разрез, отчет будет суммировать цены по всем характеристикам, что приведет к неверным данным и задваиванию строк.
  2. Ошибки типов: Если возникает ошибка несоответствия типов при передаче параметра Период в виртуальную таблицу, убедитесь, что параметр правильно определен в настройках СКД и имеет тип Дата.
  3. Условное оформление: Чтобы отчет выглядел профессионально, настройте условное оформление в СКД: если ЦенаПокупки равна 0, скройте её или выведите прочерк, так как нулевая цена часто означает отсутствие данных, а не бесплатный товар.
  4. Платформа: В более новых версиях платформы (начиная с 8.3.17) работа с параметрами виртуальных таблиц в СКД стала стабильнее, но метод разделения наборов данных остается наиболее надежным и «чистым» решением.

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

← На главную