Home General
New Blog Posts: Merging Reports - Part 1 and Part 2

Text emulation of CrossTab - table frames

edited April 2003 in General
Hi,

Is it possible to emulate in text file CrossTab frames? I want to be able to
print CrossTabs in text mode. I can create text emulation file easily but
without the frames the result is ugly.

Thank you,
Janusz Cyran

Comments

  • edited April 2003
    There was a post a while back in this newsgroup where a customer created a
    text file crosstab renderer replacement. Try a search in yoru newsreader to
    find it. The renderer class is how the crosstab draws itself based on teh
    matrix that is calculated. The renderer is replacable with a registration
    call. See ppCTRend.pas for an example of our renderer we use for our output
    devices. The registration call is at the bottom of the unit.


    Cheers,

    Jim Bennett
    Digital Metaphors


  • edited April 2003
    I tried to find the post but I failed. Could anyone direct me - what was the
    subject of the post?

    Thank you,
    Janusz Cyran


  • edited April 2003
    Here is the message:

    ----- Original Message -----
    From: "Yoav"
    Newsgroups: digital-metaphors.public.reportbuilder.general
    Sent: Sunday, September 16, 2001 5:20 AM
    Subject: CrossTab Export to Text

    Here is a simple unit, that adds two new styles to the CrossTab component.
    The new styles provide the ability to export the crosstab to a text file, in
    two fashions:
    1. as per the report - each page outputed standaloan, the pages are one
    after the other.
    2. as one page - a single matrix.

    Those two styles (the second one especially) help also in export to excel.

    Here is the code for the unit.
    The code is as is. Hope it helps you.

    unit ppUmbCTRenderer;

    interface

    Uses
    SysUtils, Classes, ppCtrls, ppCTRend, ppCTCell, ppCTMain, ppDevice,
    ppDrwCmd,
    ppPrintr, Dialogs, ppTypes;

    Const
    cUmbCTRenderer = 'Text Output Enabled';
    cUmbCTAllInOneRenderer = 'All In One Text Output';
    CellPadding = 0;

    Type
    TppUmbCTRenderer = Class(TppCrossTabRenderer)
    Private
    FMyCompletedText: TList;
    procedure MyAddTextToPage(aPage: TppPage);

    Protected

    procedure MyCreateText(aElement: TppElement; aColumn, aRow: Integer;
    aLeft, aTop,
    aWidth, aHeight, aSaveNo, aCellPadding: Integer);
    Procedure MyCreateLineEnd(aLeft, aTop, aSaveNo: Integer);
    procedure DrawCellsToPage(aPage: TppPage; aMatrix: TppMatrix; aLeft,
    aTop: Longint); override;
    Public
    procedure CreateDrawCommands(aPage: TppPage; aMatrix: TppMatrix; aLeft,
    aTop: Longint); Override;
    function CalcSpaceUsed(aMatrix: TppMatrix; aHeight, aWidth: Longint;
    aPrinter: TppPrinter): Longint; override;
    class function Description: String; override;
    class function LocalizedDescription: String; override;

    End;

    TppUmbCTAllInOneRenderer = Class(TppUmbCTRenderer)
    Public
    function CalcSpaceUsed(aMatrix: TppMatrix; aHeight, aWidth: Longint;
    aPrinter: TppPrinter): Longint; override;
    class function Description: String; override;
    class function LocalizedDescription: String; override;
    End;


    implementation


    { TppUmbCTRenderer }


    function TppUmbCTRenderer.CalcSpaceUsed(aMatrix: TppMatrix; aHeight,
    aWidth: Integer; aPrinter: TppPrinter): Longint;
    var
    llHeightAvailable: Longint;
    llWidthAvailable: Longint;
    llHeightUsed: Longint;
    llWidthUsed: Longint;
    liColumns: Integer;
    liRows: Integer;
    begin
    Inherited CalcSpaceUsed(aMatrix, aHeight, aWidth, aPrinter);

    // Here we have to reduce the size of the EndRow and EndColumn variables
    With
    // respect to the CellPadding. the best way is to recalcuate the variables
    llHeightAvailable := aHeight;
    llWidthAvailable := aWidth;

    llHeightUsed := 0;
    liRows := Matrix.RowCount;
    EndRow := StartRow;

    while (llHeightUsed <= llHeightAvailable) and (EndRow < liRows) do
    begin
    llHeightUsed := llHeightUsed + GetRowHeight(EndRow)+ CellPadding * 2;

    if (llHeightUsed <= llHeightAvailable) then
    EndRow := EndRow + 1;
    end;

    EndRow := EndRow - 1;


    llWidthUsed := 0;
    liColumns := Matrix.ColumnCount;
    EndColumn := StartColumn;

    while (llWidthUsed <= llWidthAvailable) and (EndColumn < liColumns) do
    begin
    llWidthUsed := llWidthUsed + GetColumnWidth(EndColumn) + CellPadding *
    2;

    if (llWidthUsed <= llWidthAvailable) then
    EndColumn := EndColumn + 1;
    end;

    EndColumn := EndColumn - 1;

    {set space used and overflow}
    Result := llHeightUsed;
    end;

    procedure TppUmbCTRenderer.CreateDrawCommands(aPage: TppPage;
    aMatrix: TppMatrix; aLeft, aTop: Integer);
    begin
    FMyCompletedText := TList.Create;
    Try
    inherited;
    MyAddTextToPage(aPage);
    Finally
    FMyCompletedText.Free;
    End;

    end;

    class function TppUmbCTRenderer.Description: String;
    begin
    Result := cUmbCTRenderer;
    end;

    procedure TppUmbCTRenderer.DrawCellsToPage(aPage: TppPage;
    aMatrix: TppMatrix; aLeft, aTop: Integer);
    var
    llLeft: Longint;
    llTop: Longint;
    llHeight: Longint;
    llWidth: Longint;
    liColumn: Integer;
    liRow: Integer;
    lElement: TppElement;
    liSaveNo: Integer;
    begin

    // llTop := aTop;
    llTop := aTop;

    liSaveNo := 0;
    for liRow := StartRow to EndRow do
    begin
    llHeight := GetRowHeight(liRow) + CellPadding * 2;

    if (llHeight = 0) then Continue;

    llLeft := aLeft;

    for liColumn := StartColumn to EndColumn do
    begin

    llWidth := GetColumnWidth(liColumn) + CellPadding * 2;

    // if (llWidth = 0) then Continue;

    lElement := GetElement(Matrix.ElementIndex[liColumn, liRow]);

    CrossTab.DoOnFormatCell(lElement, liColumn, liRow);

    CreateShape(lElement, llLeft, llTop, llWidth, llHeight);

    CreateLines(lElement, liColumn, liRow, llLeft, llTop, llWidth,
    llHeight);

    MyCreateText(lElement, liColumn, liRow, llLeft, llTop, llWidth,
    llHeight, liSaveNo, CellPadding);

    llLeft := llLeft + llWidth;
    Inc(liSaveNo);
    end;

    MyCreateLineEnd(llLeft, llTop, liSaveNo);
    Inc(liSaveNo);
    llTop := llTop + llHeight;
    end;

    // aLeft := llLeft;
    // aTop := llTop;

    end;

    class function TppUmbCTRenderer.LocalizedDescription: String;
    begin
    Result := cUmbCTRenderer;
    end;

    procedure TppUmbCTRenderer.MyAddTextToPage(aPage: TppPage);
    var
    liIndex: Integer;
    lDrawText: TppDrawText;
    begin

    for liIndex := 0 to FMyCompletedText.Count - 1 do
    begin
    lDrawText := TppDrawText(FMyCompletedText[liIndex]);

    lDrawText.Page := aPage;
    end;

    end;

    procedure TppUmbCTRenderer.MyCreateLineEnd(aLeft, aTop, aSaveNo: Integer);
    Const
    CaridgeReturn = #13#10;
    var
    lDrawText: TppDrawText;
    begin

    lDrawText := TppDrawText.Create(nil);

    lDrawText.Alignment := taLeftJustify;
    lDrawText.Font := CrossTab.Font;
    lDrawText.Left := aLeft;
    lDrawText.Top := aTop + ciTextMargin;
    lDrawText.Width := 10;
    lDrawText.Height := 10;
    lDrawText.AutoSize := False;
    lDrawText.Transparent := True;

    lDrawText.BandSave := CrossTab.Band.Save;
    lDrawText.BandSaveNo := CrossTab.Band.Report.ReportBandCount;
    lDrawText.Component := CrossTab;
    lDrawText.ComponentSave := True;
    lDrawText.ComponentSaveNo := aSaveNo;
    lDrawText.SaveLength := 20;

    lDrawText.Text := CaridgeReturn;

    FMyCompletedText.Add(lDrawText);
    end;

    procedure TppUmbCTRenderer.MyCreateText(aElement: TppElement; aColumn,
    aRow, aLeft, aTop, aWidth, aHeight, aSaveNo, aCellPadding: Integer);
    var
    lsText: String;
    lDrawText: TppDrawText;
    begin
    if IsCaption(aColumn, aRow) and not(Matrix.CaptionVisible[aColumn, aRow])
    then Exit;

    lsText := GetValueAsText(aColumn, aRow);

    // if (lsText = '') then Exit;

    lDrawText := TppDrawText.Create(nil);

    lDrawText.Alignment := aElement.Alignment;
    lDrawText.Font := aElement.Font;
    lDrawText.Left := aLeft + CellPadding;
    lDrawText.Top := aTop + ciTextMargin + CellPadding;
    lDrawText.Width := aWidth - CellPadding * 2;
    lDrawText.Height := aHeight - CellPadding * 2;
    lDrawText.AutoSize := False;
    lDrawText.Transparent := True;

    lDrawText.BandSave := CrossTab.Band.Save;
    lDrawText.BandSaveNo := CrossTab.Band.Report.ReportBandCount;
    lDrawText.Component := CrossTab;
    lDrawText.ComponentSave := True;
    lDrawText.ComponentSaveNo := aSaveNo;
    lDrawText.SaveLength := 20;


    ExpandTextDimensions(lDrawText, aColumn, aRow);

    case aElement.Alignment of
    taLeftJustify: lDrawText.Left := aLeft + ciTextMargin;
    taRightJustify: lDrawText.Width := lDrawText.Width - ciTextMargin;
    end;

    lDrawText.Text := GetValueAsText(aColumn, aRow);

    FMyCompletedText.Add(lDrawText);
    end;

    { TppUmbCTAllInOneRenderer }

    function TppUmbCTAllInOneRenderer.CalcSpaceUsed(aMatrix: TppMatrix;
    aHeight, aWidth: Integer; aPrinter: TppPrinter): Longint;
    begin
    Result := Inherited CalcSpaceUsed(aMatrix, aHeight, aWidth, aPrinter);
    If (StartColumn = 0) and (StartRow = 0) then
    EndColumn := Matrix.ColumnCount - 1;
    end;

    class function TppUmbCTAllInOneRenderer.Description: String;
    begin
    Result := cUmbCTAllInOneRenderer;
    end;

    class function TppUmbCTAllInOneRenderer.LocalizedDescription: String;
    begin
    Result := cUmbCTAllInOneRenderer;
    end;

    Initialization
    ppRegisterRenderer(TppUmbCTRenderer);
    ppRegisterRenderer(TppUmbCTAllInOneRenderer);
    Finalization
    ppUnRegisterRenderer(TppUmbCTRenderer);
    ppUnRegisterRenderer(TppUmbCTAllInOneRenderer);

    end.


    "Fabio" <fabiotwo@hotmail.com> wrote in message news:3de78813@dm500....
    news:3de64f0e@dm500....
    is


    --
    Cheers,

    Jim Bennett
    Digital Metaphors


  • edited April 2003
    Is it enough to add the unit to a project to have the replacement active? I
    cannot find much info on this subject in RB help. And is there any archive
    available with old messages of this newsgroup?

    Thank you very much.
    Janusz Cyran


  • edited April 2003
    Hi Janusz,


    no archive is needed, they are still here, just download them.
    Or use http://www.tamaracka.com/ (e.g. 'CrossTab ^ReportBuilder').

    regards,
    Chris Ueberall;
  • edited April 2003
    Hi Chris,

  • edited April 2003
    Janusz,


    the initialization section should it normaly do, but unfortunately I have no cross tab experience.
    I would contact Yoav.

    regards,
    Chris Ueberall;
  • edited April 2003
    I am experiencing the same problem. I've added Yoav's unit to rbCT76
    package, compiled it, then added this unit to Uses clause of my report unit.
    I am assigning ppCrossTab.Style := cUmbCTAllInOneRenderer. This compiles
    fine. But when I run the application, run the report and select Print to
    File option in Print Dialog, the file is empty. Should I create the renderer
    in OnPrintDialogCreate and initiate saving to a file somehow?



    Thanks.

    Inna.


  • edited April 2003
    When you want to use these options, you need to set the style of the
    crosstab. Rightt click over the crosstab component in the designer and
    you'll see under the Style option, there are two more choices than before.
    Choose one of the file output styles and print the report to report
    emulation text file. It works for me.


    Cheers,

    Jim Bennett
    Digital Metaphors


  • edited April 2003
    Jim,

    When I right click on the crosstab, I only see two Style options (standard,
    repeated captions). What should I do to see the other two? I've rebuilt my
    project.

    Thanks.
    Inna.


  • edited April 2003
    Inna,

    I guess it works only on runtime (for the case you tried it during design time).

    HTH,
    Chris Ueberall;
  • edited April 2003
    You should be able to create and install a new Delphi package with only
    these two renderer classes included. This can be done much like you can to
    install additional RAP pass through functions to extend RB at Delphi design
    time.


    Cheers,

    Jim Bennett
    Digital Metaphors


This discussion has been closed.