Как в справочник Номенклатура подтянуть цены из регистра сведений?

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

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

Анализ задачи и сбор требований

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

  1. Тип форм: Используются ли в вашей конфигурации Управляемые формы (характерно для 1С 8.3) или Обычные формы (характерно для 1С 8.2 и старых самописок)?
  2. Разрез цен: Хранятся ли цены только в разрезе номенклатуры или используются еще и ХарактеристикиНоменклатуры?
  3. Виды цен: Нужно ли выводить какую-то конкретную цену (например, «Розничная») или пользователь должен видеть все установленные типы цен?
  4. Место вывода: Нужно ли подтянуть данные только в форму списка для удобства подбора или также в форму элемента справочника?

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

Реализация для управляемых форм (Динамический список)

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

Рассмотрим структуру запроса, который позволит нам соединить основную таблицу справочника с виртуальной таблицей среза последних цен. Важно использовать именно ЛЕВОЕ СОЕДИНЕНИЕ, чтобы товары, для которых цена еще не установлена, не исчезли из общего списка.


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

Разберем важные особенности этого запроса:

Настройка динамического списка в конфигураторе

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

  1. Откроем форму списка справочника Номенклатура.
  2. Перейдем к свойствам основного реквизита формы (обычно это Список, тип ДинамическийСписок).
  3. Установим флаг Произвольный запрос и нажмем кнопку Открыть.
  4. Вставим наш проанализированный запрос в окно редактора.
  5. В настройках параметров списка (на закладке «Параметры») укажем значения для &Период (обычно это ТекущаяДата()) и &ВидЦены.

Полезный совет: Чтобы дать пользователю возможность менять тип отображаемой цены, можно вывести выбор вида цены на форму в виде отдельного поля и обновлять параметры запроса при его изменении.

Реализация для обычных форм (v8.2)

В случае с обычными формами подход с динамическим списком не всегда доступен в том же виде. Рассмотрим программный метод вывода данных. Для этого нам потребуется обработчик события ПриПолученииДанных.

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

Посмотрим на пример кода для этого обработчика:


Процедура СписокПриПолученииДанных(Элемент, ОформленияСтрок)
    
    // Создадим массив ссылок на номенклатуру, которая отображается в данный момент
    МассивНоменклатуры = Новый Массив;
    СоответствиеОформлений = Новый Соответствие;
    
    Для Каждого ОформлениеСтроки Из ОформленияСтрок Цикл
        МассивНоменклатуры.Добавить(ОформлениеСтроки.ДанныеСтроки.Ссылка);
        СоответствиеОформлений.Вставить(ОформлениеСтроки.ДанныеСтроки.Ссылка, ОформлениеСтроки);
    КонецЦикла;
    
    // Выполним один запрос для получения цен по всем выведенным позициям
    Запрос = Новый Запрос;
    Запрос.Текст = 
    "ВЫБРАТЬ
    |	ЦеныНоменклатурыСрезПоследних.Номенклатура КАК Номенклатура,
    |	ЦеныНоменклатурыСрезПоследних.Цена КАК Цена
    |ИЗ
    |	РегистрСведений.ЦеныНоменклатуры.СрезПоследних(&Период, Номенклатура В (&МассивНоменклатуры) И ВидЦены = &ВидЦены) КАК ЦеныНоменклатурыСрезПоследних";
    
    Запрос.УстановитьПараметр("Период", ТекущаяДата());
    Запрос.УстановитьПараметр("МассивНоменклатуры", МассивНоменклатуры);
    Запрос.УстановитьПараметр("ВидЦены", НужныйВидЦены);
    
    Выборка = Запрос.Выполнить().Выбрать();
    
    Пока Выборка.Следующий() Цикл
        // Находим строку списка и устанавливаем значение в колонку "Цена"
        Оформление = СоответствиеОформлений.Получить(Выборка.Номенклатура);
        Если Оформление <> Неопределено Тогда
            Оформление.Ячейки.Цена.УстановитьТекст(Выборка.Цена);
        КонецЕсли;
    КонецЦикла;
    
КонецПроцедуры

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

Оптимизация и безопасность

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

1. Права доступа (RLS): Если в вашей системе настроены права доступа на уровне записей, не забудьте добавить ключевое слово РАЗРЕШЕННЫЕ в текст запроса. В противном случае пользователь, не имеющий прав на просмотр всех цен, может получить ошибку при открытии справочника.

2. Кэширование данных: Если база очень большая и цены меняются редко, рассмотрите вариант записи текущей цены в реквизит самого справочника Номенклатура (например, при проведении документа «Установка цен номенклатуры»). Это позволит выводить цену в списке мгновенно, не обращаясь к регистру сведений при каждом просмотре.

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

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

← На главную