Как заполнить регистр «Цены контрагентов» в 1С:УНФ по приходным накладным без повторного проведения?

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

В процессе работы с конфигурацией 1С:Управление нашей фирмой (УНФ) часто возникает необходимость сформировать историю цен поставщиков на основании ранее введенных документов поступления. Если при первичном проведении документов флаг регистрации цен не был установлен, регистр сведений ЦеныКонтрагентов остается пустым. Ручное перепроведение сотен накладных требует времени и может повлиять на оперативные данные. Разберем, как решить эту задачу как штатно, так и с помощью программных методов.

Особенности работы регистра цен контрагентов в 1С:УНФ

Проанализируем структуру хранения данных о ценах поставщиков в платформе 1С. Регистр сведений ЦеныКонтрагентов является периодическим и подчинен регистратору (документам ПриходнаяНакладная, УстановкаЦен и др.). Это накладывает определенные ограничения:

  1. Подчиненность регистратору: Нельзя создать запись в регистре без ссылки на конкретный документ-регистратор.
  2. Уникальность ключа записи: Ключ формируется набором измерений (период, номенклатура, характеристика, вид цены контрагента). При попытке записать значение с тем же ключом данные перезаписываются.

Альтернативные и штатные способы регистрации цен

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

  1. Ввод документа «Установка цен» на основании: В 1С:УНФ можно выделить приходные накладные и ввести на их основании документ УстановкаЦен. Это позволяет зарегистрировать цены без модификации проведенных первичных документов.
  2. Загрузка цен из внешних файлов: Если прайс-листы поставщиков хранятся в форматах Excel или CSV, используйте встроенный помощник загрузки цен из карточки вида цен контрагента.
  3. Групповое изменение реквизитов: С помощью стандартной обработки ГрупповоеИзменениеРеквизитов можно проставить флаг РегистрироватьЦеныПоставщика во всех накладных за выбранный период с последующим групповым перепроведением документов.
  4. Настройка авторегистрации в договорах: Чтобы предотвратить появление данной проблемы в будущем, включите флаг автоматической регистрации цен в карточках договоров с поставщиками.

Программный метод: проверка и запись цен через запрос

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

Частая ошибка разработчиков — чтение и перебор наборов записей (НаборЗаписей) в цикле по каждому документу. Это приводит к высокой нагрузке на систему. Правильный подход заключается в проверке существующих цен единым запросом к срезу последних.

Посмотрим на пример структуры запроса для проверки актуальных цен на дату документа:


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

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

Рассмотрим пример кода для записи движений по регистру:


// Создаем набор записей регистра по документу-регистратору
НаборЗаписей = РегистрыСведений.ЦеныКонтрагентов.СоздатьНаборЗаписей();
НаборЗаписей.Отбор.Регистратор.Установить(СсылкаНаНакладную);

// Включаем режим обмена данными, чтобы отключить лишние проверки и обработчики
НаборЗаписей.ОбменДанными.Загрузка = Истина;

// Заполняем движения на основе подготовленных данных
Записи = НаборЗаписей.Добавить();
Записи.Период = СсылкаНаНакладную.Дата;
Записи.Регистратор = СсылкаНаНакладную;
Записи.ВидЦенКонтрагента = ВидЦен;
Записи.Номенклатура = СтрокаДанных.Номенклатура;
Записи.Характеристика = СтрокаДанных.Характеристика;
Записи.Цена = СтрокаДанных.НоваяЦена;

// Записываем набор в базу данных
НаборЗаписей.Записать();

Использование свойства ОбменДанными.Загрузка = Истина позволяет существенно ускорить процесс обработки исторических документов, избегая повторного вызова подписок на события и проверки остатков при перепроведении.

← На главную