Добрый день, господа из Парижу и товарищи из Пекина!
Наш сегодняшний репортаж я веду из стольного города Нерезиновска.
СУТЬ
Суть рассматриваемой проблемы в том, чтобы организовать две формы, в одной из которых мы сможем кликнуть на найденный элемент (или на иной какой), а в другой форме при этом будет произведено позиционирование на нужный элемент (вот прям как на картинке в заголовке).
ДА ДЕЛО
Итак, для организации такой казалось бы простой и элементарной операции нам потребуется внешняя, например, обработка, с парочкой форм: на первой форме мы нарисуем красочное дерево с реквизитами "СтрокаПоиска" и "ОписаниеДанных", добавим туда команду "Найти" и прибиндим обработчики. Во второй форме у нас будет таблица результата, к которой мы прибиндим обработчик активации строки, а в нем уже спозиционируем "курсор" на выбранную строку в вызвавшей поиск форме.
КОД
Код нашей первой формы достаточно прост:
&НаКлиенте
Функция НайтиРекурсивно(Узел, СтрокаПоиска, Массив = Неопределено)
Если Массив = Неопределено Тогда
Массив = Новый Массив;
КонецЕсли;
Для Каждого Ст ИЗ Узел.ПолучитьЭлементы() Цикл
Если Ст.Данные = СтрокаПоиска ИЛИ Ст.ОписаниеДанных = СтрокаПоиска Тогда
Массив.Добавить(Новый Структура("НайденнаяСтрока,СтрокаДерева", Ст.Данные + " (" + Ст.ОписаниеДанных + ")", Ст.ПолучитьИдентификатор()));
КонецЕсли;
НайтиРекурсивно(Ст, СтрокаПоиска, Массив);
КонецЦикла;
Возврат Массив;
КонецФункции
&НаКлиенте
Функция ПоучитьИмяФормы(Имя)
Возврат СтрЗаменить(ЭтаФорма.ИмяФормы, "ОсновнаяФорма", Имя);
КонецФункции
&НаКлиенте
Процедура НайтиДанные(Команда)
ПоказатьВводСтроки(Новый ОписаниеОповещения("ПослеВводаСтроки", ЭтаФорма, ), , "Введите строку поиска");
КонецПроцедуры
&НаКлиенте
Процедура ПослеВводаСтроки(Рез, Доп) Экспорт
Если НЕ рез = Неопределено Тогда
Массив = НайтиРекурсивно(Дерево, Рез);
Если Массив.Количество() > 0 Тогда
ВладелецФормы.ВремВладелецФормы = ЭтаФорма;
ОткрытьФорму(ПоучитьИмяФормы("ФормаНайдено"), Новый Структура("Данные", Массив), ВладелецФормы, Истина, , , , РежимОткрытияОкнаФормы.БлокироватьОкноВладельца);
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Все процедуры и функции - клиентские. Процедура "НайтиДанные" открывает диалог ввода строки, результат которого попадает в процедуру "ПослеВводаСтроки", в которой вызывается рекурсивная функция поиска "НайтиРекурсивно", результатом выполнения которой является массив структур, содержащих имя найденной строки и ее идентификатор.
Дальше, если строку мы нашли, то наша задача открыть форму отображения результатов поиска. И вот тут появляется проблема...
ПРОБЛЕМА
Если мы откроем новую форму в режиме без блокировки, то она отобразится на новой закладке интерфейса такси, и вытащить ее можно будет только через ПКМ с выбором размещения двух форм на одной закладке. Не все пользователи об этом знаю, а я, например, не знаю, как это сделать программно. Да и не устраивает меня статика = хочется управлять размером и положением формы.
Если мы откроем форму в режиме блокировки вызывающей формы, то мы не сможем одновременно работать в этих двух формах, что в некоторых случаях является печалькой (например, если мы нашли сто ошибок, спозиционировались на первой, чтобы ее исправить закрыли форму поиска, исправили, снова вызвали форму поиска и снова закрыли, чтобы исправить вторую ошибку из ста).
Остается вопрос, а как открыть форму без блокировки владельца, но при этом отдельно от интерфейса такси, чтобы видеть обе формы без бубна и танцев?
РЕШЕНИЕ
Мое решение такое: блокировать третью форму обоими открытыми формами. Это решает все проблемы и позволяет одновременно работать в обоих окнах. Для этого я в обработку добавил еще одну форму "ГлавнаяФорма", функция которой просто открытие окна и хранение информации о форме-владельце для формы поиска. Вот ее код:
&НаКлиенте
Перем ВремВладелецФормы Экспорт;
&НаКлиенте
Функция ПоучитьИмяФормы(Имя)
Возврат СтрЗаменить(ЭтаФорма.ИмяФормы, "ГлавнаяФорма", Имя);
КонецФункции
&НаКлиенте
Процедура ПриОткрытии(Отказ)
ПодключитьОбработчикОжидания("ОткрытьФ", 1, Истина);
КонецПроцедуры
&НаКлиенте
Процедура ОткрытьФ()
ОткрытьФорму(ПоучитьИмяФормы("ОсновнаяФорма"), , ЭтаФорма, , , , , РежимОткрытияОкнаФормы.БлокироватьОкноВладельца);
КонецПроцедуры
Здесь я в начале формы определяю переменную, в которую помещу открытую форму. Дальше в процедуре "ПриОткрытии" мне пришлось подключить обработчик ожидания, который открыл бы мне вторую форму с деревом. Ну и сама процедура открытия формы, которая вызывается уже после открытия формы (т.к. при открытии формы из процедуры "ПриОткрытии" форма не открывается, что заставило вот так выходить из ситуации).
Ну и код третьей формы со строками поиска, кликание на которые производит позиционирование на элемент дерева второй формы:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
Для Каждого Ст ИЗ Параметры.Данные Цикл
ЗаполнитьЗначенияСвойств(Таблица.Добавить(), Ст);
КонецЦикла;
КонецПроцедуры
&НаКлиенте
Процедура ТаблицаПриАктивизацииСтроки(Элемент)
ВладелецФормы.ВремВладелецФормы.Элементы.Дерево.ТекущаяСтрока = Элементы.Таблица.ТекущиеДанные.СтрокаДерева
КонецПроцедуры
Все. Цели достигнуты. Всем спасибо за внимание.