Разработка под мобильную платформу 1С:Предприятие всегда сопряжена с определенными нюансами, которые не всегда очевидны из синтакс-помощника. Одной из таких проблем является чтение внешних файлов табличных документов (форматов .xls и .xlsx) непосредственно на мобильном устройстве. Несмотря на то, что документация заявляет поддержку метода Прочитать() для мобильного сервера, на практике разработчики часто сталкиваются с «Ошибкой при выполнении файловой операции».
В этой статье мы подробно разберем, почему стандартный подход может не работать, проанализируем ограничения мобильной платформы и рассмотрим рабочие обходные пути для решения этой задачи.
Рассмотрим стандартную ситуацию: у нас есть файл Excel, расположенный в памяти смартфона. Мы получаем его путь через ДиалогВыбораФайла и пытаемся загрузить в ТабличныйДокумент на стороне мобильного сервера. На настольном компьютере этот код отрабатывает идеально, но на Android-устройстве происходит сбой.
Проанализируем основные причины такого поведения:
/storage/emulated/0/.... Даже если путь кажется правильным, операционная система может блокировать прямой доступ к файлу для низкоуровневых методов платформы 1С..xlsx представляет собой ZIP-архив с набором XML-файлов внутри. Мобильная платформа использует облегченные библиотеки для работы с графикой и шрифтами. Если файл Excel содержит сложное форматирование, сводные таблицы или защищенные области, мобильный парсер может просто не справиться с его разбором.Прежде чем пытаться прочитать файл как таблицу, нам нужно убедиться, что у приложения вообще есть к нему доступ. Рассмотрим пример кода, который позволяет проверить доступность файла и его целостность через объект ДвоичныеДанные. Этот метод часто работает даже тогда, когда ТабличныйДокумент.Прочитать() пасует, так как использует более простые системные вызовы для чтения потока байтов.
// Пример проверки доступности файла на мобильном устройстве
ПутьКФайлу = "/storage/emulated/0/Download/report.xlsx";
Попытка
ФайлДД = Новый ДвоичныеДанные(ПутьКФайлу);
РазмерФайла = ФайлДД.Размер();
Сообщить("Файл успешно прочитан как двоичные данные. Размер: " + РазмерФайла);
Исключение
Сообщить("Ошибка доступа к файлу: " + ОписаниеОшибки());
КонецПопытки;
Если этот код выполняется успешно, значит, проблема не в правах доступа Android, а именно во внутреннем механизме разбора формата .xlsx в объекте ТабличныйДокумент.
Выясним причину, связанную с «виртуальными» путями. Часто 1С на мобильных устройствах корректно работает с файлами только в том случае, если они находятся в «песочнице» приложения. Мы можем попробовать скопировать файл во временный каталог 1С и прочитать его уже оттуда.
Разберем последовательность действий:
ДвоичныеДанные.КаталогВременныхФайлов().Прочитать() для нового пути.
ИмяВременногоФайла = КаталогВременныхФайлов() + "temp_table.xlsx";
ДвоичныеДанныеФайла = Новый ДвоичныеДанные(ИсходныйПуть);
ДвоичныеДанныеФайла.Записать(ИмяВременногоФайла);
ТабДок = Новый ТабличныйДокумент;
Попытка
ТабДок.Прочитать(ИмяВременногоФайла);
Сообщить("Успешное чтение из временного каталога!");
Исключение
Сообщить("Даже из временного каталога не читает. Причина: " + ОписаниеОшибки());
КонецПопытки;
Если мобильное устройство категорически отказывается понимать структуру .xlsx, самым стабильным решением будет использование «родного» формата 1С — .mxl. Поскольку мобильная платформа оптимизирована именно под него, чтение пройдет мгновенно и с сохранением всех цветов, шрифтов и рамок.
Рассмотрим схему взаимодействия:
Прочитать()..mxl с помощью метода Записать()..mxl файл (в виде двоичных данных) возвращается на мобильное устройство..mxl без каких-либо ошибок.Посмотрим на пример кода для серверной части:
// Код на стороне основного сервера (ПК/Сервер 1С)
Функция КонвертироватьВMXL(ДвоичныеДанныеExcel) Экспорт
ИмяВремExcel = ПолучитьИмяВременногоФайла("xlsx");
ИмяВремMXL = ПолучитьИмяВременногоФайла("mxl");
ДвоичныеДанныеExcel.Записать(ИмяВремExcel);
ТабДок = Новый ТабличныйДокумент;
ТабДок.Прочитать(ИмяВремExcel); // На ПК это работает стабильно
ТабДок.Записать(ИмяВремMXL, ТипФайлаТабличногоДокумента.MXL);
Результат = Новый ДвоичныеДанные(ИмяВремMXL);
УдалитьФайлы(ИмяВремExcel);
УдалитьФайлы(ИмяВремMXL);
Возврат Результат;
КонецФункции
Если вам нужно получить только данные (значения ячеек) без оформления, можно проанализировать ситуацию и использовать перенос данных через структуру или массив. Это «путь обхода», который упоминался в обсуждении: мы считываем файл на компьютере, перекладываем значения в массив структур и передаем на мобильное устройство, где программно заполняем новый ТабличныйДокумент.
Важный нюанс: при таком подходе вы потеряете визуальное оформление (цвета, объединение ячеек, границы). Однако для получения цифр или номенклатуры этот метод является самым быстрым, так как передача сериализованной структуры происходит по протоколам 1С максимально эффективно.
В обсуждении упоминалось использование второго параметра метода Прочитать(). Стоит помнить, что системное перечисление СпособЧтенияЗначенийТабличногоДокумента может быть недоступно в некоторых контекстах мобильного приложения или требовать явного указания типа. Если вы получаете ошибку «Переменная не определена», попробуйте проверить доступность этого типа в синтакс-помощнике именно для мобильной платформы вашей версии.
Проанализировав проблему, можно сделать следующие выводы:
ТабличногоДокумента..mxl на стороне полноценного сервера 1С.Рассмотренные подходы позволят вам обойти ограничения мобильной платформы и обеспечить стабильную работу вашего приложения при взаимодействии с табличными данными из внешних источников.