I have been working as a Consultant
for TF1, the major French TV Channel, for the last
4 years, developing and maintaining APL applications
for them.
A year ago, just after the APL2000
2000 User Conference, TF1 came to me and mentioned
that one of their departments was looking for a way
to display daily TV programs in a visual graphic grid.

Since I was interested in the subject
and wanted to show once again how much APL is efficient
to solve problems, I decided to invest one of my weekends,
building a sample application for them.
I asked them for a set of real data
to play with and the next week I came up with a complete
small APL application which was able to draw and display
the above grid in an APL form with menus, context
menus, etc.
Because of the nature of the problems,
I had decided to use APL+Win drawing
facilities, therefore using wi'Draw'... to draw the various TV programs on a Picture object on the form.
The above grid displays TV programs
by hour of the day (vertically) and by day of the
week (horizontally).
Before going further on, let me apologise
for displaying screen shots in French: I have not
had time to translate this application.
On the way to a much larger application
Seeing the results and the time it had
taken to build this sample application, TF1 decided
to ask me to write the complete application they had
in mind, and in fact this proved to be a rather huge
application.
What they really wanted was the following: they
wanted to have an application to help their Marketing
Representatives sell special kinds of ads called “sponsorship
ads”. Some TV programs are sponsored by advertisers
who play their jingles at the beginning and/or end
of the program.
This meant being able to:
- Display the daily TV Programs for any given week
- Navigate through 2 years of such grids
- Display a grid showing TV Programs by Weeks over 2 years
- Display a grid showing TV Programs by Days over 2 years
- Display a grid showing Weeks by Days for a given DayPart
- Display a specific grid showing short Programs
- Display TV Program Powerpoint Pages
- Select Programs with a multi-criteria selection system
- Show the Ad booking level for each program on all these grids
- Display information tooltips about the advertisers and products for each
Program
- Print all the grids
- Print additional reports
- Select programs over periods of times and auto-generate proposals
to advertisers
- Allow the application to work on the company network with 50
simultaneous users
- Allow the application to work on portable computers not connected
to the company network
- Import data from other TF1 applications
- Instantly inform simultaneous users that new data has been imported
- Grant various levels of user rights
- Have a very sophisticated and comprehensive Help System
- Spy application errors
- Spy users connections and disconnections
- Create, change, delete users
- Create an automatic installation program working with no prompts
And there was a 60 days budget available
for developing the whole application.
When they asked me if I could do all
that, I said “yes”, putting all my belief in Patrick
Park’s and APL2000’s ability to develop a Beta version
of a Grid robust enough to run in production environments.
As a matter of fact, I knew there would
be no way to write such an application in the allotted
time, without using a Grid object. Happily I was
just returning from the APL2000 2000 Conference and
knew how the new APL+Win Grid
object would be able to help me.
The other reason why I accepted this
contract is that I knew I could use my library of
objects from my “APL+Win 3.6
Objects” product.
Deciding for an (Object) strategy
I immediately decided to develop this
application in a pure Object Oriented manner, exclusively
using objects from “APL+Win 3.6
Objects” and creating new objects for
every aspect of the application.
So everything became an Object, with
its own properties and methods.
This proved over time to have considerably
helped me since it happened many times that I could
reuse already written object properties and methods
in places where I had not even anticipated I would
need them.
All objects used in this application
are working on the same model which is reproduced
on the next page.
The TPicture object shown on next page is an excerpt from
the “APL+Win 3.6 Objects” TPicture object with one property (bitmap) and one method (AdjustSize).
An object is an APL function having
a structure similar to TPicture, where there always is a New method, which is the object Constructor. In the New method, you build your object based on one
or more native existing APL+Win objects.
Most of the time the APL+Win object(s)
upon which you base your object is(are) visual object(s). If
you need to create a non visual object like a TRegistry object to cope with the Windows Registry,
it is a good idea to use the APL+Win Menu object which is the object having the smallest memory footprint.
TPicture inherits from TObject (line 16): this means that TPicture can call any TObject property or method.
You add properties and methods to your
object, by adding :case'property' or :case'Method' sections under the :case'Action' section (see lines 35-50 for the bitmap property and lines 52-62 for the AdjustSize method).
Lines 64-65 are used when you invoke
a property or method which is not one of your specific
object properties or methods (i.e. not class, bitmap or AdjustSize).
Then the system looks for such a property
or method in higher object in the hierarchy (here TObject)
and if it does not find it there, finally looks for
it in the APL+Win object
upon which your object is derived (here Picture). If it still does not find it, it falls through to lines 68-69,
displaying an error message.
A
TPicture B;C;D;E;F;G;H;I;J;K;L;M;N;O;P;Q;R;S;T;U;V;W;X;Y;Z;io;wself
[1] © A
TPicture B -- TPicture class
[2] © A
object
name
[3] © B
'property'
[4] © or
'property'value
[5] © or
'Method'
[6] © or
'Method'argument1 ... argumentN
[7] © Requires:
(F)
[8] © (c)2000
Eric Lescasse[11jul00]
[9]
[10] io1
[11] :if
2¬nc'A' ª Awself ª :end
[12] :select
B
[13] :case'New'
[14] wselfA wi'*Create'
'Picture'
[15] C'TPicture"Action"'
[16] CC,tcnl,'TObject"Action"' © inherit
from TObject
[17] wi'*onAction'C
[18] wi'*scale'(wi'*..scale')
[19] wi'*font'(wi'*..font')
[20] wi'*onDelete'
'Common"onDelete"'
[21] wi'*onExit'
'Common"onExit"'
[22] wi'*onExitError'
'Common"onExitError"'
[23] wi'*onMove'
'Common"onMove"'
[24] wi'*onResize' "TPicture'onResize'"
[25] wi'clipsiblings'1
[26]
[27] :case'onResize'
[28] wi'*imagesize'(wi'*size')
[29]
[30] :case'Action'
[31] :selectwarg
[32] :case'class'
[33] wres'TPicture'
[34]
[35] :case'?bitmap'
[36] wres"Get
or Set the bitmap file name for the TPicture object"
[37] wreswres,tcnl,"Syntax: 'object'wi'bitmap'filename"
[38] wreswres,tcnl,"filename: a
.BMP file name"
[39] :case'bitmap'
[40] :if
1=½warg
[41] wreswi'*bitmap'
[42] :else
[43] C2warg
[44] :if~/':\'¹C
[45] C(wi'installdir'),C
[46] :end
[47] wi'*bitmap'C
[48] wi'*bitmap'C
[49] wi'*style'4
[50] :end
[51]
[52] :case'?AdjustSize'
[53] wres'Forces
TPicture object to get the exact image size'
[54] wreswres,tcnl,"Syntax: 'object'wi'AdjustSize'"
[55] :case'AdjustSize'
[56] :if~0Fwi'*bitmap'
[57] (C
D)wi'GetBitmapSize'F
[58] wi'*suppress'1
[59] wi'*size'C
D
[60] wi'*imagesize'(wi'*size')
[61] wi'*suppress'0
[62] :end
[63]
[64] :else
[65] wreswi'*'
[66] :end
[67] :else
[68] error'Unknown
TPicture command: ',B
[69] :end
To create an instance of the TPicture object we may use:
0
0½'ff'wi'Create' 'Form'('scale'5)('caption'
'TPicture Example')('where'30.0625 85.25 11.5625 29.5)
0
0½'ff.pic'wi'Create' 'TPicture'('where'5 5)
Now let’s invoke the bitmap property:
'ff.pic'wi'bitmap'
'skating.bmp'
and now the AdjustSize method:
'ff.pic'wi'AdjustSize'
So it’s possible to create new objects
and manipulate them with the wi system functions as if they were internal APL+Win objects.
Moreover, if we did not remember about
a property or method syntax, we can always do:
'ff.pic'wi'?bitmap'
Get
or Set the bitmap file name for the TPicture object
Syntax: 'object'wi'bitmap'filename
filename:
a .BMP file name (path may be omitted if install directory)
'ff.pic'wi'?AdjustSize'
Forces
TPicture object to get the exact image size
Syntax: 'object'wi'AdjustSize'
as long as we have added the object
property and method documentation within our object
as done in lines 35-38 and 52-54.
Finally, all objects inheriting from TObject, they may call any property or method resigstered within TObject, in particular the Properties and Methods which inform about the properties and methods
in any object:
'ff.pic'wi'Properties'
bitmap
'ff.pic'wi'Methods'
AdjustSize
Thus, at any time, you may know the
object specific properties and method names and then
query how to use such properties and methods. This
means that objects are always auto-documented and
this makes them very simple to use.
For all this to work, you need to:
- Register your object to the APL+Win system
This is done by adding your object to the newclasses property of the system object:
'#'wi'newclasses'(('#'wi'newclasses'),'TPicture')
- Use the following instruction:
'#'wi'*onNew'
'OnNew'
In conjunction with the following utility:
OnNew
[1] © OnNew -- Handler for all new classes
[2] © The class handler function must have
the same name as the class
[3] © Example: object 'TForm' must be handled
by function 'TForm'
[4]
[5] :if(warg)¹'#'wi'newclasses' © if
new class...
[6] warg,'"New"' © send
to class handler
[7] :end
This is the structure which has been
adopted for all objects in “APL+Win 3.6
Objects” and for all objects in the TF1 application.
Where does the APL+Win Grid fit in?
The APL+Win Grid is used literally everywhere in this application.
This application has been written to
be used by various TV channels including TF1. When
a marketing representative opens a channel database
he immediately sees a form with alerts being displayed
on the screen:
This display him everyday which proposals
to advertisers have become obsolete and should be
converted to real orders.
This is a simple use of an APL Grid
to display a list of records: but it is more flexible
to use than the Listview object for such a purpose.
Here are the instructions used to create
this Grid object:
Zwi'*.grid.Create' 'TGrid'('wherelc'30 0 '>>' '>>')('attach'1
2 3 4)('*xRows'E)('*xCols'F)('*xTabWidth'0)
Zwi'*.grid.xFontName'0 0'MS Sans Serif'
Zwi'*.grid.xFontName'¯1(¼F)'MS Sans Serif'
Zwi'*.grid.xFontName'(¼E)¯1'MS Sans Serif'
Zwi'*.grid.xFontSize'0 0 14
Zwi'*.grid.xFontSize'¯1(¼F)14
Zwi'*.grid.xFontSize'(¼E)¯1 14
Z(E+1)F½wi'*:Draw'('Font' 'MS Sans Serif'8 0'ansi')(('?Text'),,D)
Zwi'*.grid.xColSize'(¯1,¼F)(G30,16+¹1¨Z)
:if(E>0)^F>0
Zwi'*.grid.xColorBack'(¼E)(¼F)(E F½2560 255 255)
:end
Zwi'*.grid.xText'(¯1,¼E)(¯1,¼F)(((''),¼¯1+½D),AV2ANSI
D)
Zwi'*.grid.xAlign'0(¼F)(1
2 2 1 1 2)
Zwi'*.grid.xProtect'0 0 1
These instructions use the TGrid object which is a cover for APL.Grid,
capable of additional properties: wherelc and attach to position and size the grid and to resize it automatically when
its mother form is resized.
Then the next place where an APL grid
was needed was to display ad reservations per TV Program
and per week over the selected period of time. Here
it is:
Lines in this grid represent TV Programs
and columns represent weeks. The Grid cells do not
contain texts but their color represent
the level of booking for the corresponding TV program
within the concerned week.
White means that the TV Program is not yet booked.
Pink and Red means that the TV Program has been sold.
Green means that one or more advertisers have taken a booking option on
the Program.
Yellow means that several main advertisers have booked the program.
TF1 wanted to be able to represent the
fact that the some TV Program dates were not yet firmly
decided.
Since this could happen for all TV Programs
level of bookings we could not use another color. Instead we needed a mean to add this additional information
over the currently colored cells.
Happily the APL Grid allows to display
small images in cell corners and we have used this
feature extensively. When the TV Program date is
yet temporary, we display a blue triangle in its upper
left corner.
This is done with the following instructions:
images1 2 3 4°.×26 13[1+mcol2]
wi'*.grid.Image'(1 2 3 4)(¼1½mcol2)(¼1½mcol2)images
mcol2 being
the boolean APL matrix indicating if the TV Programs are temporary
or not.
Also note that we used the APL Grid Join method to display titles above group of columns. This
is done with the following instructions:
X+\1,¯1Y½¨weeksn
(S T)split 0 100monthsn
Swi('Av2Ansi'),('Jan'
'Fév' 'Mar' 'Avr' 'Mai' 'Jun' 'Jul' 'Aug' 'Sep' 'Oct'
'Nov' 'Déc')[T],¨¯2¨¨S
:for I :in ¼½weeksn
:if 1<IY
wi'*.grid.Join'¯3(IX)1(IY
:end
wi'*.grid.text'¯3(IX)(IS)
:end
where weeksn is a nested vector of week numbers per months:
]display 2weeksn
.
--------------------------------------------------.
|.
------------..
---------------------------------.|
||200138 200139||200140 200141 200142 200143 200144||
|'~------------''~---------------------------------'|
'¹--------------------------------------------------'
and where monthsn is the corresponding list of months:
]display 2monthsn
.
------------.
|200109 200110|
'~------------'
TF1 wanted the application to automatically
display dynamic information when the mouse cursor
was hovering grid cells.
So I used one of my objects, called TTipForm, which was able to display a form with a shade and no title bar and
no border. I used the onXCellMouseEnter and onXCellMouseLeave events to show and then hide the TTipForm objects. My TTipForm object was a simple form with a Listview object using the entire client area of the
form.
The tip forms were entirely dynamic,
i.e. their sizes were calculated depending on their
content which was itself depending on the cells.
All that worked fine, but quickly TF1
requested that the tip form could display various colors in their various columns.
In order to do so, and thanks to Object
technology, I merely had to change one property of
the TTipForm object
to now use a Grid object instead of a Listview object.
Here are a few examples of tip forms
displayed when hovering various cells with the mouse
cursor:
or:
or
In these cases, an APL.Grid object
was created with no border, no grid lines, various
background colors for the
various columns, various font colors for
the various columns and column width was calculated
depending on the largest text in the column.
The tip form grids are created using
the following instructions:
Zwi'*.grid.Create' 'APL.Grid'('*scale'5)('*where'0 0 L M)('*border'0)('*edge'0)
Zwi'*Set'('*.grid.xGuideLines'0)('*.grid.xColorGrid'0)
Zwi'*Set'('*.grid.xHeadCols'0)('*.grid.xHeadRows'0)
Zwi'*Set'('*.grid.xTabWidth'0)
Zwi'*Set'('*.grid.xRows'P)('*.grid.xCols'Q)
Zwi'*Set'('*.grid.xText'(¼P)(¼Q)D)('*.grid.xAlign'(¼P)(¼Q)8)
Zwi'*Set'('*.grid.xRowSize'(¼P)(14))('*.grid.xColSize'(¼Q)(J+13-(½J)1))
Zwi'*Set'('*.grid.xFontSize'(¼P)(¼Q)14)('*.grid.xColorText'0 1(256255
255 255))
Zwi('*size'),1+(C D)L M+wi'*shadedepth'
Zwi('*size'),(C D)
Another part of the application using
a Grid object was the Day Grid. Similar to the Weeks
grid, it displays the various booking levels per TV
program and per day. Here it is:
Note the various column header groupings,
each week days being under the week header (S38, S39,
S40, etc.) and the various weeks of a given month
being under the month header (Sep01, Oct01, etc.)
This application included still 2 other
types of grids: the DayPart grid,
showing the various levels of TV program ad bookings
per month and day of the weeks.
This particular grid is showing the
various possible TV programs for a given day and hour
knowing that there may be more than one.
Finally a special grid has been added
to the application to display what TF1 calls “Programmes
Courts” i.e. Short Programs, usually of less than
5 minutes like the Weather Forecasts which are also
sponsored by advertisers.
This grid displays these Short Programs
per hour of the day and per day of the week.
Here is the Short Programs grid:
This application is used on the company
network and is used by about 50 users. TF1 wanted
a mean to maintain a database of these users and the
possibility to grant them some rights.
Guess what we’ve used for this purpose?
A grid of course. But this time we
have used the possibility to include check boxes in
grid cells: this was handy since one may grant or
not grant a given right to a user and this could easily
be expressed by checking or unchecking a
check box.
Here is the grid we’ve used:
The code used to create this grid is
the following one:
wself'fmUsers.grid'wi'Create' 'APL.Grid'('scale'5)('border'1)('where'0
0,'fmUsers'wi'size')
wi'Set'('xHeadRows'2)('xHeadCols'1)('xRows'R)('xCols'C)
wi'onXCellMouseUp' 'TUsers_Handlers'
:if wi'*newgrid'
wi'onXEditKeyPress' 'TUsers_Handlers'
:end
wi'Set'('xJoin'¯2 1 1 D)('xJoin'¯2(D+1)1(C-D))('xTabWidth'0)
wi'xText'¯2(1(D+1))(1 2½AV2ANSI¨'Caractéristiques
Utilisateur' 'Droits Utilisateur')
wi'xText'¯1(¼C)(1
C½AV2ANSI¨'Nom réseau' 'Nom' 'Prénom' 'Abbréviation'
'Admin' 'Dispo' 'Bilbao' 'Alertes' 'Portable')
wi'xText'(¼R)¯1(R
1½¼R)
wi'Set'('xFontName'0
0'Arial')('xFontName'(¯2 ¯1)(¼C)'Arial')
wi'Set'('xFontName'(¼R)¯1'Arial')
wi'Set'('xFontSize'0
0 14)('xFontSize'(¯2 ¯1)(¼C)14)('xFontSize'(¼R)¯1
14)
wi'xAlign'(¼R)(D+¼C-D)4
wi'xCellType'(¼R)(D+¼C-D)2 © check boxes
wi'xRowSize'(¼R)16
wi'xColSize'(¼C)(E127 180 110 65 40 40 40 40 40)
wi'*:oldsize'(W2'fmUsers'wi'*size')
wi'*sizedif'(W-+/3E)
wi'XRedraw'
Another place where a grid is used in
this application is the form which tracks User Connections. As
a matter of fact, we record every user connection
and disconnection within a database and the application
Administrators may view this kind of information at
any time.
Here is the User Connections grid:
This grid shows who used the application,
on which date, at which time and for how long and
records the number of Simulations the user has made.
Indeed, most of the users are TF1 Marketing
Representatives and they use the Week Grid we has
seen before to send automatic proposals to Advertisers.
They may use their mouse to select one
or more TV Programs, for one or more weeks, for which
their customers want to buy ads and then choose “New
Simulation” from the “File” menu to automatically
produce a proposal.
Since selecting programs with the mouse
is too complex for Marketing Representatives we created
an assisted mode to more easily select various TV
programs over various period of times.
Clicking on the Assist Mode check box
opens 3 more (yellow) columns in the week grid, where
they can enter for each concerned TV Programs:
- The ad campaign start week
- The ad campaign end week
- The number of weeks
The start week is required, but the
user my enter either the End Week or the Number of
Weeks and the system computes the third data.
Example:
Here they have selected 2 TV Programs: first “Attention à la Marche” for 6 weeks starting October 10 and “C’est quoi l’Amour” for
2 weeks starting October 22. Clicking on the “Show
Selection” (=Montrer la
selection) button shows in black what they have selected
within the grid.
The grid code used to compute the total
number of weeks when they are entering the End Week
date use the onXEditEnd event. During
this event, the dates in columns 1 and 2 (start and
end dates) are used to calculate the number of weeks
which is then displayed in column 3.
They can choose File/New Simulation (=Fichier/Nouvelle
Simulation) to start a new simulation.
This starts the TExcel object
which opens a pre-formatted Excel spreadsheet, fills
it with data retrieved from the application database,
including prices depending on TV Programs, period
of the year etc. All this is done automatically in
a couple of seconds and Marketing Representatives
have their proposal displayed in front of them in
a summary table.
The produced TExcel object
also contains one Excel sheet per selected TV Program
with more detailed data as shown on the next page.
Users may interact with the Excel sheet
by clicking various check boxes to include or exclude
rebates within their proposals.
The Excel worksheet contains Visual
Basic for Application code to handle internal calculations
within the Spreadsheet.
This is a good example of how APL can
nowadays coexist with other popular software like
Excel and VBA in real life applications.
Once again, this entire application
has been written with objects: many were pre built
objects from my “APL+Win 3.6 Objects” product, all the others being application
specific objects created for the sole purpose of this
application.
One of the decisions I had to take during
the development of this application, was the choice
of a printing technique to print the various grids.
How could I do that, knowing the APL
Grid had no XPrint method
available?
Since my customer wanted the grid print
outs to print in color and
resemble as much as possible to the grids on the screen
I decided to pilot Excel from APL to do the job.
Therefore I used my ”APL+Win 3.6
Objects” TExcel object.
As an example of how TExcel can be used to print the content of an APL+Win Grid
object, the next page displays PrintWeekGrid , the program which prints the Week Grid.
Although the PrintWeekGrid program may seem complex at first sight, it really is not. Basically,
it simply calls properties and methods built in the TExcel object or of its sub-objects.
Such a program takes between half a
day and a day to fully write and test.
It would be too long here to comment
the PrintWeekGrid program. However just a couple of notes: this program is using
a method called ApplyMatrixProperty (see lines 91 and 96) which I have
built into TExcel and allows to apply any Excel property to any
range of cells in one instruction.
This is very useful, because only APL
knows about matrices! If we want to set the background color of a range of cells in the APL Grid we can do so in
one instruction specifying the concerned lines and
columns and specifying a matrix of color codes. But
in Excel, we must write a double loop, looping on
lines and then on columns to apply the right color property
to each cell in the range. The ApplyMatrixProperty method is handy and prevents from
having to write all this loopy code.
PrintWeekGrid;A;B;C;D;E;F;G;H;I;J;K;L;M;N;O;P;Q;R;S;T;U;V;W;X;Y;Z;;AA;io;weeksn;Blanc;Violet;Vert;Rouge;Gris;Ver2;Viole2;Roug2;AB;Jaune
[1] © PrintWeekGrid -- Prints the week Grid using Excel
[2]
[3] io1
[4] 'pg.se.p3'wi'*pointer'11
[5] 'pg'wi'*pointer'11
[6] wgive 0
[7] Infod'Printing in progress...'
[8]
[9] © Get data for the report
[10] Rwi'*:GridRowTexts'
[11] Cwi'*:GridColTexts1'
[12] Dwi'*:GridColTexts2'
[13] O'pg.se.p3.grid'wi'*GridColors'
[14] wi'*:GridTriangles'
[15] (weeksn X Y S)wi'*:GridMerge'
[16] T(2+½C)V'oo'wi'SsColumns' © last occupied
column letter
[17] N8 © number of top lines
[18] UN+½R © last occupied row
[19]
[20] © Create an instance of TExcel
[21] :if 0¬½'ex'wi'self'
[22] 'ex'wi'*visible'0
[23] 'ex'wi'XQuit'
[24] 'ex'wi'*Delete'
[25] :end
[26] wself'ex'wi'*Create' 'TExcel'
[27] Zwi'*xDisplayAlerts'0
[28] Zwi'*onClose' '"ex"wi"XQuit" ª "ex"wi"*Delete"'
[29] Zwi'xDefaultFilePath' 'c:\my documents\dispo\simul\'
[30] Zwi'AddBook'1
[31] Zwi'Sheet'1
[32] :if wi'CheckPrinter' © check if a Printer is defined on this computer
[33] Zwi'sheetname' 'WeekGrid'
[34] Zwi'*caption' 'Grille Vendable (Semaines)'
[35]
[36] © Print Parameters
[37] Zwi'*.wksht.XPageSetup>',wself,'.pgsetup'
[38] Zwi'LeftMargin'1
[39] Zwi'RightMargin'1
[40] Zwi'TopMargin'1
[41] Zwi'BottomMargin'1
[42] Zwi'Orientation' 'landscape'
[43] Zwi'CenterHorizontally'1
[44] Zwi'PaperSize' 'A4'
[45] Zwi'*.pgsetup.xLeftMargin'0
[46] Zwi'*.pgsetup.xRightMargin'0
[47] Zwi'*.pgsetup.xFooterMargin'.5
[48] Zwi'*.pgsetup.xLeftHeader'(wi'Av2Ansi' '&07 &"Verdana" &G
DISPO - Sources : Sylvie TIRABOSKI [13237]')
[49] Zwi'*.pgsetup.xRightFooter'(wi'Av2Ansi' '&07 &"Verdana" &G
Page &P/&T')
[50] Zwi'*.pgsetup.xHeaderMargin'.5
[51] Zwi'*.pgsetup.xRightHeader'(wi'Av2Ansi' '&07 &"Verdana" &G &J &H')
[52] Zwi'FitToPagesWide'2
[53] Zwi'FitToPagesTall'2
[54] Zwi'PrintTitleRows'('A1:A',N)
[55] Zwi'PrintTitleColumns' 'A1:B1' © repeat column 1 on
each page
[56] Zwi'*.pgsetup.xCenterHeader'(wi'Av2Ansi'('&G &14 &"Verdana" Grille
Vendable (Semaines)',tcnl,('pg.DAYPART'wi'*text')))
[57]
[58] © Set columns widths
[59] Zwi'Range' 'B1'
[60] Zwi'ColumnWidth'30
[61] Zwi'Range'('A1;C1:',T,'1')
[62] Zwi'ColumnWidth'4
[63]
[64] © Install row headings
[65] Zwi'Add'('A',N+1)((¨¼½R),[1.5]R)
[66] Zwi'HAlign' 'right'
[67]
[68] © Install column headings
[69] Zwi'Add'('C',N-1)((1,½C)½C)
[70] Zwi'HAlign' 'center'
[71] Zwi'Add'('C',N)((1,½D)½D¨D)
[72] Zwi'HAlign' 'center'
[73]
[74] © Column headings in merged cells
[75] :for I :in¼½X
[76] Zwi'Range'((N-2)(2+IX)1(IY))
[77] Zwi'*.rng.Merge'
[78] Zwi'Add'((N-2)(2+IX))(IS)
[79] Zwi'HAlign' 'center'
[80] :end
[81]
[82] © Handling colors
[83] P½O ª O,O
[84] (Vert Violet Rouge
Blanc Gris Jaune)256¨²¨(0 255 0)(255 0
255)(255 0 0)(255 255 255)(192 192 192)(255 255 0)
[85] (Ver2 Viole2 Roug2)256¨²¨('pg')wi¨'ColorGreen'
'ColorPurple' 'ColorRed'
[86] OP½(Vert Violet Rouge,O)[(Ver2 Viole2 Roug2,O)¼O]
[87]
[88] © Install cell colors
[89] Zwi'Range'('A',(N+1),':B',(U),';B',(N-2),':',T,N)
[90] Zwi'BackColor'(256192 192 192) © row & column
headings colors
[91] Ewi'ApplyMatrixProperty' 'BackColor'((N+1)3)(0 3O) © body
colors
[92] Ewi'Range'('A',(N-2),':B',N)
[93] Ewi'BackColor'(256255 255 255) © top left cell
colors
[94]
[95] © Legend
[96] Ewi'ApplyMatrixProperty' 'BackColor'(2 1)(5 1½Blanc Violet
Vert Rouge Jaune)
[97] Zwi'Add'(2 2)(6 1½'oo'wi'Av2Ansi' ' Disponible'
' Vendue à un Co-Partenaire Presse' ' Optionnée' '
Vendue' ' Multi-Sponsor Principal' ' Date Provisoire') © LES14jun01
added
[98] Zwi'Range' 'B2:B7'
[99] Zwi'FontSize'9
[100] Zwi'Range' 'A7'
[101] Zwi'FontName' 'Wingdings 3'
[102] Zwi'FontColor'(256255 0 0) © blue triangle
[103] Zwi'Add'(7 1)(1 1½,av[123]) © av[123]
in WingDings3 is Upper Left Triangle symbol
[104] Zwi'Range' 'A2;A3;A4;A5;A6;A7'
[105] Zwi'Border'1 2 © borders for "legend" colors
[106]
[107] © Print upper left triangles
[108] Zwi'Range'('C',(N+1),':',T,U) © grid
content
[109] Zwi'FontName' 'Wingdings 3'
[110] Zwi'FontColor'(256255 0 0) © triangles must be
blue
[111] Zwi'Add'((N+1)3)(,¨av[33 123[1+]])
[112] © Note: av[123] in WingDings3 is Upper Left Triangle symbol
[113]
[114] © Cell borders & border colors
[115] Zwi'Range'('A',(N+1),':',T,U) © select
grid content itself
[116] Zwi'GridLines'1(256255 255 255)
[117] Zwi'Range'('C',(N-2),':',T,N) © select
column titles
[118] Zwi'GridLines'1(256255 255 255)
[119]
[120] © Finish report, make it visible & Print Preview
[121] Info''
[122] Zwi'visible'1
[123] Zwi'*.wkbk.PrintOut'1 1000 1 1
[124] 'pg.se.p3'wi'*pointer'1
[125] 'pg'wi'*pointer'1
[126] :else
[127] 'pg.se.p3'wi'*pointer'1
[128] 'pg'wi'*pointer'1
[129] Infod''
[130] Z'!'Ok"You must first define a printer!"
[131] :end
[132]
[133]
I believe that APL+Win Release
4 now contains a utility workspace which allows to
print the content of an APL Grid. I have used a Beta
Version of it and it does a real nice job: it’s also
a very interesting piece of software to study.
However, the resulting printout is not
as perfect as what you can obtain by subcontracting
the Excel print engine to work for you. But it is
certainly faster and easier to use.
Printing the Grids with a Screen Capture
Utility
In this application, there was also
the need for printing parts of the screen.
For this purpose, TF1 Publicité has
acquired a Site License for an excellent and extremely
useful utility called SPX Instant Screen Capture (SPX
hereafter) from MoodySoft.
SPX is a utility which gets installed
in the Tray icon and lets you capture any part of
your screen, using your mouse and send this to:
- A file (.BMP or .GIF or .JPG)
- The Clipboard
- A Printer or Fax
- A Mail system
- A Graphics Editor
When you right click on the SPX icon
at the bottom right of your screen, a hierarchical
menu helps you choose parameters and configure the
software. Many options are possible.
To capture any part of your screen,
simply press the right mouse button for a second or
two until the cursor changes for a cross cursor. Then,
click the left mouse button and drag the mouse to
define the rectangular area you want to capture.
As soon as you release the left mouse
button the part of your screen contained