Группировка (FR 3.21)

отредактировано 18:53 Раздел: FastReport 3.0
В отчете есть GroupHeader и MasterData, они из одного DataSet'а, заданного запросом в frxADOQuery.
Поле, по которому происходит группировка (назовем его SomeField), не отсортированно.

В итоге получается странная группировка.
Каждый раз, когда меняется значение группировочного поля SomeField, создается новая группа, и, соответственно, встречаются одинаковые группы.


Как правильно задать группировку по неотсортированному полю?
«1

Комментарии

  • LexLex
    отредактировано 18:53
    Никак, нужна отсортировать запрос по этому полю
  • отредактировано 18:53
    Неужели нет механизма?

    А если идет грпппировка в группировке?
    Или еще какое-нибудь сложное условие?
  • LexLex
    отредактировано May 2006
    написал:
    А если идет грпппировка в группировке?
    В запросе Order By Field1, Field2
    написал:
    Или еще какое-нибудь сложное условие?
    Что ты понимаешь под сложным условием?
    Если сложный фильтр то не вижу как он может повлиять на группировку.
    написал:
    Неужели нет механизма?

    Чисто теоретически можно попробовать через UserDataSet но скорость будет оставлять желать лучшего.
  • отредактировано 18:53
    Допустим, что не могу я корректировать запросы (жесткие ограничения на серваке). Можно лишь вызывать процедуры, которые дают неотсортированные данные.
    Что тогда?
    FR не подходит для данного вида отчетов?
  • LexLex
    отредактировано May 2006
    написал:
    Допустим, что не могу я корректировать запросы
    а какже
    написал:
    заданного запросом в frxADOQuery
  • отредактировано 18:53
    Спосибо, получилось упорядочить данные следущим образом:

    select * from (Owner.SomeProcedure (@Parameter = :Parameter)) order by SomeField

    Но все же это не удобно. Полагаю, это недоработка FastReport'а.
    Если группировка идет по полю, то она должна идти независимо от данных!
    Я считаю, такая возможность должна быть.
  • LexLex
    отредактировано 18:53
    Дело в том что FR пользуеться для навигации только следующими методами DataSet-а: First, Next и Prior(на счет этого не уверен).
    Представляешь сколько телодвижений надо будет сделать чтобы сделать группировку по неотсортированному НД.

    ИМХО Сортиковку набора данных должен делать сервер (работа у него такая ;) )
  • отредактировано 18:53
    Согласен.
    Придется уговаривать админа на внесение доп. функциональности в БД. ;)
  • отредактировано 18:53
    Есть еще вопрос по группировке.

    Набор данных надо разбить на 2 заголовка со вложенностью + на третьем уровне сами данные.

    ГРуппирую их GroupHeder'ом,
    GroupHeader1 (по полю 1)
    ---GroupHeader2 (по полю 2)
    MasterData
    получается в итоге, что заголовок первого уровня повторяется при смене заголовка второго уровня.
    А надо слудущую структуру:
    Заголовок 1.1
    ---Заголовок 2.1.1
    Данные
    ---Заголовок 2.1.2
    Данные
    ---Заголовок 2.1.3
    Данные
    Заголовок 1.2
    ---Заголокок 2.2.1
    Данные
    ---Заголокок 2.2.2
    Данные
    ...

    Как это можно сделать?
  • LexLex
    отредактировано May 2006
    Если все правильно зделать то так и получается(по крайне мере у меня).
    А какое условие ты ставишь для группировки в первом и втором заголовках группы?
    И что ты выводишь на самих заголовках группы?
  • отредактировано 18:53
    У меня получается так

    Заголовок 1.1
    ---Заголовок 2.1.1
    Данные
    Заголовок 1.1 //не особо нужно
    ---Заголовок 2.1.2
    Данные
    Заголовок 1.1 //не особо нужно
    ---Заголовок 2.1.3
    Данные
    Заголовок 1.2
    ---Заголокок 2.2.1
    Данные
    Заголовок 1.2 //не особо нужно
    ---Заголокок 2.2.2
    Данные
    ...
  • LexLex
    отредактировано 18:53
    написал:
    А какое условие ты ставишь для группировки в первом и втором заголовках группы?
    И что ты выводишь на самих заголовках группы?

  • отредактировано 18:53
    Услоия - поля НД.
    В заголовке 1 ур. поле1, 2 ур - поле 2.
    Данные - остальные данные НД.

    Сейчас забил отчет с нуля и все отработало как надо. ;) ))
    Спосибо за советы!
  • отредактировано 18:53
    Всплывает еще один вопрос по ргуппировкам:

    Есть один набор данных.
    Нужна следущая структура отчета:
    <span style='font-family:Courier'>________________________________________________________________________________________________________
    |Группировка 1 ур. (2 поля из НД) | Группировка 2 ур. (еще одно поле) | MasterData (остальные поля НД) |
    |******************************** | ********************************* | ****************************** |</span>

    В общих словах, как сделать горизонтальную группировку?
  • gpigpi
    отредактировано 18:53
    Попробуйте в мемо скрывать повторяющиеся значения
  • отредактировано 18:53
    Каким образом это можно сделать для группировок 2-ух уровней вложенности?
  • LexLex
    отредактировано 18:53
    попробуй так:
    var
      SaveField1,
      SaveField2: String;
    
    procedure MasterData1OnBeforePrint(Sender: TfrxComponent);
    begin
      Memo1.Visible := (<ADOQuery1."a"> <> SaveField1);
      SaveField1 := <ADOQuery1."a">;
      if Memo1.Visible then
        SaveField2 := '';
      Memo2.Visible := (<ADOQuery1."b"> <> SaveField2);
      SaveField2 := <ADOQuery1."b">;
    end;
    
    begin
      SaveField1 := '';
      SaveField2 := '';
    end.
    


    <ADOQuery1."a"> - поле первой группировки
    <ADOQuery1."b"> - поле второй группировки
  • отредактировано 18:53
    В общем, решение подходящее, но есть один нюанс ;)
    Группировку со скрытыми данными практически невозможно по-человечески выделить в рамку, чтобы в итоге выглядело следущим образом:
    <span style='font-family:Courier'>
    ---------------------------------------------------------------------------------
    | Поле 1.1 | Поле 1.2 | Поле 2.1 | Данные 1 | Данные 2 | *********** | Данные n |
    |          |          |          | Данные 1 | Данные 2 | *********** | Данные n |
    |          |          |          | Данные 1 | Данные 2 | *********** | Данные n |
    |          |          |          | Данные 1 | Данные 2 | *********** | Данные n |
    |          |          |          | Данные 1 | Данные 2 | *********** | Данные n |
    |          |          |----------------------------------------------------------
    |          |          | Поле 2.2 | Данные 1 | Данные 2 | *********** | Данные n |
    |          |          | Поле 2.2 | Данные 1 | Данные 2 | *********** | Данные n |
    |          |          | Поле 2.2 | Данные 1 | Данные 2 | *********** | Данные n |
    ---------------------------------------------------------------------------------
    | Поле 1.3 | Поле 1.4 | Поле 2.5 | Данные 1 | Данные 2 | *********** | Данные n |
    |          |          |          | Данные 1 | Данные 2 | *********** | Данные n |
    |          |          |          | Данные 1 | Данные 2 | *********** | Данные n |
    |          |          |----------------------------------------------------------
    |          |          | Поле 2.4 | Данные 1 | Данные 2 | *********** | Данные n |
    ---------------------------------------------------------------------------------
    | Поле 1.3 | Поле 1.4 | Поле 2.3 | Данные 1 | Данные 2 | *********** | Данные n |
    ---------------------------------------------------------------------------------
    
    </span>

    Где Поле 1.* - два первых группировочных поля, Поле 2.* - второй уровень группировки, Данные * - MasterData
  • отредактировано 18:53
    Самое удачное, что удалось смастерить после некоторых мучений:
    --------------------------------------------------------------------------------
      Поле 1.1   Поле 1.2   Поле 2.1   Данные 1   Данные 2   ***********   Данные n  
                                       Данные 1   Данные 2   ***********   Данные n  
                                       Данные 1   Данные 2   ***********   Данные n  
                                       Данные 1   Данные 2   ***********   Данные n  
                                       Данные 1   Данные 2   ***********   Данные n  
                           ----------------------------------------------------------
                            Поле 2.2   Данные 1   Данные 2   ***********   Данные n  
                            Поле 2.2   Данные 1   Данные 2   ***********   Данные n  
                            Поле 2.2   Данные 1   Данные 2   ***********   Данные n  
    --------------------------------------------------------------------------------
      Поле 1.3   Поле 1.4   Поле 2.5   Данные 1   Данные 2   ***********   Данные n  
                                       Данные 1   Данные 2   ***********   Данные n  
                                       Данные 1   Данные 2   ***********   Данные n  
                           ----------------------------------------------------------
                            Поле 2.4   Данные 1   Данные 2   ***********   Данные n  
    --------------------------------------------------------------------------------
      Поле 1.3   Поле 1.4   Поле 2.3   Данные 1   Данные 2   ***********   Данные n  
    
    

    Когда почти вся рамка была готова, как она и задумывалясь, осталась одна проблема - рамка внизу страницы .

    Может кто знает, как просчитать смену сраницы и, при этом, нарисовать (отобразить) линию, закрывающую таблицу в MasterData на текущей странице???
  • отредактировано 18:53
    У себя я вышел из положения так - сделал отчет двухпроходным.
    На первом проходе для каждой строки заполняю StringList с признаком смены оформления ячейки (сравниваю текущее значение поля и предыдущее). На втором проходе для каждой ячейки выставляю ее оформление.
    Аналогично в UserManual сделана печать итогов в заголовке группы
  • отредактировано 18:53
    Что значит двухпроходный отчет и как это сделать?
    Каким образом определить, что ячейка является последней на данной странице (у нее же свои настнойки границ, независимо от остальных...)?
  • отредактировано 18:53
    Есть необходимость сгруппировать разные НД по одинаковому полю. Как это сделать?

    Поле в разных НД называется одинаково.
  • gpigpi
    отредактировано 18:53
    Объедините все НД в один НД, отсортируйте данные по требуемому полю
  • отредактировано 18:53
    На данный момент у меня 3 различных НД, у которых совпадают 2 первых поля. Каким образом я смогу их объединить?
  • gpigpi
    отредактировано 18:53
    Первый вариант - использовать UNION в SQL-запросе
    Второй вариант - создать таблицу, в которой есть поля из всех наборов данных, залить в неё данные и далее обрабатывать в запросе
    Третий вариант - использовать TfrxUserDataset, подсовывая ему требуемые данные, которые получены в результате обработки программой данных из трёх НД
  • отредактировано 18:53
    aseroff написал:
    Что значит двухпроходный отчет и как это сделать?
    Каким образом определить, что ячейка является последней на данной странице
    Двухпроходным отчет делается установкой Engine.doublePass=True;
    а последняя ячейка определяется по оставшемуся свободному месту на странице, в onAfterCalcHeight определяю если Engine.freespace<Memo.heght
    значит строка на эту страницу не влезет и будет перенесена на следующую
  • отредактировано 18:53
    написал:
    а последняя ячейка определяется по оставшемуся свободному месту на странице, в onAfterCalcHeight определяю если Engine.freespace<Memo.heght
    значит строка на эту страницу не влезет и будет перенесена на следующую
    У какого элемента это событие (onAfterCalcHeight)?
  • отредактировано 18:53
    С
    написал:
    Engine.freespace<Memo.heght
    разобрался.
    Но как теперь вернуться на строчку назад, чтобы поcтавить
    Memo.Frame.Typ += ftBottom;
    
    ??
  • отредактировано 18:53
    При условии, что строки одинаковой высоты подходит вариант
     if ((Engine.freespace < 2*Memo.Height) && (Engine.freespace > Memo.Height))
        Memo.Frame.Typ += ftBottom;
    
  • отредактировано 18:53
    aseroff написал: »
    При условии, что строки одинаковой высоты подходит вариант
     if ((Engine.freespace < 2*Memo.Height) && (Engine.freespace > Memo.Height))
        Memo.Frame.Typ += ftBottom;
    
    Подскажите, как быть в случаи переменной высоты строк (как их спрогнозировать и рассчитать)?

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

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