Почему не записывается партия номенклатуры при программном создании в 1С?

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

Приветствуем вас! Довольно часто при разработке интеграций, загрузок из внешних систем или автоматизации складских процессов в 1С программистам приходится сталкиваться с необходимостью программного создания элементов справочников. Одним из таких важных объектов является справочник ПартииНоменклатуры, который активно используется в конфигурациях «1С:Управление нашей фирмой» (УНФ) и «1С:Розница».

Казалось бы, задача проста: создать новый элемент, заполнить ключевые реквизиты, такие как наименование и владелец, и записать его в базу данных. Однако на практике разработчики нередко сталкиваются с ситуацией, когда код уходит в блок Исключение, не выдавая явных ошибок, а элемент в базе так и не появляется. В этой статье мы подробно разберем, почему возникает эта проблема, как правильно её локализовать и какие стандарты разработки 1С необходимо соблюдать для написания надежного кода.

Проблема избыточного использования конструкции Попытка...Исключение

Рассмотрим типичный пример кода, с которым часто начинают работу специалисты при создании партий:


&НаСервере
Процедура Расш1_СоздатьПартииПослеНаСервере()
    Для каждого Строка из Объект.Продукция цикл
        Партия = Справочники.ПартииНоменклатуры.СоздатьЭлемент();
        Партия.Наименование = Строка(Строка.Количество) + " м/п";
        Партия.Владелец = Строка.Номенклатура;
        Попытка
            Партия.Записать();
        Исключение    
            Сообщить("Партия не записалась");
        КонецПопытки;
        Строка.Партия = Партия.Ссылка;
    КонецЦикла;
КонецПроцедуры

Проанализируем эту ситуацию. С одной стороны, разработчик обезопасил транзакцию от аварийного завершения работы программы. С другой стороны, конструкция Попытка...Исключение полностью скрыла от нас системное сообщение платформы. В случае ошибки мы видим лишь сухой и малоинформативный текст «Партия не записалась».

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

Выясняем причину: обязательный реквизит «Статус»

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

Этот реквизит имеет тип данных ПеречислениеСсылка.СтатусыПартий. Если он не заполнен, платформа на уровне объектной техники (или в модуле объекта в процедурах ПередЗаписью / ПриЗаписи) блокирует транзакцию.

Давайте разберем по шагам, какие значения может принимать статус партии:

  1. Собственные запасы (Перечисления.СтатусыПартий.СобственныеЗапасы) — используется для обычного учета товаров, принадлежащих организации.
  2. Товары на комиссии (Перечисления.СтатусыПартий.ТоварыНаКомиссии) — применяется при реализации комиссионных товаров.
  3. Ответственное хранение (Перечисления.СтатусыПартий.ОтветственноеХранение) — используется для ТМЦ, принятых на склад под отчет.
  4. Давальческое сырье (Перечисления.СтатусыПартий.ДавальческоеСырье) — для переработки материалов заказчика.

Для исправления ошибки нам обязательно нужно явно инициализировать этот реквизит перед вызовом метода записи:


Партия.Статус = Перечисления.СтатусыПартий.СобственныеЗапасы; // Либо иной статус в зависимости от вашей бизнес-логики

Дополнительные реквизиты и настройки партионного учета

Помимо статуса, при работе со справочником партий следует обратить внимание на следующие нюансы:

Лучшие практики написания кода и обработки ошибок в 1С

Использование слепого блока Попытка...Исключение при записи бизнес-объектов в свою же базу данных считается плохим тоном разработки. Платформа 1С предоставляет более изящные и правильные способы контроля данных.

1. Использование метода ПроверитьЗаполнение()

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


Если Партия.ПроверитьЗаполнение() Тогда
    Партия.Записать();
    Строка.Партия = Партия.Ссылка;
Иначе
    // Платформа автоматически выведет пользователю сообщения о том, какие реквизиты не заполнены
КонецЕсли;

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

2. Правильная структура блока Исключение

Если специфика алгоритма все же требует обязательного использования блока Попытка (например, запись происходит в транзакции или при импорте данных из внешних файлов), никогда не оставляйте блок Исключение пустым или с неинформативными сообщениями. Обязательно логируйте технические подробности сбоя.

В современных версиях платформы 1С:Предприятие 8.3 для этого используются функции ИнформацияОбОшибке(), ПодробноеПредставлениеОшибки() и КраткоеПредставлениеОшибки().

Давайте посмотрим на пример правильной обработки исключения при записи объекта:


Попытка
    Партия.Записать();
    Строка.Партия = Партия.Ссылка;
Исключение
    ИнфоОбОшибке = ИнформацияОбОшибке();
    
    // 1. Записываем подробную информацию в Журнал регистрации для администратора и программиста
    ЗаписатьЖурналРегистрации("ПрограммноеСозданиеПартий", 
                              УровеньЖурналаРегистрации.Ошибка, 
                              , 
                              , 
                              ПодробноеПредставлениеОшибки(ИнфоОбОшибке));
                              
    // 2. Выводим понятное и безопасное сообщение для конечного пользователя
    ТекстОшибкиДляПользователя = КраткоеПредставлениеОшибки(ИнфоОбОшибке);
    ОбщегоНазначенияКлиентСервер.СообщитьПользователю(
        NStr("ru = 'Не удалось записать партию. Причина: '") + ТекстОшибкиДляПользователя);
КонецПопытки;

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

Итоговый правильный вариант функции создания партий

Объединив все полученные знания, перепишем исходную процедуру автора темы в соответствии со стандартами разработки «1С:Предприятие»:


&НаСервере
Процедура Расш1_СоздатьПартииПослеНаСервере()
    
    Для каждого Строка из Объект.Продукция цикл
        
        Партия = Справочники.ПартииНоменклатуры.СоздатьЭлемент();
        Партия.Наименование = Строка(Строка.Количество) + " м/п";
        Партия.Владелец = Строка.Номенклатура;
        
        // Обязательно заполняем статус партии!
        Партия.Статус = Перечисления.СтатусыПартий.СобственныеЗапасы;
        
        // Выполняем проверку и запись
        Если Партия.ПроверитьЗаполнение() Тогда
            Попытка
                Партия.Записать();
                Строка.Партия = Партия.Ссылка;
            Исключение
                ИнфоОбОшибке = ИнформацияОбОшибке();
                ЗаписатьЖурналРегистрации("СозданиеПартии", 
                                          УровеньЖурналаРегистрации.Ошибка, 
                                          Партия.Метаданные(), 
                                          , 
                                          ПодробноеПредставлениеОшибки(ИнфоОбОшибке));
                
                ВызватьИсключение NStr("ru = 'Ошибка записи партии номенклатуры. Подробности записаны в Журнал регистрации.'");
            КонецПопытки;
        КонецЕсли;
        
    КонецЦикла;
    
КонецПроцедуры

Применяя данные подходы, вы убережете свои базы данных от некорректно заполненных данных, а код сделаете прозрачным, расширяемым и легким в поддержке. Желаем вам успешной разработки в среде 1С!

← На главную