ДеревоЗначений.Скопировать

Методы · Copy

Создает полную копию исходного дерева значений.

Синтаксис

Скопировать()

Примеры платформы

НовоеДеревоСостава = ДеревоСостава.Скопировать();
Полное описание, параметры и ограничения

ДеревоЗначений.Скопировать (ValueTree.Copy)

ДеревоЗначений (ValueTree)

Скопировать (Copy)

Доступен, начиная с версии 8.0.

Синтаксис:
Скопировать()
Возвращаемое значение:
Тип: ДеревоЗначений.

Описание:

Создает полную копию исходного дерева значений.

Доступность:

Сервер, толстый клиент, внешнее соединение, мобильное приложение (сервер), мобильный автономный сервер.

Пример:

// ДеревоСостава имеет тип ДеревоЗначений

НовоеДеревоСостава = ДеревоСостава.Скопировать();

Использование в версии:

Доступен, начиная с версии 8.0.

Методическая информация

Практические примеры

Преобразовать дерево формы на сервере и вернуть обработанную копию

ДанныеФормыДерево и ДеревоЗначений — разные типы. Сервер получает значение, копирует его, меняет количество и возвращает копию в реквизит формы.

Где и как запускать

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

Подготовка

  1. В учебной базе создайте новую внешнюю обработку УчебноеДерево с пустой управляемой основной формой. Каждую задачу размещайте в отдельной копии формы.

  2. Не создавайте вручную реквизит Категории и элементы ДеревоКатегорий: код создаёт их программно.

  3. В свойствах формы → События назначьте ПриСозданииНаСервере одноимённой процедуре из кода. Остальные процедуры вставьте полностью на уровне модуля.

  4. Сохраните собственную EPF и откройте в 1С через Файл → Открыть. Данные Книга/Ручка создаются только в памяти формы.

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    Новые = Новый Массив;
    Новые.Добавить(Новый РеквизитФормы("Категории", Новый ОписаниеТипов("ДеревоЗначений")));
    Новые.Добавить(Новый РеквизитФормы("Название", Новый ОписаниеТипов("Строка"), "Категории"));
    Новые.Добавить(Новый РеквизитФормы("Количество", Новый ОписаниеТипов("Число"), "Категории"));
    ЭтаФорма.ИзменитьРеквизиты(Новые);
    Дерево = Новый ДеревоЗначений;
    Дерево.Колонки.Добавить("Название", Новый ОписаниеТипов("Строка"));
    Дерево.Колонки.Добавить("Количество", Новый ОписаниеТипов("Число"));
    Группа = Дерево.Строки.Добавить();
    Группа.Название = "Канцелярия";
    Книга = Группа.Строки.Добавить();
    Книга.Название = "Книга";
    Книга.Количество = 3;
    Ручка = Группа.Строки.Добавить();
    Ручка.Название = "Ручка";
    Ручка.Количество = 1;
    Резерв = Дерево.Строки.Добавить();
    Резерв.Название = "Резерв";

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

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

&НаКлиенте
Процедура УчебноеДействие(Команда)
    ОбработатьДеревоНаСервере();
    Корни = Категории.ПолучитьЭлементы();
    Дети = Корни.Получить(0).ПолучитьЭлементы();
    Сообщить(Дети.Количество() = 3);
    Сообщить(Дети.Получить(0).Количество = 7);
    Итого = 0;
    Для Каждого Товар Из Дети Цикл
        Итого = Итого + Товар.Количество;
    КонецЦикла;
    Сообщить(Итого = 10);
КонецПроцедуры

&НаСервере
Процедура ОбработатьДеревоНаСервере()
    Исходное = ЭтаФорма.РеквизитФормыВЗначение("Категории", Тип("ДеревоЗначений"));
    Если Исходное.Строки.Количество() <> 2 Тогда
        ВызватьИсключение "Урок рассчитан на две собственные категории";
    КонецЕсли;
    Копия = Исходное.Скопировать();
    Группа = Копия.Строки.Получить(0);
    Группа.Строки.Получить(0).Количество = 7;
    Найденные = Группа.Строки.НайтиСтроки(Новый Структура("Название", "Скрепки"));
    Если Найденные.Количество() = 0 Тогда
        Скрепки = Группа.Строки.Добавить();
        Скрепки.Название = "Скрепки";
        Скрепки.Количество = 2;
    КонецЕсли;
    Сообщить("Количество Книги до обработки: " + Строка(Исходное.Строки.Получить(0).Строки.Получить(0).Количество));
    Сообщить(Копия.Строки.Итог("Количество", Истина) = 10);
    ЭтаФорма.ЗначениеВРеквизитФормы(Копия, "Категории");
