Проблема с подсчетом AVG

отредактировано 06:00 Раздел: FastReport 2.xx VCL
Наткнулся на проблему с подсчетом AVG в FR 2.51.
Когда какая нибудь строка в столбце равна null (запрос вернул null),
стандартный [AVG([ADOQV1T2T3."P1"], MasterData1)] ее учитывает.
Т.е. добавляет null и делит на число строк. А хотелось бы этот null совсем игнорировать. Т.е. брать число строк которые не null.
Как я понял единственный выход считать AVG самому, в скрипте.
Поделитесь плииз примерчиком.

Комментарии

  • Andrew_ShAndrew_Sh г.Минск
    отредактировано October 2005
    yarik написал:
    Наткнулся на проблему с подсчетом AVG в FR 2.51.
    Когда какая нибудь строка в столбце равна null (запрос вернул null),
    стандартный [AVG([ADOQV1T2T3."P1"], MasterData1)] ее учитывает.
    Т.е. добавляет null и делит на число строк. А хотелось бы этот null совсем игнорировать. Т.е. брать число строк которые не null.
    Как я понял единственный выход считать AVG самому, в скрипте.
    Поделитесь плииз примерчиком.
    Попробуйте так:
    [SUM([ADOQV1T2T3."P1"], MasterData1) / SUM( IF(FieldIsNull('ADOQV1T2T3."P1"'),0,1), MasterData1 ) ] 
    
  • отредактировано 06:00
    Andrew_Sh написал:
    Andrew_Sh написал:
    Наткнулся на проблему с подсчетом AVG в FR 2.51.
    Когда какая нибудь строка в столбце равна null (запрос вернул null),
    стандартный [AVG([ADOQV1T2T3."P1"], MasterData1)] ее учитывает.
    Т.е. добавляет null и делит на число строк. А хотелось бы этот null совсем игнорировать. Т.е. брать число строк которые не null.
    Как я понял единственный выход считать AVG самому, в скрипте.
    Поделитесь плииз примерчиком.
    Попробуйте так:
    [SUM([ADOQV1T2T3."P1"], MasterData1) / SUM( IF(FieldIsNull('ADOQV1T2T3."P1"'),0,1), MasterData1 ) ] 
    
    Выдает ошибку class EConvertError with message "True is not valid floating point value"
    похоже не может конвертнуть булеву FieldIsNull в 1 или 0 ;)
    IF(FieldIsNull('ADOQV1T2T3."P1"'),0,1)
  • Andrew_ShAndrew_Sh г.Минск
    отредактировано October 2005
    yarik написал:
    yarik написал:
    yarik написал:
    Наткнулся на проблему с подсчетом AVG в FR 2.51.
    Когда какая нибудь строка в столбце равна null (запрос вернул null),
    стандартный [AVG([ADOQV1T2T3."P1"], MasterData1)] ее учитывает.
    Т.е. добавляет null и делит на число строк. А хотелось бы этот null совсем игнорировать. Т.е. брать число строк которые не null.
    Как я понял единственный выход считать AVG самому, в скрипте.
    Поделитесь плииз примерчиком.
    Попробуйте так:
    [SUM([ADOQV1T2T3."P1"], MasterData1) / SUM( IF(FieldIsNull('ADOQV1T2T3."P1"'),0,1), MasterData1 ) ] 
    
    Выдает ошибку class EConvertError with message "True is not valid floating point value"
    похоже не может конвертнуть булеву FieldIsNull в 1 или 0 ;)
    IF(FieldIsNull('ADOQV1T2T3."P1"'),0,1)
    попробуйте IF заключить в квадратные скобки.
    [SUM([ADOQV1T2T3."P1"], MasterData1) / SUM( [IF(FieldIsNull('ADOQV1T2T3."P1"'),0,1)], MasterData1 ) ] 
    

    чтобы проверить, как работает FieldIsNull поместите на MasterData мемку с выражением [IF(FieldIsNull('ADOQV1T2T3."P1"'),0,1)] и посмотрите, что выводит.

    для проверки работы SUM без FieldIsNull, вместо FieldIsNull подставьте true.
  • отредактировано 06:00
    Кинул мемку с [FieldIsNull('ADOQV1T2T3."P1"')]
    работает. в строках где null пишет True
    Когда исправляю на
    [(FieldIsNull('ADOQV1T2T3."P1"'),0,1)] выдает ошибку
  • отредактировано 06:00
    Попробуйте так:
    [IF(INT(FIELDISNULL([Table1."NAME"])), 0, 1)]
  • отредактировано 06:00
    Я вижу тут собрались любители походить по граблям ;) )

    2 yarik:
    Заведи 2 переменных (проинициализируй их нулями в самом начале отчёта)
    Затем в обработчике MasterData.OnBeforePrint Сравнивай с нулом чё тебе надо и плюсуй к переменным сумму и кол-во.
    Ну и в конце отчёта подели одну переменную на другую ...
  • Andrew_ShAndrew_Sh г.Минск
    отредактировано 06:00
    yarik написал:
    Кинул мемку с [FieldIsNull('ADOQV1T2T3."P1"')]
    работает. в строках где null пишет True
    Когда исправляю на
    [(FieldIsNull('ADOQV1T2T3."P1"'),0,1)] выдает ошибку
    я упустил IF

    надо в мемке для проверки написать
    [IF(FieldIsNull('ADOQV1T2T3."P1"'),0,1)]
    
  • Andrew_ShAndrew_Sh г.Минск
    отредактировано 06:00
    написал:
    Попробуйте так:
    [IF(INT(FIELDISNULL([Table1."NAME"])), 0, 1)]
    FIELDISNULL([Table1."NAME"])
    - это абсолютно неправильно. В FIELDISNULL передается ИМЯ ПОЛЯ, а не значение поля

    правильно именно
    FIELDISNULL('Table1."NAME"')
  • отредактировано 06:00
    написал:
    FIELDISNULL([Table1."NAME"])
    - это абсолютно неправильно. В FIELDISNULL передается ИМЯ ПОЛЯ, а не значение поля

    правильно именно
    FIELDISNULL('Table1."NAME"')
    Интересно, но ваш вариант у меня не работает(в отличе от моего ;) ).
    Я составил функцию с помощью "мастера" (т.е. Expression Builder ->Functions... ит.д.)
  • Andrew_ShAndrew_Sh г.Минск
    отредактировано October 2005
    написал:
    написал:
    FIELDISNULL([Table1."NAME"])
    - это абсолютно неправильно. В FIELDISNULL передается ИМЯ ПОЛЯ, а не значение поля

    правильно именно
    FIELDISNULL('Table1."NAME"')
    Интересно, но ваш вариант у меня не работает(в отличе от моего ;) ).
    Я составил функцию с помощью "мастера" (т.е. Expression Builder ->Functions... ит.д.)
    посмотрите описание функции и сделайте поиск по строке FieldIsNull по форумам FastReport.

    и увидите, что говорит сам Автор по этому поводу.
  • отредактировано 06:00
    Ну самому автору я конечтно поверю ;) .
  • отредактировано 06:00
    Действительно глюкануло ;) , что функция работает ;) .
  • Andrew_ShAndrew_Sh г.Минск
    отредактировано October 2005
    yarik написал:
    Наткнулся на проблему с подсчетом AVG в FR 2.51.
    Когда какая нибудь строка в столбце равна null (запрос вернул null),
    стандартный [AVG([ADOQV1T2T3."P1"], MasterData1)] ее учитывает.
    Т.е. добавляет null и делит на число строк. А хотелось бы этот null совсем игнорировать. Т.е. брать число строк которые не null.
    Как я понял единственный выход считать AVG самому, в скрипте.
    Поделитесь плииз примерчиком.
    Вообщем решилась проблема. И никакого скрипта кстати не надо писать.
    Вот выражение для подсчета среднего значения без учета NULL-ов.
    [SUM([ADOQV1T2T3."P1"], MasterData1) / SUM( IF(FieldIsNull('DialogForm.ADOQV1T2T3."P1"')=true,0,1), MasterData1 ) ] 
    

    Объясняю почему не работало раньше.

    FieldIsNull почему-то всегда возвращает TRUE, если задать имя поля с использованием синонима датасета из словаря данных. Т.е. в FieldIsNull надо задавать имя поля ТОЛЬКО в таком виде <span style='font-size:14pt;line-height:100%'>DialogForm.ИМЯ_ДАТАСЕТА."ИМЯ_ПОЛЯ"</span>

    Второй момент. При использовании FiledIsNull в ф-ции IF может возникать ошибка "True is not valid floating point value" или "False is not valid floating point value", если записать выражение в таком виде IF(FieldIsNull('DialogForm.ADOQV1T2T3."P1"'),0,1).
    Удалось победить добавив '=true' после вызова IF, что весьма странно ;) , т.к. FieldIsNull и так возвращает булевское значение.
    Т.е. правильным использованием FieldIsNull() совместно с IF() будет следующее выражение
    IF(FieldIsNull('DialogForm.ADOQV1T2T3."P1"')=true,0,1)
  • отредактировано 06:00
    Вариант
    [SUM([ADOQV1T2T3."P1"], MasterData1) / SUM( IF(FieldIsNull('DialogForm.ADOQV1T2T3."P1"')=true,0,1), MasterData1 ) ]
    заработал!!!
    Всем огромное спасибо за помощь!!!
    2 Andrew_Sh большой Respect!!!
    2 Moderator примерчик можно и в FAQ занести, думаю проблемка распространенная.

Оставить комментарий

Многофункциональный текстовый редактор. Чтобы отредактировать стиль параграфа, нажмите TAB, чтобы перейти к меню абзаца. Там вы можете выбрать стиль. По умолчанию не выбран ни один стиль. Когда вы выберете текст, появится встроенное меню форматирования. Нажмите TAB, чтобы войти в него. Некоторые элементы, такие как многофункциональные вставки ссылок, картинок, индикаторов загрузки и сообщений об ошибок могут быть вставлены в редактор. Вы можете перемещаться по ним, используя стрелки внутри редактора и удалять с помощью клавиш delete или backspace.