Имя: Пароль:
1C
1С v8
Дерево значений на управляемой форме с сохранением
0 asder117
 
21.09.20
14:43
Доброго времени суток. Может вопрос и изъезженный но ответа не нашел.
Задача: на форме документа сделать дерево значений (в реквизитах формы создал элемент - дерево). Программно заполнить его первый столбец (сделал это без проблем)..дальше юзвери его заполняют и всеп должно сохраняться...ДЗ и ТЗ не сохраняемые в БД элементы коллекции.
По совету создал в объекте таблицу с одноименными колонками + 2, пробовал через преобразование ДЗ-в ТЗ при сохранении и обратно при открытии. Не помогает. Кто что может посоветовать. Спасибо.
1 zippygrill
 
21.09.20
14:59
хранилище значение
2 zippygrill
 
21.09.20
15:00
Я
3 asder117
 
21.09.20
15:01
(1) Пробовал через него но что-то тоже не взлетело.Может что-то не так делал..Примерчик можно какой-то? Спасибо
4 zippygrill
 
21.09.20
15:08
//сохранение

ТвоеДеревоОбъект = РеквизитФормыВЗначение("ТвоеДеревоНаФорме");
докОбъект.ТвойРеквизитХранилище = Новый ХранилищеЗначения(ТвоеДеревоОбъект);

//восстановление
ТвоеДеревоОбъект = РеквизитФормыВЗначение("ТвоеДеревоНаФорме");
ТвоеДеревоОбъект = докОбъект.ТвойРеквизитХранилище .Получить();
ЗначениеВРеквизитФормы("ТвоеДеревоНаФорме", ТвоеДеревоОбъект )
5 Cthulhu
 
21.09.20
15:29
(4): и предварительно добавить в документ реквизит ТвойРеквизитХранилище типа Хранилище?...
6 Eiffil123
 
21.09.20
16:27
лучше сделать табчасть, в ней добавить поля GUID строки и GUID родителя. По этим полям восстанавливать дерево при открытии и сохранять - при записи.
7 asder117
 
21.09.20
21:31
(6) Я же описал что так делал и не восстанавливается
&НаСервере
Процедура ПриЗаписиНаСервере(Отказ, ТекущийОбъект, ПараметрыЗаписи)
    //Вставить содержимое обработчика
   ДерДЗ = РеквизитФормыВЗначение("ДанныеФинБюджета");

    //пер=ДерДЗ.Скопировать();
    //      масив = Новый Массив;
    //      масив.Добавить(пер);
    //      хранилище = Новый ХранилищеЗначения(масив,Новый СжатиеДанных(9));
    //тТаблица = РеквизитФормыВЗначение("Таблица");

ПреобразоватьВТЗРекурсия(ДерДЗ, Объект.ФинБюджет, Новый УникальныйИдентификатор("00000000-0000-0000-0000-000000000000"));
// тДерево.Строки.Очистить();

// ЗначениеВРеквизитФормы(тТаблица, "Таблица");
// ЗначениеВРеквизитФормы(тДерево, "Дерево");

КонецПроцедуры

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    //Вставить содержимое обработчика
    //    ////+++++создадим форму бюджета
Если Параметры.Ключ.Пустая() Тогда
//////Возврат Истина;
//////КонецЕсли;    
////    если хранилище<>Неопределено тогда
////зна = хранилище.Получить();
//////ЭлементыФормы.ТабличноеПоле2.Значение = зна[0];

////иначе
////сообщить("ХранилищеЗначения не заполнено");
////КонецЕсли;
//    
//    //СтрокаБюджета = ДанныеФинБюджета.Строки.Добавить();
    СоздатьДеревоБюжетаНаСервере();
//    ///СтрокаБюджета.СтатьяБюджета = "1 статья"
//    ////
иначе
тДерево = РеквизитФормыВЗначение("ДанныеФинБюджета");
//тТаблица = РеквизитФормыВЗначение("Таблица");

