Walking through the elements of a band?

edited August 2012 in FastReport 4.0
I have a Memo (TfrxViewMemo), I get its parent and wish to walk through its elements/components, but TfrxBand(Memo.Parent).ComponentCount is 0 and TfrxBand(Memo.Parent).Component[0] raises an index out of bounds!

How do I walk through the elements/components of a band, then? Do I have to manually assign the components when I do TfrxViewMemo.Create(Band).

I have been searching for a while, and I cannot find any one interested in doing this. The reason is that I have a band, which height decreases if one element inside it contains no data (the band is 3 lines tall), and the second and third line only contain one element, and it is only the second line that can usually be nothing.

As such, I want the memo, which is on the third line to be moved up and the height of the band decreased if the second line's memo is empty.

Something like this:
procedure MemoCollapse(Memo: TfrxMemoView);
var
  i : Integer;
  c : TfrxReportComponent;
begin
  if Memo.Text = '' then
  begin
    TfrxBand(Memo.Parent).Height := TfrxBand(Memo.Parent).Height - LineHeight;
    for i := 0 to TfrxBand(Memo.Parent).ComponentCount-1 do
      c := TfrxReportComponent(TfrxBand(Memo.Parent).Components[i]);
      if c.Top > Memo.Top then
        c.Top := c.Top - LineHeight;
  end;
end;

