Почему обработка не создает документ в 1С и как это исправить

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

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

Разбор архитектурной ошибки: Клиент-серверное взаимодействие

Первое, на что мы должны обратить внимание — это препроцессоры и контекст выполнения кода. В исходном сообщении автор использует директиву &НаСервере для процедуры Просрочка(Команда). Рассмотрим, почему это критично. В 1С команды формы (кнопки) по умолчанию должны иметь обработчик &НаКлиенте. Если вы вручную изменили &НаКлиенте на &НаСервере в коде, платформа может потерять визуальную связь между кнопкой на форме и программным методом. В результате при нажатии на кнопку просто ничего не происходит, так как событие «нажатие» ожидает клиентскую процедуру.

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


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

&НаСервере
Процедура СоздатьДокументНаСервере()
    // Здесь будет основной код создания документа
КонецПроцедуры

Исправление синтаксических ошибок в коде

Проанализируем детально код создания объекта. В тексте автора присутствует строка: НовД.Номер.Автонумерация = Истина;. Это распространенная ошибка. Свойство Автонумерация является свойством объекта метаданных в конфигураторе, а не свойством конкретного экземпляра документа в оперативной памяти. У объекта типа ДокументОбъект нет свойства Номер.Автонумерация.

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

  1. Создаем новый объект через Документы.ИмяДокумента.СоздатьДокумент().
  2. Устанавливаем дату документа (важно для определения периода нумерации).
  3. Вызываем метод УстановитьНовыйНомер().
  4. Заполняем реквизиты и табличные части.
  5. Записываем объект.

Проблема поиска ссылок и заполнения реквизитов

Еще один важный момент, который мы должны рассмотреть — это методы поиска НайтиПоНаименованию и НайтиПоКоду. Если в справочнике не будет найден склад «Основной» или номенклатура с указанным кодом, методы вернут ПустаяСсылка. Если в самом документе «СписаниеПросрочки» для этих полей стоит проверка на заполнение, то метод НовД.Записать() не сработает, и документ не будет создан. При этом система не выдаст никакой ошибки в интерфейс, если код выполняется на сервере без обработки исключений.

Также проанализируем поиск партии: Документы.Поступление.НайтиПоНомеру("000000001"). Метод НайтиПоНомеру крайне чувствителен к дате. Без указания второго параметра (даты или периода) поиск может вернуть пустую ссылку, если в базе несколько документов с таким номером за разные годы, или не найти вовсе. Мы рекомендуем всегда проверять результат поиска на Пустая() перед присвоением значения реквизиту.

Применение блока Попытка...Исключение

Для того чтобы понять, почему запись не проходит (например, из-за нехватки прав, блокировок или ошибок в модуле самого документа), необходимо обернуть вызов метода Записать() в блок обработки ошибок. Рассмотрим, как это сделать правильно:


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

Итоговый корректный вариант кода

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


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

    // Работа с табличной частью
    СтрокаТЧ = НовД.Товары.Добавить();
    
    // Безопасный поиск номенклатуры
    СсылкаНоменклатура = Справочники.Номенклатура.НайтиПоКоду("000000001");
    Если СсылкаНоменклатура.Пустая() Тогда
        Сообщить("Внимание: Номенклатура с кодом 000000001 не найдена!");
    КонецЕсли;
    
    СтрокаТЧ.Номенклатура = СсылкаНоменклатура;
    СтрокаТЧ.Количество = 1;
    СтрокаТЧ.ЦенаЗакупки = 5;
    СтрокаТЧ.Сумма = СтрокаТЧ.ЦенаЗакупки * СтрокаТЧ.Количество;
    
    // Запись с обработкой ошибок
    Попытка
        НовД.Записать(РежимЗаписиДокумента.Запись);
    Исключение
        ОбщегоНазначенияКлиентСервер.СообщитьПользователю("Ошибка при сохранении: " + ОписаниеОшибки());
    КонецПопытки;

КонецПроцедуры

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

Во-первых, помните о транзакциях. Метод Записать() запускает целую цепочку событий: ПередЗаписью, ПриЗаписи (в модуле документа), а также подписки на события. Если в любом из этих мест код установит Отказ = Истина, ваш документ не запишется.

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


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

&НаСервере
Функция СоздатьДокументНаСервере()
    // ... код создания ...
    НовД.Записать();
    Возврат НовД.Ссылка;
КонецФункции

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

← На главную