Подбор из Дерева значений
Привет всем! Есть документ в который подбираются материалы,кол-во и виды работ. Подбор осущ-ся из «формы подбора», на которой есть Таб.поле (тип ТЗ)из нее по определнным условиям подбирается номенклатура,кол-во и вид.работы, при этом на этой ТЗ есть колонка Остаток (совокупный в разрезе всех складов) при выделении которой на этой же форме подбора в другом таб.поле (тип Дерево значений — по аналогии с формой списка справочника «Номенклатура» в типовых конфах) выводятся остатки по складам. Вопрос: Как бы сделать так, чтобы при выборе номенклатуры из ТЗ можно было бы еще и выбрать склад(ы) для загрузки в ТЧ документа?
Процедура ВыполняемыеРаботыОбработкаВыбора(Элемент, ВыбранноеЗначение, СтандартнаяОбработка)
// Вставить содержимое обработчика.
Строка = ЭлементыФормы.ВыполняемыеРаботы.ТекущаяСтрока;
Если ТипЗнч(ВыбранноеЗначение) = Тип(«Структура») Тогда
ТекстВвестиЧисло = «Укажите количество материала»;
Если ВвестиЧисло(пКоличество, ТекстВвестиЧисло, 15, 3)=Истина тогда
Количество=пКоличество;
НоваяСтрока.Номенклатура=ВыбранноеЗначение.Номенклатура;
НоваяСтрока.ЕдиницаИзмерения = ВыбранноеЗначение.ЕдиницаИзмерения;
НоваяСтрока.Количество = Количество;
НоваяСтрока.ВидРаботы = ВыбранноеЗначение.ВидРаботы;
НоваяСтрока.ЕдиницаИзмеренияРаботы = ВыбранноеЗначение.Ед_изм;
//НоваяСтрока.Склад= . ;
КонецЕсли;
КонецЕсли;
ФормаПодбораСклада = Документы.ПроектНарядаНаСтроительныеРаботы.ПолучитьФорму(«ФормаПодбораСклада»);
ФормаПодбораСклада.Открыть();
ФормаПодбораСклада.РежимВыбора = Истина;
ФормаПодбораСклада.ЗакрыватьПриВыборе = Ложь;
//ФормаПодбораСклада.ЭлементыФормы.ТабличноеПолеОстаткиТоваров.Значение = ОстаткиТоваров.Скопировать();
ЗначениеДерева=ФормаПодбораМатериалов.ЭлементыФормы.ТабличноеПолеОстаткиТоваров.Значение;
Пытался так, но фигня какая-то получатся, как в выбранное значение подцепить поле «Склад»?
(2) Имеется ввиду вызывал другую (дополнительную)форму куда выгружал данные из ДЗ основной формы подбора.
Источник
Интерактивный отбор дерева значений
Решение, теория:
Так как, создатели 1С не предусмотрели отборов в дереве значений, то нам необходимо создать копию оригинального дерева, в которой будут хранится все данные, а в основном же дереве, мы будем удалять все строки не соответствующие отбору
Давай уже код:
В начале (при создании на сервере), нам необходимо скопировать структуру оригинального дерева, вызываем процедуру СоздатьНовоеПустоеДеревоКопированием
&НаКлиентеНаСервереБезКонтекста Функция ИмяКопииДереваЗаказа() Возврат "КопияДереваЗаказа"; КонецФункции &НаСервере Процедура СоздатьНовоеПустоеДеревоКопированием() Попытка Реквизит = ЭтаФорма[ИмяКопииДереваЗаказа()]; Возврат; // Дерево есть, создавать не надо Исключение КонецПопытки; // Так как возникло исключение и мы попалю сюда, то копии дерева нету ДеревоИсходник = РеквизитФормыВЗначение("ТаблицаЗаказа"); МассивДобавленныхРеквизитов = Новый Массив; НовоеДерево = Новый РеквизитФормы(ИмяКопииДереваЗаказа(), Новый ОписаниеТипов("ДеревоЗначений")); МассивДобавленныхРеквизитов.Добавить(НовоеДерево); Для Каждого ТекКол Из ДеревоИсходник.Колонки Цикл Колонка = Новый РеквизитФормы(ТекКол.Имя, ТекКол.ТипЗначения, ИмяКопииДереваЗаказа()); МассивДобавленныхРеквизитов.Добавить(Колонка); КонецЦикла; ИзменитьРеквизиты(МассивДобавленныхРеквизитов); ДеревоИсходник = Неопределено; КонецПроцедуры
Нам нужно в начале заполнить копию дерева данными, я это делаю сразу после заполнения основного дерева, вы можете сделать свои события, но вызовите эту процедуру:
&НаСервере Процедура СкопироватьДеревоЗаказа(ДеревоИсточник, ИмяРеквизитаНазначение) СоздатьНовоеПустоеДеревоКопированием(); ДеревоКопия = ДеревоИсточник.Скопировать(); ЗначениеВРеквизитФормы(ДеревоКопия, ИмяРеквизитаНазначение); КонецПроцедуры
Теперь добавляем команды которые будут отбирать значения. Сами команды кидаем на командную панель (так как только там работает «Пометка»). Этих команд отбора может быть несколько:
&НаКлиенте Процедура ОтобратьНеУдовлетворенныйСпрос(Команда) УстановитьОтборДереваЗаказаНаКлиенте(Элементы.ТаблицаЗаказаОтобратьНеУдовлетворенныйСпрос); // Передаем элемент кнопки, которая вызвала данную команду КонецПроцедуры
Все эти команды отбора вызывают главное — процедуру отбора:
&НаКлиенте Процедура УстановитьОтборДереваЗаказаНаКлиенте(Элемент) Элемент.Пометка = Не Элемент.Пометка; УстановитьОтборДереваЗаказа(); КонецПроцедуры &НаСервере Процедура УстановитьОтборДереваЗаказа() // Описываем возможные отборы СоответствиеОтборам = Новый Соответствие; СоответствиеОтборам.Вставить(Элементы.ТаблицаЗаказаОтобратьНеУдовлетворенныйСпрос, "ТолькоНеУдовлетворенныйСпрос"); // Элемент и текстовое представление (потребуется дальше). Если нужно несколько отборов, добавьте тут ещё строк Отборы = Новый Структура; ВключеноОтборов = 0; Для Каждого ЭлементОтбора Из СоответствиеОтборам Цикл Если ЭлементОтбора.Ключ.Пометка Тогда // Проходим по всем описанным элементам и проверяем, какие включены Отборы.Вставить(ЭлементОтбора.Значение); ВключеноОтборов = ВключеноОтборов + 1; КонецЕсли; КонецЦикла; // Надо снять отбор ДеревоКопия = РеквизитФормыВЗначение(ИмяКопииДереваЗаказа()); ДеревоЗаказа = РеквизитФормыВЗначение("ТаблицаЗаказа"); ДеревоЗаказа = ДеревоКопия.Скопировать(); // Замещаем основное дерево, данными из копии Если ВключеноОтборов
Завершение
Вуаля! Отборы прекрасно работают и делают это достаточно быстро!
И домашнее задание вам: Если вы предполагаете изменение дерева (когда установлен отбор), вам необходимо синхронизировать данные с копией дерева, которое хранит исходные данные (добавлять позиции или менять значения полей).
Мозг + источники идей из разных мест
Недостаточно рейтинга для добавления отрицательного голоса. Шаблон будет скрыт из ваших результатов поиска.
Орфографическая ошибка в Вуаля: Вуаля
Шаблоны кода 1С
Секреты TurboConf
Нейросети и AI
Лайфхаки 1С
Бубен админа
1С не всерьез
Комментарии
Тут изучая список методов 1С, обнаружил для себя метод "КопироватьДанныеФормы", который можно использовать в данной задаче вместо РеквизитФормыВЗначение. Правда он доступен только на сервере и возможно, по факту делает тоже самое что и у меня код, но вы имейте ввиду.
См. также
× Канал FastCode 1C в Телеграм! Шаблоны кода, статьи, полезные советы, курсы по 1С (6К участников)
Присоединиться
Источник
1С 8.3 Дерево значений - Программист 1С Минск. Автоматизация бизнеса.
Дерево Значений в 1С 8.3 - это иерархический динамически набор любого типа. По своим функциям и структуре (колонки и строки) очень схожа с Таблицей Значений, но есть виртуальная колонка "Родитель". Дерево значений рекомендуется использовать для работы именно с иерархической информацией . Каждая строка дерева значений имеет свойства "Родитель" и "Строки", а также может иметь любое количество подчиненных строк. Операции с помощью встроенного функционала (сортировка, раскраска строк, поиск, итоги, различные отборы ) могут производится с учетом подчиненных строк / уровней иерархии.
&НаСервере
Процедура ЗаполнениеРеквизитаФормыДеревоЗначений ()
// Преобразование реквизита формы в объект прикладного типа ДеревоЗначений
ДеревоЗначений = РеквизитФормыВЗначение ( "ДеревоЗначНаФорме" );
// ДеревоЗначений = Новый ДеревоЗначений; - если без реквизита
ДЗ_Корень = ДеревоЗначений . Строки . Добавить ();
ДЗ_Корень . Наименование = "Самый верхний уровень" ;
ДЗ_1уровень = ДЗ_Корень . Строки . Добавить ();
ДЗ_1уровень . Наименование = "1-ая папка (группа)" ;
ЭлементДЗ_1 = ДЗ_1уровень . Строки . Добавить ();
ЭлементДЗ_1 . Наименование = "Первый (вложенный) элемент" ;
ДЗ_2уровень = ДЗ_Корень . Строки . Добавить ();
ДЗ_2уровень . Наименование = "2-ая папка (группа)" ;
ЭлементДЗ_1 = ДЗ_2уровень . Строки . Добавить ();
ЭлементДЗ_1 . Наименование = "Первый (вложенный) элемент" ;
ЭлементДЗ_2 = ДЗ_2уровень . Строки . Добавить ();
ЭлементДЗ_2 . Наименование = "Второй (вложенный) элемент" ;
// Преобразование ДеревоЗначений в реквизит формы (табличное поле)
ЗначениеВРеквизитФормы ( ДеревоЗначений , "ДеревоЗначНаФорме" );
&НаСервере
Процедура ЗаполнениеРеквизитаФормыДеревоЗначенийИзЗапроса ()
Запрос = Новый Запрос ;
Запрос . Текст = "ВЫБРАТЬ
| Материалы.Ссылка КАК Наименование
| Материалы.Родитель КАК Родитель
|ИЗ
| Справочник.Материалы КАК Материалы
|УПОРЯДОЧИТЬ ПО
| Наименование ИЕРАРХИЯ
|ИТОГИ ПО
| Родитель" ;
//Внимание! Если правильно не указать вид обхода результата выборки по запросу,
//то мы получим обычную таблицу значений
ДеревоЗначений = Запрос . Выполнить (). Выгрузить ( ОбходРезультатаЗапроса . ПоГруппировкамСИерархией );
// Заполнение дерева значений из результата запроса
// колонка "Материалы" – это элемент справочника, колонка "Родитель" – это группа
ЗначениеВРеквизитФормы ( ДеревоЗначений , "ДеревоЗначНаФорме" ); // Преобразование в реквизит формы (табличное поле)
&НаСервере
Процедура ПоискСтрокиВДеревеЗначений () // найдём 1-ю строку со значением «Элемент №1» в дереве значений
// Преобразование реквизита формы в объект прикладного типа ДеревоЗначений
ДеревоЗначений = РеквизитФормыВЗначение ( "ДеревоЗначНаФорме" );
// Поиск строки. (если строка не найдена, вернёт "Неопределено")
НайденнаяСтрокаДЗ = ДеревоЗначений . Строки . Найти ( "Первый (вложенный) элемент" , "Наименование" , Истина);
// Анализ результата поиска
Если НайденнаяСтрокаДЗ = Неопределено Тогда
Сообщить ( "Строка не найдена" );
Иначе // вренёт первую найденную строку
Сообщить ( "Найдена: " + НайденнаяСтрокаДЗ . Наименование + " (" + НайденнаяСтрокаДЗ . Родитель . Наименование + ")" );
КонецЕсли;
&НаСервере
Процедура ПоискВсехСтрокВДеревеЗначений ()
// Преобразование реквизита формы в объект прикладного типа ДеревоЗначений
ДеревоЗначений = РеквизитФормыВЗначение ( "ДеревоЗначНаФорме" );
// Создаем структуру для поиска (условие)
НаименованиеДляПоиска = "Первый (вложенный) элемент" ;
ПараметрыОтбора = Новый Структура ;
ПараметрыОтбора . Вставить ( "Наименование" , НаименованиеДляПоиска );
// Поиск всех строк содержащих наименование "Первый (вложенный) элемент"
МассивСтрок_ДЗ = ДеревоЗначений . Строки . НайтиСтроки ( ПараметрыОтбора , Истина);
// Проверка найдены ли строки
Если МассивСтрок_ДЗ . Количество () = 0 Тогда
Сообщить ( "Ни одной строкис наименованием " + НаименованиеДляПоиска + " не найдено!" );
КонецЕсли;
// Перебор строк
Для Каждого Строка_ДЗ Из МассивСтрок_ДЗ Цикл
Если Строка_ДЗ . Родитель = Неопределено Тогда
Сообщить ( "Корень дерева значений: " + Строка_ДЗ . Наименование );
Иначе
Сообщить ( Строка_ДЗ . Наименование + " - " + Строка_ДЗ . Родитель . Наименование );
КонецЕсли
&НаСервере
Процедура УдалениеСтрокиИзДереваЗначений ()
// Преобразование реквизита формы в объект прикладного типа ДеревоЗначений
ДеревоЗначений = РеквизитФормыВЗначение ( "ДеревоЗначНаФорме" );
// С помощью данных методов возможно удаление конкретных строк
// Важно! При удалении либо очистки строки - все её подчинённые строки удалятся
// 1.Очистка всех строк
ДеревоЗначений . Строки . Очистить ();
// 2. Удаление по конкретному индексу
ДеревоЗначений . Строки . Удалить ( 0 );
// 3.Или удаление по конкретному наименованию
НайтиСтроку = ДеревоЗначений . Строки . Найти ( " Легированная сталь " , "Наименование" );
Если НЕ НайтиСтроку = Неопределено Тогда
ДеревоЗначений . Строки . Удалить ( НайтиСтроку );
КонецЕсли;
ЗначениеВРеквизитФормы ( ДеревоЗначений , "ДеревоЗначНаФорме" ); // Преобразование в реквизит формы (табличное поле)
Источник