Дерево значений и текущая строка

1. 4 16.05.13 09:34 Сейчас в теме
Имеем на форме:
- Таблица с отображением в виде дерева. Она связана с реквизитом "ДеревоДанных", который имеет тип ДеревоЗначений. Там рисуем дерево документов за период с учетом подчиненности.
- Кнопочка "Обновить", которая вызывает серверную функцию заполнения дерева и обновляет дерево документов.

Имеем код:
&НаСервере
Процедура _СформироватьДерево()
	Запрос = Новый Запрос;
... Формируем  и выполняем запрос к БД...
	Дерево = РеквизитФормыВЗначение("ДеревоДанных");
	Дерево.Строки.Очистить();
	Пока Выборка.Следующий() Цикл
... Формируем дерево по определенной логике...
	КонецЦикла;
	ЗначениеВРеквизитФормы(Дерево, "ДеревоДанных");
КонецПроцедуры

&НаКлиенте
Процедура КомандаОбновитьДерево(Команда)
	_СформироватьДерево();
КонецПроцедуры
Показать

Задача: как определить текущую подсвеченную строку в дереве значений, чтобы после обновления вновь её сделать текущей.
Ответы
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
2. mozz 148 16.05.13 09:43 Сейчас в теме
Думаю, как-то так:
&НаСервере 
Процедура _СформироватьДерево() 
Запрос = Новый Запрос; 
... Формируем и выполняем запрос к БД... 
Дерево = РеквизитФормыВЗначение("ДеревоДанных"); 
Дерево.Строки.Очистить(); 
Пока Выборка.Следующий() Цикл 
... Формируем дерево по определенной логике... 
КонецЦикла; 
ЗначениеВРеквизитФормы(Дерево, "ДеревоДанных"); 
КонецПроцедуры 
Показать


&НаКлиенте
Процедура КомандаОбновитьДерево(Команда)
СтараяТекущаяСтрока = Элементы.ДеревоНаФорме.ТекущиеДанные;
_СформироватьДерево();
// А вот тут позиционируемся обратно на строке
КонецПроцедуры
3. RocKeR_13 1011 16.05.13 09:49 Сейчас в теме
//определяем переменную для формы
Перем мОтбор;

//запоминаем данные строки
ТекСтрока = Элементы.ДеревоДанных.ТекущиеДанные;
мОтбор = Новый Структура("Колонка1, Колонка2", ТекСтрока.Колонка1, ТекСтрока.Колонка2); //запомнили

//после обновления
Дерево = РеквизитФормыВЗначение("ДеревоДанных");
Элементы.ДеревоДанных.ТекущаяСтрока = Дерево.Строки.НайтиСтроки(мОтбор)[0];
Показать


Не тестировал, но, думаю, на путь правильный направил) Колонка1, Колонка2 - колонки, по которым можно идентифицировать строку
perepetulichka; doom2good; +2 Ответить
4. foxey 4 16.05.13 12:48 Сейчас в теме
(3)На клиенте определили текущую строку, в ней есть ссылочка на документ. Это будет уникальным значением для дальнейшего поиска этой строки. Передаем эту ссылку на сервер перед обновлением дерева.

&НаКлиенте
Процедура КомандаОбновитьДерево(Команда)
	ТекущиеДанные = Элементы.ДеревоДанных.ТекущиеДанные.Ссылка;
	мОтбор = Новый Структура("Ссылка", ТекущиеДанные); //запомнили
_СформироватьДерево(мОтбор);
КонецПроцедуры

&НаСервере 
Функция _СформироватьДерево(ТекущаяСтрока = Неопределено) 
Запрос = Новый Запрос; 
... Формируем и выполняем запрос к БД... 
Дерево = РеквизитФормыВЗначение("ДеревоДанных"); 
Дерево.Строки.Очистить(); 
Пока Выборка.Следующий() Цикл 
... Формируем дерево по определенной логике... 
КонецЦикла; 
ЗначениеВРеквизитФормы(Дерево, "ДеревоДанных"); 
	ВозвращаемоеЗначение = Неопределено;
	Если НЕ ТекущаяСсылка = Неопределено Тогда
		//Элементы.ДеревоДанных.ТекущаяСтрока = Дерево.Строки.НайтиСтроки(ТекущаяСсылка, Истина)[0].ПолучитьИдентификатор(); //Не работает. Нужен объект типа ДанныеФормыЭлементДерева...
		ВозвращаемоеЗначение = Дерево.Строки.НайтиСтроки(ТекущаяСсылка, Истина)[0]; 
	КонецЕсли;
	Возврат ВозвращаемоеЗначение;
КонецФункции 
Показать

