При разработке расширений часто возникает задача создать отдельное рабочее место или журнал, где должны отображаться документы разных типов. Казалось бы, достаточно создать обработку, добавить на форму ДинамическийСписок с произвольным запросом, использующим оператор ОБЪЕДИНИТЬ (UNION), и задача решена. Однако на практике разработчики сталкиваются с неприятной особенностью: документы в таком списке отображаются, но их невозможно открыть двойным кликом, а кнопки «Создать», «Изменить» и «Удалить» просто отсутствуют или неактивны. В этой статье мы подробно разберем, почему так происходит, и рассмотрим несколько способов решения проблемы.
Для начала проанализируем поведение платформы «1С:Предприятие 8.3». Ключевым свойством любого динамического списка является Основная таблица. Именно на основе этого свойства платформа понимает, данными какого объекта она оперирует. Если основная таблица указана, 1С автоматически:
Проблема заключается в том, что когда мы пишем сложный запрос, объединяющий несколько таблиц через ОБЪЕДИНИТЬ, поле Основная таблица в настройках списка становится недоступным или очищается. Платформа не может однозначно определить, к какой таблице относятся действия пользователя, если в одной строке списка может быть «Реализация товаров», а в другой — «Поступление товаров». В результате список переходит в режим «Только просмотр».
Если нам необходимо оставить текущую структуру запроса с объединением, мы можем «оживить» список вручную. Рассмотрим, как программно реализовать открытие документов и добавление команд редактирования.
Во-первых, проанализируем событие Выбор таблицы на форме. Нам нужно перехватить двойной клик пользователя и заставить систему открыть форму документа. Реализуем это следующим кодом:
&НаКлиенте
Процедура СписокВыбор(Элемент, ВыбраннаяСтрока, Поле, СтандартнаяОбработка)
// Отменяем стандартную обработку, так как она все равно не сработает
СтандартнаяОбработка = Ложь;
// Получаем ссылку на документ из текущей строки
ТекущиеДанные = Элементы.Список.ТекущиеДанные;
Если ТекущиеДанные <> Неопределено Тогда
// Используем универсальный метод открытия значения
ПоказатьЗначение(Неопределено, ТекущиеДанные.Ссылка);
КонецЕсли;
КонецПроцедуры
Во-вторых, для реализации кнопок «Изменить» или «Создать» нам придется создать собственные команды формы. Рассмотрим пример команды для редактирования:
&НаКлиенте
Процедура КомандаИзменить(Команда)
ТекущиеДанные = Элементы.Список.ТекущиеДанные;
Если ТекущиеДанные <> Неопределено Тогда
ПараметрыФормы = Новый Структура("Ключ", ТекущиеДанные.Ссылка);
// Вычисляем имя формы на основе типа ссылки
ИмяФормы = ПолучитьИмяФормыОбъекта(ТекущиеДанные.Ссылка);
ОткрытьФорму(ИмяФормы, ПараметрыФормы);
КонецЕсли;
КонецПроцедуры
Этот путь быстрый, но он требует ручного дублирования всей стандартной логики (права доступа, обработка удаления и т.д.).
Многие разработчики ошибочно полагают, что в расширении нельзя создавать новые Журналы документов. Однако в современных версиях платформы (начиная с 8.3.11) это возможно. Если ваша цель — объединить несколько типов документов в один список с сохранением всей стандартной функциональности, создание журнала является наиболее правильным подходом.
Разберем последовательность действий:
Журнал документов.Преимущество: Платформа сама создаст динамический список с заполненной основной таблицей (вашим журналом), и все стандартные кнопки будут работать «из коробки».
Проанализируем опыт типовых конфигураций, таких как 1С:Управление торговлей 11 или 1С:ERP. В них для подобных целей часто используется специальный вспомогательный Регистр сведений (например, «Реестр документов»).
Суть метода заключается в следующем:
Регистр сведений, где измерениями или ресурсами выступают общие поля (Дата, Номер, Сумма, Контрагент), а одним из реквизитов — Ссылка на сам документ.Этот метод считается самым производительным. Посмотрим на пример настройки такого списка:
ВЫБРАТЬ
Реестр.Ссылка,
Реестр.Дата,
Реестр.Номер,
Реестр.Контрагент,
Реестр.СуммаДокумента
ИЗ
РегистрСведений.РеестрДокументов КАК Реестр
В свойствах списка указываем РегистрСведений.РеестрДокументов как основную таблицу. Теперь, чтобы при нажатии «Изменить» открывался не сам регистр, а документ, в свойствах таблицы на форме нужно убедиться, что поле Ссылка является основным, а в коде можно переопределить только событие создания нового объекта, так как для открытия существующего платформа подтянет ссылку из регистра.
Выясним еще одну важную причину, по которой кнопки могут быть недоступны. Даже если вы указали основную таблицу, команды редактирования не появятся, если в самом расширении не добавлены соответствующие Роли. Помните: права в основной базе и права в расширении суммируются. Если вы создали новую форму или динамический список внутри расширения, убедитесь, что в расширении есть роль, дающая права на чтение и изменение задействованных объектов, и эта роль назначена пользователю.
Важный нюанс: Если вы используете произвольный запрос, обязательно убедитесь, что в расширение заимствованы все объекты, участвующие в запросе (документы, справочники, перечисления), иначе запрос просто не скомпилируется в контексте расширения.
Подведем итоги нашего анализа. Если вы столкнулись с невозможностью редактирования в динамическом списке расширения:
UNION, выберите другой путь.Выбор и ПоказатьЗначение().Выбор метода зависит от сложности вашей задачи и требований к производительности системы. В большинстве случаев в рамках расширения проще всего реализовать ручную обработку выбора, но для полноценного рабочего места лучше один раз настроить вспомогательный регистр-реестр.