Solved

Delphi. How do I position a Rectangle in a Rave Report around a virtual cell derived from a String Grid

Posted on 2010-09-02
10
1,523 Views
Last Modified: 2012-05-10
I am using data from a String Grid to populate vitual cells in a Rave Report.  The vitual cells are created using a series of NewLine and SetTab commands.  How can I calculate the exact top left and bottom right coordinates of a cell in order to draw a rectangle around selected cells only.
0
Comment
Question by:HenryM2
  • 6
  • 4
10 Comments
 
LVL 13

Expert Comment

by:aflarin
ID: 33594206
something like this:

function TForm1.RvSystem1PrintPage(Sender: TObject; var PageNum: Integer):
    Boolean;
var
  iCol, iRow : Integer;
begin
  with Sender as TBaseReport do
    ....
    iCol:= 5;
    iRow:= 5;
    Rectangle( GetTab(iCol).Pos,
               iRow*LineHeight,
               GetTab(iCol).Pos + GetTab(iCol).Width,
               (iRow+1)*LineHeight
              );
 end;
end;
0
 

Author Comment

by:HenryM2
ID: 33594393
I am not 100% sure how you are thinking of implementinh this function with the rest of my program.  What role does PageNum in the Function parameters play?

I subsequintly used your code section inside my report building procedure.  Although I can see what your thinking is here, the report comes out very wrong as per the attached picture.  Above the red line, the String Grid and below, the resulting report.  This is what my code looks like:

        CellText := ReportStringGrid.Cells[iCol, iRow];

        if iCol = 0 then
        SetFont('Arial', 8)
        else
        SetFont('Arial', 10);

        if CellText = '' then
        Begin
          PrintTab('  ' + chr(7));
        End
        else
        Begin
          if ReportStringGrid.Cells[iCol, iRow] = '[   ]' then
          Begin
             Rectangle( GetTab(iCol).Pos, iRow*LineHeight,
             GetTab(iCol).Pos + GetTab(iCol).Width,
             (iRow+1)*LineHeight );
          End
          else
          PrintTab(ReportStringGrid.Cells[iCol, iRow]);
        End;
      End;
      NewLine;

Also, I would like to replace the large dots in the empty cells with a smaller dot.  chr(7) is all I can find that works, is there a better way to do this?
Cell-Borders-In-Rave-Report.png
0
 
LVL 13

Expert Comment

by:aflarin
ID: 33594511
as I thought you asked about about absolute coordinates, but if you draw a rectangle whilr printing text it would be better to use current y pos like this:

          ....
          if ReportStringGrid.Cells[iCol, iRow] = '[   ]' then
          Begin
            Rectangle( GetTab(iCol+1).Pos,
                              YPos - LineHeight,
                              GetTab(iCol+1).Pos + GetTab(iCol+1).Width,
                               YPos );
            PrintTab(''); // print nothing to go next tab
          End
          else
          ....        
0
 
LVL 13

Expert Comment

by:aflarin
ID: 33594534
>> Also, I would like to replace the large dots in the empty cells with a smaller dot.  chr(7) is all I can find that works, is there a better way to do this?

Originally, chr(7) produces beep. So it would be better use dot or other char. To make it smaller you can just change font like this:

    // set smaller font
   SetFont('Arial', 5);
   PrintTab(' . ');
   // return original font
   SetFont('Arial', 10);
0
 

Author Comment

by:HenryM2
ID: 33594579
>> as I thought you asked about about absolute coordinates, but if you draw a rectangle whilr printing text it would be better to use current y pos like this:

The TopLeft of the Tab and LinHeight works fine adn the rectangle starts in the correct place and is the correct height.  The width of the rectangle however spans over about 3 consecutive tabs.

Originally, chr(7) produces beep. So it would be better use dot or other char. To make it smaller you can just change font like this:

I originally used ' . ' instead of chr(7).  The problem is that I would like the dot to be in the middle of the row not the bottom as with ' . '.  Can one perhaps use some other graphic dot from the Rave Functions instead?
 
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
LVL 13

Expert Comment

by:aflarin
ID: 33594668
try to use chr(149) instead of dot

>> The width of the rectangle however spans over about 3 consecutive tabs.

Hm. It works well for me. Could you show the full procedure and produced report?
0
 

Author Comment

by:HenryM2
ID: 33595064
Ok 149 just prints blank in columns.

Attached my whole Procedure as its now.  The report has to include a page break when the number of lines (children) underneath certain section is too long in order to keep the sections on one page.  In preparation of the Text Grid, I add the characters *(xx), where xx represents the number of children under that parent) at the end of the lines where the children under that line is to be grouped with the parent line.  Children can be seen as indented under the parents.
procedure TReportsFrm.PrintReportStringGrid(Sender: TObject);

