Как заполнить дерево значений в управляемой форме


Дерево значение в 1С 8.3 на примерах

Объект «ДеревоЗначений» в 1С 8.3 представляет собой динамический набор значений любого типа. Для такого набора доступны свойства «колонки» и «строки» где каждая строка может иметь набор подчинённых строк, а каждая подчинённая строка набор своих подчинённых строк и т.д.  Программная инициализация дерева значений в 1С осуществляется с помощью оператора НОВЫЙ.

Пример:

ДеревоЗначений = Новый ДеревоЗначений;

Визуально, объект «ДеревоЗначений» похож на дерево групп справочника. К примеру, можно открыть справочник «Номенклатура» любой типовой конфигурации выставив форму списка в «Режим просмотра» — «Дерево».

 

Полезно понимать, что объект «ДеревоЗначений» схож с объектом «ТаблицаЗначений». Основной отличительный признак наличие дополнительного реквизита «Родитель» у объекта «ДеревоЗначений», с помощью которого и организовывается иерархия и подчинённость.

Наша команда предоставляет услуги по консультированию, настройке и внедрению 1С.
Связаться с нами можно по телефону +7 499 350 29 00.
Услуги и цены можно увидеть по ссылке.
Будем рады помочь Вам!

Содержание

Дерево значений на управляемой форме

Если появляется необходимость показать данные в виде дерева пользователю, следует на форме создать реквизит с типом «ДеревоЗначений» и определится с составом колонок.

Для отображения на форме добавим реквизит в раздел элементов формы простым перетаскиванием.

Заполнение дерева значений

Заполнить данными дерево значений в 1С можно программно (вручную) или получить из результата запроса. Рассмотрим на примерах оба способа.

Ручное заполнение реквизита формы с типом «ДеревоЗначений»

Простой пример:

&НаКлиенте
 Процедура ДЗ_НаФорме(Команда)
 ДЗ_НаФормеНаСервере();
 КонецПроцедуры
 
 &НаСервере
 Процедура ДЗ_НаФормеНаСервере()
 
 // Преобразуем реквизит формы ДЗ в объект прикладного типа
 ДеревоЗначений = РеквизитФормыВЗначение("ДЗ");
 
 Корень = ДеревоЗначений.Строки.Добавить();
 Корень.Наименование = "Корневая группа";
 
 Группа1 = Корень.Строки.Добавить();
 Группа1.Наименование = "Первая группа";
 
 Элемент1 = Группа1.Строки.Добавить();
 Элемент1.Наименование = "Элемент №1";                               
 
 Группа2 = Корень.Строки.Добавить();
 Группа2.Наименование = "Втровая группа";
 
 Элемент1 = Группа2.Строки.Добавить();
 Элемент1.Наименование = "Элемент №1";
 
 Элемент2 = Группа2.Строки.Добавить();
 Элемент2.Наименование = "Элемент №2";
         
 // Преобразуем объект ДеревоЗначений в реквизит формы         
 ЗначениеВРеквизитФормы(ДеревоЗначений,"ДЗ");                                                                     
 
 КонецПроцедуры
 

Результат запроса на форме:

Заполнение дерева значений из результата запроса

Сделаем простой запрос к справочнику «Номенклатура». Результат запроса преобразуем в дерево значений с помощью метода «Выгрузить», установив для его параметра «ТипОбхода» в значение «ПоГруппировкамСИерархией».  Для передачи сформированного дерева значений на форму, важно чтобы имена колонок совпадали с именами колонок реквизита на форме.

&НаКлиенте
 Процедура ДЗ_НаФорме(Команда)
 ДЗ_НаФормеНаСервере();
 КонецПроцедуры
 
 &НаСервере
 Процедура ДЗ_НаФормеНаСервере()
 
 Запрос = Новый Запрос;
 Запрос.Текст =
 "ВЫБРАТЬ
 |          Номенклатура.Ссылка КАК Наименование
 |ИЗ
 |          Справочник.Номенклатура КАК Номенклатура
 |
 |УПОРЯДОЧИТЬ ПО
 |          Наименование ИЕРАРХИЯ";
 ДеревоЗначений = Запрос.Выполнить().Выгрузить(ОбходРезультатаЗапроса.ПоГруппировкамСИерархией);
 
 ЗначениеВРеквизитФормы(ДеревоЗначений, "ДЗ");
 
 КонецПроцедуры
 

