В процессе автоматизации работы в 1С:Управление торговлей 11 (УТ 11), ERP или Комплексной автоматизации часто возникает необходимость программно обновить цены номенклатуры. Это может быть загрузка из внешних прайс-листов, расчет по сложным алгоритмам или интеграция с маркетплейсами. В этой статье мы разберем, какой путь выбрать — прямую запись в регистр или создание документа, а также рассмотрим пошаговый алгоритм реализации и исправим типичные ошибки программистов.
Первый вопрос, который встает перед разработчиком: можно ли записывать данные напрямую в регистр сведений ЦеныНоменклатуры? Разберем ситуацию подробнее. Теоретически, 1С позволяет делать прямые записи в наборы записей регистров. Однако в современных конфигурациях на базе УТ 11 этот путь считается крайне некорректным по следующим причинам:
ЦеныНоменклатуры является подчиненным регистратору. Это значит, что любая запись в нем должна быть привязана к конкретному документу.УстановкаЦенНоменклатуры система выполняет множество проверок: контролирует статусы (согласовано/установлено), проверяет права доступа, обновляет связанные регистры (например, срез последних или версионирование).Таким образом, правильный метод — всегда создавать документ УстановкаЦенНоменклатуры. Рассмотрим, как это сделать программно.
Рассмотрим пошагово процесс создания и заполнения документа. Основная задача — правильно заполнить шапку документа и табличную часть Товары. Проанализируем пример кода, который позволит нам создать документ и провести его.
// 1. Создаем объект документа
НовыйДокумент = Документы.УстановкаЦенНоменклатуры.СоздатьДокумент();
// 2. Заполняем основные реквизиты шапки
НовыйДокумент.Дата = ТекущаяДата();
НовыйДокумент.Ответственный = Пользователи.ТекущийПользователь();
НовыйДокумент.Согласован = Истина;
// Важно: Статус документа определяет, будут ли цены видны в системе
НовыйДокумент.Статус = Перечисления.СтатусыУстановокЦенНоменклатуры.Согласован;
// 3. Заполняем табличную часть Товары
// Предположим, у нас есть массив структур "ДанныеЦен" с полями Номенклатура, ВидЦены, Цена
Для Каждого СтрДанных Из ДанныеЦен Цикл
НоваяСтрока = НовыйДокумент.Товары.Добавить();
НоваяСтрока.Номенклатура = СтрДанных.Номенклатура;
НоваяСтрока.ВидЦены = СтрДанных.ВидЦены;
НоваяСтрока.Цена = СтрДанных.Цена;
// Если учет ведется в разрезе характеристик или упаковок, их тоже нужно заполнить
Если ЗначениеЗаполнено(СтрДанных.Характеристика) Тогда
НоваяСтрока.Характеристика = СтрДанных.Характеристика;
КонецЕсли;
// Валюта обычно берется из вида цены
НоваяСтрока.Валюта = СтрДанных.ВидЦены.ВалютаЦены;
КонецЦикла;
// 4. Попытка записи и проведения
Попытка
НовыйДокумент.Записать(РежимЗаписиДокумента.Проведение);
Сообщить("Цены успешно установлены документом " + НовыйДокумент.Ссылка);
Исключение
Сообщить("Ошибка при установке цен: " + ОписаниеОшибки());
КонецПопытки;
Многие программисты сталкиваются с тем, что метод Записать() отрабатывает нормально, а при выполнении Записать(РежимЗаписиДокумента.Проведение) система выдает ошибку о дублировании записей в регистре сведений. Разберем ситуацию: почему это происходит, даже если регистр кажется пустым?
Причина кроется в дублировании строк внутри самого документа. Если в табличную часть Товары программно добавить две строки, где совпадает комбинация Номенклатура + Характеристика + ВидЦены, то при проведении документ попытается сформировать две записи в регистр на одну и ту же дату с одинаковыми ключами. В 1С регистры сведений не допускают наличия двух записей с одинаковыми измерениями в одной точке времени.
Проанализируем типичную ошибку в циклах, которую часто совершают новички:
// ОШИБОЧНЫЙ КОД
Для каждого Товар из СписокТоваров Цикл
Для Индекс = 1 По ВсегоСтрок Цикл
// Если здесь нет проверки на уникальность,
// одна и та же номенклатура может добавиться несколько раз
НоваяСтр = СоздДокумент.Товары.Добавить();
// ... заполнение ...
КонецЦикла;
КонецЦикла;
Чтобы избежать этой проблемы, перед добавлением строки в документ рекомендуется проверять, не была ли эта позиция добавлена ранее, или использовать предварительно свернутую таблицу значений.
Выясним важный нюанс: начиная с версии УТ 11.5.7, механизм ценообразования изменился (появилась "Версия 2"). В этой версии структура документа УстановкаЦенНоменклатуры стала сложнее. Теперь данные распределены между несколькими табличными частями:
Если в вашей базе включена новая версия ценообразования, простой метод Документ.Товары.Добавить() может не сработать так, как ожидается. В этом случае правильнее использовать программный интерфейс, заложенный разработчиками в общем модуле ЦенообразованиеВызовСервера или аналогичных. Это гарантирует, что все связанные таблицы будут заполнены корректно.
Для того чтобы ваша обработка по установке цен работала стабильно, придерживайтесь следующих правил:
1. Контроль статуса документа. Чтобы цены реально начали действовать и "подтягиваться" в документы продажи, статус должен быть установлен в Установлен или Согласован (в зависимости от настроек системы). Если оставить документ в статусе Не согласован, записи в регистры не попадут.
2. Работа с характеристиками. Посмотрим на ситуацию: если в системе включен учет по характеристикам, но вы не заполняете поле Характеристика в документе, цена установится на "пустую" характеристику. Это значит, что при выборе конкретного размера или цвета в заказе цена не определится автоматически.
3. Производительность. Если вам нужно установить цены для 100 000 товаров, не пытайтесь запихнуть их все в один документ. Оптимально разбивать данные на пакеты по 1000–2000 строк в одном документе. Это снизит нагрузку на транзакции и позволит избежать блокировок базы данных.
4. Использование типовых механизмов. Рассмотрим альтернативу — загрузку через Excel. В типовой УТ 11 уже есть мощный механизм Загрузить из внешнего файла. Прежде чем писать свой код, убедитесь, что стандартная обработка не решает вашу задачу быстрее и надежнее.
Подводя итог: программная установка цен в УТ 11 — это всегда создание документа. Основное внимание стоит уделять уникальности строк в табличной части и правильному заполнению статусов и видов цен. Это обеспечит корректную работу всей системы торгового учета.