Открытие файла на компьютере пользователя из кода 1С

· 9 мин

Содержание

Открыть файл «на клиенте» значит выполнить код на компьютере пользователя, а не на сервере 1С. Серверный код чужой диск не видит, поэтому всё начинается с клиентской процедуры (директива &НаКлиенте) и метода ЗапуститьПриложение, НачатьЗапускПриложения или КомандаСистемы.

Дальше зависит от того, где работает пользователь. В тонком и толстом клиенте доступно почти всё: объект Файл, запуск программ, COM. В веб-клиенте почти всё это закрыто, и файл сначала нужно передать на компьютер. Ниже — по порядку: ограничения, проверка файла, запуск, COM, веб и диагностика.

Где выполняется код и что ему разрешено

Любой вызов, который трогает файловую систему пользователя, должен идти из клиентского контекста. Если вы вызвали его из серверной процедуры, получите ошибку компиляции: метод в этом контексте недоступен. Серверный код работает с файлами сервера, это другая задача.

Сводка по клиентам:

КлиентФайловая системаЗапуск программCOM
Толстый клиентПолный доступДаДа (Windows)
Тонкий клиентПолный доступДаДа (Windows)
Веб-клиентТолько через расширение для работы с файламиНетНет
Мобильный клиентОграниченОграниченНет

Есть ещё один фактор: режим совместимости конфигурации. В новых конфигурациях синхронные методы (Существует(), ЗапуститьПриложение) могут быть запрещены, и платформа требует асинхронные аналоги с префиксом Начать. Если синхронный вызов в вашей базе ругается, это не баг, а требование режима.

Код ниже предназначен для клиентской части формы. Не копируйте его в общий серверный модуль: он там не заработает или молча ничего не сделает.

Расширение для работы с файлами

В веб-клиенте браузер сам не даёт программе читать диск. Платформа обходит это через расширение для работы с файлами: оно ставится в браузер один раз, и тогда часть файловых методов начинает работать. Проверка и запрос установки выглядят так:

&НаКлиенте
Процедура ПроверитьРасширение()
    ОписаниеОповещения = Новый ОписаниеОповещения("ПослеПодключения", ЭтотОбъект);
    НачатьПодключениеРасширенияРаботыСФайлами(ОписаниеОповещения);
КонецПроцедуры

&НаКлиенте
Процедура ПослеПодключения(Подключено, ДополнительныеПараметры) Экспорт
    Если Не Подключено Тогда
        // Расширения нет — предложите установить или используйте обходной путь
        НачатьУстановкуРасширенияРаботыСФайлами(Неопределено);
    КонецЕсли;
КонецПроцедуры

Для тонкого клиента этот шаг не нужен: расширение требуется только браузеру.

Проверка существования файла перед открытием

Прежде чем запускать, убедитесь, что файл на месте. Пользователь мог его удалить, переименовать или потерять доступ к сетевой папке.

Синхронный вариант проще, но работает не везде:

&НаКлиенте
Процедура ОткрытьЕслиЕсть(ПутьКФайлу)
    Файл = Новый Файл(ПутьКФайлу);
    Если Файл.Существует() Тогда
        ЗапуститьПриложение(ПутьКФайлу);
    Иначе
        ПоказатьПредупреждение(, "Файл не найден: " + ПутьКФайлу);
    КонецЕсли;
КонецПроцедуры

Асинхронный вариант надёжнее, он не подвесит интерфейс на медленной сетевой папке:

&НаКлиенте
Процедура ОткрытьАсинхронно(ПутьКФайлу)
    Файл = Новый Файл(ПутьКФайлу);
    Оповещение = Новый ОписаниеОповещения("ПослеПроверки", ЭтотОбъект, ПутьКФайлу);
    Файл.НачатьПроверкуСуществования(Оповещение);
КонецПроцедуры

&НаКлиенте
Процедура ПослеПроверки(Существует, ПутьКФайлу) Экспорт
    Если Существует Тогда
        НачатьЗапускПриложения(Новый ОписаниеОповещения("ПослеЗапуска", ЭтотОбъект), ПутьКФайлу);
    Иначе
        ПоказатьПредупреждение(, "Файл не найден");
    КонецЕсли;
КонецПроцедуры

Что ещё полезно знать об объекте Файл:

  • 📁 Он не читает содержимое, а только описывает путь: имя, расширение, каталог.
  • 📏 Размер, дату изменения и признак «только чтение» тоже получают асинхронно: НачатьПолучениеРазмера, НачатьПолучениеВремениИзменения, НачатьПолучениеТолькоЧтения.
  • 🔍 Метод ЭтоКаталог() отличает папку от файла: полезно, когда пользователь ввёл путь вручную.
  • 🔗 Сетевые пути вида \\сервер\папка\файл.xlsx работают, если у учётной записи пользователя есть доступ. Учётная запись сервера 1С тут ни при чём.

