Как исправить ошибку «Использование синхронных методов на клиенте запрещено» при выборе файла Excel?

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

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

Выясним причину ошибки

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

Если в свойствах вашей конфигурации для параметра «Режим использования синхронных вызовов» установлено значение Не использовать, то любой вызов синхронного метода вызовет исключение. Это стандарт для всех современных конфигураций, таких как БП 3.0 или УТ 11.

Решение 1: Использование метода ВыбратьАсинх() (для платформы 8.3.18 и выше)

Если вы работаете на актуальной версии платформы, это самый простой и современный способ. Он позволяет сохранить «линейность» кода, используя оператор Ждать. Проанализируем, как изменится процедура выбора файла:


&НаКлиенте
Асинх Процедура ФайлНачалоВыбора(Элемент, ДанныеВыбора, ВыборДобавлением, СтандартнаяОбработка)
    
    СтандартнаяОбработка = Ложь;
    Диалог = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);    
    Диалог.Заголовок = "Выберите файл Excel";
    Диалог.Фильтр = "Excel файлы (*.xls;*.xlsx)|*.xls;*.xlsx";
    
    // Вместо Выбрать() используем ВыбратьАсинх() с оператором Ждать
    Результат = Ждать Диалог.ВыбратьАсинх();
    
    Если Результат <> Неопределено Тогда
        Файл = Результат[0]; // Результат возвращает массив выбранных путей
    КонецЕсли;

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

Обратите внимание на ключевое слово Асинх перед объявлением процедуры. Это обязательное условие для использования оператора Ждать внутри метода.

Решение 2: Использование ОписанияОповещения (универсальный способ)

Если ваша платформа ниже 8.3.18 или вы пишете универсальный код, необходимо использовать механизм обратного вызова (callback). Разберем по шагам, как это реализовать. Нам потребуется разделить одну процедуру на две: инициация выбора и обработка результата.


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

&НаКлиенте
Процедура ПослеВыбораФайла(ВыбранныеФайлы, ДополнительныеПараметры) Экспорт
    
    Если ВыбранныеФайлы <> Неопределено Тогда
        Файл = ВыбранныеФайлы[0];
    КонецЕсли;
    
КонецПроцедуры

Важный момент: процедура завершения обязательно должна иметь признак Экспорт, иначе платформа не сможет её вызвать.

Критическая ошибка: Передача пути к файлу на сервер

Проанализируем код из сообщения пользователя на форуме. Автор пытается передать строку ПутьКФайлу на сервер и там прочитать её через ТабДок.Прочитать(). Это не будет работать в клиент-серверном варианте, так как сервер «не видит» диски вашего локального компьютера.

Чтобы сервер смог прочитать файл, его нужно сначала поместить во временное хранилище. Рассмотрим правильную схему загрузки с использованием НачатьПомещениеФайла().

Решение 3: Загрузка файла через временное хранилище

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


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

&НаКлиенте
Процедура ЗагрузитьПослеПомещения(Результат, Адрес, ВыбранноеИмяФайла, ДополнительныеПараметры) Экспорт
    
    Если Результат Тогда
        // Теперь у нас есть 'Адрес' во временном хранилище. 
        // Передаем его на сервер для обработки.
        ОбработатьФайлНаСервере(Адрес);
    КонецЕсли;
    
КонецПроцедуры

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

Подведем итоги

Для успешной работы с Excel-файлами в современных конфигурациях 1С следуйте этим правилам:

  1. Забудьте про метод Диалог.Выбрать(). Используйте Диалог.ВыбратьАсинх() или Диалог.Показать().
  2. Никогда не передавайте «путь к файлу» (строку типа "C:\MyFile.xlsx") как параметр в серверную процедуру. Сервер не имеет доступа к файловой системе клиента.
  3. Используйте временное хранилище (Адрес) для передачи содержимого файла между клиентом и сервером.
  4. Для чтения Excel лучше использовать объект ТабличныйДокумент, так как он работает на сервере без необходимости устанавливать Microsoft Excel.

Применяя асинхронный подход, вы не только избавитесь от ошибок выполнения, но и сделаете вашу обработку совместимой с веб-клиентом и мобильными приложениями 1С.

← На главную