Как программно открыть форму списка регистра сведений с отбором по документу

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

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

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

Анализ исходной проблемы и типичных ошибок

Рассмотрим ситуацию: у нас есть документ Задания и регистр сведений Медиа_файлы. В регистре есть измерение (или реквизит) Задание, где хранится ссылка на документ. Нам нужно при нажатии кнопки на форме документа открыть список регистра с фильтром по текущему документу.

Разберем основные ошибки, которые совершают новички:

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

Шаг 1: Подготовка структуры отбора на клиенте

Начнем с самого простого и правильного способа реализации команды на клиенте. Если кнопка находится на форме документа, у нас уже есть доступ к ссылке текущего документа через реквизит Объект.Ссылка. Нам не нужно обращаться к серверу, чтобы получить эту ссылку.

Рассмотрим правильный алгоритм написания кода для обработчика команды:


&НаКлиенте
Процедура Файлы(Команда)
    
    // 1. Создаем структуру самого отбора. 
    // Ключ - это ИМЯ ПОЛЯ в регистре сведений, по которому фильтруем.
    // Значение - это ссылка на наш документ.
    ОтборПоЗначению = Новый Структура("Задания", Объект.Ссылка);
    
    // 2. Создаем структуру параметров для открытия формы.
    // Платформа ожидает ключ "Отбор", внутри которого лежит наша структура.
    ПараметрыОткрытия = Новый Структура("Отбор", ОтборПоЗначению);
    
    // 3. Открываем форму списка регистра.
    ОткрытьФорму("РегистрСведений.Медиа_файлы.ФормаСписка", ПараметрыОткрытия);
    
КонецПроцедуры

Важный нюанс: Обратите внимание, что имя ключа в структуре ОтборПоЗначению (в примере — "Задания") должно в точности совпадать с именем измерения или реквизита в метаданных регистра сведения. Если в конфигураторе поле называется ОбъектОснование, то и в коде должно быть Новый Структура("ОбъектОснование", Объект.Ссылка).

Шаг 2: Обеспечение уникальности окон

Проанализируем ситуацию: пользователь открыл файлы для «Задания №1», не закрыл окно, вернулся в список документов и нажал кнопку «Файлы» для «Задания №2». Если использовать код выше, 1С просто активирует уже открытое окно с файлами первого задания, и пользователь увидит неактуальные данные.

Чтобы для каждого документа открывалось свое отдельное окно, мы должны использовать КлючУникальности. В качестве такого ключа идеально подходит ссылка на сам документ.


&НаКлиенте
Процедура Файлы(Команда)
    
    ОтборПоЗначению = Новый Структура("Задания", Объект.Ссылка);
    ПараметрыОткрытия = Новый Структура("Отбор", ОтборПоЗначению);
    
    // Используем четвертый параметр функции ОткрытьФорму - КлючУникальности
    ОткрытьФорму("РегистрСведений.Медиа_файлы.ФормаСписка", 
                 ПараметрыОткрытия, 
                 ЭтаФорма, 
                 Объект.Ссылка); // Ключ уникальности
    
КонецПроцедуры

Шаг 3: Проверка настроек динамического списка

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

Продвинутый метод: Использование Фиксированных настроек

Рассмотрим ситуацию, когда стандартного отбора недостаточно. Например, если вы хотите, чтобы пользователь не мог отключить этот отбор в открывшемся окне, или если вам нужен сложный вид сравнения (например, «В списке» или «Больше»). В этом случае рекомендуется использовать ФиксированныеНастройки.

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


&НаКлиенте
Процедура ФайлыРасширенный(Команда)
    
    ПараметрыОткрытия = Новый Структура;
    // Получаем фиксированные настройки с сервера
    ПараметрыОткрытия.Вставить("ФиксированныеНастройки", ПолучитьНастройкиОтбораНаСервере(Объект.Ссылка));
    
    ОткрытьФорму("РегистрСведений.Медиа_файлы.ФормаСписка", ПараметрыОткрытия, ЭтаФорма, Объект.Ссылка);
    
КонецПроцедуры

&НаСервереБезКонтекста
Функция ПолучитьНастройкиОтбораНаСервере(СсылкаДокумента)
    
    НастройкиКомпоновки = Новый НастройкиКомпоновкиДанных;
    
    ЭлементОтбора = НастройкиКомпоновки.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
    // Указываем поле, по которому фильтруем
    ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Задания");
    ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
    ЭлементОтбора.Использование = Истина;
    // Указываем значение
    ЭлементОтбора.ПравоеЗначение = СсылкаДокумента;
    
    Возврат НастройкиКомпоновки;
    
КонецФункции

Разбор работы с контекстом: почему «Документы» не определены?

Проанализируем ошибку автора темы: Переменная не определена (Документы). Это классическая проблема понимания клиент-серверной архитектуры 1С.

В управляемом приложении код исполняется либо на Клиенте (в браузере или тонком клиенте), либо на Сервере (в кластере серверов 1С). На клиенте нам доступны:

На сервере нам доступны:

Когда вы пишете Документы.Задания.ПолучитьСсылку на клиенте, программа пытается обратиться к менеджеру всех документов «Задания», которого на клиенте просто не существует. Если вам нужно получить ссылку программно по какому-то признаку, делайте это в функции &НаСервере, а затем передавайте результат на клиент.

Заключение и рекомендации

Подведем итог. Для успешного открытия формы списка с отбором достаточно придерживаться трех правил:

  1. Всегда передавайте Ссылку (Объект.Ссылка), а не сам Объект.
  2. Используйте структуру с ключом "Отбор" для простых фильтров.
  3. Следите за тем, чтобы имена ключей в структуре совпадали с именами измерений в конфигураторе.

Если вы только начинаете свой путь в 1С, рекомендуем всегда проверять, в каком контексте исполняется ваш код. Если конфигуратор «ругается» на неизвестное имя (например, РегистрыСведений или Запрос), скорее всего, вы пытаетесь выполнить серверный код на стороне клиента.

← На главную