Как вывести розничную цену в печатную форму документа Поступление товаров в УТ 11.4

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

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

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

Постановка задачи и логика решения

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

Разберем алгоритм действий, который нам необходимо реализовать:

  1. Определить склад (магазин), на который поступает товар.
  2. Получить ВидЦены, привязанный к этому складу (обычно это реквизит РозничныйВидЦены).
  3. Для каждой строки товара в документе найти актуальную цену по выбранному виду цен в регистре ЦеныНоменклатуры.
  4. Вывести полученное значение в параметр макета печатной формы.

Вариант 1: Использование метода ПолучитьПоследнее (простой способ)

Этот способ подходит для понимания механики работы с регистрами сведений. Как выяснилось в ходе обсуждения на форуме, начинающие программисты часто сталкиваются с тем, что вместо числа в печатную форму выводится слово "Структура". Проанализируем правильный код получения цены.

Рассмотрим пример кода внутри цикла обработки строк документа:


// 1. Формируем структуру отбора для регистра
Отбор = Новый Структура;
Отбор.Вставить("Номенклатура", ВыборкаПоТоварам.Номенклатура);
Отбор.Вставить("Характеристика", ВыборкаПоТоварам.Характеристика);
Отбор.Вставить("ВидЦены", ДанныеПечати.Склад.РозничныйВидЦены);

// 2. Получаем последнее значение из регистра на дату документа
// Важно использовать дату документа, а не ТекущуюДату!
СтруктураРесурсов = РегистрыСведений.ЦеныНоменклатуры.ПолучитьПоследнее(ДанныеПечати.Дата, Отбор);

// 3. Извлекаем цену из структуры ресурсов
ЦенаРозничная = 0;
Если СтруктураРесурсов.Количество() > 0 Тогда
    ЦенаРозничная = СтруктураРесурсов.Цена;
КонецЕсли;

// 4. Заполняем параметры области макета
СтруктураДанныхЦенаРоз = Новый Структура;
СтруктураДанныхЦенаРоз.Вставить("ЦенаРозничная", ЦенаРозничная);
ОбластьДанных.Параметры.Заполнить(СтруктураДанныхЦенаРоз);

Важные замечания к этому коду:

  1. Отбор по ссылке: Всегда передавайте в отбор ссылку (Объект.Ссылка), а не наименование товара (строку). Это критично для корректной работы запроса к БД.
  2. Учет характеристик: В современных конфигурациях УТ 11.4 практически всегда ведется учет в разрезе характеристик. Если пропустить измерение Характеристика в отборе, вы рискуете получить неверную цену или пустое значение.
  3. Извлечение значения: Метод ПолучитьПоследнее всегда возвращает объект Структура, содержащий все ресурсы регистра (Цена, Валюта, Упаковка). Чтобы получить само число, нужно обратиться к ключу .Цена.

Вариант 2: Профессиональный подход через запрос (Оптимизация)

Метод ПолучитьПоследнее внутри цикла — это классическая ошибка производительности "N+1". Если в накладной 200 строк, система сделает 200 отдельных запросов к базе данных. Проанализируем, как сделать это правильно с помощью одного запроса.

Рассмотрим построение запроса для получения цен сразу по всему списку товаров из документа:


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

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

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

Такой подход работает в десятки раз быстрее и является стандартом разработки в среде 1С:Предприятие 8.

Вариант 3: Использование типового API конфигурации УТ 11.4

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

Проанализируем пример использования типового механизма:


ПараметрыОтбора = Новый Структура;
ПараметрыОтбора.Вставить("Номенклатура",  СтрокаТовара.Номенклатура);
ПараметрыОтбора.Вставить("Характеристика", СтрокаТовара.Характеристика);
ПараметрыОтбора.Вставить("ВидЦены",       СкладДокумента.РозничныйВидЦены);
ПараметрыОтбора.Вставить("Дата",          Объект.Дата);

// Типовая функция вернет уже готовую цену с учетом всех правил системы
Цена = ПродажиСервер.ПолучитьЦенуПоОтбору(ПараметрыОтбора);

Также в конфигурации Управление торговлей версии 11 существует мощный модуль ЦенообразованиеВызовСервера. Его методы позволяют получать цены массово для списка товаров, автоматически обрабатывая пересчет из одной валюты в другую.

Дополнительные нюансы, которые нельзя игнорировать

Выясним причины, по которым цена может не выводиться или быть некорректной, даже если код написан правильно:

Заключение

Мы разобрали путь от простого (но не совсем эффективного) метода ПолучитьПоследнее до использования оптимизированных запросов и типового API конфигурации. Для создания надежной внешней печатной формы в УТ 11.4 рекомендуем всегда привязываться к дате документа и использовать механизмы характеристик. Это обеспечит точность данных даже при изменении цен в будущем.

← На главную