КонецПроцедуры

Разбор по шагам

  1. Клиентская команда вызывает серверную процедуру формы с контекстом формы.

  2. РеквизитФормыВЗначение восстанавливает ДеревоЗначений. Обычные методы дерева теперь доступны на сервере.

  3. Скопировать отделяет изменения: исходное дерево текущего вызова не меняется, работа идёт с Копией.

  4. Книга получает количество 7; Скрепки 2 добавляются только при отсутствии, поэтому повторная команда не создаёт дубликаты.

  5. Итог с ВключатьПодчиненные Истина суммирует значения детей. У групп количество ноль, их повторное суммирование не завышает результат.

  6. ЗначениеВРеквизитФормы возвращает копию. Клиент заново получает строки, не использует старые идентификаторы до замены дерева.

Как проверить результат

  1. Первое нажатие: количество исходной Книги 3, в форме после обработки 7.

  2. Книга 7, Ручка 1, Скрепки 2; общий итог 10.

  3. Повторная команда сохраняет три товара и итог 10, без второй строки Скрепки.

Ожидаемый результат

Полный цикл дерево формы → серверное значение → копия → дерево формы показан на изменяемых учебных данных.

На что обратить внимание

  1. После замены дерева старые ссылки на строки и их идентификаторы не следует считать действительными.

  2. Дерево не записывается в информационную базу: нет объекта документа и команды Записать.

  3. При вычислении итогов не храните одинаковую сумму и в группе, и в её детях без отдельного правила суммирования.

Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.

Создать дерево категорий с товарами и проверить родителя

Две категории находятся в корне. Товары находятся в коллекции Строки конкретной категории, а не в общем корне.

Где и как запускать

Учебная база: создайте серверный общий модуль УчебныеЗадачи (флаг Сервер). Код без директив вставьте в тело процедуры ВыполнитьПример() Экспорт. Вызовите её из серверного обработчика команды учебной обработки. Не запускайте в рабочей базе.

Подготовка

  1. Серверный контекст. Колонки задаются один раз для всего дерева.

  2. Количество в строках категорий оставляем нулевым, чтобы их не перепутать с итогами товаров.

  3. Колонка хранит целые неотрицательные количества 0–99: КвалификаторыЧисла(2, 0, ...) сохраняют 2, 3 и значение 10 в изменяемой копии без округления. Это ограничение собственного урока, не универсальный диапазон количества.

Категории = Новый ДеревоЗначений;
Категории.Колонки.Добавить("Название", Новый ОписаниеТипов("Строка"));
Категории.Колонки.Добавить("Количество", Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(2, 0, ДопустимыйЗнак.Неотрицательный)));
Книги = Категории.Строки.Добавить();
Книги.Название = "Книги";
Товар = Книги.Строки.Добавить();
Товар.Название = "Учебник";
Товар.Установить(1, 3);
Канцелярия = Категории.Строки.Добавить();
Канцелярия.Название = "Канцелярия";
Ручка = Канцелярия.Строки.Добавить();
Ручка.Название = "Ручка";
Ручка.Количество = 2;
Сообщить(Книги.Уровень());
Сообщить(Товар.Уровень());
Сообщить(Товар.Родитель = Книги);
Сообщить(Книги.Родитель = Неопределено);
Сообщить(Товар.Получить(1));
Сообщить(Товар.Владелец() = Категории);
Сообщить(Книги.Строки.Родитель = Книги);
Копия = Категории.Скопировать();
Копия.Строки.Получить(0).Строки.Получить(0).Количество = 10;
Сообщить(Товар.Количество);

Разбор по шагам

  1. Создаём дерево и типизированные колонки.

  2. Категорию добавляем в корневые Строки, товар — в Строки категории.

  3. Проверяем родителя, владельца и уровень: у корневой строки уровень 0.

  4. Изменяем количество в копии и проверяем исходный товар.

Как проверить результат

  1. Уровни: 0 и 1; все сравнения родителей и владельца возвращают Истина.

  2. Количество учебника равно 3 и после изменения отдельной копии остаётся 3.

Ожидаемый результат

В дереве две корневые категории, в каждой по одному товару.

На что обратить внимание

  1. ДеревоЗначений нельзя создать и передать как обычный объект в тонком клиенте; для формы используйте данные формы.

  2. Владелец строки — всё дерево, Родитель — непосредственная строка категории. Это разные связи.

Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.

Не хотите разбираться сами?

Адаптируем это решение под вашу базу. Оценка бесплатно.

Оставить задачу

1С, 1С:Предприятие — товарные знаки ООО «1С». Сайт не является официальным представительством фирмы «1С» и не аффилирован с ней.