Накрутил что-то я... Отвлекают... Как нам теперь установить текущую строку в форме? И можно ли это сделать на сервере?
5. RocKeR_13 1011 16.05.13 13:38 Сейчас в теме
Посмотрите в справке "НайтиСтроки": вы указываете там ссылку, а нужно указать структуру с наименованием колонок и значениями
6. Caliban 116 16.05.13 15:40 Сейчас в теме
&НаКлиенте
Процедура НайтиСтрокуДерева(КоллекцияЭлементовДерева, ТекущиеДанные, ИдентификаторСтроки, ПрекратитьПоиск)

	Для Каждого СтрокаДерева Из КоллекцияЭлементовДерева Цикл
		Если ПрекратитьПоиск Тогда
			Возврат;
		КонецЕсли;

        Если СтрокаДерева.Ссылка = ТекущиеДанные Тогда
			ИдентификаторСтроки = СтрокаДерева.ПолучитьИдентификатор();
            ПрекратитьПоиск = Истина;
            Возврат;
        КонецЕсли;

		КоллекцияЭлементов = СтрокаДерева.ПолучитьЭлементы();

        Если КоллекцияЭлементов.Количество() > 0 Тогда
            НайтиСтрокуДерева(КоллекцияЭлементов, ТекущиеДанные, ИдентификаторСтроки, ПрекратитьПоиск);
        КонецЕсли;
	КонецЦикла;

КонецПроцедуры

&НаКлиенте 
Процедура КомандаОбновитьДерево(Команда) 
	ТекущиеДанные = Элементы.ДеревоДанных.ТекущиеДанные.Ссылка; 
	мОтбор = Новый Структура("Ссылка", ТекущиеДанные); //запомнили 
	_СформироватьДерево(мОтбор); 

	ИдентификаторСтроки = 0;
	ПрекратитьПоиск = Ложь;
	НайтиСтрокуДерева(ДеревоДанных.ПолучитьЭлементы(), ТекущиеДанные, ИдентификаторСтроки, ПрекратитьПоиск);
	Элементы.ДеревоДанных.ТекущаяСтрока = ИдентификаторСтроки;
КонецПроцедуры
Показать
Grivba; LiebeMein; nikolav; pvlunegov; mi13; Stradivari; a_a_burlakov; TMV; denvit; user659168_xec8787; Abrupt; for_questions; logarifm; Manticor; DADemishkevich; RibD; +16 Ответить
7. foxey 4 16.05.13 16:04 Сейчас в теме
(6) Да-да. Спасибо!
Уже подсмотрел в БСП. Именно так и надо решать мою задачку.
О методе ПолучитьЭлементы() у визуальной формы дерева я совсем позабыл.

В БСП процедурка описана в модуле "ОбщегоНазначенияКлиентСервер" и зовется "ПолучитьИдентификаторСтрокиДереваПоЗначениюПоля". Параметры там такие: ИмяПоля, ИдентификаторСтроки, КоллекцияЭлементовДерева, КлючСтроки, ПрекратитьПоиск.

Еще раз спасибо всем.
user717534; pvlunegov; Spacer; Xershi; DADemishkevich; +5 Ответить
12. kobayoshi 8 12.01.22 16:29 Сейчас в теме
(6) Сделал так, но ТекущаяСтрока не меняется, судя по отладчику. Может быть это из-за того, что обновление дерева у меня происходит в процедуре ДеревоЦенПриОкончанииРедактирования. Где-то натыкался на сообщение, что нельзя присвоить текущую строку в предопределённых процедурах. Но что тогда делать? У меня при изменении в документе УстановкаЦен происходит пересчёт остаков (своя колонка) и курсор уходит на первую строку.
8. wtlz 205 29.01.14 16:23 Сейчас в теме
строку подсветили - но выделена первая колонка. Как установить выделения для другой колонки?
9. VadimTer 20.07.21 20:40 Сейчас в теме
Стояла задача, при отметке на удаление одного из элементов дерева значений, пройтись по остальным элементам на сервере и для идентичных элементов проставить на форме такую же пометку (ложи или истина), как показано на первом прикрепленном скриншоте.

После выполнения на сервере метода "ЗначениеВРеквизитФормы(ДЗ,"ТаблицаНаименованийДЗКоллекция")" текущая строка принимает значение "Неопределено", дерево значений сворачиваетсяи курсор перескакивает на первую строку таблицы дерева значений.

Чтобы курсор оставался на той же позиции, на которой ставилась пометка на удаление, в процедуре "ТаблицаНаименованийДЗКоллекцияПометкаУдаленияПриИзменении(Элемент)" до начала выполнения серверной процедуры были сохранены текущие данные строки (эти данные в процедуре сопровождены комментарием).

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