Запуск приложения: файл откроется в программе по умолчанию

Самый короткий способ открыть документ, таблицу или PDF — отдать путь методу запуска. Система сама подберёт программу по расширению файла.

ЗапуститьПриложение("C:\Документы\Акт.docx");

Если нужна конкретная программа или параметры, передавайте полную командную строку. Путь с пробелами берите в кавычки, иначе система разобьёт его на части:

КомандаЗапуска = """C:\Program Files\Notepad++\notepad++.exe"" ""C:\Журнал\лог 1.txt""";
ЗапуститьПриложение(КомандаЗапуска);

У ЗапуститьПриложение три значимых параметра: команда, текущий каталог и флаг ожидания завершения. Если нужно дождаться закрытия программы (например, пользователь отредактировал файл, а вы потом его читаете), ставьте ДождатьсяЗавершения = Истина. Для длительных программ лучше асинхронный НачатьЗапускПриложения: интерфейс 1С не замирает.

Через командную строку

Запуск системной оболочки подходит, когда нужна команда start или параметры проводника:

// Windows: открыть файл в программе по умолчанию
КомандаСистемы("cmd /c start """" ""C:\Документы\Прайс.xlsx""");

// Показать файл в проводнике с выделением
ЗапуститьПриложение("explorer.exe /select,""C:\Документы\Прайс.xlsx""");

Пустые кавычки после start нужны не для красоты: без них команда примет первый путь в кавычках за заголовок окна.

На Linux и macOS вызываются их собственные команды: xdg-open и open. Тип операционной системы определяйте через СистемнаяИнформация.ТипПлатформы, не гадайте по слэшам в пути.

В конфигурациях на библиотеке стандартных подсистем есть готовая обёртка ФайловаяСистемаКлиент.ОткрытьФайл. Она учитывает веб-клиент, расширение и разные ОС. Если БСП уже подключена, пользуйтесь ею и не изобретайте своё.

Не собирайте командную строку из данных, которые ввёл пользователь, без проверки. Иначе в путь можно подставить лишнюю команду. Проверяйте, что файл существует, и берите путь в кавычки.

COM-автоматизация: когда нужно управлять программой

Простое открытие COM не требует. Он нужен, когда надо не только показать файл, но и что-то сделать внутри программы: вставить данные в Excel, заменить закладки в Word, выставить параметры печати.

&НаКлиенте
Процедура ОткрытьВExcel(ПутьКФайлу)
    Попытка
        Excel = Новый COMОбъект("Excel.Application");
        Excel.Visible = Истина;
        Excel.Workbooks.Open(ПутьКФайлу);
    Исключение
        ПоказатьПредупреждение(, "Не удалось запустить Excel: " + ОписаниеОшибки());
    КонецПопытки;
КонецПроцедуры

Другой вариант — оболочка Windows через Shell.Application. Она откроет файл так, как это делает двойной клик:

Оболочка = Новый COMОбъект("Shell.Application");
Оболочка.ShellExecute("C:\Документы\Акт.docx");

Что нужно помнить про COM:

  1. ⚙️ Работает только в Windows и только в тонком или толстом клиенте.
  2. 📦 Программа должна быть установлена на компьютере пользователя, а не на сервере.
  3. 🔢 Разрядность имеет значение: 32-битный клиент 1С и 64-битный Office могут не найти друг друга при создании объекта.
  4. 🧹 После работы освобождайте объект: Excel = Неопределено, иначе в диспетчере задач остаётся «висящий» процесс.
  5. ☁️ Если у пользователя сеанс на терминальном сервере, программа запустится в его сеансе, как и ожидается.

Всегда оборачивайте создание COM-объекта в Попытка…Исключение. Отсутствие Excel на одном из компьютеров — самая частая причина жалоб.

Какой способ выбрать

Если не хочется держать всё в голове, пройдите по сценариям:

Что нужно сделать с файлом?

Веб-клиент: файл не открыть напрямую, но получить можно

В браузере вы не запустите Блокнот или Excel на компьютере пользователя: ни ЗапуститьПриложение, ни COM там нет. Это не недоработка, а модель безопасности: страница не имеет права запускать программы.

Рабочая схема для веба такая:

  1. 🗄 Файл лежит на сервере или в базе (в присоединённых файлах, в реквизите, на диске сервера).
  2. 📤 Сервер кладёт двоичные данные во временное хранилище и возвращает адрес.
  3. 📥 Клиент вызывает получение файла, и браузер предлагает сохранить или открыть его.