ПреобразоватьВДЗРекурсия(тДерево, Объект.ФинБюджет, Новый УникальныйИдентификатор("00000000-0000-0000-0000-000000000000"));
//Объект.ФинБюджет.Очистить();

//ЗначениеВРеквизитФормы(тТаблица, "Таблица");
ЗначениеВРеквизитФормы(тДерево, "ДанныеФинБюджета");
//    
КонецЕсли;

КонецПроцедуры

&НаСервере
Процедура ПреобразоватьВДЗРекурсия(тДерево, тТаблица, ГУИД)
тПоиск = Новый Структура("Родитель", ГУИД);
тМассив = тТаблица.НайтиСтроки(тПоиск);
Для Каждого тСтр Из тМассив Цикл
нСтр = тДерево.Строки.Добавить();
нСтр.Итого = тСтр.Итого;
нСтр.Январь = тСтр.Январь;
нСтр.Февраль = тСтр.Февраль;
нСтр.Март = тСтр.Март;
нСтр.Апрель = тСтр.Апрель;
нСтр.Май = тСтр.Май;
нСтр.Июнь = тСтр.Июнь;
нСтр.Июль = тСтр.Июль;
нСтр.Август = тСтр.Август;
нСтр.Сентябрь = тСтр.Сентябрь;
нСтр.Октябрь = тСтр.Октябрь;
нСтр.Ноябрь = тСтр.Ноябрь;
нСтр.Декабрь = тСтр.Декабрь;


ПреобразоватьВДЗРекурсия(нСтр, тТаблица, тСтр.ГУИД);
КонецЦикла;
КонецПроцедуры
8 asder117
 
21.09.20
21:32
(5) реквизит объекта или реквизит формы? Спасибо
9 asder117
 
22.09.20
09:27
(4) В обработе приЗаписиНаСервере Хранилище он видит, а вот при создании и при открытии нифига...Реквизит создан как реквизит объекта
10 Fedor-1971
 
22.09.20
09:54
(8) В (4) просто сохранить/восстановить, в отчётах и для целей анализа использовать Хранилище несколько проблематично

По сути вопроса: в документе делаешь ТЧ в удобном для анализа виде с нужными тебе колонками
на форме создаёшь реквизит ТвоёДЗ
  запись в ТЧ:
  
  ТЧдокумента.Очистить();
  ур1 = ТвоёДЗ.ПолучитьЭлементы();
  Для каждого текЭлУр1 из ур1 цикл
     ур2 = текЭлУр1.ПолучитьЭлементы();
     Для каждого текЭлУр2 из ур2 цикл
        сохраняешь данные в ТЧ документа
     КонецЦикла;
  КонеЦикла;
  

  
  Восстановление:

   ТвоёДЗ.Очистить();
   Для каждого текСтрока из ТЧдокумента цикл
      ур1 = ТвоёДЗ.ПолучитьЭлементы();
      элУр1 = ур1.Добавить();
      элур1.Месяц = текСторка.Месяц;

      ур2 = элУр1.ПолучитьЭлементы();
      элУр2 = ур2.Добавить();
      элур2.ХХХХ = текСтрока.ХХХХХ;
   КонецЦикла;


Как-то так, смотри в справке про ДанныеФормыКоллекцияЭлементовДерева или синтаксис помощник + отладчик
11 asder117
 
22.09.20
10:05
(10) Попробую так...
12 Eiffil123
 
22.09.20
10:08
(10) с хранилищем не очень корректно. не работает ссылочная целостность базы
13 polosov
 
22.09.20
10:21
В (6)  самый нормальный вариант.
14 asder117
 
22.09.20
11:03
(13) Я же писал в (7) что пробовал и почему-то не взлетело. Сейчас еще раз пробую сделать...
15 asder117
 
