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

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

При разработке на платформе 1С:Предприятие 8.3 программисты часто сталкиваются с архитектурным ограничением: невозможно вызвать диалоговое окно (интерфейсное действие) непосредственно из серверного контекста. Это классическая ситуация при выгрузке данных в Excel, когда формирование файла происходит на сервере, а выбор пути сохранения должен сделать пользователь на своем компьютере. В этой статье мы подробно разберем, как правильно организовать этот процесс, проанализируем типичные ошибки и рассмотрим наиболее эффективные методы реализации. В качестве альтернативы ручному написанию кода можно использовать готовую подсистему для сохранения табличных частей форм в Excel.

Почему нельзя вызвать диалог прямо с сервера?

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

Разбор оптимального алгоритма работы

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

  1. Пользователь нажимает кнопку выгрузки (Клиент).
  2. Вызывается серверная функция, которая формирует данные (например, ТабличныйДокумент).
  3. Сервер сохраняет сформированный документ во временный файл, переводит его в ДвоичныеДанные и помещает во Временное хранилище.
  4. Сервер возвращает клиенту адрес этого хранилища.
  5. Клиент, получив адрес, вызывает диалог сохранения и записывает файл на диск пользователя.

Реализация серверной части: подготовка данных

Проанализируем код серверной функции. Нам нужно не просто создать документ, но и «передать» его на клиентскую сторону через специальный механизм. Для этого идеально подходит ПоместитьВоВременноеХранилище. При необходимости предварительного оформления выгружаемых файлов можно применить готовый шаблон для заполнения и выгрузки данных из 1С в Excel.


&НаСервере
Функция СформироватьФайлНаСервере()
    
    // Создаем табличный документ и заполняем его данными
    ТабДок = Новый ТабличныйДокумент;
    // ... здесь ваша логика заполнения ТабДок (запросы, циклы) ...
    
    // Получаем уникальное имя временного файла на сервере
    ИмяВременногоФайла = ПолучитьИмяВременногоФайла("xlsx");
    
    // Записываем документ во временный файл
    ТабДок.Записать(ИмяВременногоФайла, ТипФайлаТабличногоДокумента.XLSX);
    
    // Читаем файл в двоичные данные
    ДанныеФайла = Новый ДвоичныеДанные(ИмяВременногоФайла);
    
    // Помещаем во временное хранилище. 
    // ЭтаФорма.УникальныйИдентификатор нужен, чтобы файл жил до закрытия формы
    АдресХранилища = ПоместитьВоВременноеХранилище(ДанныеФайла, ЭтаФорма.УникальныйИдентификатор);
    
    // Удаляем временный файл с диска сервера, он больше не нужен
    УдалитьФайлы(ИмяВременногоФайла);
    
    Возврат АдресХранилища;
    
КонецФункции

Реализация клиентской части: вызов диалога (Способ 1)

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


&НаКлиенте
Процедура ВыполнитьВыгрузку(Команда)
    
    // Шаг 1: Получаем данные с сервера
    АдресФайла = СформироватьФайлНаСервере();
    
    Если ЗначениеЗаполнено(АдресФайла) Тогда
        
        // Шаг 2: Вызываем интерактивное сохранение
        // Параметры: Адрес, ИмяФайлаПриСохранении, Интерактивно
        ИмяВыгрузки = "Новые_контрагенты.xlsx";
        ПолучитьФайл(АдресФайла, ИмяВыгрузки, Истина);
        
    КонецЕсли;
    
КонецПроцедуры

Использование объекта ДиалогВыбораФайла (Способ 2)

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


&НаКлиенте
Процедура СохранитьСДиалогом(Команда)

    АдресФайла = СформироватьФайлНаСервере();
    
    // Настройка диалога
    Режим = РежимДиалогаВыбораФайла.Сохранение;
    Диалог = Новый ДиалогВыбораФайла(Режим);
    Диалог.ПолноеИмяФайла = "Выгрузка_Контрагентов";
    Диалог.Фильтр = "Файлы Excel (*.xlsx)|*.xlsx";
    Диалог.Заголовок = "Укажите, куда сохранить список новых контрагентов";
    
    // Описание оповещения для обработки выбора пользователя
    Оповещение = Новый ОписаниеОповещения("ПослеВыбораФайла", ЭтотОбъект, АдресФайла);
    
    // Показываем диалог асинхронно
    Диалог.Показать(Оповещение);

КонецПроцедуры

&НаКлиенте
Процедура ПослеВыбораФайла(ВыбранныеФайлы, ДополнительныеПараметры) Экспорт
    
    Если ВыбранныеФайлы <> Неопределено Тогда
        
        ПутьКФайлу = ВыбранныеФайлы[0];
        АдресХранилища = ДополнительныеПараметры; // Передали через ОписаниеОповещения
        
        // Получаем данные из хранилища и записываем по выбранному пути
        Данные = ПолучитьИзВременногоХранилища(АдресХранилища);
        Данные.Записать(ПутьКФайлу);
        
        ПоказатьПредупреждение(, "Файл успешно сохранен!");
        
    КонецЕсли;
    
КонецПроцедуры

Важные нюансы и рекомендации

Разберем несколько критически важных моментов, которые помогут избежать ошибок при эксплуатации системы:

Таким образом, мы выяснили, что ключ к успеху — это правильное разделение ответственности. Сервер готовит данные и передает их «через облако» (временное хранилище), а клиент подхватывает их и взаимодействует с пользователем через диалоговые окна. Следуя этим правилам, вы напишете надежный и отказоустойчивый код.

← На главную