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

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

При переходе с обычных форм (например, УПП) на управляемые формы 1С программисты часто сталкиваются с проблемой «разрыва контекста». Типичная ситуация: мы запускаем процесс загрузки данных из внешнего SQL-источника на сервере, и в какой-то момент системе требуется участие пользователя — например, чтобы вручную сопоставить контрагента или создать нового. Однако напрямую вызвать окно выбора (клиентский метод) из серверного кода невозможно.

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

Причина проблемы: Разделение контекстов

Проанализируем ситуацию: процедура &НаСервере не знает ничего о «экране» пользователя. Она выполняется в кластере серверов 1С. В то время как диалоговые окна, такие как ОткрытьФорму() или ВвестиЗначение(), существуют только в контексте &НаКлиенте. Попытка вызвать клиентский метод из серверного приведет к ошибке компиляции или времени выполнения.

Рассмотрим основные стратегии обхода этого ограничения, от простых к наиболее профессиональным.

Решение 1: Прерывистая загрузка через функцию

Это самый очевидный способ для небольших объемов данных. Вместо того чтобы пытаться вызвать клиент из сервера, мы возвращаем управление на клиент, как только возникла проблема.

Разберем пример логики:

  1. На клиенте запускается цикл обработки данных (или вызывается серверная функция для одной строки).
  2. Серверная функция ищет контрагента. Если он найден — возвращает ссылку. Если не найден — возвращает Неопределено.
  3. Клиент получает Неопределено, открывает окно выбора пользователю, получает ссылку и снова вызывает сервер для записи данных.

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


&НаСервере
Функция НайтиКонтрагентаНаСервере(НаименованиеИзSQL)
    Ссылка = Справочники.Контрагенты.НайтиПоНаименованию(НаименованиеИзSQL);
    Если Ссылка.Пустая() Тогда
        Возврат Неопределено;
    Иначе
        Возврат Ссылка;
    КонецЕсли;
КонецФункции

Решение 2: Двухэтапная загрузка (Рекомендуемый подход)

Проанализируем более эффективный подход, который часто используется в типовых конфигурациях. Мы разделяем процесс загрузки на два четких этапа: Анализ и Фиксация.

Этап 1: Анализ. На сервере считываются все данные из внешнего источника. Программа пытается сопоставить всё, что может, в автоматическом режиме. Все «непонятные» строки собираются в отдельную таблицу (или коллекцию).

Этап 2: Интерактив. Эта таблица возвращается на клиент. Пользователь в удобной форме (например, в табличной части на экране) видит список ненайденных объектов и сам проставляет ссылки или нажимает кнопку «Создать всех».

Этап 3: Запись. Когда сопоставление завершено, управление снова передается на сервер для окончательной записи документов или элементов справочников.

Решение 3: Использование временного хранилища

Выясним, как передавать большие объемы данных между этапами, не перегружая память. Если данных много (тысячи строк), передавать их напрямую как параметр ТаблицаЗначений между сервером и клиентом нельзя — это вызовет огромный трафик.

Вместо этого используем ПоместитьВоВременноеХранилище. Рассмотрим алгоритм:

  1. На сервере формируем таблицу ненайденных данных.
  2. Помещаем её в хранилище: Адрес = ПоместитьВоВременноеХранилище(ТаблицаДанных, УникальныйИдентификатор);.
  3. На клиент возвращаем только Адрес (строку).
  4. Клиент открывает форму сопоставления, передавая ей этот адрес. Форма сопоставления на своем сервере извлекает таблицу по адресу, обрабатывает и сохраняет результат обратно.

Это позволяет «гонять» между клиентом и сервером только короткую строку-ссылку, а не мегабайты данных.

Решение 4: Фоновые задания для длительных операций

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

Рассмотрим, как это работает:

  1. Клиент вызывает метод ФоновыеЗадания.Выполнить().
  2. Клиент подключает обработчик ожидания ПодключитьОбработчикОжидания(ИмяПроцедуры, Интервал).
  3. Каждые несколько секунд клиент проверяет статус задания.
  4. Если задание завершено и требует уточнения данных, клиент забирает результат из временного хранилища и показывает форму пользователю.

Использование инструментов БСП

Если ваша конфигурация основана на Библиотеке Стандартных Подсистем (БСП), не нужно изобретать велосипед. Проанализируем подсистему «Загрузка данных из файла» или «Сопоставление данных».

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

Технические нюансы передачи данных

Важно помнить, что тип ТаблицаЗначений не существует на клиенте. Для отображения данных на форме мы должны использовать ДанныеФормыКоллекция (если это табличная часть формы) или преобразовывать данные в Массив Структур при передаче через JSON, если мы работаем в веб-клиенте.

Пример преобразования для передачи на клиент:


&НаСервере
Функция ПолучитьДанныеДляСопоставления()
    ТЗ = Новый ТаблицаЗначений;
    // ... заполнение ТЗ данными из SQL ...
    
    // Преобразуем в массив структур для легкой передачи
    Результат = Новый Массив;
    Для Каждого СтрокаТЗ Из ТЗ Цикл
        Стр = Новый Структура("Наименование, ИНН, ВнешнийИдентификатор");
        ЗаполнитьЗначенияСвойств(Стр, СтрокаТЗ);
        Результат.Добавить(Стр);
    КонецЦикла;
    
    Возврат Результат;
КонецФункции

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

Для реализации качественной загрузки из внешних источников данных в управляемом приложении 1С следует придерживаться следующих правил:

  1. Никогда не пытайтесь вызвать диалог в середине серверного цикла. Разделяйте код на «тихую» серверную часть и «интерактивную» клиентскую.
  2. Используйте временное хранилище для передачи больших таблиц между серверными вызовами.
  3. Проектируйте двухэтапную загрузку: сначала сопоставление всех сущностей, затем — выполнение бизнес-логики (проведение документов, создание записей).
  4. Для больших объемов используйте фоновые задания, чтобы интерфейс пользователя оставался отзывчивым.

Такой подход сделает вашу обработку надежной, быстрой и соответствующей стандартам разработки 1С.

← На главную