После выполнения серверной процедуры из клиентской процедуры, из которой вызывалась серверная процедура, была вызвана клиентская рекурсивная "Процедура НайтиСтрокуДерева()", которая позволила идентифицировать строку второго уровня таблицы дерева значений. В результате дерево значений не сворачивалось и курсор остался на той строке, на которой ставилась пометка на удаление. Код процедур приведен ниже:


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


&НаКлиенте
Процедура ТаблицаНаименованийДЗКоллекцияПометкаУдаленияПриИзменении(Элемент)
	
	ИностранноеСловоСсылка = Элементы.ТаблицаНаименованийДЗКоллекция.ТекущиеДанные.ИностранноеСлово;
	ПометкаУдаления = Элементы.ТаблицаНаименованийДЗКоллекция.ТекущиеДанные.ПометкаУдаления;
	НаименованиеБезТранскрипции = Элементы.ТаблицаНаименованийДЗКоллекция.ТекущиеДанные.НаименованиеБезТранскрипции;
	ТекСтрока = Элементы.ТаблицаНаименованийДЗКоллекция.ТекущиеДанные;
		
	Если не ЗначениеЗаполнено(ИностранноеСловоСсылка) Тогда  	
		Элементы.ТаблицаНаименованийДЗКоллекция.ТекущиеДанные.ПометкаУдаления = Ложь;	
		Возврат;	
	КонецЕсли;        	
	
	//Получить данные первого уровня таблицы дерева значений для идентификации теущей строки до пересчета дерева значений на сервере
	//если этого не сделать, то после пересчета на сервере идентифицировать строку будет невозможно
	КоллекцияЭлементовДерева = ТаблицаНаименованийДЗКоллекция.ПолучитьЭлементы();
	ТекущиеДанныеПервогоУровня = Элементы.ТаблицаНаименованийДЗКоллекция.ТекущиеДанные.НаименованиеБезТранскрипции;
	ТекущиеДанныеВторогоУровня = Новый Структура("ИностранноеСлово,ЯзыкПеревода",Элементы.ТаблицаНаименованийДЗКоллекция.ТекущиеДанные.ИностранноеСлово,Элементы.ТаблицаНаименованийДЗКоллекция.ТекущиеДанные.ЯзыкПеревода);
	ИдентификаторСтроки = 0; 
	ПрекратитьПоиск = Ложь;
	НомерУровня = 1;       	
	
	//Проставить или убрать пометки на удаление у всех элементов справочника с одинаковыми ссылками, входящих в таблицу дерева значений
	ТаблицаНаименованийДЗКоллекцияПометкаУдаленияПриИзмененииНаС­ервере(НаименованиеБезТранскрипции,ИностранноеСловоСсылка,ПометкаУдаления);  	
	
	//Установить курсор на ту же строку, которая была активирована до пересчета дерева значений на сервере
	НайтиСтрокуДерева(КоллекцияЭлементовДерева, ТекущиеДанныеПервогоУровня, ТекущиеДанныеВторогоУровня, ИдентификаторСтроки, ПрекратитьПоиск, НомерУровня);                   	
		
КонецПроцедуры


&НаКлиенте
Процедура НайтиСтрокуДерева(КоллекцияЭлементовДерева, ТекущиеДанныеПервогоУровня, ТекущиеДанныеВторогоУровня, ИдентификаторСтроки, ПрекратитьПоиск, НомерУровня) 
	
	Для Каждого СтрокаДерева Из КоллекцияЭлементовДерева Цикл
		Если ПрекратитьПоиск Тогда
			Возврат;
		КонецЕсли;
		
		Если НомерУровня = 1 и СтрокаДерева.НаименованиеБезТранскрипции = ТекущиеДанныеПервогоУровня Тогда
			ИдентификаторСтроки = СтрокаДерева.ПолучитьИдентификатор();
			КоллекцияПодчиненныхЭлементовДерева = СтрокаДерева.ПолучитьЭлементы(); 			
			
			Если КоллекцияПодчиненныхЭлементовДерева.Количество() = 0 Тогда 				
				ПрекратитьПоиск = Истина;
				Возврат;  
			Иначе
				
				НомерУровня = НомерУровня + 1;
				ИдентификаторСтроки = 0; 
				ПрекратитьПоиск = Ложь;
				
				НайтиСтрокуДерева(КоллекцияПодчиненныхЭлементовДерева, ТекущиеДанныеПервогоУровня, ТекущиеДанныеВторогоУровня, ИдентификаторСтроки, ПрекратитьПоиск, НомерУровня);
				
			КонецЕсли;
			
		ИначеЕсли НомерУровня = 2 и СтрокаДерева.ИностранноеСлово = ТекущиеДанныеВторогоУровня.ИностранноеСлово и СтрокаДерева.ЯзыкПеревода = ТекущиеДанныеВторогоУровня.ЯзыкПеревода Тогда	
			
			ИдентификаторСтроки = СтрокаДерева.ПолучитьИдентификатор();	
			Элементы.ТаблицаНаименованийДЗКоллекция.ТекущаяСтрока = ИдентификаторСтроки;
			
		КонецЕсли;
		
	КонецЦикла;	
	
