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

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

При разработке механизмов импорта данных (например, из XML или Excel) программисты часто сталкиваются с ситуацией, когда загружаемый объект (номенклатура) ссылается на справочник, значения в котором отсутствуют или не сопоставлены. Естественное желание — прервать цикл загрузки и попросить пользователя интерактивно выбрать нужное значение. Однако в среде управляемого приложения это вызывает ряд технических сложностей, связанных с разделением контекста исполнения кода на клиент и сервер.

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

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

Разберем типичную ситуацию: вы запускаете загрузку файла. Чтение XML и создание объектов справочника происходит НаСервере, так как только там доступны манипуляции с базой данных. В процессе проверки выясняется, что ВидНоменклатуры не найден. Попытка вызвать ПолучитьФорму().Открыть() или ОткрытьФорму() внутри серверной процедуры приведет к ошибке.

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

Решение №1: Простой интерактивный выбор на клиенте

Если ваша задача — быстро «подправить» код для разовой обработки, необходимо перенести логику обхода строк на сторону клиента. Рассмотрим, как правильно вызвать форму выбора НаКлиенте.

Для открытия формы выбора справочника ВидыНоменклатуры используем стандартный метод ОткрытьФорму. Проанализируем пример кода:


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

Чтобы получить результат выбора, в модуле формы необходимо реализовать стандартное событие ОбработкаВыбора. Рассмотрим, как поймать выбранное значение:


&НаКлиенте
Процедура ОбработкаВыбора(ВыбранноеЗначение, ИсточникВыбора)
    Если ТипЗнч(ВыбранноеЗначение) = Тип("СправочникСсылка.ВидыНоменклатуры") Тогда
        // Здесь мы получаем выбранную ссылку и можем продолжить загрузку
        ПродолжитьЗагрузкуСВыбраннымВидом(ВыбранноеЗначение);
    КонецЕсли;
КонецПроцедуры

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

Решение №2: Паттерн «Таблица сопоставления» (Рекомендуемый подход)

Проанализируем более профессиональный метод, который используется в типовых конфигурациях (например, в «1С:Управление торговлей 11» при загрузке прайс-листов). Вместо того чтобы вызывать окна в цикле, мы разделим процесс на три этапа:

  1. Предварительный анализ (Сервер): Проходим по всему файлу, ищем соответствия. Если вид номенклатуры не найден, помечаем эту строку.
  2. Интерактивное сопоставление (Клиент): Выводим пользователю таблицу со всеми «проблемными» позициями. Пользователь один раз заполняет пустые колонки, выбирая значения из справочника.
  3. Запись данных (Сервер): Когда все соответствия указаны, запускаем итоговую процедуру создания объектов.

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


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

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

Использование асинхронных вызовов (платформа 8.3.15+)

В современных версиях платформы 1С настоятельно рекомендует отказываться от модальности. Если вам все же нужно открывать окна выбора последовательно, используйте механизм ОписаниеОповещения. Это позволяет коду не «замирать», а передавать управление следующей функции после закрытия окна.

Разберем пример вызова с оповещением:


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

&НаКлиенте
Процедура ПослеВыбораВида(Результат, ДополнительныеПараметры) Экспорт
    Если Результат <> Неопределено Тогда
        // Обработка результата и переход к следующей строке
    КонецЕсли;
КонецПроцедуры

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

Выясним главные правила работы с интерактивными окнами в управляемом приложении:

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

← На главную