Программное создание документов в 1С — это базовая задача для любого разработчика, однако работа с документом УстановкаЦенНоменклатуры имеет свои нюансы. Часто начинающие программисты сталкиваются с тем, что документ создается, но остается пустым, либо не проводится, выдавая неясные ошибки. В этой статье мы подробно разберем, как правильно инициализировать документ, заполнить его табличную часть и избежать типичных ловушек при работе с типами данных.
Рассмотрим ситуацию, с которой часто начинаются проблемы. Программист создает новый объект документа и пытается обойти его табличную часть циклом, чтобы заполнить данные. Проанализируем, почему этот подход ошибочен:
СсылкаДок = Документы.УстановкаЦенНоменклатуры.СоздатьДокумент();
СсылкаДок.Дата = ТекущаяДата();
ТЧТовары = СсылкаДок.Товары;
// ОШИБКА: ТЧТовары в новом документе пуста!
Для каждого СтрокаДок из ТЧТовары Цикл
СтрокаДок = ТЧТовары.Добавить();
// ... заполнение реквизитов ...
КонецЦикла;
Выясним причину: когда мы вызываем метод СоздатьДокумент(), платформа генерирует в оперативной памяти объект с пустыми табличными частями. Коллекция ТЧТовары не содержит ни одной строки. Следовательно, цикл Для каждого не совершит ни одной итерации, и код внутри него просто не выполнится. Важное правило: для заполнения нового документа мы всегда используем метод Добавить() без всяких предварительных циклов по этой же таблице.
Рассмотрим, как правильно организовать процесс добавления номенклатуры и установки цен. Вместо цикла мы должны явно вызвать создание новой строки. Посмотрим на корректный пример кода:
// Создаем объект документа
ДокОбъект = Документы.УстановкаЦенНоменклатуры.СоздатьДокумент();
ДокОбъект.Дата = ТекущаяДата();
// Обращаемся к табличной части
НоваяСтрока = ДокОбъект.Товары.Добавить();
// Заполняем реквизиты строки
НоваяСтрока.Номенклатура = Справочники.Номенклатура.НайтиПоНаименованию("Товар");
НоваяСтрока.Цена = 99; // Обратите внимание: передаем ЧИСЛО
НоваяСтрока.Валюта = Справочники.Валюты.НайтиПоКоду("643"); // Рубли
В этом примере НоваяСтрока является объектом типа ДанныеФормыСтруктура (если работаем на форме) или СтрокаТабличнойЧасти (в серверном коде). Теперь все присвоенные значения гарантированно попадут в объект документа.
Проанализируем еще одну частую ошибку — использование кавычек при установке цены: СтрокаДок.Цена = "99". В языке 1С типизация реквизитов объектов метаданных жестко определена в конфигураторе. Если для поля «Цена» установлен тип Число, передача строки может привести к следующим последствиям:
Совет: Всегда передавайте числовые значения как числа, а даты — как объекты типа Дата. Не полагайтесь на автоматическое приведение типов.
Когда документ заполнен, его необходимо сохранить в базе данных. Разберем разницу между записью и проведением. В коде автора встречалась странная конструкция: СтрокаДок.Записать(РежимЗаписиДокумента.Проведение). Это грубая ошибка, так как метод Записать() существует только у объекта документа целиком, но не у отдельной строки табличной части.
Рассмотрим правильный подход к записи с использованием обработки исключений:
Попытка
// Пытаемся сразу провести документ
ДокОбъект.Записать(РежимЗаписиДокумента.Проведение);
Сообщить("Документ успешно проведен: " + ДокОбъект.Ссылка);
Исключение
// Если проведение не удалось, просто записываем (сохраняем черновик)
ДокОбъект.Записать(РежимЗаписиДокумента.Запись);
Сообщить("Документ только записан. Причина: " + ОписаниеОшибки());
КонецПопытки;
Функция ОписаниеОшибки() крайне важна: она подскажет, какой именно обязательный реквизит вы забыли заполнить (например, «Статус», «Ответственный» или «Подразделение»).
Использование метода НайтиПоНаименованию() в программном коде считается «плохим тоном» и потенциальным источником багов. Если пользователь переименует товар или тип цен в интерфейсе, ваш код перестанет работать.
Проанализируем альтернативы:
НайтиПоКоду() или НайтиПоРеквизиту("Артикул", ...).Справочники.Валюты.Рубль.Если вы работаете в современных решениях на платформе 8.3, структура документа УстановкаЦенНоменклатуры значительно сложнее, чем в старой «Управлении торговлей 10.3». В новых версиях данные цен часто распределены по нескольким табличным частям, где одна таблица хранит товары, а другая — виды цен и их значения, связанные через индексы.
В таких случаях рекомендуется использовать не прямое заполнение ТЧ объекта, а вызов программного интерфейса (API), который предоставляется разработчиками конфигурации (например, методы в модуле менеджера документа). Это гарантирует, что все скрытые реквизиты и связанные регистры будут заполнены корректно.