Как посмотреть дерево значений в отладчике 1с
Практический пример. УНФ документ Установка цен номенклатуры. Дерево значений ВидыЦен. Как посмотреть содержимое?
ты смотри не реквизит формы, а его данные — вот там и есть строки
(8) работаем. плавали. знаем.
наклиенте и насервере оно выглядит по разному.
ещё, важно какая у тебя точка входа — элементы формы текущая строка или реквизты формы в целом.
(0) Дерево отладчик показывает как и ТЗ
Это с ВТ проблема в запросах/МВТ и ТабДок
На крайняк написать свое расширение с общим модулем своим например «Отладка»
И тупо вычислить «Отладка.Записать(ТвоеЗначение)»
Где внутри процедуры/функции Записать() я например делал вывод или запись куда то например в ёксель
строка.Строки
(10)А как его данные посмотреть?
(11)Реквизит формы.
Да если програмно создать дерево то оно смотрится нормально, а проблема с реквизитом формы.
(16) передай на сервер и там смотри
(16) На УФ есть вопросы с просмотром строк в Дереве формы
по факту перебор можно проехать только кодом, и смотреть в нём при отладке, примерно так:
уровень1 = Дерево.ПолучитьЭлементы();
Для каждого текЭлУр1 из уровень1 цикл
тут можно глянуть что творится в элеемнте уровня 1 (т.е. по аналогии со справочником — в корне)
уровень2 = текЭлУр1.ПолучитьЭлементы();
Для каждого элУр2 из Уровень2 цикл
вот тут смотри что у тебя на уровне 2 делается (в аналогии справочника — элементы из папки)
КонецЦикла;
КонецЦикла;
Можно попробовать через так: РеквизитФормыВЗначение(Дерево, «Дерево») — тут отладчик должен показать развёртку по строкам
Установите ИР и познайте счастье.
Кaк может человек ожидaть, что его мольбaм о снисхождении ответит тот, кто превыше, когдa сaм он откaзывaет в милосердии тем, кто ниже его? Петр Трубецкой
1С 8.3 : Дерево значений в таблицу значений или в табличную часть и обратно
Для одной организации надо было реализовать документы, где вместо табличной части надо использовать дерево и все это на управляемых формах. Но дерево нельзя сохранить в базе в текущем виде. Пришлось использовать табличную часть документа для хранения данных дерева. И при открытии формы получать данные из ТЧ и выводить их в дерево. Далее все манипуляции производить с деревом и при сохранении документа помещать данные в обратно в ТЧ.
Поиск по интернету не дал нужного варианта, пришлось реализовавыть свой механизм, используя информацию которая была на просторах интернета.
Для реализации такого механизма в ТЧ был добавлен реквизит “КлючСвязи” (обязательный реквизит) с типом число, куда помещался “НомерСтроки” (стандартный реквизит ТЧ) родителя (верхний уровень). А самый верхний элемент дерева имеет “КлючСвязи” равный 0.
На картинке ниже видно структуру дерева и структуру ТЧ
Нагрузка на сервер осуществляется при окрытии и при сохранении документа. А с деревом работают уже на клиенте.
На рабочей базе обрабатывается около 200 строк в одном документе.
Открытие и сохранение документа происходит моментально. С большем количеством строк не тестировалось.
Чтобы алгорит правильно работал, у рекизита фомы с типом дерево значений должны быть все реквизиты табличной части, кроме “КлючСвязи” и “НомерСтроки”. Иначе платформа выдаст ошибку. В дерево можо добавлять свои реквизиты отличные от ТЧ, они будут использоваться только в дереве.
Ниже приведен код преобразования дерева в таблицу и обратно.
&НаКлиенте
Процедура КомандаТаблицуВДерево(Команда)
КомандаТаблицуВДеревоНаСервере();
КонецПроцедуры
&НаСервере
Процедура КомандаТаблицуВДеревоНаСервере()
Дерево = ТаблицаВДерево(РеквизитФормыВЗначение("Объект"), "Товары");//Товары - имя табличной части
ЗначениеВРеквизитФормы(Дерево, "ДеревоЗначений");//ДеревоЗначений - реквизит формы с типом дерево значений
Элементы.ДеревоЗначений.Обновить();
КонецПроцедуры
&НаКлиенте
Процедура КомандаДеревоВТаблицу(Команда)
КомандаДеревоВТаблицуНаСервере();
КонецПроцедуры
&НаСервере
Процедура КомандаДеревоВТаблицуНаСервере()
Объект.Товары.Очистить();
ДОбъект = РеквизитФормыВЗначение("Объект");
ДеревоВТаблицу(ДОбъект, РеквизитФормыВЗначение("ДеревоЗначений"), "Товары");
ЗначениеВРеквизитФормы(ДОбъект, "Объект");
КонецПроцедуры
Формирование дерева из таблицы значений
//ФОРМИРОВАНИЕ ДЕРЕВА ИЗ ТАБЛИЦЫ
&НаСервере
Функция ТаблицаВДерево(ДокОбъект, НаименованиеТабличнойЧастиДокумента, КлючСвязи = NULL, ЭлементРодитель = NULL) Экспорт
//ПОДГОТОВКА КОЛОНОК ДЕРЕВА
КолонкиТаблицы = ДокОбъект.Метаданные().ТабличныеЧасти[НаименованиеТабличнойЧастиДокумента].Реквизиты;
ДеревоЗначений2 = Новый ДеревоЗначений;
Для каждого Кол из КолонкиТаблицы Цикл
Если Кол.Имя = "НомерСтроки" ИЛИ Кол.Имя = "КлючСвязи" Тогда
Продолжить;
Иначе
ДеревоЗначений2.Колонки.Добавить(Кол.Имя, Новый ОписаниеТипов(Кол.Тип));
КонецЕсли;
КонецЦикла;//ДеревоЗначений.Строки.Очистить();
Если КлючСвязи = NULL И ЭлементРодитель = NULL Тогда
//ПЕРВЫЙ ВЫЗОВ ПРОЦЕДУРЫ (КОРНЕВЫЕ ЭЛЕМЕНТЫ)
ИсточникВыборки = ДеревоЗначений2.Строки;
КлючСвязи = 0; // ЭЛЕМЕНТ ВЕРХНЕГО УРОВНЯ ИМЕЕТ НОМЕР СТРОКИ РОДИТЕЛЯ 0 (ОБЯЗАТЕЛЬНЫЙ РЕКВИЗИТ)
Иначе
//ВНУТРЕННИЙ ВЫЗОВ ПРОЦЕДУРЫ (ПОДЧИНЕННЫЕ ЭЛЕМЕНТЫ)
ИсточникВыборки = ЭлементРодитель.Строки;
КонецЕсли;
Фильтр = Новый Структура("КлючСвязи", КлючСвязи);
М = ДокОбъект[НаименованиеТабличнойЧастиДокумента].НайтиСтроки(Фильтр);
Если М.Количество() = 0 Тогда
Возврат ДеревоЗначений2;
КонецЕсли;
Для каждого Стр из М Цикл
Элемент = ИсточникВыборки.Добавить();
Для каждого Кол из КолонкиТаблицы Цикл
Если Кол.Имя = "НомерСтроки" ИЛИ Кол.Имя = "КлючСвязи" Тогда
Продолжить;
Иначе
Элемент[Кол.Имя] = Стр[Кол.Имя];
КонецЕсли;
КонецЦикла;
ТаблицаВДерево(ДокОбъект, НаименованиеТабличнойЧастиДокумента, Стр.НомерСтроки, Элемент); //ДОБАВЛЕНИЕ ПОДЧИНЁННЫХ ЭЛЕМЕНТОВ В ДЕРЕВО
КонецЦикла;
Возврат ДеревоЗначений2;
КонецФункции
Формирование таблицы из дерева
//ФОРМИРОВАНИЕ ТАБЛИЦЫ ИЗ ДЕРЕВА
&НаСервере
Процедура ДеревоВТаблицу(ДокОбъект, ДеревоЗначений, НаименованиеТабличнойЧастиДокумента, СтрокаДерева = NULL, КлючСвязи = NULL) Экспорт
Если СтрокаДерева = NULL И КлючСвязи = NULL Тогда
//ПЕРВЫЙ ВЫЗОВ ПРОЦЕДУРЫ (КОРНЕВЫЕ ЭЛЕМЕНТЫ)
ПервыйВызов = Истина;
ДокОбъект[НаименованиеТабличнойЧастиДокумента].Очистить();
ИсточникВыборки = ДеревоЗначений.Строки;
КлючСвязи = 0; // ЭЛЕМЕНТ ВЕРХНЕГО УРОВНЯ ИМЕЕТ НОМЕР СТРОКИ РОДИТЕЛЯ 0 (ОБЯЗАТЕЛЬНЫЙ РЕКВИЗИТ)
Иначе
//ВНУТРЕННИЙ ВЫЗОВ ПРОЦЕДУРЫ (ПОДЧИНЕННЫЕ ЭЛЕМЕНТЫ)
ПервыйВызов = Ложь;
ИсточникВыборки = СтрокаДерева.Строки;
КонецЕсли;
Для каждого Стр из ИсточникВыборки Цикл
НС = ДокОбъект[НаименованиеТабличнойЧастиДокумента].Добавить();
Для каждого Кол из ДокОбъект.Метаданные().ТабличныеЧасти[НаименованиеТабличнойЧастиДокумента].Реквизиты Цикл
Если Кол.Имя = "КлючСвязи" Тогда
НС.КлючСвязи = КлючСвязи
ИначеЕсли Кол.Имя = "НомерСтроки" Тогда
Продолжить;
Иначе
НС[Кол.Имя] = Стр[Кол.Имя];
КонецЕсли;
КонецЦикла;
Если НЕ Стр.Строки.Количество() = 0 Тогда
ДеревоВТаблицу(ДокОбъект,,НаименованиеТабличнойЧастиДокумента, Стр, НС.НомерСтроки);
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Разместил: E_Migachev Версии: | 8.2 УП | 8.3 | Дата: 14.09.2014 Прочитано: 71680
Возможно, вас также заинтересует
Похожие FAQ
Внутреннее устройство PostgreSQL, в помощь администраторам 1С 1
Понимание архитектуры используемой СУБД очень важно для правильной эксплуатации, но местами переоценено: администратору, DevOps-специалисту или разработчику прикладных систем вовсе необязательно знать подробности внутреннего устройства B-дерева или ДеревоЗначений в ТекстовыйДокумент 3
// Выводит данные ДереваЗначений в ТекстовыйДокумент, пригодный к рассмотрению в отладчике, окне сообщений и показу. // // Параметры: // рВетка — дерево значений, подлежащее выводу. Может иметь почти любую глубину иерархии, количество и тип ко Как открыть внешнюю обработку или отчет программно 1С УП? 7
В версии 8.2 и старше: приложение не работает непосредственно с локальными файлами, расположенными на компьютере. Файлы должны находиться на сервере. Поэтому для открытия внешней обработки нужно выполнить следующую последовательность действий: Как отобразить дерево значений на управляемой форме 0
Создадим новую внешнюю обработку. Добавляем управляемую форму и создаем обработчик ПриСозданииНаСервере(). Никаких реквизитов и элементов “вручную” не добавляем, будем делать это программно. НаСервере Процедура ПриСозданииНаСервере(Отказ, Станда Как удалить строку или очистить дерево значений 2
Помните, что при при удалении/очистке строки, все подчиненные строки удаляются. Очистить дерево значений: Дерево.Строки.Очистить(); НаСервере Процедура ОчиститьНаСервере() тДерево = РеквизитФормыВЗначение(«Дерево»); тДерево.Строки.О Посмотреть все результаты поиска похожих
Еще в этой же категории
ДеревоЗначений в ТекстовыйДокумент 3
// Выводит данные ДереваЗначений в ТекстовыйДокумент, пригодный к рассмотрению в отладчике, окне сообщений и показу. // // Параметры: // рВетка — дерево значений, подлежащее выводу. Может иметь почти любую глубину иерархии, количество и тип ко Как удалить строку или очистить дерево значений 2
Помните, что при при удалении/очистке строки, все подчиненные строки удаляются. Очистить дерево значений: Дерево.Строки.Очистить(); НаСервере Процедура ОчиститьНаСервере() тДерево = РеквизитФормыВЗначение(«Дерево»); тДерево.Строки.О Как отобразить дерево значений на управляемой форме 0
Создадим новую внешнюю обработку. Добавляем управляемую форму и создаем обработчик ПриСозданииНаСервере(). Никаких реквизитов и элементов “вручную” не добавляем, будем делать это программно. НаСервере Процедура ПриСозданииНаСервере(Отказ, Станда Посмотреть все в категории Работа с Деревом Значений
Просмотр значений в отладчике 1С
Если в момент отладки модуля нужно просмотреть содержимое таблицы значений, скажем ТЗ, то достаточно в «табло» написать ТЗ.ВыбратьСтроку() и оттрассировать любую строку кода, после чего появиться форма для выбора значения. После просмотра желательно убрать из «табло» строчку «ТЗ.ВыбратьСтроку()», иначе при последующей трассировке будет постоянно вываливаться окно с выбором значения.
Для Списка Значений можно воспользоваться
СЗ.ВыбратьЗначение(0).
А текст запроса, например, вот так хорошо смотреть:
ВвестиСтроку(текстЗапроса. 1).
во-первых: окошко многострочное;
во-вторых: можно скопировать текст запроса;
в-третьих: можно прямо в отладчике его (текст) подредактировать .
Можно вместо «а текст запроса, например, вот так хорошо смотреть: ВвестиСтроку(текстЗапроса. 1)»
вычислить «ЗначениеВФайл(«C:\tqery»,текстЗапроса)» и файл уже можешь хоть смотреть, хоть печатать (а то при «ВвестиСтроку» — длинноватая строка может получиться)
Работа с деревом значений в 1С 8.3
Дерево значений является одним из популярных типов данных, часто встречающихся на формах и конфигурации. Важным его преимуществом является заложенная платформой иерархичность, которой удобно воспользоваться в некоторых ситуациях, например, осуществить поиск по определенной группе элементов или получить отдельные итоговые суммы в различных категориях. Дерево значений в 1С – достаточно эффективный инструмент, достойный, чтобы разработчики тратили на его изучение свое время.
Размещение на форме и заполнение дерева значений
Чтобы на управляемой форме вывести дерево значений, необходимо добавить новый реквизит, выбрать нужный тип, добавить колонки и перетащить влево. На вопрос о добавлении колонок ответьте утвердительно, и перед вами предстанет общий вид дерева значений. Чтобы увидеть какие-либо записи, необходимо добавить строки дерева значений 1С с нужными данными.
Существует несколько способов заполнения дерева значений нужными нам свойствами с определенной иерархией. Самый простой вариант – заполнить вручную, последовательно добавляя элементы и внимательно самостоятельно соблюдая иерархию. Естественно, при большом количестве элементов данный вариант не должен рассматриваться разработчиками 1С. Данный способ вывода информации состоит из следующих операторов:
На стороне сервера:
-
Получение значения реквизита;
ДеревоРек = РеквизитФормыВЗначение("Дерево");
НоваяГруппа1 = ДеревоРек.Строки.Добавить(); НоваяГруппа1.ЭлементДерева = "Продукты"; НоваяГруппа1.НомерЭлемента = 1; НоваяГруппа2 = ДеревоРек.Строки.Добавить(); НоваяГруппа2.ЭлементДерева = "Мебель"; НоваяГруппа2.НомерЭлемента = 2; НовыйЭлемент1 = НоваяГруппа1.Строки.Добавить(); НовыйЭлемент1.ЭлементДерева = "Кефир"; НовыйЭлемент1.НомерЭлемента = 3; НовыйЭлемент2 = НоваяГруппа1.Строки.Добавить(); НовыйЭлемент2.ЭлементДерева = "Молоко"; НовыйЭлемент2.НомерЭлемента = 4;
ЗначениеВРеквизитФормы(ДеревоРек,"Дерево");
На стороне клиента:
-
Получение элементов дерева;
Группа1 = Дерево.ПолучитьЭлементы();
Строка1 = Группа1.Добавить(); Строка1.ЭлементДерева = "hand made"; Строка1.НомерЭлемента = 10; Группа1 = Строка1.ПолучитьЭлементы(); Подстрока1 = Группа1.Добавить(); Подстрока1.ЭлементДерева = "Шкатулка"; Подстрока1.НомерЭлемента = 12; Подстрока2 = Группа1.Добавить(); Подстрока2.ЭлементДерева = "Фенечка"; Подстрока2.НомерЭлемента = 13;
Таким способом можно оформить на управляемой форме 1С небольшое дерево значений или простую иерархию, используя цикл. Однако часто возникает задача представить на форме сложный иерархический справочник из базы данных. И здесь на помощь придет помещение результата запроса в дерево на форме. Алгоритм достаточно прост и логичен:
-
Создаем запрос и указываем нужные нам условия. Важно, чтобы псевдонимы совпадали с наименованием колонок дерева значений на форме;
Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | Номенклатура.Ссылка КАК Номенклатура |ИЗ | Справочник.Номенклатура КАК Номенклатура | |УПОРЯДОЧИТЬ ПО | Номенклатура ИЕРАРХИЯ";
Данные = Запрос.Выполнить().Выгрузить(ОбходРезультатаЗапроса.ПоГруппировкамСИерархией); ЗначениеВРеквизитФормы(Данные,"ДеревоНом")
При многократном использовании управляемой формы приходится очищать реквизиты. Не является исключением и дерево значений, если нам нужно получать актуальную информацию. Полностью очистить наш реквизит можно различными способами без особых усилий программиста:
-
На стороне клиента:
Дерево.ПолучитьЭлементы().Очистить();
ДеревоЗн = РеквизитФормыВЗначение("Дерево"); ДеревоЗн.Строки.Очистить(); ЗначениеВРеквизитФормы(ДеревоЗн, "Дерево");
Вышеперечисленные действия достаточно просты и не требуют усилий. Намного сложнее действия с конкретными строками, которые тоже необходимо использовать в работе. Ведь зачастую мы не будем иметь ни малейшего понятия о количестве строк в дереве, его иерархии, ее глубине и пр. Именно корректная работа с данными произвольной структуры требуется от качественно разработанной функциональности решения для анализа и обработки информации дерева значений.
Работа с заполненным деревом значений
В первую очередь, нужно научиться работать с данными, получая их из дерева. Для этого придется написать процедуру обхода строк дерева значений. Данные можно получить на сервере или клиенте, причем разница в алгоритмах будет небольшая. Ниже представлен алгоритм обхода дерева с краткими пояснениями операторов:
На клиентской стороне:
-
Вызываем процедуру, используя в качестве параметров строки дерева;
ОбойтиЭлементыДерева(Дерево.ПолучитьЭлементы());
&НаКлиенте Процедура ОбойтиЭлементыДерева(СтрокиДерева) Для каждого элемента Из СтрокиДерева Цикл Сообщить(элемента.ЭлементДерева); ВложенныеСтроки = элемента.ПолучитьЭлементы(); Если ВложенныеСтроки.Количество() > 0 Тогда ОбойтиЭлементыДерева(ВложенныеСтроки); КонецЕсли; КонецЦикла; КонецПроцедуры
На серверной стороне:
-
Получаем объект с формы;
ДеревоНаСервере = РеквизитФормыВЗначение("Дерево");
ОбойтиДеревоНаСервере(ДеревоНаСервере);
&НаСервере Процедура ОбойтиДеревоНаСервере(ДеревоНаСервере) Для каждого строка из ДеревоНаСервере.Строки цикл Сообщить(Строка.ЭлементДерева); Если Строка.Строки.Количество() > 0 Тогда ОбойтиДеревоНаСервере(Строка); КонецЕсли; КонецЦикла; КонецПроцедуры
Иногда в процессе обхода строк нам может потребоваться удалить что-либо. Для этого используется метод «Удалить(_параметр_)», для которого в качестве параметра может использоваться индекс или непосредственно строка. Так как в процессе обхода вы рассматриваете все строки по отдельности, не составит труда удалить некоторые из них. Будьте внимательны, так как при удалении строки удаляются все вложенные элементы.
Также достаточно распространенной задачей является преобразование дерева значений в таблицу значений. Так как нам нельзя терять иерархию, в таблице будет на 2 поля больше, чем в дереве – добавятся идентификатор и родитель. Заполнить таблицу с сохранением структуры мы сможем с помощью рекурсивной процедуры.
Целиком алгоритм состоит из:
-
Вызов процедуры с указанием начального идентификатора;
ПреобразоватьВТЗРекурсия(тДерево, тТаблица, Новый УникальныйИдентификатор("00000000-0000-0000-0000-000000000000"));
&НаСервере Процедура ПреобразоватьВТЗРекурсия(тДерево, тТаблица, ГУИД) Для Каждого тСтр Из тДерево.Строки Цикл нСтр = тТаблица.Добавить(); нСтр.Колонка1 = тСтр.Колонка1; нСтр.Колонка2 = тСтр.Колонка2; нСтр.Родитель = ГУИД; нСтр.ГУИД = Новый УникальныйИдентификатор(); Если тСтр.Строки.Количество()>0 Тогда ПреобразоватьВТЗРекурсия(тСтр, тТаблица, нСтр.ГУИД); КонецЕсли; КонецЦикла; КонецПроцедуры
Зачастую пользователям бывает мало просто добавить дерево значений в 1С на управляемую форму. Постоянно поступают запросы, чтобы была возможность посмотреть всю структуру. Для этого придется развернуть дерево значений прямо на глазах у пользователя. В 1С это можно сделать, обойдя в цикле все строки и воспользовавшись одним из их методов:
ЭлементыДерева = Дерево.ПолучитьЭлементы(); Для каждого элемента из ЭлементыДерева цикл элементы.Дерево.Развернуть(элемента.ПолучитьИдентификатор(),Истина); КонецЦикла;
Также могут случаться ситуации, когда нужно свернуть имеющееся дерево. Для сворачивания конкретной строки можно воспользоваться методом «Свернуть(_Строка_)», аналогичным по синтаксису вышеописанному «Развернуть()». Чтобы полностью свернуть все дерево, придется воспользоваться рекурсивной функцией. Ее код достаточно прост и поддерживает общую методологию работы с деревом значений:
&НаКлиенте Процедура СвернутьДерево (ЭлементыДерева) Для Каждого элемента Из ЭлементыДерева Цикл ВлЭлементыЭлемента = элемента.ПолучитьЭлементы(); Если ВлЭлементыЭлемента.Количество() > 0 тогда СвернутьДерево(ВлЭлементыЭлемента); КонецЕсли; Элементы.Дерево.Свернуть(элемента.ПолучитьИдентификатор()); КонецЦикла; КонецПроцедуры
Одним из сложных нюансов, связанных с деревом значений, является отсутствие возможности отбора, когда родитель не удовлетворяет условию, а подчиненный элемент удовлетворяет. Нет однозначного ответа, что делать в подобных ситуациях, поэтому разработчики 1С решили не добавлять стандартную возможность фильтрации для дерева значений. Однако с этим можно справиться, разработав свою методику, например, скопировать дерево, удалить неподходящие значения и изменить иерархию.
Созданный в платформе 1С тип «Дерево значений» отлично подходит для задач отображения иерархических списков и не только. Пользуясь им грамотно, можно существенно сэкономить время и удовлетворить требования пользователей по визуализации необходимых им данных, легко загрузив данные в дерево, обойти их и отразить развернутый список на управляемой форме.