В связи с тем, что у дерева значений на форме, нет интерактивного отбора, реализовываем свой отбор
Постановка задачи:
На управляемой форме имеем дерево значений, необходимо дать пользователю возможно производить отбор строк
Решение, теория:
Так как, создатели 1С не предусмотрели отборов в дереве значений, то нам необходимо создать копию оригинального дерева, в которой будут хранится все данные, а в основном же дереве, мы будем удалять все строки не соответствующие отбору
Давай уже код:
В начале (при создании на сервере), нам необходимо скопировать структуру оригинального дерева, вызываем процедуру СоздатьНовоеПустоеДеревоКопированием
&НаКлиентеНаСервереБезКонтекста
Функция ИмяКопииДереваЗаказа()
Возврат "КопияДереваЗаказа";
КонецФункции
&НаСервере
Процедура СоздатьНовоеПустоеДеревоКопированием()
Попытка
Реквизит = ЭтаФорма[ИмяКопииДереваЗаказа()];
Возврат; // Дерево есть, создавать не надо
Исключение
КонецПопытки;
// Так как возникло исключение и мы попалю сюда, то копии дерева нету
ДеревоИсходник = РеквизитФормыВЗначение("ТаблицаЗаказа");
МассивДобавленныхРеквизитов = Новый Массив;
НовоеДерево = Новый РеквизитФормы(ИмяКопииДереваЗаказа(), Новый ОписаниеТипов("ДеревоЗначений"));
МассивДобавленныхРеквизитов.Добавить(НовоеДерево);
Для Каждого ТекКол Из ДеревоИсходник.Колонки Цикл
Колонка = Новый РеквизитФормы(ТекКол.Имя, ТекКол.ТипЗначения, ИмяКопииДереваЗаказа());
МассивДобавленныхРеквизитов.Добавить(Колонка);
КонецЦикла;
ИзменитьРеквизиты(МассивДобавленныхРеквизитов);
ДеревоИсходник = Неопределено;
КонецПроцедуры
Нам нужно в начале заполнить копию дерева данными, я это делаю сразу после заполнения основного дерева, вы можете сделать свои события, но вызовите эту процедуру:
&НаСервере
Процедура СкопироватьДеревоЗаказа(ДеревоИсточник, ИмяРеквизитаНазначение)
СоздатьНовоеПустоеДеревоКопированием();
ДеревоКопия = ДеревоИсточник.Скопировать();
ЗначениеВРеквизитФормы(ДеревоКопия, ИмяРеквизитаНазначение);
КонецПроцедуры
Теперь добавляем команды которые будут отбирать значения. Сами команды кидаем на командную панель (так как только там работает "Пометка"). Этих команд отбора может быть несколько:
&НаКлиенте
Процедура ОтобратьНеУдовлетворенныйСпрос(Команда)
УстановитьОтборДереваЗаказаНаКлиенте(Элементы.ТаблицаЗаказаОтобратьНеУдовлетворенныйСпрос); // Передаем элемент кнопки, которая вызвала данную команду
КонецПроцедуры
Все эти команды отбора вызывают главное - процедуру отбора:
&НаКлиенте
Процедура УстановитьОтборДереваЗаказаНаКлиенте(Элемент)
Элемент.Пометка = Не Элемент.Пометка;
УстановитьОтборДереваЗаказа();
КонецПроцедуры
&НаСервере
Процедура УстановитьОтборДереваЗаказа()
// Описываем возможные отборы
СоответствиеОтборам = Новый Соответствие;
СоответствиеОтборам.Вставить(Элементы.ТаблицаЗаказаОтобратьНеУдовлетворенныйСпрос, "ТолькоНеУдовлетворенныйСпрос");
// Элемент и текстовое представление (потребуется дальше). Если нужно несколько отборов, добавьте тут ещё строк
Отборы = Новый Структура;
ВключеноОтборов = 0;
Для Каждого ЭлементОтбора Из СоответствиеОтборам Цикл
Если ЭлементОтбора.Ключ.Пометка Тогда // Проходим по всем описанным элементам и проверяем, какие включены
Отборы.Вставить(ЭлементОтбора.Значение);
ВключеноОтборов = ВключеноОтборов + 1;
КонецЕсли;
КонецЦикла;
// Надо снять отбор
ДеревоКопия = РеквизитФормыВЗначение(ИмяКопииДереваЗаказа());
ДеревоЗаказа = РеквизитФормыВЗначение("ТаблицаЗаказа");
ДеревоЗаказа = ДеревоКопия.Скопировать(); // Замещаем основное дерево, данными из копии
Если ВключеноОтборов <= 0 Тогда
ЗначениеВРеквизитФормы(ДеревоЗаказа, "ТаблицаЗаказа"); // Возвращаем данные на форму
Возврат;
КонецЕсли;
// Надо поставить отбор
Родители = ДеревоЗаказа.Строки;
РодителиКУдалению = Новый Массив;
Для Каждого ТекРодитель Из Родители Цикл
СтрокаРодителяСоответствуетОтбору = Истина;
Если Отборы.Свойство("ТолькоНеУдовлетворенныйСпрос") и ТекРодитель.СпросУдовлетворен Тогда
СтрокаРодителяСоответствуетОтбору = Ложь;
КонецЕсли;
Если СтрокаРодителяСоответствуетОтбору и Отборы.Свойство("...") и ТекРодитель.... Тогда
СтрокаРодителяСоответствуетОтбору = Ложь;
КонецЕсли;
Если Не СтрокаРодителяСоответствуетОтбору Тогда
РодителиКУдалению.Добавить(ТекРодитель);
Иначе
// Если надо, добавьте тут отборы детей (подчиненных элементов)
КонецЕсли;
КонецЦикла;
Для Каждого Родитель Из РодителиКУдалению Цикл
ДеревоЗаказа.Строки.Удалить(Родитель);
КонецЦикла;
ЗначениеВРеквизитФормы(ДеревоЗаказа, "ТаблицаЗаказа"); // Передаем на форму, наше обновленное дерево
КонецПроцедуры
Завершение
Вуаля! Отборы прекрасно работают и делают это достаточно быстро!
И домашнее задание вам: Если вы предполагаете изменение дерева (когда установлен отбор), вам необходимо синхронизировать данные с копией дерева, которое хранит исходные данные (добавлять позиции или менять значения полей).
Мозг + источники идей из разных мест
Орфографическая ошибка в Вуаля: Вуаля
ИнтерактивноеИзменениеВыгрузки_СформироватьДеревоЗначений (БСП)
ДеревоМетаданныхКонфигурации (БСП)
ИнтерактивноеИзменениеВыгрузкиОчисткаОбщегоОтбора (БСП)
МассивИзДереваЗначенийНаСервере
Вывод данных СКД в таблицу значений (дерево)
ИнтерактивноеИзменениеВыгрузкиОчисткаДетально (БСП)
ИнтерактивноеИзменениеВыгрузкиОписаниеДополненияОбщегоОтбора (БСП)
ИнтерактивноеИзменениеВыгрузкиОписаниеДетальногоОтбора (БСП)
#1, 18 июля 2020 12:41
Тут изучая список методов 1С, обнаружил для себя метод "КопироватьДанныеФормы", который можно использовать в данной задаче вместо РеквизитФормыВЗначение. Правда он доступен только на сервере и возможно, по факту делает тоже самое что и у меня код, но вы имейте ввиду.