22.09.20
11:40
(13) Главное в табличну чать пишу и я ее при закрытии вижу но когда повторно открываю док тама пусто
16 Fedor-1971
 
22.09.20
13:18
(15) В каком месте записываешь?
17 asder117
 
22.09.20
15:32
(16) Перед записью на сервере
18 Fedor-1971
 
22.09.20
15:57
(17) чисто уточнить данные заносишь в Объект.ТвояТЧ или в ТекущийОбъект.ТвояТЧ?

ПередЗаписьюНаСервере(<Отказ>, <ТекущийОбъект>, <ПараметрыЗаписи>) - таки ТекущийОбъект, то что будет записано в БД
19 asder117
 
22.09.20
16:10
(18) Объект.ТвояТЧ
20 asder117
 
22.09.20
16:10
(18) ну и ТекущийОбъект.ТвояТЧ тоже пробовал..не взлетело
21 Fedor-1971
 
22.09.20
16:41
(20) Обманываешь, ТекущийОбъект - это то, что из формы прошло контроль и преобразовалось из Формы в ДокументОбъект

В модуле объекта в ПередЗаписью проверь, заполнилась ли ТвояТЧ
22 Fedor-1971
 
22.09.20
16:44
21+ т.е. у тебя Объект - это старые данные формы, ТекущийОбъект - уже заполненный данными формы ДокументОбъект

но, в обработчике, ты имеешь доступ одновременно к Реквизитам формы и ДокументОбъект, вот и перелей своё дерево в ТЧ документа
23 asder117
 
22.09.20
20:51
(22) В оконцовке перед записью Объект.ТабЧасть заполненная а вот после закрытия при открытии в процедуре ПриСозданииНаСервере - пустая
24 nicxxx
 
22.09.20
21:58
надеюсь, идея будет понятна
подход, как в (10) тоже имеет право на существование, но имхо, забрать дерево на сервер методом ДанныеФормыВЗначение() а потом вернуть обратно несколько проще.

&НаСервере
Процедура ПередЗаписьюНаСервере(Отказ, ТекущийОбъект, ПараметрыЗаписи)
    ДеревоБДРФорма = ДанныеФормыВЗначение(ДеревоБДР,Тип("ДеревоЗначений"));
    
    _год = Формат(Год(Объект.Дата), "ЧГ=;ЧРГ=;ЧРД=");
    
    ТекущийОбъект.БюджетПоМесяцам.Очистить();
    СохранитьДеревоБДРвТаблицуДокументаРекурсивноСервер(ДеревоБДРФорма.Строки, ТекущийОбъект.БюджетПоМесяцам,  _год);    
КонецПроцедуры


Процедура СохранитьДеревоБДРвТаблицуДокументаРекурсивноСервер(СтрокиДереваФормы, БюджетПоМесяцам_, _год)
    
    Для Каждого Стр Из СтрокиДереваФормы Цикл
        
        Если Стр.ЭтоГруппа Тогда
            СохранитьДеревоБДРвТаблицуДокументаРекурсивноСервер(Стр.Строки, БюджетПоМесяцам_, _год);
        Иначе
            //пропустим строки, в которых Итого - пусто (значит и в других колонках пусто)
            Если Стр.План13 = 0 Тогда
                Продолжить;
            КонецЕсли;

            //цикл по колонкам - месяцам. 13-я колонка (Итого по статье) не нужна, она не хранится, а вычисляется в дереве
            Для сч = 1 по 12 Цикл
                
                Если Стр["План"+сч] = 0 Тогда
                    Продолжить;
                КонецЕсли;    
                
                // план на месяц пишем в первое число месяца
                ДатаДвижения = Дата(_год, Строка(сч), "1");
                
                // новая запись в ТЧ БюджетПоМесяцам
                Запись                 = БюджетПоМесяцам_.Добавить();
                Запись.Период         = ДатаДвижения;
                Запись.Статья         = Стр.СтатьяДР;
                Запись.СуммаПлан     = Стр["План"+сч];
                
            КонецЦикла;
            
        КонецЕсли;    
        
    КонецЦикла;
    
