Как правильно добавить признак ручного изменения цены в типовой регистр «Цены номенклатуры» в 1С:УТ 11

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

При разработке механизмов автоматического ценообразования часто возникает задача: пометить определенные цены как «установленные вручную», чтобы автоматические обработки не затирали их при очередном обновлении прайс-листа. На первый взгляд, задача кажется простой — добавить поле в регистр сведений ЦеныНоменклатуры. Однако выбор между добавлением измерения, ресурса или использованием регистратора может радикально повлиять на стабильность всей системы.

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

Анализ рисков: почему нельзя просто добавить измерение

Первоначальная идея многих разработчиков заключается в добавлении нового измерения типа Булево (например, УстановленоВручную) в регистр сведений ЦеныНоменклатуры. Давайте проанализируем, к каким последствиям это приведет.

Проблема уникальности записей и «задвоения» данных. Измерения в 1С определяют уникальность записи в регистре. Если мы добавим измерение, система позволит хранить две разные записи на одну и ту же дату для одного и того же сочетания «Номенклатура — Вид цены — Характеристика»: одну со значением Истина, другую со значением Ложь. Это в корне меняет поведение типовых механизмов.

Рассмотрим стандартную ситуацию получения цены через метод СрезПоследних. Если в базе окажутся две записи по одному ключу (но с разными значениями нашего нового измерения), типовой запрос вернет две строки вместо одной. Большинство типовых отчетов, документов (например, «Заказ клиента») и программных функций не рассчитаны на такой поворот событий. Это приведет к непредсказуемым результатам в расчетах и ошибкам в интерфейсе.

Влияние на производительность. Регистр ЦеныНоменклатуры является одним из самых интенсивно используемых объектов в 1С:УТ 11. Добавление измерения влечет за собой перестроение индексов базы данных на уровне SQL-сервера. Это увеличит время записи документов «Установка цен номенклатуры» и замедлит выборку актуальных цен, так как СУБД придется обрабатывать дополнительное поле в индексе.

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

Если мы заменим измерение на ресурс, ситуация станет значительно стабильнее. Ресурс не входит в ключ уникальности, а значит, на один момент времени для одной номенклатуры по-прежнему будет существовать только одна цена.

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

  1. Совместимость со срезом последних: Стандартные механизмы получения цен продолжат работать корректно, возвращая ровно одну актуальную цену.
  2. Безопасность для типового кода: Функции, которые не знают о вашем новом ресурсе, просто проигнорируют его, не вызывая критических сбоев.
  3. Простота реализации: Вам достаточно добавить поле, и оно станет доступно в наборе записей регистра.

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

Использование связи с регистратором

Рассмотрим еще один элегантный способ, который позволяет избежать изменения структуры самого регистра. Поскольку регистр ЦеныНоменклатуры подчинен регистратору, мы можем хранить признак «Ручной установки» непосредственно в документе УстановкаЦенНоменклатуры.

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


ВЫБРАТЬ
    Цены.Номенклатура КАК Номенклатура,
    Цены.Цена КАК Цена,
    Цены.Регистратор.УстановленоВручную КАК ЭтоРучнаяЦена
ИЗ
    РегистрСведений.ЦеныНоменклатуры.СрезПоследних(&Период, ) КАК Цены

Важный нюанс: Обращение через точку к реквизитам регистратора в запросе вызывает неявное соединение с таблицами документов. Если видов документов-регистраторов много, это может существенно замедлить выполнение запроса. В случае с УТ 11 регистратором чаще всего выступает только один документ, поэтому такой подход допустим, но требует осторожности при больших объемах данных.

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

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

  1. Создаем расширение конфигурации.
  2. Добавляем в расширение регистр сведений ЦеныНоменклатуры и добавляем в него новый ресурс ИзмененоВручную (Тип: Булево).
  3. Добавляем аналогичный реквизит в табличную часть документа УстановкаЦенНоменклатуры.
  4. Реализуем обработчик в расширении (например, в модуле объекта документа перед записью), который будет транслировать значение из табличной части документа в ресурс регистра при проведении.

Теперь проанализируем логику работы автоматической обработки, которая обновляет цены. Чтобы она «не трогала» ручные цены, код должен выглядеть примерно так:


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

Запрос.УстановитьПараметр("ДатаСреза", ТекущаяДата());
Результат = Запрос.Выполнить().Выгрузить();

Для Каждого СтрокаЦены Из Результат Цикл
    Если СтрокаЦены.ИзмененоВручную Тогда
        // Пропускаем обработку этой номенклатуры
        Продолжить;
    КонецЕсли;
    
    // Здесь логика автоматического расчета новой цены
    РассчитатьНовуюЦену(СтрокаЦены.Номенклатура);
КонецЦикла;

Альтернативный вариант: создание параллельного регистра

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

Алгоритм действий будет следующим:

Этот метод является самым «чистым» с точки зрения обновляемости конфигурации, так как типовые объекты вообще не меняют свою структуру данных.

Итоги и выводы

Подводя итог нашему анализу, можно выделить следующие правила:

  1. Никогда не добавляйте измерения в типовые регистры сведений, если вы не планируете полностью переписывать всю бизнес-логику работы с этим объектом.
  2. Использование ресурса — это допустимый компромисс, который обеспечивает работоспособность среза последних, но требует внимания при использовании расширений (данные ресурса могут быть потеряны при удалении расширения).
  3. Анализ через Регистратор подходит для простых задач, но может снижать производительность на сверхбольших базах.
  4. Параллельный регистр — лучший выбор для опытных архитекторов, стремящихся к максимальной независимости своего кода от вендорских обновлений.

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

← На главную