КонецПроцедуры
Показать
Прикрепленные файлы:
11. dakork 25 04.08.21 09:42 Сейчас в теме
(9)Спасибо! Очень помогло. Немного подкорректировал под три уровня
&НаКлиенте
Процедура НайтиСтрокуДерева(КоллекцияЭлементовДерева, ТекущиеДанныеПервогоУровня, ТекущиеДанныеВторогоУровня, ТекущиеДанныеТретьегоУровня, ИдентификаторСтроки=0, ПрекратитьПоиск=Ложь, НомерУровня=1)
...содержимое
КонецПроцедуры
10. VadimTer 21.07.21 11:30 Сейчас в теме
Для позиционирования на текущей строке после обращения на сервер нам необходимо получить идентификатор строки, т.е. использовать метод "ПолучитьИдентификатор()". Однако этот метод недоступен для ДереваЗначений на форме, которое на клиенте имеет тип "ДанныеФормыДерево". метод "ПолучитьИдентификатор()" есть у "ДанныеФормыКоллекцияЭлементовДерева". Эта коллекция может быть получена на клиенте у "ДанныеФормыДерево" (у реквизита "ДеревоЗначений" формы), используя метод "ПолучитьЭлементы()". (В одной из приведенных процедур приведен данный код: КоллекцияЭлементовДерева = ТаблицаНаименованийДЗКоллекция.ПолучитьЭлементы();)

Данный код позволяет получить на клиенте коллекцию элементов первого уровня дерева значений, которые можно перебрать с помощью цикла, например, с помощью цикла "Для каждого из Цикл КонецЦикла" и найти нужный элемент как у Таблицы значений, используя сохраненные данные строки первого уровня (в примере: "ТекущиеДанныеПервогоУровня = Элементы.ТаблицаНаименованийДЗКоллекция.ТекущиеДанные.НаименованиеБезТранскрипции;
").
Если ДеревоЗначений имеет более одного уровня вложенности, то для поиска текущей строки второго и далее уровней будет удобно использовать рекурсивную функцию, как показано в примере.

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

Для этого мы перебираем коллекцию первого уровня (Для Каждого СтрокаДерева Из КоллекцияЭлементовДерева Цикл
), и для найденной по условию строки также применяем метод "ПолучитьЭлементы()", получив коллекцию элементов второго уровня (в примере: КоллекцияПодчиненныхЭлементовДерева = СтрокаДерева.ПолучитьЭлементы();).

Далее, полученную коллекцию второго уровня перебираем с помощью рекурсивной процедуры, и у найденной по условию строки определяем идентификатор (в примере: ИдентификаторСтроки = СтрокаДерева.ПолучитьИдентификатор();) и полученный идентификатор присваиваем свойству строки (Элементы.ТаблицаНаименованийДЗКоллекция.ТекущаяСтрока = ИдентификаторСтроки;)

Последний приведенный код присваивания идентификатора обеспечивает позиционирование курсора на текущую строку ДЗ формы.
Прикрепленные файлы:
13. __MaxImuS__ 13.01.22 15:13 Сейчас в теме
В ERP есть процедура, вставить ее после обновления дерева и она вернет все в нужную строку:
ОбщегоНазначенияКлиентСервер.ПолучитьИдентификаторСтрокиДереваПоЗначениюПоля("НомерСметный", Элементы.ДеревоЗнач.ТекущаяСтрока, ДеревоЗнач.ПолучитьЭлементы(), ТекущиеДанные.НомерСметный, Ложь);
Оставьте свое сообщение
Вопросы с вознаграждением
Вакансии
Аналитик 1С
Санкт-Петербург
зарплата до 150 000 руб.
Полный день

Программист 1С
Москва
зарплата от 150 000 руб. до 220 000 руб.
Полный день

1С Программист по 1С:Управление торговлей
Кострома
зарплата от 100 000 руб. до 110 000 руб.
Полный день

Руководитель отдела разработки
Москва
зарплата от 200 000 руб. до 230 000 руб.
Полный день

Программист 1С
Москва
зарплата от 150 000 руб. до 150 000 руб.
Полный день