Результат запроса на форме может выглядеть так:

Поиск строк в дереве значений

Для поиска строк в дереве значений существует два способа, точнее говоря, метода.

Метод «Найти()»

Возвращает строку дерева значений, если строка не найдена, вернёт «Неопределено». Поиск можно ограничивать, указав в параметре <Колонки> нужные колонки для поиска. Также расширять, указав для параметра <ВключатьПодчиненные> значение «Истина», тогда в поиске будут участвовать строки подчинённых коллекций.

Для примера найдём строку со значением «Элемент №1» в дереве значений вида:

Пример кода:

&НаКлиенте
 Процедура НайтиСтрокуДЗ(Команда)
             НайтиСтрокуДЗ_НаСервере();
 КонецПроцедуры
 
 &НаСервере
 Процедура НайтиСтрокуДЗ_НаСервере()
 
 // Преобразуем реквизит формы ДЗ в объект прикладного типа
 ДеревоЗначений = РеквизитФормыВЗначение("ДЗ");
 
 // Ищем строку
 НайденнаяСтрока = ДеревоЗначений.Строки.Найти("Элемент №1","Наименование", Истина);
 
 // Анализ результата поиска
 Если НайденнаяСтрока = Неопределено Тогда
 Сообщить("Строка не найдена");
 Иначе
 Сообщить(НайденнаяСтрока.Наименование + " - " + НайденнаяСтрока.Родитель.Наименование);
 КонецЕсли;
           
 КонецПроцедуры

Результат:

Из результата видно, что метод вернул первую попавшуюся строку, и поиск был прекращён.

Метод «НайтиСтроки()»

Если необходимо найти все строки со значением «Элемент №1» тогда следует использовать метод НайтиСтроки()

Где <ПараметрыОтбора> — это условия для поиска в виде структуры, а параметр <ВключатьПодчиненные> с помощью значений Ложь/Истина контролирует возможность поиска в подчинённых коллекциях.

Пример кода:

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

Результат:

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

Для очистки дерева значений пригодятся методы  Очистить(), Удалить(). Пример кода:

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

С помощью данных методов возможно удаление конкретных строк дерева значений.

!!!При удалении либо очистки строки все её подчинённые строки удалятся!!!

Обход дерева значений в 1С

Обойти все строки дерева значений удобнее всего с помощью рекурсии.  Таким способом мы сможем обойти дерево значений любой вложенности.

Пример:

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

Как преобразовать дерево значений в таблицу значений

Состав элементов и реквизитов формы:

&НаКлиенте
 Процедура ВТЗ(Команда)
 ВТЗНаСервере();
 КонецПроцедуры
 
 &НаСервере
 Процедура ВТЗНаСервере()
 
 
 ДеревоЗначений = РеквизитФормыВЗначение("ДЗ");
 ТаблицаЗначений = РеквизитФормыВЗначение("ТЗ");
 
 ПреобразоватьВ_ТЗ(ДеревоЗначений, ТаблицаЗначений, Новый УникальныйИдентификатор("00000000-0000-0000-0000-000000000000"));
 ДеревоЗначений.Строки.Очистить();
 
 ЗначениеВРеквизитФормы(ТаблицаЗначений, "ТЗ");
 ЗначениеВРеквизитФормы(ДеревоЗначений, "ДЗ");
 КонецПроцедуры
 
 &НаСервере
 Процедура ПреобразоватьВ_ТЗ(Данные, ТаблицаЗначений, ГУИД)
 
 Для Каждого Строка Из Данные.Строки Цикл
 
 НовСтрока = ТаблицаЗначений.Добавить();
 НовСтрока.Наименование = Строка.Наименование;
 НовСтрока.Родитель = ГУИД;
 НовСтрока.ГУИД = Новый УникальныйИдентификатор();
 
 Если Строка.Строки.Количество()>0 Тогда
 ПреобразоватьВ_ТЗ(Строка, ТаблицаЗначений, НовСтрока.ГУИД);
 КонецЕсли;
 
 КонецЦикла;
 
 КонецПроцедуры
 

Используя данный способ можно легко преобразовать таблицу значений обратно в дерево значений.  Из примера «ГУИД» это уникальный идентификатор строки, а «Родитель» уникальный идентификатор родителя. Если обратного преобразования не требуется можно исключить использование колонок «Родитель» и  «ГУИД».

