Почему цены не регистрируются при программном создании документа "Установка цен номенклатуры" в 1С:УТ 11.5?

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

При переходе с конфигурации "Управление торговлей" версии 10.3 на более современную 11.5, а также при активной разработке нового функционала, мы часто сталкиваемся с необходимостью программного создания типовых документов. Одна из распространенных задач — это формирование документа "Установка цен номенклатуры" (УЦН) для регистрации актуальных цен. Однако нередко возникает ситуация, когда документ успешно создается, проводится и сохраняется без видимых ошибок, но при этом установленные цены не регистрируются в базе данных и не отображаются в прайс-листе. Давайте разберем, почему это происходит, и как решить данную проблему.

Анализируем исходную проблему: почему цены не регистрируются?

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

Изначальный код, с которым мы работали, выглядел следующим образом:


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

ВидЦены1 = Справочники.ВидыЦен.НайтиПоНаименованию("Розничная");

ТЧВидЦены = Док.ВидыЦен.Добавить;
ТЧВидЦены.ВидЦены = ВидЦены1;
ТЧВидЦены.НастройкиКомпоновкиДанных.Получить; // Эта строка может быть лишней при программном создании

ТЧТовары = Док.Товары.Добавить; // Здесь кроется одна из ключевых проблем
ДобН = Справочники.Номенклатура.НайтиПоНаименованию("Тестовая номенклатура");
ТЧТовары.Номенклатура = ДобН.Ссылка;
ТЧТовары.ВидЦены = ВидЦены1;
ТЧТовары.Цена = 2500;
ТЧТовары.Характеристика = Перечисления.ВариантыИспользованияХарактеристикНоменклатуры.НеИспользовать;
ТЧТовары.Валюта = Справочники.Валюты.НайтиПоКоду("643"); // Здесь также есть нюанс
ТЧТовары.Упаковка = Справочники.УпаковкиЕдиницыИзмерения.ПустаяСсылка;
ТЧТовары.ЦенаИзмененаВручную = Истина;

Док.Проведен = Истина;
Док.Записать(РежимЗаписиДокумента.Проведение);

Несмотря на кажущуюся корректность кода, цены в прайс-листе не появлялись. Это наталкивает нас на мысль о глубоких изменениях в механизме ценообразования между версиями 10.3 и 11.5.

Ключевое решение: правильное использование табличной части и валюты

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

  1. Использование табличной части Товары2_5 вместо Товары:

    В УТ 11.5 и более поздних версиях, а также в связанных конфигурациях (КА 2.5, ERP 2.5), для регистрации цен следует заполнять табличную часть Товары2_5. Табличная часть Товары, которая использовалась в старых версиях или для других целей, больше не используется для этих целей в новой подсистеме ценообразования.

    Нам необходимо изменить строку, где мы добавляем новую строку в табличную часть:

    Было:

    ТЧТовары = Док.Товары.Добавить;

    Стало:

    ТЧТовары = Док.Товары2_5.Добавить();

    Важно: убедитесь, что в вашей конфигурации активно новое ценообразование. Это зависит от настроек в разделе "НСИ и администрирование" -> "CRM и маркетинг" (или аналогичном) — там должны быть включены соответствующие флаги, управляющие версией подсистемы ценообразования. Если вы все еще используете устаревшее ценообразование, возможно, вам придется использовать табличную часть Товары, но это маловероятно для чистой УТ 11.5.

  2. Корректное указание валюты:

    Еще один важный момент — это правильное указание валюты. Хотя поиск по коду ("643" для российского рубля) может работать, гораздо надежнее и правильнее с точки зрения типовой архитектуры использовать предопределенную константу для валюты регламентированного учета.

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

    Было:

    ТЧТовары.Валюта = Справочники.Валюты.НайтиПоКоду("643");

    Стало:

    ТЧТовары.Валюта = Константы.ВалютаРегламентированногоУчета.Получить();

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

Обновленный программный код для установки цен

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


// Создаем новый документ Установка цен номенклатуры
Док = Документы.УстановкаЦенНоменклатуры.СоздатьДокумент();

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

// Находим нужный вид цены
ВидЦены1 = Справочники.ВидыЦен.НайтиПоНаименованию("Розничная");
Если ВидЦены1.Пустая() Тогда
    // Обработка ситуации, если вид цены не найден
    ВызватьИсключение "Не найден вид цены 'Розничная'!";
КонецЕсли;

// Добавляем вид цены в табличную часть 'ВидыЦен' документа
ТЧВидЦены = Док.ВидыЦен.Добавить();
ТЧВидЦены.ВидЦены = ВидЦены1;
// Строка ТЧВидЦены.НастройкиКомпоновкиДанных.Получить; в данном контексте не требуется
// и может быть удалена, если она не используется для динамического расчета на основе СКД.

// Добавляем строку с номенклатурой и ценой в табличную часть 'Товары2_5'
// Это критически важное изменение для УТ 11.5 и выше
ТЧТовары = Док.Товары2_5.Добавить();

// Находим номенклатуру
ДобН = Справочники.Номенклатура.НайтиПоНаименованию("Тестовая номенклатура");
Если ДобН.Пустая() Тогда
    // Обработка ситуации, если номенклатура не найдена
    ВызватьИсключение "Не найдена номенклатура 'Тестовая номенклатура'!";
КонецЕсли;

ТЧТовары.Номенклатура = ДобН; // Ссылка на найденную номенклатуру
ТЧТовары.ВидЦены = ВидЦены1;
ТЧТовары.Цена = 2500;

