Как программно создать и рассчитать документ «Установка цен номенклатуры» по расписанию в 1С:ERP

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

В процессе автоматизации работы в 1С:ERP или УТ 11 часто возникает необходимость автоматического формирования цен или автоматического копирования прайс-листа по видам цен. Основная трудность заключается в том, что стандартный механизм расчета цен в документе УстановкаЦенНоменклатуры тесно связан с экранными формами. При попытке выполнить расчет в регламентном задании (на сервере) разработчики сталкиваются с тем, что типовые процедуры требуют передачи объекта Форма, который недоступен в фоновом режиме. Рассмотрим подробнее, как обойти это ограничение и реализовать полноценный серверный расчет.

Анализ проблемы: почему не работает стандартный вызов?

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

Выясним причину ошибки: когда мы запускаем код в серверном контексте (регламентное задание или внешняя обработка по расписанию), объект Форма равен Неопределено. Следовательно, прямое копирование логики нажатия кнопки «Рассчитать вычисляемые цены» приведет к исключению. Нам необходимо либо использовать штатные механизмы автоматизации, либо эмулировать контекст формы для серверных процедур.

Решение 1: Использование штатного механизма «Поддерживать цены в актуальном состоянии»

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

  1. Откроем справочник Виды цен.
  2. Найдем настройку «Поддерживать цены в актуальном состоянии» и установим соответствующий флаг.
  3. Настроим расписание в регламентном задании «Применение цен номенклатуры».

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

Решение 2: Программное создание документа с серверным расчетом

Рассмотрим по шагам, как программно создать документ и заставить систему рассчитать цены по формулам, не обращаясь к форме. В некоторых случаях данные могут поступать не только из базы, но и извне, тогда может потребоваться загрузка цен из табличного документа Excel или Word непосредственно в объект документа.

Посмотрим на пример кода, который инициализирует расчет:


// 1. Создаем новый документ
НовыйДокумент = Документы.УстановкаЦенНоменклатуры.СоздатьДокумент();
НовыйДокумент.Дата = ТекущаяДата();
НовыйДокумент.Статус = Перечисления.СтатусыУстановокЦенНоменклатуры.Согласовано;
НовыйДокумент.Ответственный = Пользователи.ТекущийПользователь();

// 2. Заполняем виды цен
НоваяСтрокаВидЦены = НовыйДокумент.ВидыЦен.Добавить();
НоваяСтрокаВидЦены.ВидЦены = ВыбранныйВидЦены;

// 3. Подготавливаем параметры для расчета (эмуляция параметров формы)
ПараметрыЗаполнения = УстановкаЦенСервер.ПодготовитьСтруктуруПараметров();
ПараметрыЗаполнения.Вставить("Дата", НовыйДокумент.Дата);
ПараметрыЗаполнения.Вставить("ВидыЦен", НовыйДокумент.ВидыЦен.ВыгрузитьКолонку("ВидЦены"));

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

В этом примере мы подготавливаем структуру ПараметрыЗаполнения, которая заменяет данные, обычно собираемые с экранных полей. Метод РассчитатьЦеныПоДаннымИБ заполнит табличную часть Товары актуальными позициями и рассчитает их стоимость согласно настройкам вида цены.

Решение 3: Прямая запись в регистр сведений

В некоторых случаях (например, при интеграции с внешними системами) создание документа УстановкаЦенНоменклатуры может быть избыточным. Если ваша задача — просто обновить значения, проанализируем вариант записи напрямую в регистр ЦеныНоменклатуры.

Внимание: Этот способ не рекомендуется для ERP, так как он обходит механизмы проверки. Если же вам необходим сквозной перенос всей истории цен номенклатуры из старых систем (УПП, КА 1.1), лучше использовать специализированные инструменты переноса, которые корректно создают документы установки.


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

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

Особенности работы с СКД в регламентных заданиях

Разберем нюанс, связанный с использованием произвольных запросов в видах цен. Если формула цены опирается на схему компоновки данных (СКД), то программный вызов должен учитывать параметры компоновки. Чтобы проверить корректность итоговых цифр после программного расчета, полезно выполнить анализ наценки на закупочные цены с помощью отчетов.

Выясним причину, по которой расчет может вернуть пустой результат: часто в СКД установлены обязательные параметры (например, Склад или Период), которые не заполняются автоматически при серверном вызове. Проанализируем пример настройки параметров компоновки:


// Добавление настроек компоновки для расчета
НастройкиКД = Новый Структура;
НастройкиКД.Вставить("Период", НовыйДокумент.Дата);
// Передаем эти настройки в процедуру заполнения
УстановкаЦенСервер.ЗаполнитьПоДаннымИБ(НовыйДокумент, ПараметрыЗаполнения, НастройкиКД);

Подведение итогов и рекомендации

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

При работе с большими объемами данных (более 50 000 позиций) обязательно разбивайте процесс на порции или используйте механизм длительных операций, чтобы избежать блокировок базы данных и аварийного завершения регламентного задания по таймауту.

← На главную