Имя: Пароль:
1C
1С v8
Флажок в ДеревоЗначений Управляемые формы
0 ahahaev
 
19.11.12
15:38
Добрый день. Такой вопрос. У меня есть массив, который я хочу вывести на форму в виде иерархии. Хотелось бы, чтобы при этом можно было помечать флажками нужные мне данные, после чего возвращался бы массив выбранных значений.
Подскажите пожалуйста, возможно ли реализовать это на управляемых формах и если да, то в каком направлении копать?
1 ahahaev
 
19.11.12
16:42
Подниму.
Кроме как сделать дополнительную колонку и написать для нее обработку никаких способов нигде не нашел, но вдруг есть стандартное решение, как было в 8.1.
2 vmv
 
19.11.12
18:24
и завопели страждущие "халява прийди" и разверзлись хляби - она пришла

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////// Внеконтекстные методы коллекций

//----------- Методы относительно ТаблицФормы типа ДанныеФормыСтруктураСКоллекцией (дерево)

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

Процедура ДзМодифицироватьФлажкиРодКоллекций(ДзКоллекция, ДзЭлементДз, ПолеФлажкаИмя) Экспорт
   
   # Если Сервер Тогда
       Если ТипЗнч(ДзКоллекция) = Тип("ДеревоЗначений") Тогда
           ЭтоДз = Истина;
       Иначе    
           ЭтоДз = Ложь;
       КонецЕсли;
   # Иначе      
       ЭтоДз = Ложь;
   # КонецЕсли  
   
   Если ДзЭлементДз = Неопределено Тогда
       Возврат;
   Иначе    
       Если ЭтоДз Тогда
           ДзЭлементРодитель = ДзЭлементДз.Родитель;
       Иначе    
           ДзЭлементРодитель = ДзЭлементДз.ПолучитьРодителя();
       КонецЕсли;
   КонецЕсли;
   Если ДзЭлементРодитель = Неопределено Тогда
       Возврат;
   КонецЕсли;
   
   Если ЭтоДз Тогда
       ДзЭлементРодительСтроки = ДзЭлементРодитель.Строки;
   Иначе    
       ДзЭлементРодительСтроки = ДзЭлементРодитель.ПолучитьЭлементы();
   КонецЕсли;
   
   ДзЭлементРодительСтрокиКоличество = ДзЭлементРодительСтроки.Количество();
   Если НЕ ДзЭлементРодительСтрокиКоличество Тогда
       Возврат;
   КонецЕсли;
   
   КоличествоСостояний0 = 0; КоличествоСостояний1 = 0;    КоличествоСостояний2 = 0;
   
   Для каждого ДзЭлементРодительВложеннаяСтрока Из ДзЭлементРодительСтроки Цикл
       
       ЗначениеСостоянияФлажка = ДзЭлементРодительВложеннаяСтрока[ПолеФлажкаИмя];
       
       Если ЗначениеСостоянияФлажка = 0 Тогда    
           КоличествоСостояний0 = КоличествоСостояний0 + 1;
       ИначеЕсли ЗначениеСостоянияФлажка = 1 Тогда
           КоличествоСостояний1 = КоличествоСостояний1 + 1;
       ИначеЕсли ЗначениеСостоянияФлажка = 2 Тогда
           КоличествоСостояний2 = КоличествоСостояний2 + 1;
       КонецЕсли;
       
   КонецЦикла;
   
   Если КоличествоСостояний2 Тогда
       ДзЭлементРодитель[ПолеФлажкаИмя] = 2;
   Иначе    
       Если КоличествоСостояний0 = ДзЭлементРодительСтрокиКоличество Тогда
           ДзЭлементРодитель[ПолеФлажкаИмя] = 0;
       ИначеЕсли КоличествоСостояний1 = ДзЭлементРодительСтрокиКоличество Тогда    
           ДзЭлементРодитель[ПолеФлажкаИмя] = 1;
       Иначе      
           ДзЭлементРодитель[ПолеФлажкаИмя] = 2;
       КонецЕсли;
   КонецЕсли;
   
   ДзМодифицироватьФлажкиРодКоллекций(ДзКоллекция, ДзЭлементРодитель, ПолеФлажкаИмя);
   
КонецПроцедуры


как получить в массив отмеченные флажком множества

типа так, там имена в кавычках колонки флажков, как загнать ети массивы строк в массивы колонок - вопрос не уместен

