Дерево значений и текущая строка
Имеем на форме:
— Таблица с отображением в виде дерева. Она связана с реквизитом «ДеревоДанных», который имеет тип ДеревоЗначений. Там рисуем дерево документов за период с учетом подчиненности.
— Кнопочка «Обновить», которая вызывает серверную функцию заполнения дерева и обновляет дерево документов.
&НаСервере Процедура _СформироватьДерево() Запрос = Новый Запрос; . Формируем и выполняем запрос к БД. Дерево = РеквизитФормыВЗначение("ДеревоДанных"); Дерево.Строки.Очистить(); Пока Выборка.Следующий() Цикл . Формируем дерево по определенной логике. КонецЦикла; ЗначениеВРеквизитФормы(Дерево, "ДеревоДанных"); КонецПроцедуры &НаКлиенте Процедура КомандаОбновитьДерево(Команда) _СформироватьДерево(); КонецПроцедуры
Задача: как определить текущую подсвеченную строку в дереве значений, чтобы после обновления вновь её сделать текущей.
&НаСервере Процедура _СформироватьДерево() Запрос = Новый Запрос; . Формируем и выполняем запрос к БД. Дерево = РеквизитФормыВЗначение("ДеревоДанных"); Дерево.Строки.Очистить(); Пока Выборка.Следующий() Цикл . Формируем дерево по определенной логике. КонецЦикла; ЗначениеВРеквизитФормы(Дерево, "ДеревоДанных"); КонецПроцедуры
//определяем переменную для формы Перем мОтбор; //запоминаем данные строки ТекСтрока = Элементы.ДеревоДанных.ТекущиеДанные; мОтбор = Новый Структура("Колонка1, Колонка2", ТекСтрока.Колонка1, ТекСтрока.Колонка2); //запомнили //после обновления Дерево = РеквизитФормыВЗначение("ДеревоДанных"); Элементы.ДеревоДанных.ТекущаяСтрока = Дерево.Строки.НайтиСтроки(мОтбор)[0];
Не тестировал, но, думаю, на путь правильный направил) Колонка1, Колонка2 — колонки, по которым можно идентифицировать строку
(3)На клиенте определили текущую строку, в ней есть ссылочка на документ. Это будет уникальным значением для дальнейшего поиска этой строки. Передаем эту ссылку на сервер перед обновлением дерева.
&НаКлиенте Процедура КомандаОбновитьДерево(Команда) ТекущиеДанные = Элементы.ДеревоДанных.ТекущиеДанные.Ссылка; мОтбор = Новый Структура("Ссылка", ТекущиеДанные); //запомнили _СформироватьДерево(мОтбор); КонецПроцедуры &НаСервере Функция _СформироватьДерево(ТекущаяСтрока = Неопределено) Запрос = Новый Запрос; . Формируем и выполняем запрос к БД. Дерево = РеквизитФормыВЗначение("ДеревоДанных"); Дерево.Строки.Очистить(); Пока Выборка.Следующий() Цикл . Формируем дерево по определенной логике. КонецЦикла; ЗначениеВРеквизитФормы(Дерево, "ДеревоДанных"); ВозвращаемоеЗначение = Неопределено; Если НЕ ТекущаяСсылка = Неопределено Тогда //Элементы.ДеревоДанных.ТекущаяСтрока = Дерево.Строки.НайтиСтроки(ТекущаяСсылка, Истина)[0].ПолучитьИдентификатор(); //Не работает. Нужен объект типа ДанныеФормыЭлементДерева. ВозвращаемоеЗначение = Дерево.Строки.НайтиСтроки(ТекущаяСсылка, Истина)[0]; КонецЕсли; Возврат ВозвращаемоеЗначение; КонецФункции
Накрутил что-то я. Отвлекают. Как нам теперь установить текущую строку в форме? И можно ли это сделать на сервере?
Посмотрите в справке «НайтиСтроки»: вы указываете там ссылку, а нужно указать структуру с наименованием колонок и значениями
&НаКлиенте Процедура НайтиСтрокуДерева(КоллекцияЭлементовДерева, ТекущиеДанные, ИдентификаторСтроки, ПрекратитьПоиск) Для Каждого СтрокаДерева Из КоллекцияЭлементовДерева Цикл Если ПрекратитьПоиск Тогда Возврат; КонецЕсли; Если СтрокаДерева.Ссылка = ТекущиеДанные Тогда ИдентификаторСтроки = СтрокаДерева.ПолучитьИдентификатор(); ПрекратитьПоиск = Истина; Возврат; КонецЕсли; КоллекцияЭлементов = СтрокаДерева.ПолучитьЭлементы(); Если КоллекцияЭлементов.Количество() > 0 Тогда НайтиСтрокуДерева(КоллекцияЭлементов, ТекущиеДанные, ИдентификаторСтроки, ПрекратитьПоиск); КонецЕсли; КонецЦикла; КонецПроцедуры &НаКлиенте Процедура КомандаОбновитьДерево(Команда) ТекущиеДанные = Элементы.ДеревоДанных.ТекущиеДанные.Ссылка; мОтбор = Новый Структура("Ссылка", ТекущиеДанные); //запомнили _СформироватьДерево(мОтбор); ИдентификаторСтроки = 0; ПрекратитьПоиск = Ложь; НайтиСтрокуДерева(ДеревоДанных.ПолучитьЭлементы(), ТекущиеДанные, ИдентификаторСтроки, ПрекратитьПоиск); Элементы.ДеревоДанных.ТекущаяСтрока = ИдентификаторСтроки; КонецПроцедуры
madway; noctar; Grivba; LiebeMein; nikolav; pvlunegov; mi13; Stradivari; a_a_burlakov; TMV; denvit; user659168_xec8787; Abrupt; for_questions; logarifm; Manticor; DADemishkevich; RibD; + 18 – Ответить
(6) Да-да. Спасибо!
Уже подсмотрел в БСП. Именно так и надо решать мою задачку.
О методе ПолучитьЭлементы() у визуальной формы дерева я совсем позабыл.
В БСП процедурка описана в модуле «ОбщегоНазначенияКлиентСервер» и зовется «ПолучитьИдентификаторСтрокиДереваПоЗначениюПоля». Параметры там такие: ИмяПоля, ИдентификаторСтроки, КоллекцияЭлементовДерева, КлючСтроки, ПрекратитьПоиск.
(6) Сделал так, но ТекущаяСтрока не меняется, судя по отладчику. Может быть это из-за того, что обновление дерева у меня происходит в процедуре ДеревоЦенПриОкончанииРедактирования . Где-то натыкался на сообщение, что нельзя присвоить текущую строку в предопределённых процедурах. Но что тогда делать? У меня при изменении в документе УстановкаЦен происходит пересчёт остаков (своя колонка) и курсор уходит на первую строку.
Стояла задача, при отметке на удаление одного из элементов дерева значений, пройтись по остальным элементам на сервере и для идентичных элементов проставить на форме такую же пометку (ложи или истина), как показано на первом прикрепленном скриншоте.
После выполнения на сервере метода «ЗначениеВРеквизитФормы(ДЗ,»ТаблицаНаименованийДЗКоллекция»)» текущая строка принимает значение «Неопределено», дерево значений сворачиваетсяи курсор перескакивает на первую строку таблицы дерева значений.
Чтобы курсор оставался на той же позиции, на которой ставилась пометка на удаление, в процедуре «ТаблицаНаименованийДЗКоллекцияПометкаУдаленияПриИзменении(Элемент)» до начала выполнения серверной процедуры были сохранены текущие данные строки (эти данные в процедуре сопровождены комментарием).
Также на втором прикрепленном скриншоте показаны текущие данные текущей строки, часть из которых и была использована для будущей точной идентификации текущей строки.
После выполнения серверной процедуры из клиентской процедуры, из которой вызывалась серверная процедура, была вызвана клиентская рекурсивная «Процедура НайтиСтрокуДерева()», которая позволила идентифицировать строку второго уровня таблицы дерева значений. В результате дерево значений не сворачивалось и курсор остался на той строке, на которой ставилась пометка на удаление. Код процедур приведен ниже:
&НаСервере Процедура ТаблицаНаименованийДЗКоллекцияПометкаУдаленияПриИзмененииНаСервере(НаименованиеБезТранскрипции,ИностранноеСловоСсылка,ПометкаУдаления) ИностранноеСловоОбъект = ИностранноеСловоСсылка.ПолучитьОбъект(); Если ПометкаУдаления Тогда ИностранноеСловоОбъект.УстановитьПометкуУдаления(Истина); Сообщить("Помечено на удаление слово " + ИностранноеСловоСсылка + "!"); Иначе ИностранноеСловоОбъект.УстановитьПометкуУдаления(Ложь); Сообщить("Снята пометка на удаления у слова " + ИностранноеСловоСсылка + "!"); КонецЕсли; ДЗ = РеквизитФормыВЗначение("ТаблицаНаименованийДЗКоллекция"); НайденнаяКореннаяСтрокаДЗ = ДЗ.Строки.Найти(НаименованиеБезТранскрипции,"НаименованиеБезТранскрипции"); Для каждого Стр Из НайденнаяКореннаяСтрокаДЗ.Строки Цикл Если Стр.ИностранноеСлово = ИностранноеСловоСсылка Тогда Стр.ПометкаУдаления = ПометкаУдаления; КонецЕсли; КонецЦикла; ЗначениеВРеквизитФормы(ДЗ,"ТаблицаНаименованийДЗКоллекция"); КонецПроцедуры &НаКлиенте Процедура ТаблицаНаименованийДЗКоллекцияПометкаУдаленияПриИзменении(Элемент) ИностранноеСловоСсылка = Элементы.ТаблицаНаименованийДЗКоллекция.ТекущиеДанные.ИностранноеСлово; ПометкаУдаления = Элементы.ТаблицаНаименованийДЗКоллекция.ТекущиеДанные.ПометкаУдаления; НаименованиеБезТранскрипции = Элементы.ТаблицаНаименованийДЗКоллекция.ТекущиеДанные.НаименованиеБезТранскрипции; ТекСтрока = Элементы.ТаблицаНаименованийДЗКоллекция.ТекущиеДанные; Если не ЗначениеЗаполнено(ИностранноеСловоСсылка) Тогда Элементы.ТаблицаНаименованийДЗКоллекция.ТекущиеДанные.ПометкаУдаления = Ложь; Возврат; КонецЕсли; //Получить данные первого уровня таблицы дерева значений для идентификации теущей строки до пересчета дерева значений на сервере //если этого не сделать, то после пересчета на сервере идентифицировать строку будет невозможно КоллекцияЭлементовДерева = ТаблицаНаименованийДЗКоллекция.ПолучитьЭлементы(); ТекущиеДанныеПервогоУровня = Элементы.ТаблицаНаименованийДЗКоллекция.ТекущиеДанные.НаименованиеБезТранскрипции; ТекущиеДанныеВторогоУровня = Новый Структура("ИностранноеСлово,ЯзыкПеревода",Элементы.ТаблицаНаименованийДЗКоллекция.ТекущиеДанные.ИностранноеСлово,Элементы.ТаблицаНаименованийДЗКоллекция.ТекущиеДанные.ЯзыкПеревода); ИдентификаторСтроки = 0; ПрекратитьПоиск = Ложь; НомерУровня = 1; //Проставить или убрать пометки на удаление у всех элементов справочника с одинаковыми ссылками, входящих в таблицу дерева значений ТаблицаНаименованийДЗКоллекцияПометкаУдаленияПриИзмененииНаСервере(НаименованиеБезТранскрипции,ИностранноеСловоСсылка,ПометкаУдаления); //Установить курсор на ту же строку, которая была активирована до пересчета дерева значений на сервере НайтиСтрокуДерева(КоллекцияЭлементовДерева, ТекущиеДанныеПервогоУровня, ТекущиеДанныеВторогоУровня, ИдентификаторСтроки, ПрекратитьПоиск, НомерУровня); КонецПроцедуры &НаКлиенте Процедура НайтиСтрокуДерева(КоллекцияЭлементовДерева, ТекущиеДанныеПервогоУровня, ТекущиеДанныеВторогоУровня, ИдентификаторСтроки, ПрекратитьПоиск, НомерУровня) Для Каждого СтрокаДерева Из КоллекцияЭлементовДерева Цикл Если ПрекратитьПоиск Тогда Возврат; КонецЕсли; Если НомерУровня = 1 и СтрокаДерева.НаименованиеБезТранскрипции = ТекущиеДанныеПервогоУровня Тогда ИдентификаторСтроки = СтрокаДерева.ПолучитьИдентификатор(); КоллекцияПодчиненныхЭлементовДерева = СтрокаДерева.ПолучитьЭлементы(); Если КоллекцияПодчиненныхЭлементовДерева.Количество() = 0 Тогда ПрекратитьПоиск = Истина; Возврат; Иначе НомерУровня = НомерУровня + 1; ИдентификаторСтроки = 0; ПрекратитьПоиск = Ложь; НайтиСтрокуДерева(КоллекцияПодчиненныхЭлементовДерева, ТекущиеДанныеПервогоУровня, ТекущиеДанныеВторогоУровня, ИдентификаторСтроки, ПрекратитьПоиск, НомерУровня); КонецЕсли; ИначеЕсли НомерУровня = 2 и СтрокаДерева.ИностранноеСлово = ТекущиеДанныеВторогоУровня.ИностранноеСлово и СтрокаДерева.ЯзыкПеревода = ТекущиеДанныеВторогоУровня.ЯзыкПеревода Тогда ИдентификаторСтроки = СтрокаДерева.ПолучитьИдентификатор(); Элементы.ТаблицаНаименованийДЗКоллекция.ТекущаяСтрока = ИдентификаторСтроки; КонецЕсли; КонецЦикла; КонецПроцедуры
Источник
Дерево значений на форме
Как получить текущий элемент в дереве значений и обращаясь к нему добавить подчиненную группу? Но у меня группа добавляется только в корень дерева.
ДеревоОбъектов на форме обработки
КорневыеЭлементы = ДеревоОбъектов.ПолучитьЭлементы(); НовыйКорневойЭлемент = КорневыеЭлементы.Добавить(); ДочерныеЭлементыНовогоКорневого = НовыйКорневойЭлемент.ПолучитьЭлементы(); НовыйВложенныйЭлемент = ДочерныеЭлементыНовогоКорневого.Добавить(); НовыйВложенныйЭлемент.Код = ЛистЭксель.Cells(Строка, 1).value; НовыйВложенныйЭлемент.Наименование = ЛистЭксель.Cells(Строка, 2).value; НовыйВложенныйЭлемент.ЭтоГруппа = Истина;
Элементы.дерево.текущаястрока — это идентификатор. Дерево.найти по идентификатор(текстрока).
ПолучитьЭлементы().добавить() — это добавить элемент с текущей строкой в качестве родителя.
Элементы.дерево.текущаястрока — это идентификатор. Дерево.найти по идентификатор(текстрока).
ПолучитьЭлементы().добавить() — это добавить элемент с текущей строкой в качестве родителя.
через текущую строку не получается, она не определена, получается обратиться только по индексу Элемент1 = ДеревоОбъектов.ПолучитьЭлементы()[0].ПолучитьЭлементы(); но только это не правильно, мне нужно каждый раз получать следующий элемент
(4)
(5) ну Вы же пишите, что «текущий элемент» хотите «обработать», а как Вы узнаете, какой из элементов «Текущий»? Если у Вас в «ТекущаяСтрока» «неопределено», то это значит, что нет у Вас «текущего элемента» — печалька.
Для работы с деревом значений в управляемых формах подход такой: само дерево значений как реквизит формы, может быть обработано как обычное дерево значений с той разницей, что подчиненные строки не из ЭлементДерева.Строка доступны, а из «ЭлементДерева.ПолучитьЭлементы()», а вот выделенные строки, текущая строка, на которой пользователь жамкнул и прочее — это все в Элементы.Дерево.ТекущаяСтрка/ВыделенныеСтроки. И последние содержат либо идентификатор строки, который уже в реквизите ищется через «ПолучитьПоИдентификатору(Идентификатор)», а если в текущей строке «неопределено», а в выделенных строках — пустой массив, то это говорит о том, что пользователь на элемент дерева не жамкнул. И в этом случае что=то добавлять следует, полагаю, в корень (т.е. Дерево.ПолучитьЭлементы().Добавить», а не «Дерево.ПолучитьПоИдентификатору(ТекСтрока).ПолучитьЭлементы().Добавить()» — вот и вся суть всей разницы.
Источник