КонецПроцедуры

это было сохранение
теперь то, что надо сделать при открытии

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

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

Процедура ЗаполнитьДеревоБДРРекурсивноСервер(Выборка, СтрокаДереваФормы)
    
    Пока Выборка.Следующий() Цикл
        
        //это чтобы группы не попадали внутрь группировки
        //пример того, что будет без этого условия, показан на
        //общей картинке ОбходЗапросаПоГруппировкамСИерархией
        //зеленым выделены правильные итоги по иерархии
        //синим - итоги по группировкам элементов (там один элемент, но этого для примера достаточно)
        //красным - итоги по группировкам, где в качестве группирующего объекта
        //выступает группа справочника, по которой выше уже были выведены
        //итоги, но по иерархии.
        Если Выборка.ТипЗаписи() = ТипЗаписиЗапроса.ИтогПоГруппировке И Выборка.ЭтоГруппа Тогда
            Продолжить;
        КонецЕсли;
                    
        НовСтр                 = СтрокаДереваФормы.Строки.Добавить();
        НовСтр.СтатьяДР     = Выборка.СтатьяДР;
        
        Для сч = 1 по 13 Цикл
            НовСтр["План"+сч]     = Выборка["План"+сч];
            НовСтр["Факт"+сч]     = Выборка["Факт"+сч];
            НовСтр["Рез"+сч]      = ?(Выборка["План"+сч] = 0, 0, Выборка["Факт"+сч]/Выборка["План"+сч]*100);
        КонецЦикла;
        
        НоваяВыборка = Выборка.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкамСИерархией, "СтатьяДР");
        
        ЗаполнитьДеревоБДРРекурсивноСервер(НоваяВыборка, НовСтр);
            
    КонецЦикла;
        
КонецПроцедуры