Работа с деревом значений в 1С 8.3

Дерево значений является одним из популярных типов данных, часто встречающихся на формах и конфигурации. Важным его преимуществом является заложенная платформой иерархичность, которой удобно воспользоваться в некоторых ситуациях, например, осуществить поиск по определенной группе элементов или получить отдельные итоговые суммы в различных категориях. Дерево значений в 1С – достаточно эффективный инструмент, достойный, чтобы разработчики тратили на его изучение свое время.

Размещение на форме и заполнение дерева значений

Чтобы на управляемой форме вывести дерево значений, необходимо добавить новый реквизит, выбрать нужный тип, добавить колонки и перетащить влево. На вопрос о добавлении колонок ответьте утвердительно, и перед вами предстанет общий вид дерева значений. Чтобы увидеть какие-либо записи, необходимо добавить строки дерева значений 1С с нужными данными.

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

Существует несколько способов заполнения дерева значений нужными нам свойствами с определенной иерархией. Самый простой вариант – заполнить вручную, последовательно добавляя элементы и внимательно самостоятельно соблюдая иерархию. Естественно, при большом количестве элементов данный вариант не должен рассматриваться разработчиками 1С. Данный способ вывода информации состоит из следующих операторов:

На стороне сервера:

  1. Получение значения реквизита;

Дерево значений. Категория: 1С:Предприятие • Программирование

Дерево значений представляет из себя некую структуру с иерархией. Каждая строка имеет свойства «Родитель» и «Строки». У каждой строки может быть сколько угодно подчиненных строк. При этом такие операции как поиск, сортировка, подсчет итогов можно проводить с учетом уровня иерархии и подчиненных строк.

Программное создание дерева значений

Как уже упоминалось выше, каждая строка имеет свойство Строки, которое содержит коллекцию дочерних строк. И сам объект ДеревоЗначений имеет свойство Строки, которое содержит коллекцию строк верхнего уровня.

&НаКлиенте Процедура СоздатьДеревоЗначений(Команда) СоздатьДеревоЗначенийНаСервере(); КонецПроцедуры &НаСервере Процедура СоздатьДеревоЗначенийНаСервере() // создаем объект ДеревоЗначений и добавляем колонки ДеревоЗначений = Новый ДеревоЗначений(); ДеревоЗначений.Колонки.Добавить("Код"); ДеревоЗначений.Колонки.Добавить("Наименование"); ДеревоЗначений.Колонки.Добавить("Количество"); // добавляем две строки верхнего уровня ГруппаТовары = ДеревоЗначений.Строки.Добавить(); ГруппаТовары.Код = "001"; ГруппаТовары.Наименование = "Товары"; ГруппаТовары.Количество = ""; ГруппаУслуги = ДеревоЗначений.Строки.Добавить(); ГруппаУслуги.Код = "002"; ГруппаУслуги.Наименование = "Услуги"; ГруппаУслуги.Количество = ""; // для первой строки верхнего уровня добавляем дочерние строки ПервыйТовар = ГруппаТовары.Строки.Добавить(); ПервыйТовар.Код = "003"; ПервыйТовар.Наименование = "Первый товар"; ПервыйТовар.Количество = 5; ПервыйТовар = ГруппаТовары.Строки.Добавить(); ПервыйТовар.Код = "004"; ПервыйТовар.Наименование = "Второй товар"; ПервыйТовар.Количество = 7; // для второй строки верхнего уровня добавляем дочерние строки ПерваяУслуга = ГруппаУслуги.Строки.Добавить(); ПерваяУслуга.Код = "005"; ПерваяУслуга.Наименование = "Первая услуга"; ПерваяУслуга.Количество = ""; ВтораяУслуга = ГруппаУслуги.Строки.Добавить(); ВтораяУслуга.Код = "006"; ВтораяУслуга.Наименование = "Вторая услуга"; ВтораяУслуга.Количество = ""; // цикл по строкам верхнего уровня Для Каждого ТекущаяГруппа Из ДеревоЗначений.Строки Цикл Сообщить("Код: " + ТекущаяГруппа.Код + ", Группа: " + ТекущаяГруппа.Наименование); // цикл по дочерним строкам текущей строки верхнего уровня Для Каждого ТекущийТоварИлиУслуга Из ТекущаяГруппа.Строки Цикл Сообщить( "Код: " + ТекущийТоварИлиУслуга.Код + ", Товар или услуга: " + ТекущийТоварИлиУслуга.Наименование ); КонецЦикла; КонецЦикла; КонецПроцедуры
Код: 001, Группа: Товары Код: 003, Товар или услуга: Первый товар Код: 004, Товар или услуга: Второй товар Код: 002, Группа: Услуги Код: 005, Товар или услуга: Первая услуга Код: 006, Товар или услуга: Вторая услуга
КоллекцияКолонокДереваЗначений.Добавить(Имя, Тип, Заголовок, Ширина) 
КоллекцияСтрокДереваЗначений.Добавить()

