Как заменить файл в форме 1С после его конвертации на сервере?

Программист 1С v8.3 (Управляемые формы) 1С:Документооборот IT и автоматизация бизнеса
← На главную

Часто в работе с 1С возникает задача, когда нужно выполнить длительную или ресурсоемкую операцию с файлом (например, конвертацию, подписание, архивацию) и затем обновить интерфейс пользователя, чтобы он увидел результат. Классический пример: в форме есть список прикрепленных файлов, пользователь выбирает один из них, нажимает кнопку, файл на сервере конвертируется из .txt в .pdf, и теперь в списке должен отображаться новый .pdf файл вместо старого .txt.

Основная сложность здесь кроется в архитектуре платформы 1С: форма и ее элементы существуют на клиенте, а все операции с файлами и базой данных происходят на сервере. Прямой вызов клиентской процедуры обновления формы из серверного кода невозможен. Разберем, как правильно организовать такое взаимодействие.

Анализ проблемы: почему нельзя просто обновить форму с сервера?

Проанализируем ситуацию. У нас есть клиентская форма, где пользователь видит список файлов. По нажатию кнопки мы вызываем серверную процедуру, которая выполняет конвертацию. После того как на сервере появился новый файл, серверный код "ничего не знает" о клиентской форме, с которой его вызвали. Он не может напрямую сказать форме: "Эй, форма, обнови свой список!".

Это фундаментальный принцип разделения контекста в 1С. Сервер обрабатывает запросы от множества клиентов и работает только с данными. Клиент отвечает за взаимодействие с пользователем и отображение этих данных. Связь между ними всегда инициируется клиентом.

Таким образом, наша задача — построить правильную цепочку вызовов: Клиент → Сервер → Клиент.

Правильный алгоритм замены файла в форме

Рассмотрим по шагам, как реализовать необходимый функционал, чтобы он работал корректно и соответствовал архитектуре платформы.

  1. Вызов серверной функции с клиента.

    Ключевой момент — с клиента нужно вызывать не процедуру, а именно функцию. Процедура просто выполняет действия на сервере и ничего не возвращает. Функция же может выполнить действия и вернуть на клиент результат своей работы, что нам и нужно.

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

  2. Обработка файла на сервере.

    Серверная функция, получив данные о файле, выполняет всю "тяжелую" работу:

    • Находит исходный файл в хранилище или на диске сервера.
    • Запускает внешний процесс конвертации (в нашем примере — jar-конвертор).
    • Получает результат — новый файл в формате .pdf.
    • Программно добавляет новый файл в систему. В типовых конфигурациях, таких как "1С:Документооборот", для этого существуют специальные общие модули, например РаботаСФайлами. С помощью его функций нужно создать новый элемент справочника "Присоединенные файлы" (или аналога), связав его с тем же объектом-владельцем, что и у исходного файла.
    • Удаляет или деактивирует старый файл. После успешного добавления нового файла старый можно пометить на удаление или удалить физически, чтобы он больше не отображался в списках.
    • Возвращает результат на клиент. По завершении всех операций функция должна вернуть на клиент информацию об успехе или неудаче. Это может быть простое булево значение (Истина/Ложь) или, что более удобно, структура, содержащая статус и сообщение об ошибке в случае неудачи.
  3. Обновление формы на клиенте.

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

    Получив от сервера подтверждение успешной конвертации, клиентский код должен инициировать обновление списка файлов. Есть несколько способов это сделать:

    • Вызвать процедуру, которая изначально заполняет список. Это самый надежный способ. Нужно найти в коде формы процедуру, которая отвечает за чтение данных и их вывод в список, и вызвать ее повторно.
    • Использовать стандартные методы формы. В большинстве случаев достаточно вызвать метод формы ОбновитьОтображениеДанных(). Этот метод заставит форму перечитать свои данные с сервера и обновить все элементы, связанные с ними.

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

Пример реализации (псевдокод)

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


// Клиентский обработчик команды "Конвертировать"
&НаКлиенте
Процедура КонвертироватьФайл(Команда)
    // Получаем данные о текущем выбранном файле
    ТекущиеДанные = Элементы.СписокФайлов.ТекущиеДанные;
    Если ТекущиеДанные = Неопределено Тогда
        Сообщить("Файл не выбран!");
        Возврат;
    КонецЕсли;

    // Вызываем серверную функцию для выполнения конвертации
    // Передаем ссылку на объект присоединенного файла
    РезультатВыполнения = ВыполнитьКонвертациюНаСервере(ТекущиеДанные.СсылкаНаФайл);

    // После возврата управления с сервера анализируем результат
    Если РезультатВыполнения.Успешно Тогда
        // Если все прошло хорошо, обновляем отображение данных на форме
        ОбновитьОтображениеДанных();
        Сообщить("Файл успешно сконвертирован!");
    Иначе
        // Если произошла ошибка, выводим сообщение
        ПоказатьПредупреждение(Неопределено, РезультатВыполнения.ТекстОшибки);
    КонецЕсли;
КонецПроцедуры

// Серверная функция, выполняющая основную логику
&НаСервере
Функция ВыполнитьКонвертациюНаСервере(СсылкаНаСтарыйФайл)
    Результат = Новый Структура("Успешно, ТекстОшибки");
    Результат.Успешно = Ложь;

    // Шаг 1: Получаем данные старого файла
    // ... здесь код для получения двоичных данных, имени, расширения из объекта СсылкаНаСтарыйФайл

    // Шаг 2: Запускаем внешний конвертор
    // ... код для вызова КомандаСистемы() или ЗапуститьПриложение() для jar-конвертора
    // Предположим, получили путь к новому файлу
    ПутьКНовомуФайлу = "C:\temp\converted_file.pdf";

    // Шаг 3: Добавляем новый файл в систему через API конфигурации
    // В 1С:Документооборот это может быть функция из общего модуля РаботаСФайлами
    // Например: РаботаСФайлами.ДобавитьФайл(ВладелецФайла, ПутьКНовомуФайлу, ...);
    // ...

    // Шаг 4: Помечаем на удаление старый файл
    ОбъектСтарогоФайла = СсылкаНаСтарыйФайл.ПолучитьОбъект();
    ОбъектСтарогоФайла.ПометкаУдаления = Истина;
    ОбъектСтарогоФайла.Записать();
    
    // Если все шаги прошли без ошибок
    Результат.Успешно = Истина;
    
    // Возвращаем структуру с результатом на клиент
    Возврат Результат;

    // Здесь также должна быть обработка исключений с помощью Попытка...Исключение
КонецФункции

Альтернативные способы обновления

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

Однако для простой задачи замены одного файла в текущей форме описанный выше алгоритм "вызов серверной функции и обновление по результату" является самым простым, надежным и правильным решением.

← На главную