Как открыть форму документа из динамического списка, объединяющего разные типы данных?

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

При разработке интерфейсов на платформе 1С:Предприятие 8.3 (Управляемые формы) часто возникает задача создания универсального рабочего места. Одним из инструментов является динамический список, который собирает данные не из одной таблицы, а из нескольких разных документов с помощью оператора ОБЪЕДИНИТЬ (или UNION в терминах SQL). Однако здесь разработчики сталкиваются со сложностью: при двойном клике или нажатии клавиши Enter система не всегда «понимает», форму какого именно документа нужно открыть, особенно если свойство ОсновнаяТаблица не заполнено. Разберем подробно, как решить эту задачу и сделать интерфейс отзывчивым.

Выясним причину проблемы

Когда мы указываем в динамическом списке конкретную основную таблицу, платформа берет на себя всю работу по управлению стандартными командами: открытие формы, создание нового объекта, пометка на удаление. Но как только мы используем сложный запрос с объединением нескольких таблиц (например, Документ.РеализацияТоваровУслуг и Документ.ОказаниеУслуг), автоматика перестает работать. Платформа не может однозначно определить, к какому метаданному относится выбранная ссылка, если это явно не запрограммировано. Рассмотрим шаги, которые позволят нам вернуть привычное поведение системы.

Способ 1. Использование стандартного метода ПоказатьЗначение

Проанализируем самый простой и эффективный способ, который подходит для большинства задач. Если нам достаточно открыть форму объекта по умолчанию, мы можем воспользоваться встроенным методом ПоказатьЗначение. Этот метод универсален, так как он самостоятельно определяет тип переданной ссылки и вызывает соответствующую форму.

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

  1. Перейдем в свойства элемента формы (вашего списка).
  2. Найдем событие Выбор и нажмем на лупу для создания процедуры на клиенте.
  3. Вставим программный код, который будет определять текущую строку и открывать её.

Рассмотрим пример кода:


&НаКлиенте
Процедура СписокВыбор(Элемент, ВыбраннаяСтрока, Поле, СтандартнаяОбработка)
    
    // Отменяем стандартную обработку, чтобы платформа не пыталась выполнить действие по умолчанию
    СтандартнаяОбработка = Ложь;
    
    // Получаем данные текущей строки списка
    ТекущиеДанные = Элементы.Список.ТекущиеДанные;
    
    // Проверяем, что строка выбрана и содержит ссылку
    Если ТекущиеДанные <> Неопределено Тогда
        // Используем метод ПоказатьЗначение для открытия формы документа
        // Первый параметр - описание оповещения (необязательно), второй - сама ссылка
        ПоказатьЗначение(, ТекущиеДанные.Ссылка);
    КонецЕсли;
    
КонецПроцедуры

Способ 2. Расширенное открытие через ОткрытьФорму

Иногда простого открытия формы недостаточно. Рассмотрим ситуацию, когда вам нужно передать в открываемый документ дополнительные параметры, например, открыть его в режиме «Только просмотр» или передать специфический ключ владельца. В этом случае метод ПоказатьЗначение не подойдет, и нам следует использовать функцию ОткрытьФорму.

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


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

Важные настройки динамического списка

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

  1. Поля ключа: В настройках списка (закладка «Настройка списка») убедитесь, что для поля Ссылка установлена роль Поле ключа. Без этого платформа не сможет корректно идентифицировать строки при их выборе.
  2. Использовать всегда: Перейдите в список полей динамического списка и найдите поле Ссылка. Установите для него флажок Использовать всегда. Это критически важно: если пользователь скроет колонку со ссылкой в настройках формы, программный код ТекущиеДанные.Ссылка вызовет ошибку, если этот флаг не установлен.
  3. Структура запроса: При использовании ОБЪЕДИНИТЬ следите за тем, чтобы во всех частях запроса состав и типы колонок совпадали. Если в одном документе есть поле Контрагент, а в другом нет — во второй части запроса добавьте пустую ссылку: ЗНАЧЕНИЕ(Справочник.Контрагенты.ПустаяСсылка).

Обработка кнопок командной панели

Посмотрим на ситуацию шире: если мы отключили стандартную обработку в событии Выбор, нам также нужно позаботиться о кнопках «Изменить» или «Просмотреть» на командной панели. По умолчанию они могут быть неактивны, так как у списка нет основной таблицы.

Мы рекомендуем создать собственную команду формы (например, КомандаИзменить), вынести её на командную панель и назначить ей тот же программный код, который мы написали для события Выбор. Для этого лучше вынести логику открытия в отдельную процедуру:


&НаКлиенте
Процедура ВыполнитьОткрытиеДокумента()
    ТекущиеДанные = Элементы.Список.ТекущиеДанные;
    Если ТекущиеДанные <> Неопределено Тогда
        ПоказатьЗначение(, ТекущиеДанные.Ссылка);
    КонецЕсли;
КонецПроцедуры

&НаКлиенте
Процедура СписокВыбор(Элемент, ВыбраннаяСтрока, Поле, СтандартнаяОбработка)
    СтандартнаяОбработка = Ложь;
    ВыполнитьОткрытиеДокумента();
КонецПроцедуры

&НаКлиенте
Процедура КомандаИзменить(Команда)
    ВыполнитьОткрытиеДокумента();
КонецПроцедуры

Управление контекстным меню

Проанализируем еще один нюанс — контекстное меню, вызываемое правой кнопкой мыши. Если основная таблица не задана, состав меню будет скудным. Чтобы добавить туда пункт «Изменить», перейдите в свойства таблицы формы, найдите раздел Контекстное меню и добавьте в него кнопку, связанную с вашей командой КомандаИзменить. Таким образом, вы обеспечите полноценный пользовательский опыт, ничем не уступающий работе со стандартными списками.

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

← На главную