Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Printing a report in columns

Status
Not open for further replies.

grandriver

Technical User
Dec 14, 2016
3
US
I have a table that has 2 fields- name and grade.
there are only three grades A,B or C
I would like to make a report that I could save as a pdf

I can get it to print a report as follows

name grade
name grade
etc

I would like the report to print as follows

grade A Grade B Grade C

name name name

printing all names under their designated grade

not sure if this is difficult or I am missing something easy
thanks
 
You are asking more than a single question.

1. Getting your data onto a Report Form in the manner you want.
This is done by getting the data you send to your Report Form in the order that will give you the results you want - either by using a separate SQL Query to organize the data as needed
- or creating an Index on the data to organize the data
- or SORTing the data to another ReportData table.

Since this is a very basic VFP skill I am guessing that you are somewhat unfamiliar with VFP.
With that in mind I'll recommend that you spend some time looking at the free on-line VFP Tutorial videos at:
You might want to pay special attention to those named:
Basic Reporting - Pt. 1​
Basic Reporting - Pt. 2​

2. How to get your Report to print out to a PDF document.
There are a number of PDF Print drivers available on the web. Many of them are Free.
I generally use BullZip, but that is just one of many.

When you have your Report looking like you want, you need only change where you want your Report to print out.
Instead of the normal default printer you just send the report to whatever PDF Print Driver you have installed.

Good Luck,
JRB-Bldr
 
Regarding the first part of your question:

Create a report containing three columns. Give them headers: Grade A, Grade B, Grade C. Place the Name field in each of the three columns (the same field in each case).

Next, for each of those three fields, right-cllck on the field and choose Properties. Click on the "Print when" tab in the Properties dialogue.

For the first field, in the "Print only when expression is true" box, put [tt]Grade = "A"[/tt]. Similarly with the second field, but in this case put [tt]Grade = "B"[/tt]. As [tt]Grade = "C"[/tt] for the third field.

I think that will do what you want, but if I have misunderstood what you are trying to achieve, perhaps you could clarify it.

For the second part of your question, JRB-Bldr has already pointed you in the right direction.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
If you do as Mike suggests you get output like follows.

Input data of the report
Student Grade
Aaron A
Betty B
Chris C

Report output as Mike suggests

[pre]
Grade A | Grade B | Grade C
Aaron | |
| Betty |
| | Chris
[/pre]

If you'd rather want output like
[pre]
Grade A | Grade B | Grade C
Aaron | Betty | Chris
[/pre]
If you want this output, then you really have to prepare a cursor or (temp) table with columns GradeA, GradeB, GradeC and fill it with the names, starting first students of each grade in recno 1, second in recno 2, etc. One list will end before others, most probably, that's left empty and the longest list determines number of records needed.

The way you can define columns in the page layout properties means you make the detail band narrower and can then print top to bottom or left to right. In left to right mode you might also get what you want, but then would need to sort data to always have a grade A,B, and C name in that order, then repeat, if Grade A list ends before B and C , you still need an empty entry for Column 1, you need a multiple of three records.

In top to bottom fill mode you could sort by grade, but then would need gap records for each column to fill it up so Grade B and C start printing in their own column. You then need to count how many names fit on a page and thereby know the necessary number of gap records. The number of records then is number of lines x2 + number of Grade C students at least. It's least favorable, as it might fail when one day the paper size changes or printable area or font size...

So perhaps still the simplest case would be preparing one new report cursor with three columns as needed for output. The possibility to define report columns and set them to fill left to right is needing an unusal preparation of the data in the A,B,C,A,B,C,A,B,C... pattern and would then need to change, if you ever introduce a Grade D column.
Bye, Olaf.

Edit: What I said earlier about the capabilities to specify start of data grouping is crap, if you introduce columns you get new options. You can set fill mode to "top to bottom" and set data grouping to let each group start in a new column. That only has the downside if you ever have too many names for one column that group will populate two columns and may therefore have the wrong column caption. Further groups will end up in the next column and shift all further names to next columns.
 
If you'd rather want output like
[tt]
Grade A | Grade B | Grade C
Aaron | Betty | Chris[/tt]

That seeme more likely.

In that case, as Olaf suggested, you will need to create a cursor to drive the report. Here is some code to get you started:

