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