При разработке на платформе 1С:Предприятие 8.3 программисты нередко сталкиваются с ситуацией: код написан, процедура выполняется без видимых ошибок, но новый документ так и не появляется в списке. Эта проблема особенно актуальна для управляемых форм, где взаимодействие между клиентом и сервером имеет свои строгие правила.
В этой статье мы подробно разберем, почему обработка может «молчать» и не создавать документы, проанализируем типичные ошибки в коде и выясним, как правильно организовать запись объектов в базу данных.
Рассмотрим фрагмент кода, который часто становится причиной остановки выполнения программы. Одной из критических ошибок в примере автора является попытка обращения к свойству номера, которого не существует в контексте объекта.
НовыйДокумент.Номер.Автонумерация = Истина;
Проанализируем этот момент. В языке 1С свойство Номер у документа является обычной строкой. У строки не может быть подчиненного свойства Автонумерация. Сама настройка автонумерации задается в конфигураторе для всего типа документа. Если же вам нужно, чтобы система назначила номер программно прямо сейчас, следует использовать метод УстановитьНовыйНомер().
Важный нюанс: если код натыкается на обращение к несуществующему свойству (как в случае с Номер.Автонумерация), выполнение процедуры прерывается. Если это происходит на сервере без надлежащей обработки исключений, пользователь может даже не увидеть сообщения об ошибке, а документ просто не дойдет до стадии выполнения метода Записать().
Одной из главных причин, по которой код «не срабатывает», является неправильная привязка команды к кнопке на форме. В управляемом приложении работа распределена между Клиентом (тонкий клиент, веб-клиент) и Сервером (сервер приложений 1С).
Разберем, как правильно организовать вызов:
&НаКлиенте.&НаСервере или &НаСервереБезКонтекста).ДокументыМенеджер и ДокументОбъект доступна только там.Посмотрим на правильную структуру вызова:
&НаКлиенте
Процедура КомандаСоздатьДокумент(Команда)
// Вызываем серверную часть для работы с базой данных
СоздатьДокументНаСервере();
Сообщить("Операция завершена");
КонецПроцедуры
&НаСервере
Процедура СоздатьДокументНаСервере()
НовыйДокумент = Документы.СписаниеПросрочки.СоздатьДокумент();
// ... заполнение реквизитов ...
НовыйДокумент.Записать(РежимЗаписиДокумента.Запись);
КонецПроцедуры
Если назначить серверную процедуру напрямую на действие кнопки, это может привести к нестабильному поведению формы и трудностям при отладке. Платформа 1С рекомендует соблюдать цепочку Команда -> Клиент -> Сервер.
Выясним причину, по которой метод Записать() может не создавать объект. Автор темы пытался использовать режим оперативного проведения:
НовыйДокумент.Записать(РежимЗаписиДокумента.Проведение, РежимПроведенияДокумента.Оперативный);
Рассмотрим, какие опасности здесь таятся:
Записать() с параметром Проведение запускает целую цепочку событий: ПередЗаписью, ПриЗаписи, ОбработкаПроведения. Если в любом из этих модулей (или в подписках на события) сработает условие Отказ = Истина, вся транзакция откатится. В итоге в базе данных не останется даже черновика документа.Дата) хотя бы на секунду отличается от текущего времени сервера в меньшую сторону, система может заблокировать запись.Совет: При программном создании документов для диагностики всегда пробуйте сначала просто записать объект: НовыйДокумент.Записать(РежимЗаписиДокумента.Запись). Если документ появился в списке как «непроведенный», значит, проблема кроется в логике проведения (нехватка остатков, отсутствие прав, ошибки в модуле проведения), а не в самом коде создания.
Проанализируем ситуацию с заполнением реквизитов. В коде часто используются методы поиска:
НовыйДокумент.Склад = Справочники.Склады.НайтиПоНаименованию("Основной");
НовыйДокумент.Товары[0].Номенклатура = Справочники.Номенклатура.НайтиПоКоду("000000001");
Методы НайтиПоНаименованию и НайтиПоКоду коварны. Если объект не найден (например, склад переименовали или в коде номенклатуры лишний ноль), метод вернет пустую ссылку. 1С позволяет записать документ с пустой ссылкой, но если этот реквизит критичен для проведения (например, склад в документе списания), то попытка проведения завершится ошибкой, и документ не будет создан (транзакция откатится).
Всегда проверяйте результат поиска перед использованием:
СкладОбъект = Справочники.Склады.НайтиПоНаименованию("Основной");
Если СкладОбъект.Пустая() Тогда
Сообщить("Внимание: Склад 'Основной' не найден в справочнике!");
Возврат;
КонецЕсли;
НовыйДокумент.Склад = СкладОбъект;
Если документ не создается, а код кажется верным, воспользуемся инструментами платформы.
Откройте Журнал регистрации (Меню - Администрирование - Журнал регистрации). Установите фильтр по событию «Данные -> Ошибка выполнения». Если документ не записался из-за ошибки в модуле объекта, информация об этом обязательно там появится. Часто там можно встретить сообщения вида «Поле 'Склад' не заполнено» или «Ошибка в строке 45 модуля документа...».
Поставим точку останова на строке НовыйДокумент.Записать(). Когда программа остановится, выполним следующие шаги:
НовыйДокумент.ПроверитьЗаполнение(). Если функция возвращает Ложь, значит, не все обязательные поля заполнены.НовыйДокумент.Товары.Количество() > 0.ПередЗаписью в модуле документа.Таким образом, создание документа — это процесс, требующий не только правильного заполнения полей, но и соблюдения архитектурных правил платформы 1С. Исправив вызов с клиента на сервер, удалив ошибочные обращения к свойствам и добавив проверки на пустые ссылки, мы гарантируем стабильную работу нашей обработки.