Имя: Пароль:
1C
1С v8
v8: Итоги в СписокРегистрСведений
,
0 haggart
 
25.05.12
13:24
Вопрос уже поднимался, что выводить итоги в подвале для Табличного поля, у которого источником данных регистр сведений - невозможно, нужно программно определять итоги и выводить.
Но у меня в регистре сведений около 15 измерений. И если в табличном поле пользователь выбрал 5 отборов из 15, то как можно повторить такое же в запросе? Не перебирать же все отборы и составлять текст запроса... Можно как-то готовый отбор передать в условие запроса?
1 haggart
 
25.05.12
13:35
up
2 kn
 
25.05.12
13:38
посмотри например ПроверитьСтроку
3 kn
 
25.05.12
13:40
можно через построительзапроса
как-то так
Построитель = Новый ПостроительЗапроса;
   Построитель.ИсточникДанных = Новый ОписаниеИсточникаДанных(Номенклатура);
   Для Каждого ЭлементОтбора из ЭлементыФормы.Номенклатура.ОтборСтрок Цикл
     ЗаполнитьЗначенияСвойств(Построитель.Отбор.Добавить(ЭлементОтбора.Имя), ЭлементОтбора);
   КонецЦикла;
   
   ТемрТЗ = Построитель.Результат.Выгрузить();
   ВесОтбора = ТемрТЗ.Итог("ВесНоменклатурыВАналоговойГруппе");
4 haggart
 
25.05.12
13:53
//Сделал так:

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


Но появляется ошибка:

{Справочник.FamilyAgreements.Форма.ФормаЭлемента.Форма(90)}: Ошибка при вызове метода контекста (Добавить)
     ЗаполнитьЗначенияСвойств(Построитель.Отбор.Добавить(ЭлементОтбора.Имя), ЭлементОтбора);
по причине:
Недопустимое значение параметра (параметр номер '1')
5 kn
 
25.05.12
14:06
ДетальныеУсловияПлатежей - какого типа,
а ЭлементыФормы.ДетальныеУсловияПлатежей.ОтборСтрок не получается?
код в (3)рабочий
6 haggart
 
25.05.12
14:07
// вот так не выдает ошибку, но результат пустой... нет строк, хотя должны быть
Построитель = Новый ПостроительЗапроса;
Построитель.ИсточникДанных = Новый ОписаниеИсточникаДанных(РегистрыСведений.ДетальныеУсловияДоговоровСемей.СоздатьНаборЗаписей());
   Для Каждого ЭлементОтбора из ЭлементыФормы.ДетальныеУсловияПлатежей.Значение.Отбор Цикл
ЗаполнитьЗначенияСвойств(Построитель.Отбор.Добавить(ЭлементОтбора.Имя), ЭлементОтбора);
КонецЦикла;
   
ТемрТЗ = Построитель.Результат.Выгрузить();
ИтогFEE = ТемрТЗ.Итог("Fee");
Сообщить("Итог "+ИтогFEE);
7 haggart
 
25.05.12
14:08
(5)
ОтборСтрок - нет такого
Но отбор и в моем случае заполнился нормально...
Интересно, а можно текст запроса посмотреть, который получился у построителя? :)
8 kn
 
25.05.12
14:11
Делай тогда через(1), то есть обойди записи РС или что у тебя в ТЧ и если ПроверитьСтроку вернет истина то суммируй

Для Каждого Стр Из Номенклатура Цикл
Если ЭлементыФормы.Номенклатура.ПроверитьСтроку(Стр) Тогда
 //тут суммировать нужные ресурсы
КонецЕсли
КонецЦикла
9 kn
 
25.05.12
14:12
(7)да можно Построитель.Текст
,наверно тут Построитель.ИсточникДанных = Новый ОписаниеИсточникаДанных(РегистрыСведений.ДетальныеУсловияДоговоровСемей.СоздатьНаборЗаписей()) - не то что надо
10 haggart
 
25.05.12
14:19
текст построителя пустой.

к строкам ДетальныеУсловияДоговоровСемей обратиться не могу, нет строк....
11 kn
 
25.05.12
14:21
ДетальныеУсловияДоговоровСемей какого типа?
12 haggart
 
