1с текущий элемент дерева

Как получить текущую строку дерева управляемой формы на сервере?

На форме есть дерево значений. В серверной процедуре мне необходимо определять текущие данные. Отрабатывает нормально, но только до тех пор, пока стока не станет подчинённой. Например у меня 5 строк, а в первой строке ещё несколько строк. И у вложенной первой строки переменная ТекущаяСтрока = 8. И тогда Текущие данные будет = Неопределено. Это неправильно. Помогите разобраться.

ТекущаяСтрока = Элементы.МоеДерево.ТекущаяСтрока; Если ТекущаяСтрока = Неопределено Тогда Возврат; КонецЕсли; ТекущиеДанные = МоеДерево.НайтиПоИдентификатору(ТекущаяСтрока);

(1) Текущую строку надо получать на клиенте и передавать идентификатор на сервер. А на сервере уже обрабатывать.

(8) При передачи с клиента на контекстный серверный вызов происходит передача всего контекста формы на сервер. Что там будет с текущей строкой и как она связана именно с текущей строкой, который ты видишь? Так что получай идентификатор строки на клиенте и передавай его на сервер.

(13) Попробовал передать с клиента на сервер. На клиенте тот же самый идентификатор строки = 8. Хотя строк всего 8, должны быть идентификаторы от 0 до 7.

(18) Да я вот уже выяснил, что идентификатор строки никак не связан с её номером и количеством строк)

(1) Все прекрасно работает. Может у вас конфликт пространств имен или еще какая-нить чехарда. Попробуйте поменять имена переменных для начала и на простейшей тестовой обработке попробуйте воспроизвести проблему.

ТекущиеДанные = Элементы.МоеДерево.ТекущиеДанные

(6) Из текущих данных получай идентификатор строки и ищи на сервере. Но ты так и не ответил, откуда берешь данные для построения дерева.

(9) Данные берутся из базы данных в процедуре ПриСоздании на сервере. А вопрос связан уже совсем с другим с событием ПриАктивизацииСтроки (другого дерева), но это и не должно быть важно.
Так вот, по идентификатору строки не сервере и не получается. Он находит идентификатор текущей строки = 8, но такой строки не существует. То есть МоеДерево.НайтиПоИдентификатору(ИдентификаторСтроки) будет равно Неопределено.

(10) Возможно, чертовщина происходит из-за того, что делаете контекстный серверный вызов в событии ПриАктивизацииСтроки.

(11) Как избавиться от этой чертовщины? Должен же быть способ получить на сервере данные текущей строки, имея весь контекст формы.

Читайте также:  Скрипка страдивари из какого дерева

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

Согласен. Только реквизит формы МоеДерево надо перед этим превратить в значение. Ну а после манипуляций — обратно.

(12) Пока не определишься из каких данных строишь дерево и что хочешь изменить, программировать бессмысленно и невозможно.

Если бы вы в дереве создали и заполнили уникальными значениями реквизит «КлючСтроки» (условно), то у вас не было бы проблем найти строку по этому ключу хоть на клиенте, хоть на сервере.

(17) Интересное решение. А не будет ли это велосипедом? Может получить текущую строку всё-таки можно как-то с помощью платформы? Или хотя бы через БСП? Интуиция подсказывает, что такая простая задача как «Получить текущие данные» уже избита и должна решаться простым способом.

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

