Каталог решений - ЛайфХак: окно с результатами поиска и динамическим позиционированием в найденном

ЛайфХак: окно с результатами поиска и динамическим позиционированием в найденном

ЛайфХак: окно с результатами поиска и динамическим позиционированием в найденном

В наличии

Вот есть на форме дерево (или макет) с кучей данных. Нажимаем Ctrl+F и находим искомое. А потом еще раз, потом еще, потом еще… Ну и так далее. Есть мысль, как это все улучшить и углубить, ну и решить одну интересную проблему с «модальностью».

Категория:

Описание

Добрый день, господа из Парижу и товарищи из Пекина!

Наш сегодняшний репортаж я веду из стольного города Нерезиновска.

СУТЬ

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

ДА ДЕЛО

Итак, для организации такой казалось бы простой и элементарной операции нам потребуется внешняя, например, обработка, с парочкой форм: на первой форме мы нарисуем красочное дерево с реквизитами "СтрокаПоиска" и "ОписаниеДанных", добавим туда команду "Найти" и прибиндим обработчики. Во второй форме у нас будет таблица результата, к которой мы прибиндим обработчик активации строки, а в нем уже спозиционируем "курсор" на выбранную строку в вызвавшей поиск форме.

КОД

Код нашей первой формы достаточно прост:


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

&НаКлиенте
Функция ПоучитьИмяФормы(Имя)
	Возврат СтрЗаменить(ЭтаФорма.ИмяФормы, "ОсновнаяФорма", Имя);
КонецФункции

&НаКлиенте
Процедура НайтиДанные(Команда)
	ПоказатьВводСтроки(Новый ОписаниеОповещения("ПослеВводаСтроки", ЭтаФорма, ), , "Введите строку поиска");
КонецПроцедуры

&НаКлиенте
Процедура ПослеВводаСтроки(Рез, Доп) Экспорт 
	Если НЕ рез = Неопределено Тогда 
		Массив = НайтиРекурсивно(Дерево, Рез);
		Если Массив.Количество() > 0 Тогда 
			ВладелецФормы.ВремВладелецФормы = ЭтаФорма;
			ОткрытьФорму(ПоучитьИмяФормы("ФормаНайдено"), Новый Структура("Данные", Массив), ВладелецФормы, Истина, , , , РежимОткрытияОкнаФормы.БлокироватьОкноВладельца);
		КонецЕсли;
	КонецЕсли;
КонецПроцедуры

Все процедуры и функции — клиентские. Процедура "НайтиДанные" открывает диалог ввода строки, результат которого попадает в процедуру "ПослеВводаСтроки", в которой вызывается рекурсивная функция поиска "НайтиРекурсивно", результатом выполнения которой является массив структур, содержащих имя найденной строки и ее идентификатор.

Дальше, если строку мы нашли, то наша задача открыть форму отображения результатов поиска. И вот тут появляется проблема…

ПРОБЛЕМА

Если мы откроем новую форму в режиме без блокировки, то она отобразится на новой закладке интерфейса такси, и вытащить ее можно будет только через ПКМ с выбором размещения двух форм на одной закладке. Не все пользователи об этом знаю, а я, например, не знаю, как это сделать программно. Да и не устраивает меня статика = хочется управлять размером и положением формы.

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

Остается вопрос, а как открыть форму без блокировки владельца, но при этом отдельно от интерфейса такси, чтобы видеть обе формы без бубна и танцев?

РЕШЕНИЕ

Мое решение такое: блокировать третью форму обоими открытыми формами. Это решает все проблемы и позволяет одновременно работать в обоих окнах. Для этого я в обработку добавил еще одну форму  "ГлавнаяФорма", функция которой просто открытие окна и хранение информации о форме-владельце для формы поиска. Вот ее код:

&НаКлиенте
Перем ВремВладелецФормы Экспорт;

&НаКлиенте
Функция ПоучитьИмяФормы(Имя)
	Возврат СтрЗаменить(ЭтаФорма.ИмяФормы, "ГлавнаяФорма", Имя);
КонецФункции

&НаКлиенте
Процедура ПриОткрытии(Отказ)
	ПодключитьОбработчикОжидания("ОткрытьФ", 1, Истина);
КонецПроцедуры

&НаКлиенте
Процедура ОткрытьФ()
	ОткрытьФорму(ПоучитьИмяФормы("ОсновнаяФорма"), , ЭтаФорма, , , , , РежимОткрытияОкнаФормы.БлокироватьОкноВладельца);
КонецПроцедуры

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

Ну и код третьей формы со строками поиска, кликание на которые производит позиционирование на элемент дерева второй формы:


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
	Для Каждого Ст ИЗ Параметры.Данные Цикл 
		ЗаполнитьЗначенияСвойств(Таблица.Добавить(), Ст);
	КонецЦикла;
КонецПроцедуры

&НаКлиенте
Процедура ТаблицаПриАктивизацииСтроки(Элемент)
	ВладелецФормы.ВремВладелецФормы.Элементы.Дерево.ТекущаяСтрока = Элементы.Таблица.ТекущиеДанные.СтрокаДерева
КонецПроцедуры

Все. Цели достигнуты. Всем спасибо за внимание.

has been added to your cart:
Оформление заказа