Функция ПолучитьТекстЗапроса(Запрос)
    
    ВременнаяТаблицаПлан(Запрос); //если заполняется по документу
    
    ВременнаяТаблицаФакт(Запрос);
    
    ВременнаяТаблицаПланФакт(Запрос);
    
    //использование функции ЕстьNULL - обязательно!
    //если не использовать - в дереве будут поля NULL
    ТекстЗапроса  =
    "ВЫБРАТЬ
    |    СтатьиДоходовРасходов.Ссылка КАК СтатьяДР,
    |    СтатьиДоходовРасходов.ЭтоГруппа,
    |    СУММА(ЕСТЬNULL(ПланФакт.План1, 0)) КАК План1,
    |    СУММА(ЕСТЬNULL(ПланФакт.Факт1, 0)) КАК Факт1,
    |    СУММА(ЕСТЬNULL(ПланФакт.План2, 0)) КАК План2,
    |    СУММА(ЕСТЬNULL(ПланФакт.Факт2, 0)) КАК Факт2,
    |    СУММА(ЕСТЬNULL(ПланФакт.План3, 0)) КАК План3,
    |    СУММА(ЕСТЬNULL(ПланФакт.Факт3, 0)) КАК Факт3,
    |    СУММА(ЕСТЬNULL(ПланФакт.План4, 0)) КАК План4,
    |    СУММА(ЕСТЬNULL(ПланФакт.Факт4, 0)) КАК Факт4,
    |    СУММА(ЕСТЬNULL(ПланФакт.План5, 0)) КАК План5,
    |    СУММА(ЕСТЬNULL(ПланФакт.Факт5, 0)) КАК Факт5,
    |    СУММА(ЕСТЬNULL(ПланФакт.План6, 0)) КАК План6,
    |    СУММА(ЕСТЬNULL(ПланФакт.Факт6, 0)) КАК Факт6,
    |    СУММА(ЕСТЬNULL(ПланФакт.План7, 0)) КАК План7,
    |    СУММА(ЕСТЬNULL(ПланФакт.Факт7, 0)) КАК Факт7,
    |    СУММА(ЕСТЬNULL(ПланФакт.План8, 0)) КАК План8,
    |    СУММА(ЕСТЬNULL(ПланФакт.Факт8, 0)) КАК Факт8,
    |    СУММА(ЕСТЬNULL(ПланФакт.План9, 0)) КАК План9,
    |    СУММА(ЕСТЬNULL(ПланФакт.Факт9, 0)) КАК Факт9,
    |    СУММА(ЕСТЬNULL(ПланФакт.План10, 0)) КАК План10,
    |    СУММА(ЕСТЬNULL(ПланФакт.Факт10, 0)) КАК Факт10,
    |    СУММА(ЕСТЬNULL(ПланФакт.План11, 0)) КАК План11,
    |    СУММА(ЕСТЬNULL(ПланФакт.Факт11, 0)) КАК Факт11,
    |    СУММА(ЕСТЬNULL(ПланФакт.План12, 0)) КАК План12,
    |    СУММА(ЕСТЬNULL(ПланФакт.Факт12, 0)) КАК Факт12,
    |    СУММА(ЕСТЬNULL(ПланФакт.План13, 0)) КАК План13,
    |    СУММА(ЕСТЬNULL(ПланФакт.Факт13, 0)) КАК Факт13
    |ИЗ
    |    Справочник.фдСтатьиДвиженийДенежныхСредств КАК СтатьиДоходовРасходов
    |        ЛЕВОЕ СОЕДИНЕНИЕ ВремТаблПланФакт КАК ПланФакт
    |        ПО (ПланФакт.СтатьяДР = СтатьиДоходовРасходов.Ссылка)
    |
    |СГРУППИРОВАТЬ ПО
    |    СтатьиДоходовРасходов.Ссылка,
    |    СтатьиДоходовРасходов.ЭтоГруппа
    |
    |УПОРЯДОЧИТЬ ПО
    |    СтатьиДоходовРасходов.Код,
    |    СтатьиДоходовРасходов.Наименование
    |ИТОГИ
    |    СУММА(План1),
    |    СУММА(Факт1),
    |    СУММА(План2),
    |    СУММА(Факт2),
    |    СУММА(План3),
    |    СУММА(Факт3),
    |    СУММА(План4),
    |    СУММА(Факт4),
    |    СУММА(План5),
    |    СУММА(Факт5),
    |    СУММА(План6),
    |    СУММА(Факт6),
    |    СУММА(План7),
    |    СУММА(Факт7),
    |    СУММА(План8),
    |    СУММА(Факт8),
    |    СУММА(План9),
    |    СУММА(Факт9),
    |    СУММА(План10),
    |    СУММА(Факт10),
    |    СУММА(План11),
    |    СУММА(Факт11),
    |    СУММА(План12),
    |    СУММА(Факт12),
    |    СУММА(План13),
    |    СУММА(Факт13)
    |ПО
    |    СтатьяДР ИЕРАРХИЯ";    
    
    Возврат ТекстЗапроса;
    
КонецФункции
25 asder117
 
23.09.20
08:40
(24) Спасибо за функционал..попробую накрутить под свою задачу..по ошибкам отпишусь
26 nicxxx
 
23.09.20
12:57
вот здесь может быть: "Стр.ЭтоГруппа"
Процедура СохранитьДеревоБДРвТаблицуДокументаРекурсивноСервер(СтрокиДереваФормы, БюджетПоМесяцам_, _год)
    Для Каждого Стр Из СтрокиДереваФормы Цикл
        Если Стр.ЭтоГруппа Тогда

У меня это колонка в дереве "ЭтоГруппа". Но можно и так:
    Если Стр.СтатьяДР.ЭтоГруппа Тогда

Если оставлять колонку, то надо ее заполнять:

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