Заполнить табличное поле на форме

Визуальное представление дерева значений на форме обеспечивает элемент Таблица.

Пример программного заполнения дерева значений для управляемых форм:

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

Результат выполнения запроса очень легко преобразовать в дерево значений, для этого нужно воспользоваться методом Выгрузить() и указать параметр ТипОбхода отличным от того, что стоит по умолчанию, т.е. ПоГруппировкам или ПоГруппировкамСИерархией.

&НаКлиенте Процедура ЗаполнитьТабличноеПоле(Команда) ЗаполнитьТабличноеПолеНаСервере(); КонецПроцедуры &НаСервере Процедура ЗаполнитьТабличноеПолеНаСервере() Запрос = Новый Запрос(); Запрос.Текст = "ВЫБРАТЬ | Номенклатура.Наименование КАК ПерваяКолонка, | Номенклатура.Код КАК ВтораяКолонка |ИЗ | Справочник.Номенклатура КАК Номенклатура |УПОРЯДОЧИТЬ ПО | ПерваяКолонка ИЕРАРХИЯ"; ДеревоЗначений = Запрос.Выполнить().Выгрузить( ОбходРезультатаЗапроса.ПоГруппировкамСИерархией ); ЗначениеВРеквизитФормы(ДеревоЗначений, "РеквизитДеревоЗначений"); КонецПроцедуры

Свернуть и развернуть строки дерева значений

Свернуть и развернуть дочерние строки элемента дерева значений можно с помощью методов Свернуть() и Развернуть().

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

Для представления в форме объектов конфигурации (справочники, документы и т.п.) существуют специальные типы данных:

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

Удалить строку и очистить дерево значений

&НаКлиенте Процедура УдалитьСтрокуДереваЗначений(Команда) УдалитьСтрокуДереваЗначенийНаСервере(); КонецПроцедуры &НаСервере Процедура УдалитьСтрокуДереваЗначенийНаСервере() ДеревоЗначений = РеквизитФормыВЗначение("РеквизитДеревоЗначений"); // удаляем первую строку дерева значений ДеревоЗначений.Строки.Удалить(0); ЗначениеВРеквизитФормы(ДеревоЗначений, "РеквизитДеревоЗначений"); КонецПроцедуры
&НаКлиенте Процедура ОчиститьДеревоЗначений(Команда) ОчиститьДеревоЗначенийНаСервере(); КонецПроцедуры &НаСервере Процедура ОчиститьДеревоЗначенийНаСервере() ДеревоЗначений = РеквизитФормыВЗначение("РеквизитДеревоЗначений"); ДеревоЗначений.Строки.Очистить(); ЗначениеВРеквизитФормы(ДеревоЗначений, "РеквизитДеревоЗначений"); КонецПроцедуры

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

Среди наиболее часто используемых методов стоит отметить метод Найти() коллекции строк дерева значений.

КоллекцияСтрокДереваЗначений.Найти(Значение, Колонки, ВключатьПодчиненные)

Метод осуществляет поиск значения в дереве в указанных колонках коллекции строк дерева значений. Возвращает строку (тип СтрокаДереваЗначений), которая содержит искомое значение. Если значение не найдено, то возвращается значение Неопределено. Предназначен для поиска уникальных значений.

