Change DataSet of each objects on sheet

edited June 2009 in FastReport 4.0
I have saved report in file (or database). There are on it barcode (dataset DBDane, datafield ean13 ), text (dataset DBDane, datafield tekst) etc. Everything is from dataset. Dataset is named DBDane.
I want to write multithreaded service. And if one thread makes object of class TfrxDBDataset named DBDane, another can't (I've got exception "A component named DBDane already exists") .
How can I change properties of every elements of my report to change dataset for another name?

my code:
    mDBDane[miejsce]=new TfrxDBDataset(XSVSQLResp);
    mDBDane[miejsce]->DataSet=zapytania[miejsce];
    mDBDane[miejsce]->UserName="DBDane";
    mDBDane[miejsce]->Name="DBDane";// If I change this name report doesn't prepare
    mDBDane[miejsce]->Enabled=true;
    zapytania[miejsce]->Active=true;
    (...)
    raporty[miejsce]=new TfrxReport(XSVSQLResp);
    raporty[miejsce]->EngineOptions->EnableThreadSafe=true;
    raporty[miejsce]->EngineOptions->DestroyForms=false;
    raporty[miejsce]->EngineOptions->ReportThread=this;
    raporty[miejsce]->EngineOptions->SilentMode=true;
    raporty[miejsce]->EngineOptions->UseFileCache=false;

    raporty[miejsce]->EngineOptions->UseGlobalDataSetList = false;
    raporty[miejsce]->EnabledDataSets->Clear();
    raporty[miejsce]->EnabledDataSets->Add(mDBDane[miejsce]);
    (...)
    ms[miejsce]=new TMemoryStream();
    Dekoder[miejsce]=new TIdDecoderMIME(XSVSQLResp);
    Dekoder[miejsce]->DecodeToStream(zapytania2[miejsce]->FieldByName("raport")->AsString,ms[miejsce]);
    ms[miejsce]->Position=0;
    raporty[miejsce]->LoadFromStream(ms[miejsce]);

    raporty[miejsce]->DataSets->Clear();
    raporty[miejsce]->DataSets->Add(mDBDane[miejsce]);
    raporty[miejsce]->DataSets->BeginUpdate();
    raporty[miejsce]->DataSet=mDBDane[miejsce];
    raporty[miejsce]->DataSetName="DBDane";

        raporty[miejsce]->PrepareReport(true)

(...)

Please help!

Comments

  • Anu de DeusAnu de Deus Hampshire, UK
    edited 11:26AM
    You can change the dataset, but do more things than you did.
    The secret is to keep the dataset name stored in a variable (string), so you can replace it everywhere, in every component if necessary.

    I have a code that loops through several datasets, creating them on then fly, take a look at this:

    fDBDataSetName := 'ffrDBDataset' + inttostr(pIdx); <<--- this is what you are missing mainly

    ffrDBDataset := TfrxDBDataset.Create(nil);
    ffrDBDataset.Name := fDBDataSetName; //'frxDBDataset1'; << see the name being replaced here?
    ffrDBDataset.UserName := fDBDataSetName; //'frxDBDataset1'; << see the name being replaced here?
    ffrDBDataset.CloseDataSource := False; << probably not necessary for you
    ffrDBDataset.BCDToCurrency := False; << probably not necessary for you
    ffrDBDataset.DataSet := fADODataSet; << you can change the dataset source too, with or without changing the name, if you want

    pParentReport.DataSets.Add(ffrDBDataset); << this was also missing in your code, I think, so the prepare doesn't fail.

    I hope this gives you some ideas. After this, you may need to change the individual Dataset properties of all tfrxMemoView components etc in the report, if it's changed.

    Cheers
  • edited June 2009
    Thank for reply.
    I know how I can change name of my dataset.
    But when I load raport from file I don't know what kind of elements and how named they are loaded.
    My question is:
    Ist there any solution to write some kind of loop to change DataSet in every element of loaded from file (stream) report?
  • Anu de DeusAnu de Deus Hampshire, UK
    edited 11:26AM
    Sure, list all the objects belonging to the report, if they are of a type that uses a dataset (or have it populated) then you change it.
    Something like:

    <!--fonto:Courier New--><span style="font-family:Courier New"><!--/fonto-->var lC : tfrxComponent;

    for i := 0 to fReport.PagesCount - 1 do
    begin
    for c := 0 to fReport.Pages.Objects.Count - 1 do
    begin
    lC := tfrxComponent(fReport.Pages.Objects[c]);
    if lC is tfrxMemoView then begin
    if tfrxMemoView(lC).Dataset <> '' then // maybe <> nil, I didn't try compiling this code, I'm just posting it in the forum.
    tfrxMemoView(lC).Dataset := your new dataset.
    // maybe you need this too, test it:
    tfrxMemoView(lC).text := '';
    end;
    //repeat situation for bands, or any other db type :
    if lC is tfrxMasterData then begin
    tfrxMasterData (lC).Dataset := your new dataset.
    end;<!--fontc--></span><!--/fontc-->

    and so on.

    Also, you may need to extend the loop to include all children of the objects you just did


  • edited 11:26AM
    Hey. Thanks for reply!
    I already did it using TList of objects fastReport->AllObjects.
    But thanks anyway!

Leave a Comment

Rich Text Editor. To edit a paragraph's style, hit tab to get to the paragraph menu. From there you will be able to pick one style. Nothing defaults to paragraph. An inline formatting menu will show up when you select text. Hit tab to get into that menu. Some elements, such as rich link embeds, images, loading indicators, and error messages may get inserted into the editor. You may navigate to these using the arrow keys inside of the editor and delete them with the delete or backspace key.