Как программно получить цену номенклатуры по договору в 1С?

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

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

Основы работы с ценами в 1С

В конфигурациях, таких как УТП или УТ 10.3, цены на товары хранятся в регистре сведений ЦеныНоменклатуры. Для получения актуальной цены на определенную дату используется механизм виртуальных таблиц, а именно — СрезПоследних. Это самый быстрый и надежный способ обратиться к актуальным данным регистра.

Разбор типичных ошибок при разработке

Многие начинающие разработчики сталкиваются с ошибкой Индекс находится за границами массива. Это происходит, когда мы пытаемся обратиться к результату запроса через индекс, например Результат[0], не проверяя, вернул ли запрос хоть какие-то данные. Если цена в регистре для указанной номенклатуры или типа цен отсутствует, массив оказывается пустым, и обращение к нему вызывает критическую ошибку.

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

Пошаговое решение задачи

Чтобы корректно получить цену, следуйте этому алгоритму:

  1. Определите ТипЦен из договора контрагента.
  2. Сформируйте запрос к регистру сведений ЦеныНоменклатуры.СрезПоследних.
  3. Используйте параметры для фильтрации данных прямо в тексте запроса.
  4. Обработайте результат запроса через выборку, а не через прямой доступ по индексу.

Посмотрим на пример кода, который делает это правильно:


ТипЦен = ЭтотОбъект.ДоговорКонтрагента.ТипЦен;
ДатаДокумента = ЭтотОбъект.Дата;
НоменклатураСсылка = ЭлементыФормы.Товары.ТекущиеДанные.Номенклатура;

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

Запрос.УстановитьПараметр("Дата", ДатаДокумента);
Запрос.УстановитьПараметр("ТипЦен", ТипЦен);
Запрос.УстановитьПараметр("Номенклатура", НоменклатураСсылка);

РезультатЗапроса = Запрос.Выполнить();
Выборка = РезультатЗапроса.Выбрать();

Если Выборка.Следующий() Тогда
    // Цена успешно найдена
    Цена = Выборка.Цена;
Иначе
    // Цена не найдена, обработаем ситуацию
    Цена = 0;
КонецЕсли;

Важные советы по оптимизации

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

  1. Соберите все товары из табличной части в массив или список значений.
  2. Используйте оператор ГДЕ Номенклатура В (&СписокНоменклатуры) в тексте запроса.
  3. Выгрузите результат в таблицу значений и свяжите её с данными документа.

Использование типового функционала

Перед тем как приступать к написанию собственного кода, внимательно изучите возможности самой конфигурации. В большинстве типовых решений, таких как 1С:Управление торговлей или УТП, механизм подстановки цен уже реализован. Часто бывает достаточно просто правильно заполнить реквизит ТипЦен в документе, и система сама автоматически подставит нужные цены при добавлении товаров в табличную часть.

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

← На главную