&НаКлиенте Процедура НайтиСтрокуДереваЗначений(Команда) ЗаполнитьТабличноеПолеНаСервере(); НайтиСтрокуДереваЗначенийНаСервере(); КонецПроцедуры &НаСервере Процедура НайтиСтрокуДереваЗначенийНаСервере() ДеревоЗначений = РеквизитФормыВЗначение("РеквизитДеревоЗначений"); РезультатПоиска = ДеревоЗначений.Строки.Найти( ИскомоеЗначение, "ПерваяКолонка,ВтораяКолонка", Истина ); Если РезультатПоиска <> Неопределено Тогда Сообщить( "Первая колонка: " + РезультатПоиска.ПерваяКолонка + ", Вторая колонка: " + РезультатПоиска.ВтораяКолонка ); Иначе Сообщить("Ничего не найдено"); КонецЕсли; КонецПроцедуры &НаСервере Процедура ЗаполнитьТабличноеПолеНаСервере() Запрос = Новый Запрос(); Запрос.Текст = "ВЫБРАТЬ | Номенклатура.Наименование КАК ПерваяКолонка, | Номенклатура.Код КАК ВтораяКолонка |ИЗ | Справочник.Номенклатура КАК Номенклатура |УПОРЯДОЧИТЬ ПО | ПерваяКолонка ИЕРАРХИЯ"; ДеревоЗначений = Запрос.Выполнить().Выгрузить( ОбходРезультатаЗапроса.ПоГруппировкамСИерархией ); ЗначениеВРеквизитФормы(ДеревоЗначений, "РеквизитДеревоЗначений"); КонецПроцедуры

Поиск: 1С:Предприятие • Дерево значений • Иерархия • Коллекция • Таблица формы • Типы данных • Управляемая форма

Заполнение реквизита формы (дерево значений)

Внешняя обработка заполнения объекта

 

Эту и другие технические статьи написали наши программисты 1С и получили за них премии. Если вы тоже работаете с 1С и любите делиться опытом, приходите разработчиком в Neti →

 

Рассмотрим задачу, когда нужно заполнить данные формы объекта, которые не являются реквизитами объекта.

Рассмотрим на примере. Заполним элемент ДеревоЦен (реквизит формы, не реквизит Объекта!) формы документа Установка цен номенклатуры конфигурации УТ 11.0.7.21:

Элемент ДеревоЦен

В элемент ДеревоЦен записываются данные по номенклатуре, а в подчиненные номенклатуре строки – данные по характеристикам номенклатуры. В результате в табличной части Товары документа Установка цен номенклатуры находятся строки по Номенклатуре (без характеристики) и строки по Характеристикам номенклатуры (т.е. получается как развернутый вид дерева значений ДеревоЦен).

Элемент ДеревоЦен будем заполнять товарами из ассортимента выбранного партнера, для этого в конфигурацию добавлен регистр сведений пр_АссортиментТоваров с измерениями Партнер и Характеристика; в документ Установка цен номенклатуры добавлен реквизит пр_Партнер.

Т.к. рассматриваем пример внешней обработки по заполнению объекта, то в модуле внешней обработки прописываем соответствующие процедуры:


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

Далее, т.к. используем ВызовКлиентскогоМетода, добавляем форму обработки. В модуле формы обработки прописываем процедуру ВыполнитьКоманду():


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