// Указываем характеристику номенклатуры. Если характеристики не используются,
// рекомендуется явно указать пустую ссылку, а не Перечисления.ВариантыИспользованияХарактеристикНоменклатуры.НеИспользовать
// в поле "Характеристика", так как это поле должно содержать ссылку на элемент справочника ХарактеристикиНоменклатуры.
ТЧТовары.Характеристика = Справочники.ХарактеристикиНоменклатуры.ПустаяСсылка;

// Корректно указываем валюту, используя константу регламентированного учета
ТЧТовары.Валюта = Константы.ВалютаРегламентированногоУчета.Получить();

// Упаковка. Если упаковки не используются, указываем пустую ссылку.
ТЧТовары.Упаковка = Справочники.УпаковкиЕдиницыИзмерения.ПустаяСсылка;

// Флаг, указывающий, что цена изменена вручную (или задана программно)
ТЧТовары.ЦенаИзмененаВручную = Истина;

// Проводим и записываем документ
Док.Записать(РежимЗаписиДокумента.Проведение);

// Если необходимо показать документ пользователю после создания
// Показать(Док);

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

Дополнительные рекомендации и методы отладки

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

  1. Механизм "ручного перепроведения" и формы документа:

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

    Чтобы понять, что именно делает форма, мы можем:

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

    Даже если для вашей "Тестовой номенклатуры" характеристики и упаковки не используются, всегда следует явно указывать пустые ссылки для полей Характеристика и Упаковка в строке табличной части. Отсутствие явного значения может быть интерпретировано системой как необходимость заполнить эти поля, что может привести к ошибкам при проведении или неправильной регистрации цен, если конфигурация ожидает эти значения.

    Пример (уже включен в исправленный код):

    
    ТЧТовары.Характеристика = Справочники.ХарактеристикиНоменклатуры.ПустаяСсылка;
    ТЧТовары.Упаковка = Справочники.УпаковкиЕдиницыИзмерения.ПустаяСсылка;
    
  3. Статус документа и согласование:

    Мы уже устанавливаем флаг Согласован = Истина и статус Перечисления.СтатусыУстановокЦенНоменклатуры.Согласован. Это важные реквизиты, которые указывают системе, что документ готов к тому, чтобы его цены вступили в действие. Убедитесь, что ваш вид цены позволяет регистрировать цены документом с таким статусом.

  4. Детальная отладка и замер производительности:

    Если проблема сохраняется или вам необходимо понять более глубокие причины, воспользуйтесь мощным инструментарием отладки 1С:Предприятия. Мы рекомендуем следующий пошаговый подход:

    1. Подготовка: Откройте конфигуратор, установите точки останова в модуле объекта документа "Установка цен номенклатуры" (в процедуре ОбработкаПроведения) и в модулях, которые, по вашему мнению, могут быть задействованы (например, в общих модулях ценообразования).
    2. Замер производительности (ручной вариант):

      Запустите 1С:Предприятие в режиме отладки. Откройте документ "Установка цен номенклатуры", который вы заполняете вручную и который корректно регистрирует цены. Перед проведением этого документа включите замер производительности (меню "Отладка" -> "Замер производительности"). Проведите документ. После проведения отключите замер производительности. Сохраните отчет замеров.

    3. Замер производительности (программный вариант):

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

    4. Сравнение отчетов:

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

    5. Пошаговая отладка:

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

  5. Использование процедуры Заполнить(ДанныеЗаполнения):

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

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

    
    Док = Документы.УстановкаЦенНоменклатуры.СоздатьДокумент();
    
    // Подготавливаем структуру с данными для заполнения
    ДанныеЗаполнения = Новый Структура();
    ДанныеЗаполнения.Вставить("ВидЦены", Справочники.ВидыЦен.НайтиПоНаименованию("Розничная"));
    ДанныеЗаполнения.Вставить("Номенклатура", Справочники.Номенклатура.НайтиПоНаименованию("Тестовая номенклатура"));
    ДанныеЗаполнения.Вставить("Цена", 2500);
    ДанныеЗаполнения.Вставить("Валюта", Константы.ВалютаРегламентированногоУчета.Получить());
    // Добавьте другие необходимые данные в структуру
    
    // Вызываем процедуру заполнения документа
    Док.Заполнить(ДанныеЗаполнения);
    
    // Устанавливаем оставшиеся реквизиты, которые не были заполнены автоматически
    Док.Дата = ТекущаяДата();
    Док.Согласован = Истина;
    Док.Ответственный = Пользователи.ТекущийПользователь();
    Док.Статус = Перечисления.СтатусыУстановокЦенНоменклатуры.Согласован;
    
    // Записываем и проводим документ
    Док.Записать(РежимЗаписиДокумента.Проведение);
    

    Этот подход может помочь, если типовые механизмы заполнения содержат скрытую логику, которую сложно воспроизвести вручную.

  6. Настройки ценообразования в системе:

    Мы также должны убедиться, что в самой конфигурации правильно настроены виды цен, их назначение и способы задания (например, "Ручное назначение", "Наценка на другой вид цен"). Соответствующие флажки в разделе "НСИ и администрирование" -> "CRM и маркетинг" должны быть включены для поддержки нового ценообразования, использования нескольких видов цен, ценовых групп и т.д.

Итак, основная проблема с программным созданием документа "Установка цен номенклатуры" в 1С:УТ 11.5 решается путем корректного использования табличной части Товары2_5 и правильного указания валюты. В сочетании с внимательной отладкой и пониманием архитектурных изменений конфигурации, мы сможем успешно перенести и реализовать любую необходимую функциональность.

← На главную