При разработке обработок загрузки данных из внешних файлов (Excel, MXL) (поможет универсальный импорт данных из Excel в любые справочники) программисты часто сталкиваются с ошибкой при вызове метода Прочитать() объекта ТабличныйДокумент. Ситуация осложняется тем, что на локальном компьютере разработчика (в файловой базе) код работает идеально, но при переносе в рабочую клиент-серверную среду возникает отказ. Рассмотрим детально, почему это происходит и как правильно организовать работу с файлами в 1С.
Главная причина, по которой возникает Ошибка доступа к файлу по пути вида C:\Users\ИмяПользователя\Documents\..., заключается в архитектуре клиент-серверного приложения. Выясним, что происходит в момент вызова кода:
&НаСервере или &НаСервереБезКонтекста, код исполняется на стороне сервера (в процессе rphost.exe).C:, рабочий стол или папку «Мои документы».USR1CV8). У этой учетной записи нет прав на доступ к личным папкам пользователей Windows.Разберем ситуацию, упомянутую в обсуждении: после сбоя электропитания права доступа в операционной системе могут «слететь» или заблокироваться антивирусом. Если сервер 1С не может достучаться до файла даже во временном каталоге, система выдаст ошибку файловой операции.
Для того чтобы сервер смог прочитать файл, мы должны физически доставить его данные в контекст сервера. Рассмотрим по шагам самый надежный алгоритм с использованием временного хранилища.
Шаг 1. На стороне клиента:
Мы выбираем файл и помещаем его в «облако» 1С (временное хранилище). В ответ получаем уникальный адрес (строку).
&НаКлиенте
Процедура ВыбратьИЗагрузитьФайл()
ПеременнаяВыбора = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
ПеременнаяВыбора.Фильтр = "Excel (*.xlsx)|*.xlsx";
Если ПеременнаяВыбора.Выбрать() Тогда
ОписаниеФайла = Новый ОписаниеПередаваемогоФайла(ПеременнаяВыбора.ПолноеИмяФайла);
МассивФайлов = Новый Массив;
МассивФайлов.Добавить(ОписаниеФайла);
// Помещаем файл во временное хранилище
НачатьПомещениеФайловНаСервер(,, МассивФайлов, УникальныйИдентификатор, Истина, Новый ОписаниеОповещения("ЗавершитьЗагрузку", ЭтотОбъект));
КонецЕсли;
КонецПроцедуры
Шаг 2. На стороне сервера:
Получаем данные по адресу, сохраняем их во временный файл на диске сервера и только потом вызываем Прочитать().
&НаСервере
Процедура ЗагрузитьНаСервере(АдресХранилища)
// Генерируем уникальное имя файла в папке временных файлов сервера
ИмяФайлаНаСервере = ПолучитьИмяВременногоФайла("xlsx");
// Извлекаем двоичные данные из хранилища
ДанныеФайла = ПолучитьИзВременногоХранилища(АдресХранилища);
// Записываем данные на диск сервера
ДанныеФайла.Записать(ИмяФайлаНаСервере);
// Теперь читаем файл табличным документом
ТабДок = Новый ТабличныйДокумент;
Попытка
ТабДок.Прочитать(ИмяФайлаНаСервере);
// Обработка данных ТабДока...
Исключение
ОбщегоНазначенияКлиентСервер.СообщитьПользователю("Ошибка при чтении файла: " + ОписаниеОшибки());
КонецПопытки;
// Важно: Удаляем временный файл после использования
УдалитьФайлы(ИмяФайлаНаСервере);
КонецПроцедуры
Проанализируем сообщение №12 и №14 из обсуждения. Пользователь допустил классическую ошибку: он удалил файл УдалитьФайлы(ИмяФайла); непосредственно ПЕРЕД или СРАЗУ после вызова команды чтения, не убедившись в завершении процесса. Посмотрим на этот фрагмент:
// ОШИБОЧНЫЙ КОД
MXL.Прочитать(ИмяФайла);
УдалитьФайлы(ИмяФайла); // Если это внутри цикла или условий, файл может быть занят
MXL.Прочитать(ИмяФайла); // Здесь будет ошибка, так как файл уже удален выше!
Важный момент: если вы используете метод Прочитать() для формата Excel, убедитесь, что расширение временного файла (параметр в ПолучитьИмяВременногоФайла("xlsx")) совпадает с реальным форматом данных. Если передать пустую строку, 1С может не распознать внутреннюю структуру файла. Для этой задачи есть универсальный инструмент загрузки данных из Excel без программирования.
Если даже при передаче через хранилище возникает ошибка «Отказано в доступе», проанализируем состояние системных папок. После аварийного завершения работы сервера (отключение света), файлы блокировок (например, fts-state.lock) или временные файлы могут остаться в «подвешенном» состоянии.
Выполним следующие действия для исправления:
1C:Enterprise 8.3 Server Agent. Обычно это USR1CV8.srvinfo), выберем «Свойства» -> «Безопасность» и убедимся, что у пользователя USR1CV8 есть права «Полный доступ».C:\Windows\Temp и C:\Users\USR1CV8\AppData\Local\Temp. Желательно очистить эти каталоги от старых временных файлов 1С, которые могут вызывать конфликты имен.Подводя итог, отметим: работа с файлами в 1С требует строгого разделения зон ответственности. Клиент отвечает за выбор файла и его «упаковку» в хранилище, а сервер — за распаковку и обработку данных. Никогда не передавайте в серверные процедуры прямые пути к файлам на клиентском компьютере. Используйте объект ДвоичныеДанные и временные файлы сервера с обязательным указанием расширения. Дополнительно изучить особенности взаимодействия с файловой системой поможет руководство по работе с файлами в управляемых формах.
При возникновении трудностей всегда проверяйте системный журнал событий Windows. Если там фигурируют ошибки доступа к папкам внутри Program Files\1cv8\srvinfo, значит проблема носит административный характер и требует вмешательства системного администратора для восстановления прав доступа после сбоя.