Построение отчета

отредактировано 10:59 Раздел: FastReport 3.0
Есть отчет, состоящий из однотипных по разметке страниц, отличие только в содержимом Memo и данных таблицы. Число столбцов также может различаться от страницы к странице. Отчет я строю динамически. Заполняю MasterData через UserDataset, беря значение из StringGrid. При построении отчета данные во всех таблицах отчета оказываются одинаковыми и соответствующими последней странице. Что можно сделать?
Кроме варианта загнать данные всех страниц в таблицу StringGrid и из нее считывать. Хотелось бы в таблице StringGrid в любой момент времени иметь данные, относящиеся только к одной странице.

Комментарии

  • gpigpi
    отредактировано 10:59
    Попробуйте для каждой страницы отчёта использовать свой UserDataset.
  • отредактировано 10:59
    то есть их динамически добавлять?
  • отредактировано 10:59
    не помогло
    результат все тот же
  • отредактировано 10:59
    Занесение данных я делаю в событии OnGetValue. В хелпе написано, что событие наступает, когда встречена неизвестная переменная. Пробовал вызывать построение отчета после добавления каждой страницы - не помогает. Т.е. при каждом новом вызове все поля всех страниц считаются неизвестными и данные заполняются согласно тому, что лежит в таблице - тому, что должно отображаться на последней странице
  • gpigpi
    отредактировано February 2006
    Код привести можете?
    А лучше тестовый проект выложите.
  • отредактировано February 2006
    {
    //главная функция
    ...
    Dataset=(TfrxUserDataSet**)malloc(3*sizeof(TfrxUserDataSet*));
    Dataset[0]=Main_form->frxUserDataSet1;
    Dataset[1]=Main_form->frxUserDataSet2;
    Dataset[2]=Main_form->frxUserDataSet3;
    for(int i=1;i<=3;i++)
         FillAttendRepGroup(name,MyString[i]);
    ...
    }
    
    void FillAttendRepGroup(AnsiString name,AnsiString s)
    {
    //запрос, занесение данных в таблицу
    //после этого в таблице ServTable типа StringGrid  оказывается таблица, которую мне надо вывести 
    Dataset[datacount]->RangeEnd=reCount;
    Dataset[datacount]->RangeEndCount=Main_form->ServTable->RowCount-1;
    //формирую страницу
    TfrxReportPage *Page;
    TfrxMemoView *Memo1;
    Page=new TfrxReportPage(Main_form->Report);
    Page->CreateUniqueName();
    Page->SetDefaults();
    Page->Orientation=poLandscape;
    Main_form->Report->DataSets->Add(Dataset[datacount]);
    //создаю заголовок страницы
    TfrxPageHeader *Header=new TfrxPageHeader(Page);
    Header->CreateUniqueName();
    Header->SetBounds(Page->Top,36,0,30);
    Memo1=new TfrxMemoView(Header);
    Memo1->CreateUniqueName();
    Memo1->SetBounds(5,0,127,27);
    //...устанавливаю шрифт и прочее, потом добавляю надпись        Memo1->Memo->Add("Страница"+datacount+"Всякая фигня");
    //делаю таблицу
    //сначала заголовок
    TfrxHeader *TableHead=new TfrxHeader(Page);
    TableHead->SetBounds(10,Header->Top+Header->Height+5,240,100);
    TableHead->CreateUniqueName();
    TfrxMemoView **Memo;
    Memo=(TfrxMemoView**)malloc(Main_form->ServTable->ColCount*sizeof(TfrxMemoView*));
    for(i=0;i<Main_form->ServTable->ColCount;i++)
    {
          Memo[i]=new TfrxMemoView(TableHead);
          Memo[i]->CreateUniqueName();
          Memo[i]->Font->Name="Times New Roman Cyr";
          Memo[i]->Frame->Typ=TfrxFrameTypes()<<ftLeft<<ftRight<<ftTop<<ftBottom;
          Memo[i]->Font->Style=TFontStyles();
          Memo[i]->Font->Size=12;
          Memo[i]->Memo->Add("[H"+AnsiString(i)+"]");
    }
          Memo[0]->SetBounds(5,0,50,TableHead->Height);
          Memo[1]->SetBounds(55,0,150,TableHead->Height);
          for(i=2;i<Main_form->ServTable->ColCount;i++)
    {
    Memo[i]->SetBounds((i-2)*40+Memo[1]->Left+Memo[1]->Width,0,40,TableHead->Height);
                    Memo[i]->Rotation=90;
    }
    //теперь сама таблица
    TfrxMasterData *RepTable=new TfrxMasterData(Page);
    RepTable->DataSet=Dataset[datacount];
    RepTable->SetBounds(0,TableHead->Top+1,(Main_form->RepRowData->RangeEndCount-1)*22,22);
    TfrxMemoView**TableMemo=(TfrxMemoView**)malloc(Main_form->ServTable->ColCount*sizeof(TfrxMemoView*));
    for(i=0;i<Main_form->ServTable->ColCount;i++)
    {
          TableMemo[i]=new TfrxMemoView(RepTable);
          TableMemo[i]->CreateUniqueName();
          TableMemo[i]->Font->Name="Times New Roman Cyr";
          TableMemo[i]->Font->Size=12;
          TableMemo[i]->Memo->Add("["+AnsiString(i)+"]");
          TableMemo[i]->Frame->Typ=TfrxFrameTypes()<<ftLeft<<ftBottom<<ftRight;
    }
    TableMemo[0]->SetBounds(5,0,50,22);
    TableMemo[1]->SetBounds(55,0,150,22);
    for(i=2;i<Main_form->ServTable->ColCount;i++)
     TableMemo[i]->SetBounds((i-2)*40+TableMemo[1]->Left+TableMemo[1]->Width,0,40,22);
    
          datacount++;
    
    }    
    
    
    //заполнение отчета производится при вызове
    void __fastcall TMain_form::ReportGetValue(const AnsiString VarName,
          Variant &Value)
    {
    	if(VarName.SubString(1,1)=="H")
      Value=ServTable->Cells[VarName.SubString(2,VarName.Length()-1).ToInt()][0];
            else
            	Value=ServTable->Cells[VarName.ToInt()][RepRowData->RecNo+1];
    }
    
  • gpigpi
    отредактировано 10:59
    В Си я не разбираюсь, так что могу и ошибиться:
    судя по коду, StringGrid заполняется разными данными на этапе построения шаблона отчёта, т.е. на момент построения самого отчёта StringGrid содержит данные для последней страницы.
    Решение вижу в следующем (на Delphi):
    использовать два frxreport. Один - для итогового отчёта, второй - для промежуточного
         //здесь программно создаётся frxreport1 
         frxreport1.PrepareReport(true);
         for i:=1 to 3 do
           begin
             //здесь программно создаётся frxreport2 для i-ой страницы  
             frxreport2.PrepareReport(True);
             frxreport1.PreviewPages.AddFrom(frxreport2);
           end;
         frxreport1.PreviewPages.DeletePage(0); // удаляем первую пустую страницу, которая появилась после frxreport1.PrepareReport(true);
         frxreport1.ShowPreparedReport;
    

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

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