При реализации механизмов интеграции и загрузки данных из внешних текстовых файлов разработчики часто сталкиваются с ошибками разбора строковых данных и поиска ссылочных элементов. Рассмотрим типичную ситуацию, когда при попытке заполнить реквизит документа возникает ошибка «Значение не является значением объектного типа (ссылка)», выясним причины ее возникновения и разберем по шагам правильные способы восстановления документа.
Проанализируем проблемную строку, на которой прерывается выполнение алгоритма:
Элемент = Справочники[ПолноеИмяСпр].НайтиПоКоду(КодЗначения).Ссылка;
Исключение времени выполнения обусловлено сразу несколькими факторами платформы 1С:Предприятие:
НайтиПоКоду() возвращает готовую ссылку типа СправочникСсылка.<ИмяСправочника>. Обращение через точку к свойству Ссылка является избыточным.НайтиПоКоду() возвращает Неопределено. Попытка обратиться к свойству .Ссылка у значения Неопределено немедленно вызывает ошибку «Значение не является значением объектного типа».Автор=Абдулов Юрий Владимирович#Пользователи значением является ФИО пользователя, то есть наименование, а не числовой или строковый код. Поиск наименования через НайтиПоКоду() заведомо возвращает Неопределено. Для таких реквизитов требуется вызов НайтиПоНаименованию().Разберем, как правильно организовать поиск элементов справочника с проверкой результата. Избавимся от лишнего обращения к .Ссылка и добавим проверку на корректность найденного значения:
МенеджерСправочника = Справочники[ПолноеИмяСпр];
// Ищем элемент по наименованию или по коду в зависимости от формата данных
ЭлементСсылка = МенеджерСправочника.НайтиПоНаименованию(КодЗначения);
Если Не ЗначениеЗаполнено(ЭлементСсылка) Тогда
// Если по наименованию не найден, пробуем найти по коду
ЭлементСсылка = МенеджерСправочника.НайтиПоКоду(КодЗначения);
КонецЕсли;
Если ЗначениеЗаполнено(ЭлементСсылка) Тогда
НовыйДокумент[Шреквизит.Имя] = ЭлементСсылка;
Иначе
// Обрабатываем ситуацию, когда элемент не найден в базе
ЗаписьЖурналаРегистрации("ЗагрузкаДокумента", УровеньЖурналаРегистрации.Предупреждение, , , "Не найден элемент: " + КодЗначения);
КонецЕсли;
Помимо ошибки поиска ссылок, в исходном коде парсера присутствует ряд критических недочетов, которые приводят к сбоям при разборе документа. Проанализируем их:
ТабличныеЧасти;Запасы|ДатаОтгрузки=.... При этом в алгоритме выполняется поиск одинарной кавычки (РазделительТЧ = Найти(Стр, "'")). Функция не находит разделитель, возвращает 0, и вычисление позиций через Сред() падает с ошибкой неверной длины подстроки. Для разделителя ТЧ необходимо искать символ "|"."#" отделяет имя справочника (#Пользователи, #БанковскиеСчета), а разделитель "&" вовсе отсутствует. В коде же символ "#" жестко привязан к обращению к коллекции Перечисления. Необходимо согласовать формат файла и кода либо проверять принадлежность имени к метаданным: Метаданные.Справочники.Найти(ИмяОбъекта) или Метаданные.Перечисления.Найти(ИмяОбъекта).Дата(ДатаДокумента) со строкой вида "20.04.2022 0:00:00" вызывает ошибку. Конструктор Дата() принимает строки только в каноническом представлении вида "ГГГГММДДЧЧММСС". Для даты пользовательского формата требуется предварительный разбор подстрок (день, месяц, год).Если НаименованиеРТЧ = "Номенклатура". Однако в файле первой строкой ТЧ идет реквизит ДатаОтгрузки. В итоге переменная НоваяСтрока не инициализируется, и обращение к ней приводит к ошибке. Новую строку следует добавлять при изменении номера строки или явном маркере начала позиции.Документы[Имя].СоздатьДокумент() объект существует только в оперативной памяти. В конце процедуры обязательно должен вызываться метод НовыйДокумент.Записать().Разбор нестандартных текстовых форматов вручную через строковые функции Найти(), Лев() и Сред() крайне ненадежен и чувствителен к любым изменениям структуры данных. Рассмотрим более надежные стандартные механизмы 1С для выгрузки и загрузки документов:
СериализаторXDTO.ПрочитатьXML() и СериализаторXDTO.ЗаписатьXML() автоматически сохраняет и восстанавливает структуру документа, табличные части и точные типы данных без необходимости ручного приведения типов и разбора строк.УникальныйИдентификатор. Восстановление ссылки через Справочники[Имя].ПолучитьСсылку(Новый УникальныйИдентификатор(СтрокаUUID)) гарантирует однозначное сопоставление объектов и исключает дублирование.