Функция ДеревоВставитьЭлемент(Узел,КлючСтрокиПоследний,Индекс,Реквизиты) Экспорт Элементы=Узел.ПолучитьЭлементы(); Если ТипЗнч(Узел)=Тип("ДанныеФормыДерево") Тогда КлючСвязи=0; Иначе КлючСвязи=Узел.КлючСтроки; КонецЕсли; Эл=Элементы.Вставить(Индекс); ЗаполнитьЗначенияСвойств(Эл,Реквизиты); КлючСтрокиПоследний=КлючСтрокиПоследний+1; Эл.КлючСтроки=КлючСтрокиПоследний; Эл.КлючСвязи=КлючСвязи; ДеревоПеренумеровать(Узел); Возврат Эл; КонецФункции Функция ДеревоПолучитьЭлементПоРеквизиту(Узел,Реквизит,ЗначениеРеквизита,СРекурсией=Истина) Экспорт Элементы=Узел.ПолучитьЭлементы(); Для каждого Эл Из Элементы Цикл Если Эл[Реквизит]=ЗначениеРеквизита Тогда Возврат Эл; КонецЕсли; Если СРекурсией Тогда Эл1=ДеревоПолучитьЭлементПоРеквизиту(Эл,Реквизит,ЗначениеРеквизита,СРекурсией); Если Эл1<>Неопределено Тогда Возврат Эл1; КонецЕсли; КонецЕсли; КонецЦикла; Возврат Неопределено; КонецФункции Функция ДеревоПолучитьЭлемент(Узел,КлючСтроки) Экспорт Возврат ДеревоПолучитьЭлементПоРеквизиту(Узел,"КлючСтроки",КлючСтроки,Истина); КонецФункции

Источник

УФ: Установить текущую строку дерева значений

Всем привет! Суть задачи в следующем
Имеется механизм назначения на смену, в определенный цех исполнителей(бригад). Бригада состоит из сотрудников. В течении смены можно менять состав бригады(а не бригаду).
Создана форма подбора бригад и сотрудников(типо слева дерево бригад,где на верхем уровне — статус(свободна/занята), а на нижнем — сама бригада, при выборе бригады справа заполняется таблица значений, где перечисляется состав бригады). При открытии в нее передается текущая бригада(справочник.ссылка).
Возможно ли, после заполнения дерева бригад установить текущую строку по переданной текущей бригаде?
Что дерево бригад, что таблица её состава — реквизиты формы

Читайте также:  Какие деревья выделяют сок

(1) То есть на сервере, после выгрузки результата запроса в дерево, получить строку по текущей бригаде. А на клиенте уже установить её текущей?

Обходом находишь строку дерева с нужной бригадой и потом
Элемент.ТекущаяСтрока = СтрокаДерева.ПолучитьИдентификатор()

(3) Сделал что-то подобное.
&НаКлиенте
Процедура ОбновитьБригады()
СтрокаБригады = неопределено;
ОбновитьБригадыНаСервере(СтрокаБригады);
Элементы.Бригады.ТекущаяСтрока = СтрокаБригады;//Бригады.НайтиПоИдентификатору(СтрокаБригады.ПолучитьИдентификатор());
КонецПроцедуры

Процедура ОбновитьБригадыНаСервере передает в СтрокаБригады — найденную строку дерева. Только возникает ошибка
«Отсутствует отображение для типа ‘СтрокаДереваЗначений'» — похоже, нужно создавать реквизит формы «СтрокаБригады» и передавать это значение через ЗначениеВРеквизитФормы() — но как-то стремно выглядит

получается, что строка дерева значений доступна нам на сервере. А метод, устанавливающий текущую строку — на клиенте.

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

(11) На клиенте дерева значений нет. Оно трансформируется в ДанныеФормыДерево, у которого узлами ДанныеФормыЭлементДерева. Забей это в СП и посмотри свойства/методы.

Для всех древовидных объектов реализовал универсальные функции получения адреса (Дерево_ПутьСтрокойЛкс) и нахождения по этому адресу строки дерева (Дерево_НайтиПоПутиСтрокойЛкс).
Правда для тонкого клиента не расставлял экранирование недоступных типов.
В частности задачу (0) можно решить так
1. Найти в дереве значений на сервере нужную строку например через ДеревоЗначений.НайтиСтроки(Отбор, Истина)
2. Найти ту же строку в проекции этого дерева в реквизит формы. НайденнаяСтрока = Дерево_НайтиПоПутиСтрокойЛкс(ДеревоФормы, «», Дерево_ПутьСтрокойЛкс(СтрокаДерева, «»))
3. Элементы.Дерево.ТекущаяСтрока = НайденнаяСтрока.ПолучитьИдентификатор()