&НаСервере
Функция ВиДеревоПолучитьПодвал(СоздаватьКорень, Дз = Неопределено)
   
    ствЗначенияПодвалов = Новый Соответствие;
    ствЗначенияПодвалов.Вставить("РФВиДеревоВсегоСтрок", "");
   
    Если Дз = Неопределено Тогда
        фОчистить   = Истина;
        Дз = РеквизитФормыВЗначение("РФВиДерево");
    Иначе
        фОчистить   = Ложь;
    КонецЕсли;
    Если Не Дз.Строки.Количество() Тогда
        Дз = 0;
        Возврат ствЗначенияПодвалов;
    КонецЕсли;
    ВиВсего             = Дз.Строки.НайтиСтроки(Новый Структура("Уровень", 1), Истина).Количество();
    ВиВсегоПолучать     = Дз.Строки.НайтиСтроки(Новый Структура("Уровень, Получать", 1, 1), Истина).Количество() + Дз.Строки.НайтиСтроки(Новый Структура("Уровень, Получать", 1, 2), Истина).Количество();
    ВиТаблВсего         = Дз.Строки.НайтиСтроки(Новый Структура("Уровень", 2), Истина).Количество();
    ВиТаблВсегоПолучать = Дз.Строки.НайтиСтроки(Новый Структура("Уровень, Получать", 2, 1), Истина).Количество() + Дз.Строки.НайтиСтроки(Новый Структура("Уровень, Получать", 2, 2), Истина).Количество();
   
    ВсегоСтрокПодвал =
    Формат(ВиВсего        , "ЧГ=") + " / " + Формат(ВиТаблВсего        , "ЧГ=") + " , " +
    Формат(ВиВсегоПолучать, "ЧГ=") + " / " + Формат(ВиТаблВсегоПолучать, "ЧГ=");
   
    ствЗначенияПодвалов.Вставить("РФВиДеревоВсегоСтрок", ВсегоСтрокПодвал);
   
    // Если дерево неоднородно, т.е. содержит данные не только примитивных типов,
    // то при передаче управления с сервера на клиент возникает системная ошибка.
    // Видимо деструктор "не может" убить переменную этой процедуры корректно.
    // В этом случае простая ручная терминация дерева устраняет эту ошибку
    Если фОчистить Тогда
        Дз = 0;
    КонецЕсли;
   
    Возврат ствЗначенияПодвалов;
   
КонецФункции




как все это заточить под более простой случай Тз, Тч - вопрос не уместен. изучай
3 Поросенок Петр
 
19.11.12
18:33
Какое блудняк с пометкой нижестоящих и вышестоящик флажков... У меня в несколько строк вместилось.
4 Поросенок Петр
 
19.11.12
18:38
А по поводу

"     // Видимо деструктор "не может" убить переменную этой процедуры корректно."

вообще ржачно. Почему умное слово деструктор должно убивать переменную Дз, если она параметром функции по ссылке является?
5 vmv
 
19.11.12
18:41
(4) это я для себя писал, чтобы протестить на новых релизах 8.2 в версиях до 8.2.15 была такая трабла и даже подвержедена в багах 1С, сфорулируй как тебе нравиться, или ты считаешь, что при точке выхода из процедуры, функции созданные в ней переменные не уничтожаються в локальном контексте на уровне платформы?

давай об этом пагаварим, можешь ассемблерные или сишные вставки кидать - обажаю гуру)
6 vmv
 
19.11.12
18:42
+(5) вначале Дз создавалось в этом же методе, камент переполз уже с обертки
7 Поросенок Петр
 
19.11.12
18:46
Х.З. про этот "баг" тока от "мегакодеров" слышал. То в реквизит формы -  коллекцию что-нить сунут, то в параметр метода, то в возвращаемую структуру.
8 vmv
 
19.11.12
18:50
(5) вставки по по параметру ПолеПринудительнойУстановкиИмя уберои и получишь свои несколько строк, пример вызова там не верен, а длудняк нужен для трех состояний ибо если мы модифицируем дерево в глубоком узле, то вынуждены пройти вниз от него и вверх даже если нет трех состояний, верно

выложи свою обработку флажков в дереве не привязанную к форме, контексту и т.д. а работащую только с коллеецией дерава и именами флаговых колонок
9 ChAlex
 
19.11.12
19:56
(2) - вот так и рождаются типовые конфигурации. Простой вопрос, есть простое решение (а именно Дерево.Строки.Найти() на сервере), но нужно замутить так... что без пол-литра даже неохота вникать :)
10 ahahaev
 
20.11.12
10:38
(9) Спасибо :)
Требовать и эффективности, и гибкости от одной и той же программы — все равно, что искать очаровательную и скромную жену... по-видимому, нам следует остановиться на чем-то одном из двух. Фредерик Брукс-младший