25.05.12
14:23
(11)
Табличное поле на форме ДетальныеУсловияПлатежей, тип значения РегистрСведенийСписок.ДетальныеУсловияДоговоровСемей
13 Живой Ископаемый
 
25.05.12
14:24
погоди секунду
14 Fragster
 
гуру
25.05.12
14:24
сначала надо ВидОтбора заполнить, иначе ВСписке не заработает
15 Живой Ископаемый
 
25.05.12
14:28
В (4) все правильно, но будет работать только в том случае если все используемые отборы только на равенство:


Процедура РегистрСведенийСписокПриПолученииДанных(Элемент, ОформленияСтрок)
   //что касается отборов. Нас интересует - используется ли хотя бы один
   //и есть ли среди используемых хотя бы один на неравенство - если есть, тогда нельзя юзать кэш, потому что метод
   //Скопировать() отбирает из ТЗ только строки по равенству на значения в структуре.
   //Поэтому, в таком случае нужно будет получать на лету - через построитель
   ХотьОдинОтборИспользуется = ложь;
   ВсеОтборыТолькоНаРавенство = истина;
   Для Каждого ЭлементОтбора Из Элемент.Значение.Отбор Цикл
       Если (ЭлементОтбора.ВидСравнения <> ВидСравнения.Равно) И (ЭлементОтбора.Использование) Тогда
           ВсеОтборыТолькоНаРавенство = ложь;
       КонецЕсли;
       Если ЭлементОтбора.Использование Тогда
           ХотьОдинОтборИспользуется = истина;
       КонецЕсли;
   КонецЦикла;



   //Все отборы только на равенство, либо не используются вовсе - тогда итоги получаем из кэша
   Если ПоказыватьИтогВПодвале И ЗначениеЗаполнено(тзКэш) И ВсеОтборыТолькоНаРавенство Тогда
       Если ЗначениеЗаполнено(Элемент.Значение.Отбор.Действует.Значение) И Элемент.Значение.Отбор.Действует.Использование Тогда
           отборКэша.Вставить("Действует", Элемент.Значение.Отбор.Действует.Значение);
       Иначе
           отборКэша.Удалить("Действует");
       КонецЕсли;        
       //Если ЗначениеЗаполнено(Элемент.Значение.Отбор.ДокументРасчетов.Значение) И Элемент.Значение.Отбор.ДокументРасчетов.Использование
       //    И Элемент.Значение.Отбор.ДокументРасчетов.ВидСравнения = ВидСравнения.Равно  Тогда
       //    отборКэша.Вставить("ДокументРасчетов", Элемент.Значение.Отбор.ДокументРасчетов.Значение);
       //Иначе
       //    отборКэша.Удалить("ДокументРасчетов");
       //КонецЕсли;
       Если ЗначениеЗаполнено(Элемент.Значение.Отбор.Договор.Значение) И Элемент.Значение.Отбор.Договор.Использование
           И Элемент.Значение.Отбор.Договор.ВидСравнения = ВидСравнения.Равно Тогда
           отборКэша = Новый Структура();
           отборКэша.Вставить("Договор", Элемент.Значение.Отбор.Договор.Значение);
       Иначе
           отборКэша.Удалить("Договор");
       КонецЕсли;
       Если ЗначениеЗаполнено(Элемент.Значение.Отбор.Контрагент.Значение) И Элемент.Значение.Отбор.Контрагент.Использование
           И Элемент.Значение.Отбор.Контрагент.ВидСравнения = ВидСравнения.Равно Тогда
           отборКэша.Вставить("Контрагент", Элемент.Значение.Отбор.Контрагент.Значение);
       Иначе
           отборКэша.Удалить("Контрагент");
       КонецЕсли;
       Если ЗначениеЗаполнено(Элемент.Значение.Отбор.ДатаПлатежа.Значение) И Элемент.Значение.Отбор.ДатаПлатежа.Использование
           И Элемент.Значение.Отбор.ДатаПлатежа.ВидСравнения = ВидСравнения.Равно Тогда
           отборКэша.Вставить("ДатаПлатежа", Элемент.Значение.Отбор.ДатаПлатежа.Значение);
       Иначе
           отборКэша.Удалить("ДатаПлатежа");
       КонецЕсли;
       Если ЗначениеЗаполнено(ОтборКэша) Тогда
           тзБуф = тзКэш.Скопировать(отборКэша);
       Иначе
           тзБуф = тзКэш.Скопировать();
       КонецЕсли;
   КонецЕсли;