После подключения внешней обработки в пользовательском режиме (после добавления в справочник Дополнительные отчеты и обработки), в документе Установка цен номенклатуры появится кнопка Заполнение…, после нажатия на которую появится окно Команды заполнения объектов с названием команды, которую мы прописали в модуле объекта внешней обработки в процедуре СведенияОВнешнейОбработке() в строке «ДобавитьКоманду(ТаблицаКоманд, “Заполнить по Ассортименту товаров”»:

Заполнение документа


 

Работа с Деревом Значений » FAQ 1С 8.x » HelpF.pro

ДеревоЗначений в ТекстовыйДокумент[8.x, 8.2 УП, 8.3]
Как в дереве значений строку перекинуть в другой родитель?[8.x, 8.2 УП]
Как вывести в справочник в виде дерева значений[8.x]
Как из ДереваЗначений сделать ТаблицуЗначений по определенному уровню[8.x]
Как обойти, перебрать дерево значений?[8.x, 8.2 УП]
Как самостоятельно заполнить дерево значений?[8.x, 8.2 УП]
Как Свернуть, Развернуть узлы Дерева значений на форме?[8.x, 8.2 УП]
Как удалить строку или очистить дерево значений[8.x, 8.2 УП, 8.3]
Пересчет дерева, суммы и коэффициенты.[8.x, 8.2 УП]
Преобразование дерева значений в таблицу значений и обратно[8.x]
Примеры работы с Деревом значений в УП[8.x, 8.2 УП]

Пример работы с деревом значений в 1С. Часть первая

Работа с деревом значений немного отличается от работы с таблицей значений, в частности это видно на операции добавления строк. Смотрим на примере.

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

Рассмотрим работу с деревом значений на примере решения следующей задачи:

Выведем в строки даты (год, месяц, число) за 2013, 2014 годы в три уровня. На первом уровне будет год, на втором месяц и на третьем день.

Для этого поместим на форму табличное поле.

Перейдем в его палитру свойств.

Укажем тип значения «ДеревоЗначений».

Укажем, что это дерево.

Теперь добавим в табличное поле колонку «Дата».

Далее перейдем в палитру свойств колонки «Дата».

Установим галку «ОтображатьИерархию».

Поместим алгоритм формирования строк дерева в процедуру обработки открытия формы.

Алгоритм примерно следующий:

Перем СоответствиеМесяцы;Функция ПолучитьПредставлениеМесяцаНомерМесяца)      ПредставлениеМесяца = СоответствиеМесяцы.ПолучитьНомерМесяца);      Возврат ?(ПредставлениеМесяца=Неопределено, НомерМесяца, ПредставлениеМесяца);КонецФункции // ПолучитьПредставлениеМесяца()Процедура ПриОткрытии()      МассивГод = Новый Массив;   МассивГод.Добавить("2013");   МассивГод.Добавить("2014");      Для каждого СтрокаГод Из МассивГод Цикл            Дата = Дата(""+СтрокаГод+"0101");            СтрокаДереваГод = Дерево.Строки.Добавить();      СтрокаДереваГод.Дата = Год(Дата);               Для Кол = 1 По 12 Цикл         СтрокаДереваМесяц          = СтрокаДереваГод.Строки.Добавить();         СтрокаДереваМесяц.Дата       = ПолучитьПредставлениеМесяца(Месяц(Дата));                  КоличествоДнейВМесяце = День(КонецМесяца(Дата));         Для КолДней = 1 По КоличествоДнейВМесяце Цикл            СтрокаДереваДень = СтрокаДереваМесяц.Строки.Добавить();            СтрокаДереваДень.Дата = Строка(КолДней);         КонецЦикла;                  Дата = ДобавитьМесяц(Дата, 1);      КонецЦикла;      КонецЦикла;   КонецПроцедурыСоответствиеМесяцы = Новый Соответствие;СоответствиеМесяцы.Вставить(1, "Январь");СоответствиеМесяцы.Вставить(2, "Февраль");СоответствиеМесяцы.Вставить(3, "Март");СоответствиеМесяцы.Вставить(4, "Апрель");СоответствиеМесяцы.Вставить(5, "Май");СоответствиеМесяцы.Вставить(6, "Июнь");СоответствиеМесяцы.Вставить(7, "Июль");СоответствиеМесяцы.Вставить(8, "Август");СоответствиеМесяцы.Вставить(9, "Сентабрь");СоответствиеМесяцы.Вставить(10, "Октябрь");СоответствиеМесяцы.Вставить(11, "Ноябрь");СоответствиеМесяцы.Вставить(12, "Декабрь");

Теперь разберем его.

Первое что необходимо сделать, это объявить переменную, содержащую строковое представление месяца.

Перем СоответствиеМесяцы;

Потом создадим массив, элементы которого хранят год; месяцы и дни, по которым необходимо вывести.

МассивГод = Новый Массив;МассивГод.Добавить("2013");МассивГод.Добавить("2014");

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

Для каждого СтрокаГод Из МассивГод ЦиклДата = Дата(""+СтрокаГод+"0101");      СтрокаДереваГод = Дерево.Строки.Добавить();СтрокаДереваГод.Дата = Год(Дата);   …КонецЦикла;

Второй цикл обходит месяцы и заносит их на второй уровень строк, родителями которых являются строки, введенные нами выше (содержащие год).

Для Кол = 1 По 12 Цикл   СтрокаДереваМесяц    = СтрокаДереваГод.Строки.Добавить();   СтрокаДереваМесяц.Дата = ПолучитьПредставлениеМесяца(Месяц(Дата));   КоличествоДнейВМесяце = День(КонецМесяца(Дата));   …   Дата = ДобавитьМесяц(Дата, 1);КонецЦикла;

В этом цикле мы используем функцию «ПолучитьПредставлениеМесяца(Месяц)», которая возвращает строковое представление месяца по переданному номеру.

