При разработке внешних обработок для облачного сервиса 1С:Фреш программисты часто сталкиваются с ситуацией, когда код, идеально работающий в локальной файловой базе, полностью отказывает в работе после публикации в облаке. Одной из самых распространенных ошибок является Переменная не определена (ТипУзлаXML). В этой статье мы разберем, почему это происходит, и как правильно спроектировать загрузку XML-файлов, чтобы она соответствовала требованиям безопасности и архитектуры веб-клиента.
Проанализируем контекст исполнения кода. В среде 1С:Фреш пользователи чаще всего работают через веб-клиент (браузер) или тонкий клиент. Системное перечисление ТипУзлаXML, которое необходимо для определения того, является ли текущий узел началом элемента, текстом или концом элемента, имеет ограниченную область видимости. Согласно синтакс-помощнику, этот объект доступен только на сервере, в толстом клиенте или во внешнем соединении.
Когда вы запускаете процедуру разбора XML под директивой &НаКлиенте, веб-клиент просто «не знает» о существовании этого типа. Рассмотрим типичный ошибочный код, который приводит к сбою:
&НаКлиенте
Процедура ПрочитатьФайл_XML()
ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.ОткрытьФайл(Объект.ПутьКФайлу);
Пока ЧтениеXML.Прочитать() Цикл
// ОШИБКА: ТипУзлаXML недоступен на клиенте в веб-интерфейсе
Если ЧтениеXML.ТипУзла = ТипУзлаXML.НачалоЭлемента Тогда
// Логика обработки
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Вторая серьезная проблема, на которую указывает аудит 1С:Фреш, — это невозможность прямой работы с локальными файлами на сервере. В клиент-серверном варианте (которым и является Фреш) сервер и клиент физически находятся на разных компьютерах. Сервер 1С не имеет доступа к вашему диску C:\. Чтобы сервер смог прочитать XML, файл должен быть сначала передан в специальное Временное хранилище.
Для успешной работы нам необходимо реализовать трехэтапную схему:
ЧтениеXML и ТипУзлаXML, должна выполняться строго в процедуре &НаСервере.Современные стандарты платформы 1С:Предприятие 8.3 требуют использования асинхронных вызовов для работы с файлами. Это гарантирует, что интерфейс браузера не «зависнет» во время загрузки. Рассмотрим, как реализовать выбор файла и его отправку на сервер:
&НаКлиенте
Процедура ВыполнитьЗагрузку(Команда)
// Описываем параметры выбора файла
ПараметрыЗагрузки = Новый ПараметрыПередачиФайлаНаСервер;
// Используем асинхронный метод для помещения файла в хранилище
НачатьПомещениеФайлаНаСервер(Новый ОписаниеОповещения("ПослеПомещенияФайла", ЭтотОбъект), , , , ПараметрыЗагрузки);
КонецПроцедуры
&НаКлиенте
Процедура ПослеПомещенияФайла(Результат, ДополнительныеПараметры) Экспорт
Если Результат <> Неопределено Тогда
// Файл успешно загружен в хранилище, адрес находится в Результат.Адрес
ПрочитатьФайлНаСервере(Результат.Адрес);
ПоказатьПредупреждение(, "Загрузка завершена!");
КонецЕсли;
КонецПроцедуры
Теперь разберем, что происходит на стороне сервера. Мы получаем адрес во временном хранилище, создаем временный файл на диске сервера и спокойно используем все возможности объекта ЧтениеXML, так как на сервере ТипУзлаXML доступен без ограничений.
&НаСервере
Процедура ПрочитатьФайлНаСервере(АдресХранилища)
// Получаем уникальное имя временного файла на сервере
ИмяВременногоФайла = ПолучитьИмяВременногоФайла("xml");
// Извлекаем данные из хранилища и записываем в файл на сервере
ДанныеИзХранилища = ПолучитьИзВременногоХранилища(АдресХранилища);
ДанныеИзХранилища.Записать(ИмяВременногоФайла);
ЧтениеXML = Новый ЧтениеXML;
Попытка
ЧтениеXML.ОткрытьФайл(ИмяВременногоФайла);
Пока ЧтениеXML.Прочитать() Цикл
// Здесь ТипУзлаXML работает корректно!
Если ЧтениеXML.ТипУзла = ТипУзлаXML.НачалоЭлемента Тогда
ИмяУзла = ЧтениеXML.Имя;
// Ваша логика разбора
ИначеЕсли ЧтениеXML.ТипУзла = ТипУзлаXML.Текст Тогда
Значение = ЧтениеXML.Значение;
// Сохранение данных в базу
КонецЕсли;
КонецЦикла;
ЧтениеXML.Закрыть();
Исключение
ОбщегоНазначенияКлиентСервер.СообщитьПользователю("Ошибка чтения файла: " + ОписаниеОшибки());
КонецПопытки;
// Не забываем удалять временный файл после работы
УдалитьФайлы(ИмяВременногоФайла);
КонецПроцедуры
Чтобы ваша обработка успешно прошла аудит в сервисе 1С:Фреш, необходимо правильно заполнить функцию СведенияОВнешнейОбработке. Поскольку мы используем временные файлы на стороне сервера, нам нужно явно запросить разрешение на использование каталога временных файлов. В противном случае система безопасности (безопасный режим) заблокирует создание файла.
Проанализируем структуру формирования разрешений:
Функция СведенияОВнешнейОбработке() Экспорт
ПараметрыРегистрации = ДополнительныеОтчетыИОбработки.СведенияОВнешнейОбработке("2.2.2.1");
// ... заполнение основных параметров ...
// Запрашиваем разрешения
Разрешения = Новый Массив;
// Важно: разрешение на работу с временными файлами
Разрешения.Добавить(РаботаВБезопасномРежиме.РазрешениеНаИспользованиеКаталогаВременныхФайлов());
ПараметрыРегистрации.Вставить("Разрешения", Разрешения);
Возврат ПараметрыРегистрации;
КонецФункции
Разберем основные правила, которые мы вывели для стабильной работы загрузки во Фреше:
Во-первых, никогда не используйте ТипУзлаXML на клиенте. Переносите всю логику парсинга в серверный модуль или серверную процедуру формы.
Во-вторых, забудьте о прямых путях к файлам типа C:\MyFiles\data.xml. В облаке файл сначала «летит» в хранилище, а затем «приземляется» во временную папку сервера.
В-третьих, используйте асинхронные методы (НачатьПомещениеФайлаНаСервер), чтобы соответствовать современным требованиям платформы и обеспечивать комфортную работу пользователя в браузере.
Соблюдение этих рекомендаций не только решит проблему с ошибкой Переменная не определена, но и позволит вашей обработке легко проходить технический аудит сервиса 1С:Фреш.