//Есть хоть один отбор не на равенство, а что-то другое - больше-меньше, в иерахии, в группе, и т.п.
   //приходится юзать построитель
   Если НЕ (ВсеОтборыТолькоНаРавенство )
       и ПоказыватьИтогВПодвале Тогда
       Построитель = Новый ПостроительЗапроса;
       Построитель.ИсточникДанных = Новый
       ОписаниеИсточникаДанных(РегистрСведенийСписок);
       Результат = Построитель.Результат; //отобранные строки типа РезультатЗапроса
       тзБуф = Результат.Выгрузить();
   КонецЕсли;
   //Теперь, какой объект использую в каком случае для подсчета итогов
   //и вывода их в подвале
   //Если ВсеОтборыТолькоНаРавенство, значит у нас  
   Если ПоказыватьИтогВПодвале  Тогда
       Элемент.Колонки.ЗаОборудование.ТекстПодвала =
       Формат(тзБуф.Итог("ЗаОборудование"),"ЧДЦ=2");
       Элемент.Колонки.Процент.ТекстПодвала =
       Формат(тзБуф.Итог("Процент"),"ЧДЦ=2");
       Элемент.Колонки.Платеж.ТекстПодвала =
       Формат(тзБуф.Итог("Платеж"),"ЧДЦ=2");
       Элемент.Колонки.Картинка.ТекстПодвала =
       тзБуф.Количество();
   Иначе
       Элемент.Колонки.ЗаОборудование.ТекстПодвала = "";
       Элемент.Колонки.Процент.ТекстПодвала = "";
       Элемент.Колонки.Платеж.ТекстПодвала = "";
       Элемент.Колонки.Картинка.ТекстПодвала = "";
   КонецЕсли;
   
   //Далее выведу в подвале измерений значения отборов по ним - для красоты,
   //буду их выводить в независмости от значения галки  ПоказыватьИтогВПодвале
   //Если ЗначениеЗаполнено(Элемент.Значение.Отбор.ДокументРасчетов.Значение) И Элемент.Значение.Отбор.ДокументРасчетов.Использование  Тогда
   //    Элемент.Колонки.ДокументРасчетов.ТекстПодвала = Элемент.Значение.Отбор.ДокументРасчетов.Значение;
   //Иначе
   //    Элемент.Колонки.ДокументРасчетов.ТекстПодвала = "";
   //КонецЕсли;
   Если ЗначениеЗаполнено(Элемент.Значение.Отбор.Договор.Значение) И Элемент.Значение.Отбор.Договор.Использование  Тогда
       Элемент.Колонки.Договор.ТекстПодвала = Элемент.Значение.Отбор.Договор.Значение;
   Иначе
       Элемент.Колонки.Договор.ТекстПодвала = "";
   КонецЕсли;
   Если ЗначениеЗаполнено(Элемент.Значение.Отбор.Контрагент.Значение) И Элемент.Значение.Отбор.Контрагент.Использование  Тогда
       Элемент.Колонки.Контрагент.ТекстПодвала = Элемент.Значение.Отбор.Контрагент.Значение;
   Иначе
       Элемент.Колонки.Контрагент.ТекстПодвала = "";
   КонецЕсли;
   Если ЗначениеЗаполнено(Элемент.Значение.Отбор.ДатаПлатежа.Значение) И Элемент.Значение.Отбор.ДатаПлатежа.Использование  Тогда
       Элемент.Колонки.ДатаПлатежа.ТекстПодвала = Формат(Элемент.Значение.Отбор.ДатаПлатежа.Значение,"ДФ=MMMM.yyyy");
       ЭлементыФормы.ОсновныеДействияФормы.Доступность = истина;
   Иначе
       Элемент.Колонки.ДатаПлатежа.ТекстПодвала = "";
       ЭлементыФормы.ОсновныеДействияФормы.Доступность = ложь;
   КонецЕсли;
   //Если ни один отбор не используется - то и значения фильтров в подвале измерений не вывожу
   Если Элемент.Значение.Отбор.ДокументРасчетов.Использование ИЛИ Элемент.Значение.Отбор.ДатаПлатежа.Использование
       ИЛИ Элемент.Значение.Отбор.Контрагент.Использование ИЛИ Элемент.Значение.Отбор.Договор.Использование Тогда
   Иначе
       Элемент.Колонки.ЗаОборудование.ТекстПодвала = "";
       Элемент.Колонки.Процент.ТекстПодвала = "";
       Элемент.Колонки.Платеж.ТекстПодвала = "";
   КонецЕсли;

