При написании процедур загрузки данных или обработок создания документов разработчики часто сталкиваются с ошибкой синтаксического контроля: «Обнаружено логическое завершение исходного текста модуля КонецПопытки<<?>> (Проверка: Сервер)». При этом сама конструкция Попытка ... Исключение ... КонецПопытки визуально оформлена правильно, а точка с запятой на месте. Разберем по шагам, почему возникает эта ошибка, как синтаксический анализатор платформы 1С обрабатывает модуль и как правильно организовать загрузку и запись объектов.
Синтаксический анализатор платформы 1С:Предприятие разбирает исходный код последовательно сверху вниз. Когда в коде выше блока обработки исключений присутствуют грубые синтаксические нарушения, парсер теряет контекст дерева разбора. В результате реальная ошибка находится в одном месте, а платформенная диагностика указывает на закрывающие операторы структуры (КонецПопытки, КонецЦикла или КонецПроцедуры).
Проанализируем основные причины такого поведения:
Документ.ДатаДокумента = ; или Документ.РучнаяКорректировка = ;, компилятор ожидает выражение справа от знака равенства. Пропуская синтаксический мусор, платформа сбивается со стека блоков и выдает ошибку о завершении модуля на первой встретившейся закрывающей конструкции.Попытка, Исключение или КонецПопытки часть букв набрана на английской раскладке (например, латинские «C», «e», «o», «p», «a»), платформа воспринимает их как имена переменных, нарушая парность открывающих и закрывающих операторов.0xA0), которые синтаксический анализатор не может обработать корректно.#КонецЕсли после условий компиляции (#Если Сервер Тогда) также приводит к внезапному логическому завершению модуля.Когда указатель ошибки указывает на синтаксически верную строку КонецПопытки;, применим проверенную методику изоляции проблемных участков кода:
Попытка и проверим модуль заново. Если синтаксический контроль прошел успешно, раскомментируем фрагменты по очереди, отслеживая появление ошибки.Неопределено или ТекущаяДата()).Посмотрим на пример ошибочного кода, приводящего к сбою парсера:
Для Счетчик = 1 По ВсегоСтрок Цикл
Документ = Документы.АЭ_ЗаймПредоставленный.СоздатьДокумент();
// Ошибочные строки: пустое значение справа от знака равенства
Документ.ДатаДокумента = ;
Документ.РучнаяКорректировка = ;
Документ.ДатаНачала = ;
Попытка
Документ.Записать();
Исключение
// Обработка ошибки
КонецПопытки;
КонецЦикла;
Исправим данный фрагмент, указав корректные значения по умолчанию:
Для Счетчик = 1 По ВсегоСтрок Цикл
Документ = Документы.АЭ_ЗаймПредоставленный.СоздатьДокумент();
// Корректное заполнение реквизитов
Документ.ДатаДокумента = ТекущаяДата();
Документ.РучнаяКорректировка = Ложь;
Документ.ДатаНачала = НачалоДня(ТекущаяДата());
Попытка
Документ.Записать(РежимЗаписиДокумента.Запись);
Исключение
// Корректная обработка исключения
КонецПопытки;
КонецЦикла;
При записи нового объекта в блоке Попытка ... Исключение важно учитывать специфику работы с объектом СообщениеПользователю. До момента успешной первой записи ссылка на новый документ в базе данных отсутствует (метод Документ.Ссылка возвращает пустую ссылку неинициализированного объекта). Поэтому свойство КлючДанных в блоке Исключение привязывать к не записанному объекту бессмысленно.
Также для формирования подробной информации об ошибке рекомендуется использовать современные платформенные функции КраткоеПредставлениеОшибки() и ПодробноеПредставлениеОшибки() в связке с ИнформацияОбОшибке().
Рассмотрим правильный шаблон перехвата ошибок при создании документов:
Попытка
Документ.Записать(РежимЗаписиДокумента.Запись);
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = СтрШаблон("%1. Документ %2 от %3 успешно создан.", Счетчик, Документ.Номер, Формат(Документ.Дата, "ДФ=dd.MM.yyyy"));
Сообщение.КлючДанных = Документ.Ссылка;
Сообщение.Сообщить();
Исключение
ИнфоОбОшибке = ИнформацияОбОшибке();
ТекстОшибки = КраткоеПредставлениеОшибки(ИнфоОбОшибке);
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = СтрШаблон("%1. Документ %2 не удалось записать. Причина: %3", Счетчик, Документ.Номер, ТекстОшибки);
Сообщение.Сообщить();
КонецПопытки;
При написании обработок загрузки частой ошибкой начинающих разработчиков является поиск ссылочных реквизитов методами НайтиПоНаименованию() и НайтиПоНомеру() внутри тела цикла. Это создает избыточные запросы к СУБД на каждую строчку, что катастрофически замедляет загрузку.
Для оптимизации процесса загрузки рекомендуется применять следующие подходы:
Соответствие, где ключом выступает наименование или код, а значением — ссылка на элемент.ЗаполнитьЗначенияСвойств(). При совпадении имен реквизитов документа и колонок источника использовать метод ЗаполнитьЗначенияСвойств(Документ, СтрокаИсточника) вместо десятков явных строчек присваивания.