Code:
* Open your main table (change the name here as appropriate)
IF NOT USED("MyTable")
  USE MyTable IN 0 ALIAS Names
ENDIF

* Create a cursor (that is, a temporary table)
CREATE CURSOR csrClasses (ClassA C(16), ClassB C(16), ClassC C(16))

SELECT Names
SCAN

  SELECT csrClasses

  IF Names.CLASS = "A"

    * Find first record in the cursor for which a ClassA
    * name has not yet been filled in
    LOCATE FOR EMPTY(ClassA)

    * If no such record, create a new one
    IF NOT FOUND()
      APPEND BLANK
    ENDIF

    * Now insert the name into the record
    REPLACE ClassA WITH Names.NAME

  ENDIF


  * Repeat with Class B
  IF Names.CLASS = "B"

    LOCATE FOR EMPTY(ClassB)

    IF NOT FOUND()
      APPEND BLANK
    ENDIF

    REPLACE ClassB WITH Names.NAME

  ENDIF

  * And with Class C
  IF Names.CLASS = "C"

    LOCATE FOR EMPTY(ClassC)

    IF NOT FOUND()
      APPEND BLANK
    ENDIF

    REPLACE ClassC WITH Names.NAME

  ENDIF

ENDSCAN


That will produce a cursor with three fields. Each record will contain the name, in the field appropriate to the class. You can check that it worked by doing a Browse.

The report should have three fields in the Detail band: ClassA, ClassB and ClassC.

Now, provided the cursor (csrClasses) is selected when you run the report, it should give you the output you want.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Thanks Mike
I got three columns, the names are in the right grade column
the only thing is it repeats the first name in each list throughout the whole report
any suggestions

ie.

Bob Bill Fred
Bob Bill Fred
etc etc
 
You have to [tt]SELECT csrClasses[/tt] before calling the report.

Bye, Olaf.
 
As I said earlier:

provided the cursor (csrClasses) is selected when you run the report, it should give you the output you want.

By "selected", I mean that it is in the current work area (you change the work area by using the SELECT command).

It looks like you have the original table in the current work area at the time the report is run. This means that the report will contain one detail record for each record in the original table, but the contents of the report will be derived from the cursor. That would explain why you are seeing the same data over and over.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
The reasoning is as Mike says. To expand a little more: If you changed report fields to print [tt]ClassA,ClassB,[/tt] and [tt]ClassC[/tt] and even if you prefixed field names with [tt]csrClasses.[/tt], the report scans through the currently active workarea [tt]Names[/tt] and since it does not move through [tt]csrClasses[/tt] repeats [tt]csrClasses[/tt] current record all over again, as many times as there are records in [tt]Names[/tt].

That said it's also a nice way to have a number of arbitrary infos, values, texts to print, to put them in one record also available while the report runs, in a table which is not involved in iterating its rows, a table whichs current record stays. The report engine will only scan through further workareas, if there are relations set, which make a record SKIP in the main report driving current workarea cause a SKIP in another workarea or even cascading into further ones, the report engine will only ever actively skip row by row in the current workarea, all other skips will need to be done by relations.

By the way, this dependency of the current workarea also is shown in Garfield Hudson Videos you were pointed to. In "Basic Reporting Pt.1" from 17:45 onwards, the last less than 2 minutes. Even if you don't have the time to watch 20 minute videos, this part alone is worth watching to get a grip on this basic behavior, and while you're at it, you surely find more answers in this and all other videos. In the end they are worth watching.

Another thing is, while I pointed out downsides of "real" report columns and grouping by column, if you do put students in columns by grade for your classes for many years and know there never are too many students in a course to surpass the capacity of a column, this way of structuring the report might be simpler, as it doesn't require an extra report cursor, you just need to be able to sort your data by grade with most significance and perhaps by name in secondary sort order, which could be done by [tt]INDEX ON grade+name TAG gradesort[/tt] once and [tt]SET ORDER TO gradesort[/tt] before the report.

Bye, Olaf.

 
It would be nice of you to say or mark which posts helped, this also helps others finding this later.

Mark the helpful posts - most likely Mikes as far as I interpret you were doing his code - via the purple star "Great Post".

Bye, Olaf.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top