КонецПроцедуры
16 Живой Ископаемый
 
25.05.12
14:30
Если хоть один отбор не на равенство, то нужно будет:


   //Есть хоть один отбор не на равенство, а что-то другое - больше-меньше, в иерахии, в группе, и т.п.
   //приходится юзать построитель
   Если НЕ (ВсеОтборыТолькоНаРавенство )
       и ПоказыватьИтогВПодвале Тогда
       Построитель = Новый ПостроительЗапроса;
       Построитель.ИсточникДанных = Новый
       ОписаниеИсточникаДанных(РегистрСведенийСписок);
       Результат = Построитель.Результат; //отобранные строки типа РезультатЗапроса
       тзБуф = Результат.Выгрузить();
   КонецЕсли;



то есть построителю скармливаешь весь РегистрСведенийСписок, а это может быть долго
17 haggart
 
25.05.12
14:31
(15) Так вот я и не хотел вручную для 15ти измерений приписывать условия для запроса....
18 Живой Ископаемый
 
25.05.12
14:32
тогда 16, но если записей более 10 тысяч, то пользователи почувсвтуют неиллюзороно
19 haggart
 
25.05.12
14:38
(18) тогда как в (16) передать отбор?
20 Живой Ископаемый
 
25.05.12
14:38
м... он там уже будет
21 Живой Ископаемый
 
25.05.12
14:39
наверное...
22 kn
 
25.05.12
14:40
а вот это как

ОписаниеИсточникаДанных (DataSourceDescription)
ИсточникДанных (DataSource)
Использование:

Чтение и запись.
Описание:

Тип: ТаблицаЗначений; РезультатЗапроса; ОбластьЯчеекТабличногоДокумента; Табличная часть; РегистрНакопленияНаборЗаписей.<Имя регистра накопления>; РегистрСведенийНаборЗаписей.<Имя регистра сведений>; РегистрБухгалтерииНаборЗаписей.<Имя регистра бухгалтерии>; РегистрРасчетаНаборЗаписей.<Имя регистра расчета>.
Содержит описываемый источник данных.

Доступность:

Сервер, толстый клиент, внешнее соединение.

стыкуется с ОписаниеИсточникаДанных(РегистрСведенийСписок);
23 haggart
 
25.05.12
14:43
(22)


Построитель = Новый ПостроительЗапроса;
Построитель.ИсточникДанных = Новый ОписаниеИсточникаДанных(ДетальныеУсловияПлатежей);
ТемрТЗ = Построитель.Результат.Выгрузить();
ИтогFEE = ТемрТЗ.Итог("Fee");
Сообщить("Итог "+ИтогFEE);


Все работает! Но как только я стараюсь добавить отбор, ошибка...

Построитель = Новый ПостроительЗапроса;
   Построитель.ИсточникДанных = Новый ОписаниеИсточникаДанных(ДетальныеУсловияПлатежей);
   Для Каждого ЭлементОтбора из ЭлементыФормы.ДетальныеУсловияПлатежей.Значение.Отбор Цикл
       ЗаполнитьЗначенияСвойств(Построитель.Отбор.Добавить(ЭлементОтбора.Имя), ЭлементОтбора);
   КонецЦикла;
   //
   ТемрТЗ = Построитель.Результат.Выгрузить();
   ИтогFEE = ТемрТЗ.Итог("Fee");
   Сообщить("Итог "+ИтогFEE);