// Параметры:
// ИмяКолонки — Строка — если задать пустое значение, то будет использован индекс строк дерева
// ИгнорироватьПростойПервыйУровень — Булево — если на первом уровне только одна строка, то игнорировать ее
Функция Дерево_ПутьСтрокойЛкс(СтрокаДерева, ИмяКолонки = «Имя», ИгнорироватьПростойПервыйУровень = Ложь, Разделитель = «.», Дерево = Неопределено, Исключения = Неопределено) Экспорт

Если Не ЗначениеЗаполнено(ИмяКолонки) Тогда
Родитель = РодительСтрокиДереваЛкс(СтрокаДерева, Дерево);
Если Ложь
Или ТипЗнч(Родитель) = Тип(«ДеревоЗначений»)
Или ТипЗнч(Родитель) = Тип(«СтрокаДереваЗначений»)
Тогда
Результат = Родитель.Строки.Индекс(СтрокаДерева);
ИначеЕсли Ложь
Или ТипЗнч(Родитель) = Тип(«ОтборКомпоновкиДанных»)
Или ТипЗнч(Родитель) = Тип(«ГруппаЭлементовОтбораКомпоновкиДанных»)
Или ТипЗнч(Родитель) = Тип(«ДоступныеПоляКомпоновкиДанных»)
Или ТипЗнч(Родитель) = Тип(«ДоступноеПолеКомпоновкиДанных»)
Или ТипЗнч(Родитель) = Тип(«ДоступноеПолеОтбораКомпоновкиДанных»)
Тогда
Результат = Родитель.Элементы.Индекс(СтрокаДерева);
ИначеЕсли Ложь
Или ТипЗнч(Родитель) = Тип(«ДанныеФормыДерево»)
Или ТипЗнч(Родитель) = Тип(«ДанныеФормыЭлементДерева»)
Тогда
Результат = Родитель.ПолучитьЭлементы().Индекс(СтрокаДерева);
Иначе
ВызватьИсключение «Неподдерживаемый тип элемента дерева — » + ТипЗнч(Родитель);
КонецЕсли;
Иначе
Если Исключения <> Неопределено Тогда
Для Каждого Структура Из Исключения Цикл
Если СравнитьЗначенияСвойствЛкс(СтрокаДерева, Структура, Структура.СвойстваДляСравнения) Тогда
Результат = Структура[ИмяКолонки];
Прервать;
КонецЕсли;
КонецЦикла;
КонецЕсли;
Если Результат = Неопределено Тогда
Результат = СтрокаДерева[ИмяКолонки];
КонецЕсли;
КонецЕсли;
Попытка
Родитель = СтрокаДерева.Родитель;
Исключение
Родитель = СтрокаДерева.ПолучитьРодителя();
КонецПопытки;
Если Родитель = Неопределено Тогда
Если Истина
И ИгнорироватьПростойПервыйУровень
И СтрокаДерева.Владелец().Строки.Количество() = 1
Тогда
Результат = Неопределено;
КонецЕсли;
Иначе
РезультатСверху = Дерево_ПутьСтрокойЛкс(Родитель, ИмяКолонки, ИгнорироватьПростойПервыйУровень, Разделитель, Дерево, Исключения);
Если РезультатСверху <> Неопределено Тогда
Результат = РезультатСверху + Разделитель + Результат;
КонецЕсли;
КонецЕсли;
Возврат XMLСтрока(Результат);

Читайте также:  Чем обрабатывать деревья при цветении

// Параметры:
// ИмяКолонки — Строка — если задать пустое значение, то будет использован индекс строк дерева
// ИгнорироватьПростойПервыйУровень — Булево — если на первом уровне только одна строка, то игнорировать ее
Функция Дерево_НайтиПоПутиСтрокойЛкс(СтрокаДерева, ИмяКолонки = «Имя», Путь, ИгнорироватьПростойПервыйУровень = Ложь) Экспорт