Comments

  • gordkgordk St.Catherines On. Canada.
    edited 6:16PM
    the objects of a band are a 0 based array of tobjects
    typically
    var
    i: Integer;
    c: TObject;

    for i := 0 to Sender.Objects.Count - 1 do
    begin
    c := Sender.Objects
    if c is TfrxMemoView then
    TfrxMemoView©.Visible := False
    else if c is TfrxLineView then
    TfrxLineView©.Visible := True
    end;

    it is not clear as to what the layout in the band is
  • edited 6:16PM
    Thanks for the quick response. However, it seems to me that when I do this in a 'BeforePrint' function, this seems to manipulate every occurrence of the band, which I only wish to manipulate individual occurrences. I want the band to collapse in size when less data is present. And I can easily alter the height of the band as well as the Memo that creates the alternating background, but not the top of the element now outside the band.
    [A] [B] [C] [X] [D]
                [Y]
                [Z]
    

    That is the 'layout' of the band. If Y is empty, I want the band to 'collapse' to 2 lines (rather than its default 3 lines) and Z be moved up a line (as Z is not a 'collapse-able' element; at least not in my configuration). To end up like this:
    [A] [B] [C] [X] [D]
                [Z]
    

    The reasoning here is that X, Y and Z are all part of an address. But in most cases, the secondary address (Y) does not appear, i.e. it is empty.
  • gordkgordk St.Catherines On. Canada.
    edited 6:16PM
    you could add y and z to attached child bands
    the band containing y can have its visible prop set in the obp event
    or when all datafields are contained within one memoview you can use
    the onafterdataevent of the memoview
    procedure mLabelOnAfterData(Sender: TfrxComponent);
    var i: integer;

    begin
    for i := TfrxMemoView(Sender).Lines.Count - 1 downto 0 do
    begin
    if TfrxMemoView(Sender).Lines.Strings = '' then
    TfrxMemoView(Sender).Memo.Delete(i);
    end;
    end;
  • edited 6:16PM
    gordk wrote: »
    you could add y and z to attached child bands
    the band containing y can have its visible prop set in the obp event

    I tried that, but then both bands disappear, because the children occur in order: X -> Y -> Z, and if a band is not visible, its children disappears (as well as any further children down the line). It would be strange to suddenly reattach Z to X in this case, and attach it back to Y once Y contains data.
    gordk wrote: »
    or when all datafields are contained within one memoview you can use
    the onafterdataevent of the memoview
    procedure mLabelOnAfterData(Sender: TfrxComponent);
    var i: integer;

    begin
    for i := TfrxMemoView(Sender).Lines.Count - 1 downto 0 do
    begin
    if TfrxMemoView(Sender).Lines.Strings = '' then
    TfrxMemoView(Sender).Memo.Delete(i);
    end;
    end;

    How do I assign more than one datafield to a memoview, and more importantly, ensure that they each appear on their own line?
  • gordkgordk St.Catherines On. Canada.
    edited 6:16PM
    look at the properties that can be set for the bands
    ie: printchildifinvisible
    bands can only grow NOT shrink set the band stretch prop and the memo's stretch mode, wordwrap etc

    very seldom do you need to try to manipulate design settings, but if you do you must reset them to prior
    settings or you can widow objects to the page, after several iterations.
    a memoview is a multilined text object it can contain expressions, text and datafields.
    just don't set the datafield prop.
    use the [] braces inside the memo.
    [datasetname."fieldname1"] some text [datasetname."fieldname2"]
    [datasetname."fieldname3"]
  • edited 6:16PM
    gordk wrote: »
    look at the properties that can be set for the bands
    ie: printchildifinvisible
    bands can only grow NOT shrink set the band stretch prop and the memo's stretch mode, wordwrap etc

    very seldom do you need to try to manipulate design settings, but if you do you must reset them to prior
    settings or you can widow objects to the page, after several iterations.
    a memoview is a multilined text object it can contain expressions, text and datafields.
    just don't set the datafield prop.
    use the [] braces inside the memo.
    [datasetname."fieldname1"] some text [datasetname."fieldname2"]
    [datasetname."fieldname3"]

    Good, I got that to work, but now I am having trouble here:
    gordk wrote: »
    you could add y and z to attached child bands
    the band containing y can have its visible prop set in the obp event
    or when all datafields are contained within one memoview you can use
    the onafterdataevent of the memoview
    procedure mLabelOnAfterData(Sender: TfrxComponent);
    var i: integer;

    begin
    for i := TfrxMemoView(Sender).Lines.Count - 1 downto 0 do
    begin
    if TfrxMemoView(Sender).Lines.Strings = '' then
    TfrxMemoView(Sender).Memo.Delete(i);
    end;
    end;

    Where do I insert this procedure? Apparently, TfrxMemoView().OnAfterData takes a string rather than a procedure like TfrxReport().OnBeforePrint does. I am at loss at where I need to implement this procedure.
  • gordkgordk St.Catherines On. Canada.
    edited 6:16PM
    in design mode select the memoview
    on the right hand side select the events tab the dbleclick the desired event and you will move to the code page,
    where you can write the code
  • edited 6:16PM
    gordk wrote: »
    in design mode select the memoview
    on the right hand side select the events tab the dbleclick the desired event and you will move to the code page,
    where you can write the code

    Ah well, I am actually creating the whole report from code alone, I am not in the design view at all.
  • gordkgordk St.Catherines On. Canada.
    edited September 2012
    whish you would have stated that earlier.
  • hsmhsm
    edited 6:16PM
    gordk wrote: »
    whish you would have stated that earlier.

    @Gordk

    Related to this and following on from your valuable replies Gordk, I also need to identify a particular column - but of a TfrxDBCrossView.
    I have highlighted a particular column header by comparing the contents of the Column0 with my serach text. Now I want to highlight every cell below that header as well so the whole column is highlighted. To do this I think I need to know the column number of the header I highlighted and then identify that same column number when printing the Cell0.
    How can it be done?
  • gpigpi
    edited 6:16PM
    sample in attach
  • hsmhsm
    edited 6:16PM
    gpi wrote: »
    sample in attach
    Thank you for such a fast reply.
    I couldn't get your report to disply (dataset 'cross' not found), but I saw how you did it and using the same method in my report it now does what I want.

    BTW
    When can I find out about all these things that helpful posters such as yoursef seem to know?
    Now I know about HeaderIndexes and ColumnIndex it makes sense However the the components in fastreport seem to have loads of useful properties and helpful methods (like these two properties) that don't seem to be documented anywhere. Is there a list somewhere or must it all be done by trawling though the source code of the componets or by posting on this forum? >
  • gpigpi
    edited 6:16PM
    Yes. You can see a sources, event's headers
    wrote:
    or by posting on this forum?
    Better to create support ticket http://www.fast-report.com/en/support/ticket_list.php
  • edited 6:16PM
    gordk wrote: »
    whish you would have stated that earlier.

    I do apologise! But thanks for all the helpful replies. I have made significant process so far.

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.