{Справочник.FamilyAgreements.Форма.ФормаЭлемента.Форма(92)}: Ошибка при вызове метода контекста (Добавить)
     ЗаполнитьЗначенияСвойств(Построитель.Отбор.Добавить(ЭлементОтбора.Имя), ЭлементОтбора);
по причине:
Недопустимое значение параметра (параметр номер '1')
24 kn
 
25.05.12
14:43
можно просто самому написать текст запроса для построителя с где {}указав в них всевозможные поля отбора, потом устанавливать отборы для построителя согдасно отборам на форме
25 haggart
 
25.05.12
14:44
(24) так я как раз и не хотел руками писать все возможные поля отбора... но видимо придется
26 kn
 
25.05.12
14:46
так там просто на вкладке Построитель перенести нужные поля в условии
27 Живой Ископаемый
 
25.05.12
14:47
не, ну здрасьте:
Построитель.Отбор.Добавить(ЭлементОтбора.Имя)
в отборы добавляешь строку?
28 hhhh
 
25.05.12
14:53
(25) да, и это будет в 5 раз быстрее, чем ЗаполнитьЗначенияСвойств().
29 Живой Ископаемый
 
25.05.12
15:03
2(24,28) можете пример кинуть?
30 haggart
 
25.05.12
15:05
Короче, сделал так:

Запрос = Новый Запрос;
   Запрос.Текст="ВЫБРАТЬ
                |    ДетальныеУсловияДоговоровСемей.FeeUAH,
                |    ДетальныеУсловияДоговоровСемей.Fee
                |ИЗ
                |    РегистрСведений.ДетальныеУсловияДоговоровСемей КАК ДетальныеУсловияДоговоровСемей";
   
                   
   УслГде =0;
   Для Каждого ЭлементОтбора из ЭлементыФормы.ДетальныеУсловияПлатежей.Значение.Отбор Цикл
       //ЭлементОтбора.Имя ЭлементОтбора
       Если ЭлементОтбора.Использование=Истина Тогда
           Если УслГде=0 Тогда
               УслГде=1;
               Запрос.Текст=Запрос.Текст+" Где ДетальныеУсловияДоговоровСемей."+ЭлементОтбора.Имя +" = &Значение"+ЭлементОтбора.Имя;
               Запрос.Параметры.Вставить("Значение"+ЭлементОтбора.Имя,ЭлементОтбора.Значение);
           ИНаче
               Запрос.Текст=Запрос.Текст+    " И ДетальныеУсловияДоговоровСемей."+ЭлементОтбора.Имя +" = &Значение"+ЭлементОтбора.Имя;
               Запрос.Параметры.Вставить("Значение"+ЭлементОтбора.Имя,ЭлементОтбора.Значение);
           КонецЕсли;    
       КонецЕсли;
   КонецЦикла;
   Табл=Запрос.Выполнить().Выгрузить();
   
   ИтогFEE = Табл.Итог("Fee");
   Сообщить("Итог "+ИтогFEE);
31 Живой Ископаемый
 
25.05.12
15:07
2(30) Ну а если пользователь скажет "В Иерархии" и выберет группу?
32 haggart
 
25.05.12
15:18
(31) тогда будет ошибка ...

но вопрос в другом, на какое событие привязать этот расчет?
33 Живой Ископаемый
 
25.05.12
15:25
при получении данных
34 haggart
 
25.05.12
15:26
ПриПолученииДанных не отрабатывает, когда добавляется отбор, которым убираются все данные.
35 haggart
 
25.05.12
15:27
как отловить событие наложения отбора, которым не соответствует ни одна строка данных (регистра сведений)?
36 Живой Ископаемый
 
25.05.12
15:29
хм..
37 haggart
 
25.05.12
15:57
Реально только на обновлениеОтображения формы.
Бред конечно, но по-другому никак....
38 kn
 
25.05.12
16:08
39 kn
 
25.05.12
16:20
а насчет (23) и ошибки там наверно из-за того что этих полей, которые пытаешься добавить в отбор нет среди Доступных полей Построителя, может нужно сначала добавить в Доступные поля и как вариант использовать Построитель.Текст - Текстзапроса с {},тогда там автоматом будут доступные поля
2 + 2 = 3.9999999999999999999999999999999...