3 frxMasterData на одной странице.

отредактировано 21:04 Раздел: FastReport 3.0
Сразу к делу.
есть таблица. в ней 3 поля : id, Name, Desc
есть отчет, в котором одна страничка и 3 frxMasterData. На каждом мастердате по одной мемке. каждая мемка настроена на поле в таблице. Получается примерно вот такая картинка.
table.jpg
Записей в таблице 100.... то есть каждый frxMasterData растянется на 3 странички.
Теперь вопрос....
как мне можно вывести эти 3 frxMasterData таким образом, чтобы сохранился порядок. То есть: первая страница - frxMasterData1, вторая - frxMasterData2, третья - frxMasterData3, четвертая frxMasterData1, пятая - frxMasterData2 и так далее....?
никто не сталкивался с таким?

Комментарии

  • gpigpi
    отредактировано 21:04
    Может быть, лучше добавить один MasterData1, к нему сделать дочерним Child1, к Child1 дочерним сделать Child2. У всех трёх бэндов установить StartNewPage=True
  • отредактировано 21:04
    В таком варианте, каждая запись выводиться на новой странице....
    а необходимо, чтобы выводился набор записей помещающихся на странице из каждого бенда
  • gpigpi
    отредактировано 21:04
    Вот совет применительно к двум MasterData, при необходимости можно расширить и на три:
    1. В проекте создаются дубликаты датасета, который нужно выводить, и frxDBDataSet, к которому подключается MasterData.
    2. В отчёте создаётся MasterData2, к которому подключается frxDBDataSet2.
    3. Для страницы, на которой расположены MasterData в скрипте создаём
    var i:integer;
    procedure Page1OnManualBuild(Sender: TfrxComponent);
    begin
        i:=1;
        MasterData1.DataSet.First;
        MasterData2.DataSet.First;
        repeat
          case i of
            1: begin
                 if not MasterData1.DataSet.Eof then
                   begin
                     if Engine.FreeSpace>=MasterData1.Height then
                       begin
                         Engine.ShowBand(MasterData1);
                         MasterData1.DataSet.Next;
                       end
                     else
                       begin
                         i:=2;
                         if not MasterData2.DataSet.Eof then
                           begin
                             Engine.ShowBand(MasterData2);
                             MasterData2.DataSet.Next;
                           end;
                       end;
                   end
                 else
                   begin
                     i:=2;
                     Engine.NewPage;
                   end;
               end;
            2: begin
                 if not MasterData2.DataSet.Eof then
                   begin
                     if Engine.FreeSpace>=MasterData2.Height then
                       begin
                         Engine.ShowBand(MasterData2);
                         MasterData2.DataSet.Next;
                       end
                     else
                       begin
                         i:=1;
                         if not MasterData1.DataSet.Eof then
                           begin
                             Engine.ShowBand(MasterData1);
                             MasterData1.DataSet.Next;
                           end;
                       end;
                   end
                 else
                   begin
                     i:=1;
                     Engine.NewPage;
                   end;
               end;
          end;
        until MasterData2.DataSet.Eof and MasterData1.DataSet.Eof;
    end;
    
  • отредактировано 21:04
    gpi, спасибо за совет!!!
    Попробовал... работает как надо. Но.... клонировать БД - себя не уважать..... работаю с объемами в десятки миллионов записей. Сам понимаешь, что это не есть гуд.
    Немного посидев за фастскриптом нашел все-таки способ.
    Вот код, мож пригодится кому нить:
    function Ceil(const X: extended): integer;
    begin
      Result := (Trunc(X));
      if Frac(X) > 0 then
        Inc(Result);
    end;
    
    procedure DrowBand(MasterData: TfrxMasterData; CountDisplay: integer; FirstRec: integer);
    var
      i: integer;
    begin
      SetRecNo(FirstRec);
      for i := 0 to CountDisplay - 1 do
      begin
        if not MasterData1.DataSet.EOF then
          Engine.ShowBand(MasterData)
        else
          break;
        MasterData1.DataSet.Next;
      end;
    end;
    
    procedure SetRecNo(RecNo: integer);
    var
      i: integer;
    begin
      if MasterData1.DataSet.RecNo > RecNo then
        for i := 1 to (MasterData1.DataSet.RecNo - RecNo) do
          MasterData1.DataSet.Prior;
      if MasterData1.DataSet.RecNo < RecNo then
        for i := 1 to (RecNo - MasterData1.DataSet.RecNo) do
          MasterData1.DataSet.Next;
    end;
    
    procedure Page1OnManualBuild(Sender: TfrxComponent);
    var
      RecPerPage, RecFirst, Blocks, i: integer;
    begin
      MasterData1.DataSet.First;
      RecFirst := MasterData1.DataSet.RecNo;
      while not MasterData1.DataSet.EOF do
      begin
        if Engine.FreeSpace >= MasterData1.Height then
          engine.showband(MasterData1)
        else
          break;
        MasterData1.DataSet.Next;
      end;
      RecPerPage := MasterData1.DataSet.RecNo;
      Blocks := ceil((MasterData1.DataSet.RecordCount) / MasterData1.DataSet.RecNo);
      for i := 1 to Blocks - 1 do
      begin
        if i > 1 then
        begin
          DrowBand(MasterData1, RecPerPage, RecFirst);
          Engine.Newpage;
        end;
        DrowBand(MasterData2, RecPerPage, RecFirst);
        Engine.Newpage;
    // Здесь генерируется нужное количество строк для количества мастердат
    //    DrowBand(MasterData[b]N[/b], RecPerPage, RecFirst);
    //    Engine.Newpage;
    //
        RecFirst := RecFirst + RecPerPage;
        SetRecNo(RecFirst);
      end;
      DrowBand(MasterData1, RecPerPage, RecFirst);
      Engine.Newpage;
      DrowBand(MasterData2, RecPerPage, RecFirst + 1);
    //  Здесь тоже генерируется нужное количество блоков вида:
    //Engine.Newpage;
    //DrowBand(MasterData[b]N[/b], RecPerPage, RecFirst + [b]N-1[/b]);
    //
    end;
    
    begin
    
    end.
    

    Возник вопросик к разработчикам.
    Ну неужели так друдно было добавить Букмарки к датасету? или хотябы не делать ReadOnly свой-во RecNo ? А то приходится извращаться, портить весь код процедурой SetRecNo и тупо ходить вперед/зад по датасету =(.

    так вобщем то работает, если запуск идет из дизайнера, например.
    Но при запуске из моего основного модуля выводится не вся инфа....
    подозреваю что это связано с ClientDataSet.PaketRecord = 20 и ClientDataSet.Unidirectional = true. (Можете не искать в стандартном компоненте последнее св-во - его там нет =))), для примера можете сделать связку ClientDataSet + Query, получите тот же эффект). Так что с этим потом разберемся....
    Вобщем, спасибо, всем кто помогал мне. =)

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

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