Функция ПолучитьПредставлениеМесяца(НомерМесяца)      ПредставлениеМесяца = СоответствиеМесяцы.Получить(НомерМесяца);      Возврат ?(ПредставлениеМесяца=Неопределено, НомерМесяца, ПредставлениеМесяца);КонецФункции // ПолучитьПредставлениеМесяца()

Для перехода к следующему месяцу используем встроенную функцию «ДобавитьМесяц(Дата, 1)».

И, наконец, третий цикл обеспечивает заполнение дней месяца, строки которого является их родителями.

Для КолДней = 1 По КоличествоДнейВМесяце Цикл   СтрокаДереваДень = СтрокаДереваМесяц.Строки.Добавить();   СтрокаДереваДень.Дата = Строка(КолДней);КонецЦикла;

Чтобы узнать сколько дней в каждом конкретном месяце мы будем использовать встроенную функцию КонецМесяца(), передавая ей, обрабатываемую в текущий момент, дату.

КоличествоДнейВМесяце = День(КонецМесяца(Дата));

В модуль формы вставим блок, обеспечивающий заполнение универсальной коллекции значений «Соответствие», хранящей строковое представление месяца.

СоответствиеМесяцы = Новый Соответствие;СоответствиеМесяцы.Вставить(1, "Январь");СоответствиеМесяцы.Вставить(2, "Февраль");СоответствиеМесяцы.Вставить(3, "Март");СоответствиеМесяцы.Вставить(4, "Апрель");СоответствиеМесяцы.Вставить(5, "Май");СоответствиеМесяцы.Вставить(6, "Июнь");СоответствиеМесяцы.Вставить(7, "Июль");СоответствиеМесяцы.Вставить(8, "Август");СоответствиеМесяцы.Вставить(9, "Сентабрь");СоответствиеМесяцы.Вставить(10, "Октябрь");СоответствиеМесяцы.Вставить(11, "Ноябрь");СоответствиеМесяцы.Вставить(12, "Декабрь");

Готово. Теперь при открытии формы происходит формирование строк дерева в три уровня.

Скачать готовый пример Работа с деревом значений (часть 1)

Вы еще не читали? Вам это будет интересно...

К списку новостей и статей

php - как заполнить значение в некотором элементе с помощью zend_form

Переполнение стека
  1. Около
  2. Товары
  3. Для команд
  1. Переполнение стека Общественные вопросы и ответы
  2. Переполнение стека для команд Где разработчики и технологи делятся частными знаниями с коллегами
  3. Вакансии Программирование и связанные с ним технические возможности карьерного роста
  4. Талант
.

php - Laravel: как заполнить форму значениями из сеанса

Переполнение стека
  1. Около
  2. Товары
  3. Для команд
  1. Переполнение стека Общественные вопросы и ответы
  2. Переполнение стека для команд Где разработчики и технологи делятся частными знаниями с коллегами
  3. Вакансии Программирование и связанные с ним технические возможности карьерного роста
  4. Талант
.

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

Переполнение стека
  1. Около
  2. Товары
  3. Для команд
  1. Переполнение стека Общественные вопросы и ответы
  2. Переполнение стека для команд
.

javascript - Как автоматически заполнить HTML-форму и мгновенно ее отправить?

Переполнение стека
  1. Около
  2. Товары
  3. Для команд
  1. Переполнение стека Общественные вопросы и ответы
  2. Переполнение стека для команд Где разработчики и технологи делятся частными знаниями с коллегами
.

php - Как отправить сообщение в форму и заполнить несколько вариантов?

Переполнение стека
  1. Около
  2. Товары
  3. Для команд
  1. Переполнение стека Общественные вопросы и ответы
  2. Переполнение стека для команд Где разработчики и технологи делятся частными знаниями с коллегами
  3. Вакансии Программирование и связанные с ним технические возможности карьерного роста
  4. Талант
.

java - Использование цикла For для заполнения массива

Переполнение стека
  1. Около
  2. Товары
  3. Для команд
  1. Переполнение стека Общественные вопросы и ответы
  2. Переполнение стека для команд Где разработчики и технологи делятся частными знаниями с коллегами
.

Смотрите также

Сайт о Бане - проект, посвященный строительству, эксплуатации и уходу за русской баней. Большой сборник статей, который может быть полезен любому любителю бани

Содержание, карта сайта.