Вход | Регистрация
 
1С:Предприятие :: 1С:Предприятие 8 общая

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

УФ: Установить текущую строку дерева значений
Я
   Родом из детства
 
23.09.21 - 11:38
Всем привет! Суть задачи в следующем
Имеется механизм назначения на смену, в определенный цех исполнителей(бригад). Бригада состоит из сотрудников. В течении смены можно менять состав бригады(а не бригаду).
Создана форма подбора бригад и сотрудников(типо слева дерево бригад,где на верхем уровне - статус(свободна/занята), а на нижнем - сама бригада, при выборе бригады справа заполняется таблица значений, где перечисляется состав бригады). При открытии в нее передается текущая бригада(справочник.ссылка).
Возможно ли, после заполнения дерева бригад установить текущую строку по переданной текущей бригаде?
Что дерево бригад, что таблица её состава - реквизиты формы
   mikecool
 
1 - 23.09.21 - 11:49
   Родом из детства
 
2 - 23.09.21 - 11:54
(1) То есть на сервере, после выгрузки результата запроса в дерево,  получить строку по текущей бригаде. А на клиенте уже установить её текущей?
   fisher
 
3 - 23.09.21 - 12:03
Обходом находишь строку дерева с нужной бригадой и потом
Элемент.ТекущаяСтрока = СтрокаДерева.ПолучитьИдентификатор()
   fisher
 
4 - 23.09.21 - 12:05
Элементы.Дерево.ТекущаяСтрока = СтрокаБригады.ПолучитьИдентификатор()
   Родом из детства
 
5 - 23.09.21 - 12:21
(3) Сделал что-то подобное.
&НаКлиенте
Процедура ОбновитьБригады()
    СтрокаБригады = неопределено;
    ОбновитьБригадыНаСервере(СтрокаБригады);
    Элементы.Бригады.ТекущаяСтрока = СтрокаБригады//Бригады.НайтиПоИдентификатору(СтрокаБригады.ПолучитьИдентификатор());

КонецПроцедуры
   Родом из детства
 
6 - 23.09.21 - 12:23
Процедура ОбновитьБригадыНаСервере передает в СтрокаБригады - найденную строку дерева. Только возникает ошибка
"Отсутствует отображение для типа 'СтрокаДереваЗначений'" - похоже, нужно создавать реквизит формы "СтрокаБригады" и передавать это значение через ЗначениеВРеквизитФормы() - но как-то стремно выглядит
   Родом из детства
 
7 - 23.09.21 - 12:31
А нет - тип строка дерева значений не может использоваться в данных формы.
   Родом из детства
 
8 - 23.09.21 - 12:31
получается, что строка дерева значений доступна нам на сервере. А метод, устанавливающий текущую строку - на клиенте...
   fisher
 
9 - 23.09.21 - 12:38
Если двухуровневое дерево, то можно без рекурсии:
НайденнаяСтрокаБригады = Неопределено;
Для Каждого СтрокаСтатуса Из Дерево.ПолучитьЭлементы() Цикл
     Для Каждого СтрокаБригады Из СтрокаСтатуса.ПолучитьЭлементы() Цик
         Если СтрокаБригады.Бригада = ИскомаяБригада Тогда
             НайденнаяСтрокаБригады = СтрокаБригады;
             Прервать;
         КонецЕсли;
     КонецЦикла;
     Если НайденнаяСтрокаБригады <> Неопределено Тогда
         Прервать;
     КонецЕсли;
КонецЦикла;
Элементы.Дерево.ТекущаяСтрока = НайденнаяСтрокаБригады.ПолучитьИдентификатор();

   fisher
 
10 - 23.09.21 - 12:39
А, черт. Забыл в конце проверку на Неопределено.
   Родом из детства
 
11 - 23.09.21 - 12:40
(10) А, слушай, да. Про получитьЭлементы я не знал. Спасибо!
   fisher
 
12 - 23.09.21 - 12:43
(11) На клиенте дерева значений нет. Оно трансформируется в ДанныеФормыДерево, у которого узлами ДанныеФормыЭлементДерева. Забей это в СП и посмотри свойства/методы.
   Родом из детства
 
13 - 23.09.21 - 12:48
(12) Хорошо, спасибо ещё раз)
   TormozIT
 
14 - 23.09.21 - 17:02
Для всех древовидных объектов реализовал универсальные функции получения адреса (Дерево_ПутьСтрокойЛкс) и нахождения по этому адресу строки дерева (Дерево_НайтиПоПутиСтрокойЛкс).
Правда для тонкого клиента не расставлял экранирование недоступных типов.
В частности задачу (0) можно решить так
1. Найти в дереве значений на сервере нужную строку например через ДеревоЗначений.НайтиСтроки(Отбор, Истина)
2. Найти ту же строку в проекции этого дерева в реквизит формы. НайденнаяСтрока = Дерево_НайтиПоПутиСтрокойЛкс(ДеревоФормы, "", Дерево_ПутьСтрокойЛкс(СтрокаДерева, "")) 
3. Элементы.Дерево.ТекущаяСтрока = НайденнаяСтрока.ПолучитьИдентификатор()

// Параметры:

//   ИмяКолонки - Строка - если задать пустое значение, то будет использован индекс строк дерева
//   ИгнорироватьПростойПервыйУровень - Булево - если на первом уровне только одна строка, то игнорировать ее

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

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

// Параметры:

//   ИмяКолонки - Строка - если задать пустое значение, то будет использован индекс строк дерева
//   ИгнорироватьПростойПервыйУровень - Булево - если на первом уровне только одна строка, то игнорировать ее

Функция Дерево_НайтиПоПутиСтрокойЛкс(СтрокаДерева, ИмяКолонки = "Имя", Путь, ИгнорироватьПростойПервыйУровень = Ложь) Экспорт

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

КонецФункции

Список тем форума
 
Миста — веселый ресурс со своими эксклюзивными тараканами Ymryn
ВНИМАНИЕ! Если вы потеряли окно ввода сообщения, нажмите Ctrl-F5 или Ctrl-R или кнопку "Обновить" в браузере.