Переход с файловой версии 1С:Предприятие на клиент-серверную (MS SQL) — это важный шаг в развитии информационной системы, однако он часто сопровождается техническими сложностями. Одной из самых распространенных проблем является внезапный отказ привычных обработок, работающих с внешними файлами, в частности с Microsoft Excel. Если раньше код Новый Файл(Путь) успешно находил документ, то в клиент-серверном варианте система упорно сообщает: "Файл не существует".
В этой статье мы подробно разберем, почему возникает эта ошибка, как правильно организовать передачу данных между клиентом и сервером и какие современные инструменты 1С позволяют работать с Excel эффективнее и стабильнее.
Давайте проанализируем ситуацию. В файловом варианте 1С весь код выполняется на компьютере пользователя. Программа имеет доступ к тем же дискам и папкам, что и сам человек. После перехода на SQL выполнение кода строго разделяется на клиентское (на компьютере пользователя) и серверное (на сервере приложений 1С).
Когда вы запускаете процедуру с директивой &НаСервере, система пытается найти файл не на вашем компьютере, а на дисках сервера. Рассмотрим основные причины, по которым сервер "не видит" ваш файл:
C:\Users\User\Desktop\file.xlsx на сервере либо отсутствует, либо ведет в пустую папку профиля серверной службы.Z:\, сервер его не увидит, так как сетевые диски подключаются для конкретного пользователя в его сессии, а служба сервера 1С работает в своем изолированном окружении.1C:Enterprise 8.3 Server Agent обычно запускается под специальной учетной записью (например, USR1CV8). У этой учетной записи по умолчанию нет прав на доступ к вашим личным папкам или сетевым ресурсам.Это самый правильный и надежный способ. Вместо того чтобы заставлять сервер искать файл на клиенте, мы сами передаем содержимое файла на сервер. Разберем этот процесс по шагам.
Сначала на стороне клиента мы превращаем файл в объект ДвоичныеДанные и помещаем его в специальное хранилище, получая уникальный адрес:
&НаКлиенте
Процедура ЗагрузитьФайл(Команда)
// Выбираем файл на компьютере пользователя
Диалог = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
Диалог.Фильтр = "Excel (*.xlsx)|*.xlsx";
Если Диалог.Выбрать() Тогда
ПутьКФайлу = Диалог.ПолноеИмяФайла;
// Помещаем файл во временное хранилище
ДанныеФайла = Новый ДвоичныеДанные(ПутьКФайлу);
АдресХранилища = ПоместитьВоВременноеХранилище(ДанныеФайла, УникальныйИдентификатор);
// Передаем адрес на сервер для обработки
ОбработатьФайлНаСервере(АдресХранилища);
КонецЕсли;
КонецПроцедуры
Затем на стороне сервера мы извлекаем данные из хранилища и сохраняем их во временный файл, с которым уже может работать Excel или сама платформа:
&НаСервере
Процедура ОбработатьФайлНаСервере(АдресХранилища)
// Получаем двоичные данные из хранилища
Данные = ПолучитьИзВременногоХранилища(АдресХранилища);
// Создаем имя временного файла на сервере
ИмяВременногоФайла = ПолучитьИмяВременногоФайла("xlsx");
// Записываем данные в файл на диске сервера
Данные.Записать(ИмяВременногоФайла);
// Теперь файл существует для сервера, и его можно открыть
Попытка
Excel = Новый COMОбъект("Excel.Application");
Книга = Excel.WorkBooks.Open(ИмяВременногоФайла);
// ... дальнейшая логика чтения ...
Excel.Quit();
Исключение
Сообщить("Ошибка при работе с Excel на сервере: " + ОписаниеОшибки());
КонецПопытки;
// Не забываем удалять временный файл
УдалитьФайлы(ИмяВременногоФайла);
КонецПроцедуры
Использование COMОбъект("Excel.Application") на сервере считается "плохим тоном" и часто приводит к зависанию процессов excel.exe в памяти сервера. Рассмотрим более современный способ — использование объекта ТабличныйДокумент, который умеет читать файлы .xlsx напрямую без установленного Microsoft Office.
Выясним преимущества этого метода: он работает быстрее, не требует лицензий Office на сервере и гораздо стабильнее при многопоточной работе. Посмотрим на пример кода:
&НаСервере
Процедура ПрочитатьExcelПлатформой(АдресХранилища)
Данные = ПолучитьИзВременногоХранилища(АдресХранилища);
ИмяФайла = ПолучитьИмяВременногоФайла("xlsx");
Данные.Записать(ИмяФайла);
ТабДок = Новый ТабличныйДокумент;
Попытка
// Используем встроенный метод платформы
ТабДок.Прочитать(ИмяФайла, СпособЧтенияXLSX.Native);
// Теперь данные в ТабДок, можем перебрать строки
Для НомерСтроки = 1 По ТабДок.ВысотаТаблицы Цикл
Значение = ТабДок.Область(НомерСтроки, 1).Текст;
// Обработка значения
КонецЦикла;
Исключение
Сообщить("Не удалось прочитать файл: " + ОписаниеОшибки());
КонецПопытки;
УдалитьФайлы(ИмяФайла);
КонецПроцедуры
Если вы все же решили использовать COM-объект на сервере, проанализируем несколько критических моментов, без которых система может не заработать даже с правильным кодом:
dcomcnfg разрешить запуск Microsoft Excel пользователю, под которым работает сервер 1С.C:\Windows\System32\config\systemprofile\DesktopC:\Windows\SysWOW64\config\systemprofile\Desktop (для 64-битных систем)\\ИмяСервера\Папка\Файл.xlsx. Никогда не используйте буквы дисков (Z:, Y:), так как сервер их не распознает.Подводя итог, можно сказать, что проблема "невидимости" файла — это лишь следствие архитектурных особенностей клиент-серверной работы. Для исправления ситуации мы рекомендуем:
ТабличныйДокумент.Прочитать() вместо COMОбъект. Это избавит вас от проблем с правами доступа и зависшими процессами в диспетчере задач сервера.Следуя этим правилам, вы обеспечите стабильную работу своих обработок в любом режиме работы 1С:Предприятия.