&НаСервере
Функция ПодготовитьФайл(ПутьНаСервере)
    Данные = Новый ДвоичныеДанные(ПутьНаСервере);
    Возврат ПоместитьВоВременноеХранилище(Данные, УникальныйИдентификатор);
КонецФункции

&НаКлиенте
Процедура СкачатьФайл()
    Адрес = ПодготовитьФайл("/data/report.pdf");
    ПолучитьФайл(Адрес, "report.pdf", Истина);
КонецПроцедуры

Параметр Интерактивно = Истина показывает диалог выбора места сохранения. Дальше пользователь открывает скачанный файл сам. Для PDF и картинок иногда удобнее другой путь: выложить документ по ссылке и открыть вкладку браузера через ПерейтиПоНавигационнойСсылке.

В обратную сторону — с компьютера пользователя на сервер — файл попадает через НачатьПомещениеФайла или диалог выбора. Для небольшой формы этого достаточно.

Если вам нужно именно запустить программу локально и дать ей поработать с файлом, веб-клиент не подходит. Договоритесь с пользователями о тонком клиенте либо перенесите сценарий на сервер: сформируйте результат там и отдайте готовый файл.

Присоединённые файлы и временные копии

Часто открыть нужно не файл с диска, а вложение из базы: скан договора, прайс-лист поставщика. Схема та же: данные уходят на клиент, сохраняются во временный каталог и открываются программой по умолчанию.

  1. 📥 Получите двоичные данные вложения на сервере и положите их во временное хранилище.
  2. 📂 На клиенте узнайте каталог временных файлов (НачатьПолучениеКаталогаВременныхФайлов).
  3. 💾 Сохраните данные в файл с понятным именем и правильным расширением.
  4. ▶️ Откройте файл через НачатьЗапускПриложения.

Расширение в имени критично: по нему система выбирает программу. Файл акт без .pdf не откроется так, как вы ожидаете.

Временные копии не копятся сами. Если пользователь открывает по десять вложений в день, через месяц в каталоге лежат сотни файлов с чужими данными. Удаляйте копию при закрытии формы или чистите каталог по своему префиксу в имени.

Правки в такой копии не попадут обратно в базу. Если пользователь должен редактировать вложение, после закрытия программы предложите загрузить файл обратно.

Ошибки при открытии файла: что проверить в первую очередь

Большинство проблем сводится к четырём вещам: не тот контекст, не тот клиент, нет прав и неверный путь. Ниже типичные симптомы.

Диагностика: выберите симптом

Чтобы быстро локализовать проблему, добавьте в код временный вывод: Сообщить(ОписаниеОшибки()) внутри Исключение и Сообщить(Файл.ПолноеИмя) перед запуском. Через минуту станет видно, что именно получила платформа.

Диагностика на стороне клиента

Если у одного пользователя файл открывается, а у другого нет, код тут обычно ни при чём. Проверьте по очереди:

  1. Тот же ли тип клиента у обоих (тонкий и браузер ведут себя по-разному).
  2. Есть ли у второго пользователя права на сетевую папку и на запуск программы.
  3. Не блокирует ли запуск антивирус или политика безопасности: это часто выглядит как «ничего не происходит».
  4. Установлено ли нужное приложение для типа файла.

Права на каталог проверяйте от имени пользователя, а не администратора: рабочая картина под админом ничего не доказывает.

Частые вопросы

Можно ли открыть файл на клиенте из серверной процедуры?
Нет. Сервер не имеет доступа к диску пользователя. Верните данные на клиент через временное хранилище или параметры и откройте там.
Почему в веб-клиенте не запускается программа?
Браузер не позволяет странице запускать приложения на компьютере. Используйте получение файла через ПолучитьФайл или работайте в тонком клиенте.
Чем `ЗапуститьПриложение` отличается от `НачатьЗапускПриложения`?
Первый метод ждёт результата и может подвесить интерфейс. Второй возвращает управление сразу и сообщает о завершении через оповещение. В новых режимах совместимости нужен второй.
Как открыть папку, а не файл?
Передайте путь к каталогу тем же ЗапуститьПриложение или вызовите explorer.exe "Путь". Проводник покажет содержимое.
Нужно ли подключать расширение для работы с файлами в тонком клиенте?
Нет. Оно требуется только браузеру.
Как открыть файл по умолчанию на Linux?
Вызовите xdg-open с путём к файлу через КомандаСистемы или НачатьЗапускПриложения.