Const Col0Width = 3.8;

      CheckColWidth = 0.2;

      HeaderHeight = 2.0;

 procedure PrintGridHeader;

  var

    iCol: Integer;

    curY: Double;

  begin

    with Sender as TBaseReport do

    begin

      SetFont('Arial', 14);

      NewLine;

      PrintCenter(ReportName, 4); // Report Title

      YPos:= YPos + HeaderHeight; // Sets bottom start for bottom of vertical text header cols

      SetFont('Arial', 10);

      FontRotation:= 90;

      Bold := True;

      TabJustify:= tjLeft;

      for iCol:= 1 to ReportStringGrid.ColCount-1 do

      begin

        curY:= YPos;



        PrintXY( Col0Width{Col[0] width } + iCol*CheckColWidth {Col width} + 0.15{some shift}, YPos, ReportStringGrid.Cells[iCol, 0]);

        YPos:= curY;

      end;

      //NewLine;

      Bold := False;

      FontRotation:= 0;

      YPos := YPos + 0.15;

      MoveTo( 0.2, YPos );

      LineTo( PageWidth - 0.2, YPos );

      YPos := YPos + 0.2;

    end;

  end;



  procedure PrintGridFooter;

  var QtyPages : Integer;

  begin

  with Sender as TBaseReport do

    begin

      YPos := YPos + 0.1;

      MoveTo( 0.15, YPos);

      LineTo( PageWidth - 0.2, YPos ); // Line at bottom of the page

      NewLine;

      NewLine;



      QtyPages := (ReportStringGrid.RowCount div 50);

      if (ReportStringGrid.RowCount mod 50) > 0 then

      inc(QtyPages);

      PrintCenter('Page ' + IntToStr(CurrentPage) + ' Of ' + IntToStr(QtyPages), PageWidth/2);

    end;

  end;



var

  iCol, iRow, QtyChildren, ChildCountPos : Integer;

  PageInfoStr, CellText : String;

  CurrentFont : TFont;

begin

  with Sender as TBaseReport do

  begin

    //NewLine;

    // PrintCenter(ReportType, 4); // Report Title

    //NewLine;

    ClearTabs;

    SetTab(0.2, pjLeft, Col0Width, 0, 0, 0); // SetTab(NewPos: double; NewJustify: TPrintJustify; NewWidth: double; NewMargin: double; NewLines: byte; NewShade: byte);

    for iCol:= 1 to ReportStringGrid.ColCount-1 do

      SetTab(Col0Width + iCol*CheckColWidth, pjRight, 0.5, 0, 0, 0);



    PrintGridHeader;



    Bold := False;

    for iRow := 1 to ReportStringGrid.RowCount - 1 do

    begin

      for iCol:= 0 to ReportStringGrid.ColCount-1 do

      Begin



        CellText := ReportStringGrid.Cells[iCol, iRow];



        if iCol = 0 then

        Begin

          ChildCountPos := Pos(' *(', CellText);

          if ChildCountPos > 0 Then

          Begin

            //CTL := Length(CellText);

            //ChildCountPos := ChildCountPos + 3;

            //ChildrenText := Copy(CellText,(ChildCountPos + 3), Length(CellText) - (ChildCountPos + 3));

            QtyChildren := StrToInt(Copy(CellText,(ChildCountPos + 3), Length(CellText) - (ChildCountPos + 3)));

            if iRow + QtyChildren > 49 then

            Begin

              PrintGridFooter;

              NewPage;

              PrintGridHeader;

            End;

          End;

        End;



        if iCol = 0 then

        SetFont('Arial', 8)

        else

        SetFont('Arial', 10);



        if CellText = '' then

        Begin

          PrintTab('  ' + chr(7));

        End

        else

        Begin

          if ReportStringGrid.Cells[iCol, iRow] = '[   ]' then

          Begin

            Rectangle( GetTab(iCol+1).Pos,

                              YPos - LineHeight,

                              GetTab(iCol+1).Pos + GetTab(iCol+1).Width,

                               YPos );

            PrintTab(''); // print nothing to go next tab

          End

          else

          PrintTab(ReportStringGrid.Cells[iCol, iRow]);

        End;

      End;

      NewLine;



      // 50 lines per page

      if (iRow mod 50) = 0 then

      begin

        PrintGridFooter;

        NewPage;

        PrintGridHeader;

      end;



    end;

    PrintGridFooter;

  end;

end;

Open in new window

Cell-Borders.png
0
 
LVL 13

Expert Comment

by:aflarin
ID: 33595224
I see. You didn't change the tab width to the new right value. Change it here and your code will work:

    for iCol:= 1 to ReportStringGrid.ColCount-1 do
        SetTab(Col0Width + iCol*CheckColWidth, pjRight, CheckColWidth, 0, 0, 0);



0
 
LVL 13

Accepted Solution

by:
aflarin earned 500 total points
ID: 33595346
>> Ok 149 just prints blank in columns.

ASCII codes that greater than 127 may be different in various character sets. Unfortunately there is not a centered dot with code 0-127.

You have 3 ways:

1. you can find the centered dot in your character set. Use Character Map app (All Programs > Accessories > System Tool ) to find it

2. you can draw a dot instead of printing it. Use this method:

procedure Ellipse(X1,Y1,X2,Y2: double);
Description
This method draws an ellipse bounded by the rectangle defined by (X1,Y1) and (X2,Y2).

3. You set smaller font to print char(7)
0
 

Author Closing Comment

by:HenryM2
ID: 33596348
>> I see. You didn't change the tab width to the new right value. Change it here and your code will work:

Thanks, Stupid mistake, I guess I still have to used to Rave Reportsm but I like what I see so far.


>> 2. you can draw a dot instead of printing it. Use this method:

This work fine.
0

Featured Post

How to improve team productivity

Quip adds documents, spreadsheets, and tasklists to your Slack experience
- Elevate ideas to Quip docs
- Share Quip docs in Slack
- Get notified of changes to your docs
- Available on iOS/Android/Desktop/Web
- Online/Offline

Join & Write a Comment

Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
I'd like to talk about something that is near and dear to my heart: build systems. Without them, building software is all about compiling locally, with software versions everywhere. It can be a mess. Today we are going to discuss building a small di…
This tutorial will introduce the viewer to VisualVM for the Java platform application. This video explains an example program and covers the Overview, Monitor, and Heap Dump tabs.
This tutorial explains how to use the VisualVM tool for the Java platform application. This video goes into detail on the Threads, Sampler, and Profiler tabs.

743 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now