1с копирование дерева значений

Копирование части дерева значений

Здравствуйте, коллеги! Есть управляемая форма с двумя реквизитами типа «ДеревоЗначений».
Дерево1 изначально заполнено, Дерево2 пустое.
Как сделать так, чтобы при активации строки в Дереве1 автоматически заполнялось Дерево2? В Дерево2 должна встать ветка Дерева1, которая подчинена выделенной строке Дерева1.

Например: Дерево1
Элемент1
Элемент2
Элемент3
Элемент4

При активации строки Элемент2 Дерево2 принимает следующий вид:
Элемент2
Элемент3
Элемент4

&НаКлиенте Процедура Дерево1ПриАктивизацииСтроки(Элемент) Если Элементы.Дерево1.ТекущиеДанные <> Неопределено Тогда Дерево2.ПолучитьЭлементы().Очистить(); ДобавленнаяСтрока = ДобавитьСтрокуВДверево2(Неопределено, Элементы.Дерево1.ТекущиеДанные); ЗаполнитьДерево2(ДобавленнаяСтрока, Элементы.Дерево1.ТекущиеДанные.ПолучитьЭлементы()); КонецЕсли; КонецПроцедуры &НаКлиенте Процедура ЗаполнитьДерево2(Родитель, Строкы) Для Каждого ТекСтрока Из Строкы Цикл ДобавленнаяСтрока = ДобавитьСтрокуВДверево2(Родитель, ТекСтрока); ЗаполнитьДерево2(ДобавленнаяСтрока, ТекСтрока.ПолучитьЭлементы()); КонецЦикла; КонецПроцедуры &НаКлиенте Функция ДобавитьСтрокуВДверево2(Родитель, СтрокаДляЗаполнения) Если Родитель = Неопределено Тогда НоваяСтрока = Дерево2.ПолучитьЭлементы().Добавить(); Иначе НоваяСтрока = Родитель.ПолучитьЭлементы().Добавить(); КонецЕсли; // НоваяСтрока.Колонка1 = СтрокаДляЗаполнения.Колонка1; // НоваяСтрока.Колонка2 = СтрокаДляЗаполнения.Колонка2; // . Возврат НоваяСтрока; КонецФункции

Дерево2 заполняется полностью при открытии формы, если не нужно или очисти Дерево2 (

Дерево2.ПолучитьЭлементы().Очистить()

) при откритии или имей переменная типа булево и заполняй Дерево2 когда переменная истина (переменная будет истина при откритии)

Источник

Дерево значений 1с

Дерево значений 1с относится к универсальным коллекциям значений. Отличие от Таблицы значений в том, что строки Дерева Значений могут быть подчинены друг другу.

ДеревоЗначений — это программный объект встроенного языка, позволяющий строить произвольные иерархические наборы данных в памяти компьютера, отображать их в табличном и\или древовидном виде, а также программно и интерактивно манипулировать ими (добавлять, редактировать, удалять и сортировать строки).

Как и таблица значений, дерево состоит из строк и колонок. Строки располагаются вниз по вертикали, а колонки — вправо по горизонтали. Однако, в отличие от таблицы значений, строки дерева значений могут иметь подчиненные строки любой глубины вложенности.

Читайте также:  Живица смола хвойных деревьев 9 букв ответ

Строки и колонки имеют индексы, по которым к ним можно обращаться напрямую (начинаются с 0). Кроме этого, к колонкам можно обращаться по идентификатору.

Свойства Дерева Значений 1с

Свойство Колонки Дерева значений

Содержит коллекцию колонок дерева значений.

Свойство Строки Дерева значений

Содержит коллекцию корневых строк дерева значений.

Методы Дерева Значений 1с

метод Скопировать() Дерева значений

Создает новый объект копированием текущего (копируются все колонки и строки).

метод ВыбратьСтроку() Дерева значений

Открывает диалог для интерактивного выбора строки дерева значений.

Дерево значений серверный тип данных, поэтому доступ к нему получаем на стороне сервера.

&НаКлиенте Процедура Дерево(Команда) ДеревоНаСервере(); Конецпроцедуры &НаСервере Процедура ДеревоНаСервере() ДеревоЗнач=Новый ДеревоЗначений; ДеревоЗнач.Колонки.Добавить("Склад"); ДеревоЗнач.Колонки.Добавить("Ячейка"); ДеревоЗнач.Колонки.Добавить("Количество"); Строка=ДеревоЗнач.Строки.Добавить(); Строка.Склад="Оптовый"; Строка.Ячейка="10"; Строка.Количество=150; КонецПроцедуры

Добавим несколько вложенных значений:

СтрокаН=Строка.Строки.Добавить(); СтрокаН.Ячейка="15"; СтрокаН=Строка.Строки.Добавить(); СтрокаН.Ячейка="25";

Создаем реквизит Дерево тип ДеревоЗначений. Для Реквизита указываются колонки:

Дерево значений 1с

  • Склад;
  • Ячейка;
  • Количество.

Далее перетаскиваем Реквизит на форму.

В Завершении в модуль процедуры на Сервере добавляем код. Этот код выполняется аналогично выгрузке Таблицей Значений:

ЗначениеВДанныеФормы(ДеревоЗнач,объект.Дерево);

В результате получим следующее Дерево значений:

Дерево значений 1с

Полный код работы с Деревом значений 1с:

Дерево значений 1с

Обработка дерева значений 1с

Обработка дерева значений в 1с производиться при помощи рекурсивной процедуры, т.е. процедуры вызывающей саму себя. Процесс обработки дерева значений может состоять из трех шагов:

Во-первых команда на клиенте:

Во-вторых процедура на Сервере получающая Дерево значений:

&НаСервере Процедура Команда2НаСервере() ДеревоЗнач=новый ДеревоЗначений; ДеревоЗнач=ДанныеФормыВЗначение(объект.Дерево,Тип("ДеревоЗначений")); Строки=ДеревоЗнач.строки; ОбработатьДерево(Строки); КонецПроцедуры

В третьих рекурсивная процедура обрабатывающая строки Дерева Значений:

&НаСервере Процедура ОбработатьДерево(Строки) Для каждого Строка из Строки цикл Сообщить(Строка(Строка.Склад)+":"+Строка(Строка.Ячейка)+":" +Строка(Строка.Количество)); ОбработатьДерево(Строка.Строки); конеццикла; конецпроцедуры 

Полный код обработки Дерева значений:

Источник

Программное копирование узла/строки дерева значений на управляемой форме (УФ, ДанныеФормыДерево, ДанныеФормыЭлементДерева) в вариантах на клиенте и на сервере

  • Clip2net_210110203430.png

1С при интерактивном копировании строки дерева значений в управляемой форме копирует только саму строку, без его всех вложенных узлов/строк, жаль — решим! А также найдем способ передачи ДанныеФормыЭлементДерева с клиента на сервер при вставке дерева из другого элемента справочника.

Описание: пользователь создает личный кабинет B2B портала из готовых преформ/блоков — шапки, слайдера акций (по овощам) и меню, потом добавляет еще один слайдер, изменяет источник данных — по фруктам. Давайте разберемся, как подобное сделать Вам в своих конфигурациях. Рассмотрим первый пример — копирование в дереве значений на управляемой форме (ДанныеФормыДерево). Для начала получим активную строку/узел (ДанныеФормыЭлементДерева), на которой пользователь нажал кнопку «Копировать».

СтрокаТЧ = Элементы.СтруктураСтраницы.ТекущиеДанные;

Копировать будем в родителя текущего узла, поэтому получим родителя текущего узла/строки и опишем это в коде:

Куда = СтрокаТЧ.ПолучитьРодителя(); Если Куда=Неопределено Тогда Куда = СтруктураСтраницы; КонецЕсли; 

Теперь можем вызвать нашу функцию, которая на клиенте скопирует выбранную пользователем строку в родителя:

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

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

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

Как видно, мы всегда предполагаем, что у нашего дерева есть корневая строка (root) и если её нет, то мы её добавляем. Внутри идет вызов процедуры ДобавитьУзлыСтраницы, которая объявлена в контексте сервера, т.е. мы уходим с клиента на сервер и вот тут хитрость — мы не можем передать на сервер ДанныеФормыЭлементДерева, как в первом примере — получим ошибку: Ошибка отображения типов: Отсутствует отображение для типа ‘ДанныеФормыЭлементДерева’ по причине: Ошибка передачи данных между клиентом и сервером. Значение недопустимого типа. по причине: Ошибка преобразования данных XDTO: Запись значения свойства ‘param’: форма: Элемент имя: http://v8.1c.ru/8.2/managed-application/modules>param по причине: Ошибка отображения типов: Отсутствует отображение для типа ‘ДанныеФормыЭлементДерева’ поэтому, мы будем передавать не сам тип ДанныеФормыЭлементДерева, а числовой идентификатор элемента в ДанныеФормыДерево. Функция ДобавитьУзлыСтраницы довольно простая, ее задача получить из хранилища значений дерево значений и вызвать уже серверную функцию по копированию структуры, куда передать ДанныеФормыЭлементДерева, получив его по числовому идентификатору.

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

Интересно, да? ДанныеФормыЭлементДерева есть и в контексте Сервера и в контекста Клиента, но передать его с клиента на сервер напрямую мы не можем, поэтому делаем это через идентификатор. Теперь осталось описать функцию по копированию узлов дерева значений (СтрокаДереваЗначений) в наше дерево значений формы (ДанныеФормыДерево)

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

В итоге мы с Вами решили обе задачки по копированию, разобрались с работой ДанныеФормыДерево, передачей с клиента на сервер ДанныеФормыЭлементДерева — пользователь может копировать и вставлять/подбирать нужные ему блоки страницы веб приложения. Надеюсь, моя публикация была Вам полезна и сэкономит Ваше время, ссылка на все публикации SizovE, например, в публикации Отображение и редактирование в дереве большого количества настроек/параметров/опций программы, конфигурации, документа, справочника — без программного создания элементов формы мной были рассмотрены и другие решения/ситуации по работе с деревьями значений на форме. Подписывайтесь на мой канал (наверху), будет много интересного бесплатного контента 🙂

Читайте также:  Домашние паразиты от деревьев

Источник

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