Если Истина
И ИгнорироватьПростойПервыйУровень
И ТипЗнч(СтрокаДерева) = Тип(«ДеревоЗначений»)
И СтрокаДерева.Строки.Количество() = 1
Тогда
Возврат Дерево_НайтиПоПутиСтрокойЛкс(СтрокаДерева.Строки[0], ИмяКолонки, Сред(Путь, 2));
КонецЕсли;
ТекущийУровень = ПервыйФрагментЛкс(Путь);
Если Не ЗначениеЗаполнено(ТекущийУровень) Тогда
Возврат СтрокаДерева;
КонецЕсли;
ОстальнойПуть = Сред(Путь, СтрДлина(ТекущийУровень) + 2);
Если Не ЗначениеЗаполнено(ИмяКолонки) Тогда
ЗначениеИндекса = Число(ТекущийУровень);
Если Ложь
Или ТипЗнч(СтрокаДерева) = Тип(«ДеревоЗначений»)
Или ТипЗнч(СтрокаДерева) = Тип(«СтрокаДереваЗначений»)
Тогда
Если СтрокаДерева.Строки.Количество() > ЗначениеИндекса Тогда
ТекущаяСтрока = СтрокаДерева.Строки[ЗначениеИндекса];
КонецЕсли;
ИначеЕсли Ложь
Или ТипЗнч(СтрокаДерева) = Тип(«ОтборКомпоновкиДанных»)
Или ТипЗнч(СтрокаДерева) = Тип(«ГруппаЭлементовОтбораКомпоновкиДанных»)
Или ТипЗнч(СтрокаДерева) = Тип(«ДоступныеПоляКомпоновкиДанных»)
Или ТипЗнч(СтрокаДерева) = Тип(«ДоступноеПолеКомпоновкиДанных»)
Или ТипЗнч(СтрокаДерева) = Тип(«ДоступноеПолеОтбораКомпоновкиДанных»)
Тогда
Если СтрокаДерева.Элементы.Количество() > ЗначениеИндекса Тогда
ТекущаяСтрока = СтрокаДерева.Элементы[ЗначениеИндекса];
КонецЕсли;
ИначеЕсли Ложь
Или ТипЗнч(СтрокаДерева) = Тип(«ДанныеФормыДерево»)
Или ТипЗнч(СтрокаДерева) = Тип(«ДанныеФормыЭлементДерева»)
Тогда
Если СтрокаДерева.ПолучитьЭлементы().Количество() > ЗначениеИндекса Тогда
ТекущаяСтрока = СтрокаДерева.ПолучитьЭлементы()[ЗначениеИндекса];
КонецЕсли;
Иначе
ВызватьИсключение «Неподдерживаемый тип элемента дерева — » + ТипЗнч(СтрокаДерева);
КонецЕсли;
Иначе
Если Ложь
Или ТипЗнч(СтрокаДерева) = Тип(«ДанныеФормыДерево»)
Или ТипЗнч(СтрокаДерева) = Тип(«ДанныеФормыЭлементДерева»)
Тогда
ТекущаяСтрока = Неопределено;
ДочерниеЭлементы = СтрокаДерева.ПолучитьЭлементы();
Для Каждого ДочернийЭлемент Из ДочерниеЭлементы Цикл
Если ДочернийЭлемент[ИмяКолонки] = ТекущийУровень Тогда
ТекущаяСтрока = ДочернийЭлемент;
Прервать;
КонецЕсли;
КонецЦикла;
Иначе
ТекущаяСтрока = СтрокаДерева.Строки.Найти(ТекущийУровень, ИмяКолонки);
КонецЕсли;
КонецЕсли;
Если ТекущаяСтрока <> Неопределено Тогда
Возврат Дерево_НайтиПоПутиСтрокойЛкс(ТекущаяСтрока, ИмяКолонки, ОстальнойПуть);
Иначе
Возврат СтрокаДерева;
КонецЕсли;

Источник

Оцените статью