Программная установка цен в современных конфигурациях на платформе «1С:Предприятие 8.3» (таких как «1С:Управление торговлей 11», «1С:ERP Управление предприятием» и «1С:Комплексная автоматизация 2») существенно отличается от старых версий (например, УТ 10.3). Разработчики часто сталкиваются с ситуацией, когда написанный код выполняется без видимых ошибок, однако цены в прайс-листах или карточках товаров не появляются.
В этой статье мы подробно разберем, как правильно написать код для программной установки цен, проанализируем внутреннюю архитектуру этого механизма, выявим типичные ошибки новичков и рассмотрим готовые шаблоны кода для интеграции.
Рассмотрим ситуацию, с которой часто сталкиваются начинающие разработчики. При создании новой номенклатуры (например, при импорте из Excel) и попытке сразу же назначить ей цену с помощью документа УстановкаЦенНоменклатуры, изменения не вступают в силу. Выясним причину этой проблемы.
Основная ошибка кроется в жизненном цикле самого объекта номенклатуры. Прежде чем передавать ссылку на товар в табличную часть документа установки цен, этот элемент должен быть физически создан и корректно записан в базу данных. Если в процессе записи справочника произошел сбой (например, из-за незаполненных обязательных реквизитов), метод Записать() не отработает должным образом, и ссылка на товар останется пустой.
В конфигурации «1С:Управление торговлей 11» ключевым реквизитом для справочника Номенклатура является ВидНоменклатуры. Без его заполнения элемент просто не запишется. Проанализируем правильный шаблон предварительного создания карточки товара:
// Создание и запись нового элемента номенклатуры
НовыйТовар = Справочники.Номенклатура.СоздатьЭлемент();
НовыйТовар.Наименование = "Элемент Номенклатуры Тест";
НовыйТовар.НаименованиеПолное = "Элемент Номенклатуры Тест (Полное)";
// Находим и заполняем обязательный вид номенклатуры
ВидТовара = Справочники.ВидыНоменклатуры.НайтиПоНаименованию("Товар");
Если ВидТовара.Пустая() Тогда
ВызватьИсключение "Не найден обязательный вид номенклатуры 'Товар'!";
КонецЕсли;
НовыйТовар.ВидНоменклатуры = ВидТовара;
// Заполняем ставку НДС (также критично для корректного учета)
НовыйТовар.СтавкаНДС = Перечисления.СтавкиНДС.НДС20;
Попытка
НовыйТовар.Записать();
Исключение
ЗаписьЖурналаРегистрации("ПрограммноеСозданиеТовара",
УровеньЖурналаРегистрации.Ошибка,,,
ОписаниеОшибки());
Возврат;
КонецПопытки;
Только после того как объект НовыйТовар.Ссылка успешно записан в базу данных, мы можем переходить к процедуре назначения цен.
Важно понимать, что в системе «1С:УТ 11» цены не хранятся внутри реквизитов справочника номенклатуры. Они записываются в периодический регистр сведений ЦеныНоменклатуры. Документ УстановкаЦенНоменклатуры выступает в роли единственного легитимного регистратора для этого регистра.
Для того чтобы цены начали действовать и отобразились в прайс-листах или карточках товаров:
РежимЗаписиДокумента.Проведение).10000), а не строковый ("10000"). Передача строки вместо числа — частая ошибка, которая может приводить к неявной конвертации типов или ошибкам проведения.В старых релизах конфигураций использовался булев реквизит Согласован = Истина. В современной подсистеме ценообразования (начиная с версии 11.5) логика изменилась.
Теперь документ использует реквизит Статус, принимающий значения из перечисления СтатусыУстановокЦенНоменклатуры. Если программно создать документ и не заполнить этот статус (или оставить его в значении «Не согласован»), документ проведется, но движения по регистру сведений совершены не будут, и новые цены не вступят в силу. Необходимо явно указывать статус:
ДокЦена.Статус = Перечисления.СтатусыУстановокЦенНоменклатуры.Согласован; // Или "Действует" в зависимости от версии
В пользовательском интерфейсе документ «Установка цен номенклатуры» выглядит как сложная кросс-таблица (дерево цен), где строки — это товары, а колонки — виды цен. Однако в базе данных этот документ хранится в виде двух абсолютно плоских табличных частей:
Рассмотрим эту структуру на примере. Если мы хотим установить для «Товара 1» закупочную цену в 1000 рублей и продажную в 1500 рублей, в табличную часть Товары необходимо добавить две отдельные строки.
С учетом всех описанных нюансов, разберем по шагам готовый листинг кода для программного создания и проведения документа установки цен:
// Шаг 1. Создаем объект документа
ДокЦена = Документы.УстановкаЦенНоменклатуры.СоздатьДокумент();
ДокЦена.Дата = ТекущаяДата();
ДокЦена.Ответственный = Пользователи.ТекущийПользователь();
// Шаг 2. Устанавливаем актуальный статус согласования
ДокЦена.Статус = Перечисления.СтатусыУстановокЦенНоменклатуры.Согласован;
// Шаг 3. Находим нужные виды цен в справочнике
ВидЦеныЗакупочная = Справочники.ВидыЦен.НайтиПоНаименованию("Закупочные");
ВидЦеныПродажная = Справочники.ВидыЦен.НайтиПоНаименованию("Продажные");
Если ВидЦеныЗакупочная.Пустая() Или ВидЦеныПродажная.Пустая() Тогда
ВызватьИсключение "Не найдены необходимые виды цен в справочнике!";
КонецЕсли;
// Шаг 4. Заполняем табличную часть "ВидыЦен"
СтрокаВид1 = ДокЦена.ВидыЦен.Добавить();
СтрокаВид1.ВидЦены = ВидЦеныЗакупочная;
СтрокаВид2 = ДокЦена.ВидыЦен.Добавить();
СтрокаВид2.ВидЦены = ВидЦеныПродажная;
// Шаг 5. Заполняем табличную часть "Товары"
// Ссылка на предварительно сохраненную номенклатуру
СсылкаНаТовар = Справочники.Номенклатура.НайтиПоНаименованию("Элемент Номенклатуры Тест");
Если Не СсылкаНаТовар.Пустая() Тогда
// Строка для закупочной цены
НоваяСтрокаЗакупка = ДокЦена.Товары.Добавить();
НоваяСтрокаЗакупка.Номенклатура = СсылкаНаТовар;
НоваяСтрокаЗакупка.ВидЦены = ВидЦеныЗакупочная;
НоваяСтрокаЗакупка.Цена = 10000; // Числовое значение!
// Строка для продажной цены
НоваяСтрокаПродажа = ДокЦена.Товары.Добавить();
НоваяСтрокаПродажа.Номенклатура = СсылкаНаТовар;
НоваяСтрокаПродажа.ВидЦены = ВидЦеныПродажная;
НоваяСтрокаПродажа.Цена = 15500; // Числовое значение!
Иначе
ВызватьИсключение "Номенклатура для установки цен не найдена в базе данных!";
КонецЕсли;
// Шаг 6. Запись и обязательное проведение документа
Попытка
ДокЦена.Записать(РежимЗаписиДокумента.Проведение);
Сообщить("Цены успешно установлены документом " + Строка(ДокЦена.Ссылка));
Исключение
Сообщить("Ошибка проведения документа цен: " + ОписаниеОшибки(), СтатусСообщения.Важное);
КонецПопытки;
Проанализируем важную деталь: если в вашей системе настроены зависимые цены (например, «Розничная» цена рассчитывается автоматически по формуле «Закупочная + 25%»), то при ручном вводе закупочной цены в интерактивном режиме розничная цена пересчитается автоматически на форме.
Однако при программном создании документа автоматический расчет формул не сработает сам по себе, если вы просто добавили одну строку с базовой ценой. Платформа запишет только то, что вы явно передали в табличную часть Товары.
Чтобы выполнить расчет зависимых цен программно, рекомендуется задействовать экспортные процедуры общего модуля ценообразования. В современных версиях конфигураций для этого используется вызов серверных методов API, таких как процедуры общего модуля УстановкаЦенСервер.
Если в вашей информационной базе включен учет по характеристикам или используются индивидуальные упаковки товаров, обязательно заполняйте соответствующие реквизиты в табличной части Товары:
Характеристика — если учет по характеристикам включен для данного вида номенклатуры, иначе цена запишется «пустой» характеристике и не будет подставляться в документы продаж.Упаковка — если цена устанавливается за конкретную логистическую единицу (коробка, паллета), а не за базовую единицу хранения (штуки, литры).Для минимизации ручного написания кода заполнения табличных частей используйте встроенный механизм создания на основании. Например, если вы хотите установить цены по результатам прихода товара от поставщика (документ ПриобретениеТоваровУслуг), используйте стандартный метод Заполнить():
ДокЦена = Документы.УстановкаЦенНоменклатуры.СоздатьДокумент();
ДокЦена.Дата = ТекущаяДата();
// Инициализируем заполнение на основании документа поступления
ДокЦена.Заполнить(СсылкаНаДокументПоступления);
ДокЦена.Статус = Перечисления.СтатусыУстановокЦенНоменклатуры.Согласован;
ДокЦена.Записать(РежимЗаписиДокумента.Проведение);
Этот подход гарантирует автоматический расчет всех связанных наценок, НДС, подстановку характеристик и минимизирует риски возникновения ошибок из-за обновления метаданных конфигурации при будущих обновлениях «1С:Управление торговлей».