Green-screen Chart/Graph
Contents
Green-screen Chart/Graph
Background
It is sometimes useful to display a graph of values on the AS400 green-screen. Although there are commercial products available for the AS400, these are often difficult to use and not available everywhere. This product was designed to allow for a simple text-based line-graph to be displayed on the screen. It will take a data-structure from another program, and build up the screen accordingly.
The program has been written to work correctly on either a wide screen (27x132) or a normal screen(24x80).
Screen Layout
- a. This is the header as passed to the program
- b. This is the Y-label, as passed to the program
- c. The Y-axis values will be build based on the chart type or the chart calc function
- d. If the number of data points exceed the screen width, the program will create additional pages. Page Up/Down will show the rest of the entries. If you want to jump to the 1st page, press F17, or last page press F18.
- e. If you position your cursor on any data item/column, and press F1, the program will display information about the data point
Objects
The following objects will be used by the program:
- a. GENCHART#D - Display File
- b. GENCHART#R – RPG Program
GenChart Program Parameters
The GENCHART#R program requires the following parameters:
- a. Data structure (see point 4):
- - The data structure will be passed from your program, to the GENCHART#R program, by using pointers. When you call the program, the variable has to use %ADDR(DSNAME).
- b. Heading:
- - Char (100).
- - The heading you need for your chart
- c. Y-Axis Label:
- - Char(30)
- - Here you can specify a label for the Y-Axis.
- - Label will be affected by the Chart Type variable
- d. Total Items:
- - Int(10)
- - Specify the number of values to be passed via the DataStructure
- e. Max Value:
- - Packed(31:2)
- - Specify the Maximum value. This is needed to determine the sizing of the bars
- f. Chart Type
- - Char(10)
- - Allows for two types of charts. Can be either
- *PCT: Determine %, betwee max value and actual value
- *NORMAL: Display the values on the screen as they are
- g. Chart Calc:
- - Char(10)
- - If the values are too big, the program can scale them. Allowed values are:
- *NONE – Keep the values as is
- *TB – Scale the values in Terrabytes
- *GB – Scale the values in Gigabytes
- *KB – Scale the values in Megabytes
- *KB – Scale the values in Kilobytes
RPG Program Usage
In order to use the GENCHART functionality inside your RPG program, the following is needed:
- a. Data structure: A datastructure has to be passed onto the calling program. This data structure HAS to use the following definitions:
- - The DataStructure must be limited to 9999 entries.
- - Field 1 is a description field, 30 chars long. It will be used for the X-Axis
- - Field 2 is a numeric field, packed 31:2.
*====================================================================* dcl-ds TestDS qualified dim(9999); wDescription char(30); wDataItem packed(31:2); end-ds; *====================================================================*
- b. GenChart Prototype: Add the prototype for the external program:
*====================================================================* dcl-pr GenChart extpgm('GENCHART#R'); p_InputDS pointer const; p_Heading char(100) const; p_Ylabel char(30) const; p_TotalItems like(TInt) const; p_MaxValue packed(31:2) const; p_ChartType char(10) const; p_YCalc char(10) const; End-pr; *====================================================================*
- c. Clear the data structure: You have to clear the data structure before you use it, to ensure it does not contain null values.
*====================================================================* clear TestDS; *====================================================================*
- d. Build up your SQL String:
- - Limit your data to 9999 entries, either in the SQL String or in the fetch statement
- - Use casting in SQL to ensure the data match the data structure
*====================================================================* SQLString = 'SELECT cast( ADATE as char(30)) as "WorkDate", cast(aspsizusd as '+ 'decimal(31,2)) as "Value" FROM aspinf#p order by aDate'; *====================================================================*
- e. Prepare the SQL cursor now:
- - Use SQL diagnostics to determine the number of records returned
*====================================================================* exec sql Prepare SQLGET1 from :SqlString; exec sql declare IntCursor1 insensitive cursor for SQLGet1; exec sql Open IntCursor1; exec sql get diagnostics :wRecCount = DB2_NUMBER_ROWS; *====================================================================*
- f. Fetch the data:
*====================================================================* exec sql fetch IntCursor1 for 9999 rows into :TestDs; // Cose the Cursor exec sql close Intcursor1; *====================================================================*
- g. Determine the maximum size for the range:
*====================================================================* exec sql select max(aspsiztot) into :wMaxValue from ASPINF#P; *====================================================================*
- h. Generate the chart now:
*====================================================================* GenChart(%addr(TestDs):'ASP Information - % Usage':'% Storage': wRecCount:wMaxValue:'*PCT':'*NONE'); GenChart(%addr(TestDs):'ASP Information':'Size in GB':wRecCount: wMaxValue:'*NORMAL':'*NONE');
Example program
THIS SOURCE CODE IS PROVIDED AS IS, USE IT AT YOUR OWN RISK!'
CTL-OPT COPYRIGHT('Pieter Henrico') DATFMT(*ISO) TIMFMT(*HMS:) DFTACTGRP(*NO) OPTIMIZE(*NONE) OPTION(*NODEBUGIO) USRPRF(*USER) TEXT(*SRCMBRTXT) CopyNest(128) BndDir('QC2LE') Thread(*Serialize); *================================================================ * Declare files here *================================================================ // File Description here 0 *================================================================ * Copy Programs *================================================================ * Setup *Entry Parameters *================================================================ dcl-pr TESTCHART# extpgm('TESTCHART# '); end-pr; dcl-pi TESTCHART# ; end-pi; * ------------------------------------------------------------------------ dcl-s wRecCount int(10) inz(0); dcl-s SqlString char(5000); dcl-s wCur int(10) inz(1); dcl-s wMaxValue packed(31:2) inz(0); *====================================================================* dcl-ds TestDS qualified dim(9999); wDescription char(30); wDataItem packed(31:2); end-ds; *====================================================================* dcl-pr GenChart extpgm('GENCHART#R'); p_InputDS pointer const; p_Heading char(100) const; p_Ylabel char(30) const; p_TotalItems int(10) const; p_MaxValue packed(31:2) const; p_ChartType char(10) const; p_YCalc char(10) const; End-pr; *====================================================================* * Mainline * *====================================================================* *================================================================ * Check if the data files are available *================================================================ Clear TestDS; // Build up the SQL String Exec SQL Set Option DatFmt = *ISO; SQLString = 'SELECT cast( ADATE as char(30)) as "WorkDate", cast(aspsizusd as '+ 'decimal(31,2)) as "Value" FROM aspinf#p order by aDate'; // ================================================================ // Prepare the SQL here // ================================================================ exec sql Prepare SQLGET1 from :SqlString; exec sql declare IntCursor1 insensitive cursor for SQLGet1; exec sql Open IntCursor1; exec sql get diagnostics :wRecCount = DB2_NUMBER_ROWS; // ================================================================ // Fill the datastructure // ================================================================ exec sql fetch IntCursor1 for 9999 rows into :TestDs; // Cose the Cursor, as it will be recreated exec sql close Intcursor1; exec sql select max(aspsiztot) into :wMaxValue from ASPINF#P; SndstsMsg('Loading Chart 1...'); GenChart(%addr(TestDs):'ASP Information - % Usage':'% Storage': wRecCount:wMaxValue:'*PCT':'*NONE'); GenChart(%addr(TestDs):'ASP Information':'Size in GB':wRecCount: wMaxValue:'*NORMAL':'*NONE'); // ================================================================ // Program ends here // ================================================================ *InLR = *On; return;
GENCHART#D - Source code
THIS SOURCE CODE IS PROVIDED AS IS, USE IT AT YOUR OWN RISK!
A*%%TS SD 20210608 135832 REKA REL-V7R3M0 5770-WDS A*%%EC A DSPSIZ(27 132 *DS4 - A 24 80 *DS3) A INDARA A R MAIN A*%%TS SD 20210607 181701 REKA REL-V7R3M0 5770-WDS A CF03(03 'Exit') A PAGEDOWN(40 'PageDown') A PAGEUP(41 'PageUP') A CF01(01 'Info') A CF18(18 'Last Page') A CF17(17 'First Page') A RTNCSRLOC(*RECNAME &CSRREC &CSRFLD) A RTNCSRLOC(*MOUSE &CSRROW &CSRCOL) A CSRLOC(ROWPOS COLPOS) A OVERLAY A PRINT A CSRFLD 10A H A CSRREC 10A H A COLPOS 3S 0H A ROWPOS 3S 0H A CSRROW 3S 0H A CSRCOL 3S 0H A HLINE 120 O 1 7DSPATR(HI) A DLINE01 131A O 3 1 A DLINE02 131A O 4 1 A DLINE03 131A O 5 1 A DLINE04 131A O 6 1 A DLINE05 131A O 7 1 A DLINE06 131A O 8 1 A DLINE07 131A O 9 1 A DLINE08 131A O 10 1 A DLINE09 131A O 11 1 A DLINE10 131A O 12 1 A DLINE11 131A O 13 1 A DLINE12 131A O 14 1 A DLINE13 131A O 15 1 A DLINE14 131A O 16 1 A DLINE15 131A O 17 1 A DLINE16 131A O 18 1 A DLINE17 131A O 19 1 A DLINE18 131A O 20 1 A DLINE19 131A O 21 1 A DLINE20 131A O 22 1 A DLINE21 131A O 23 1 A DLINE22 131A O 24 1 A DLINE23 131A O 25 1 A DLINE24 131A O 26 1 A YDESC 40 O 2 1COLOR(BLU) A FLINE1 50A O 27 82DSPATR(HI) A 27 1'F1=Item Info' A COLOR(BLU) A 27 16'F3=Exit' A COLOR(BLU) A 27 26'F17=First Page' A COLOR(BLU) A 27 43'F18=Last Page' A COLOR(BLU) A R INFO A*%%TS SD 20210608 134900 REKA REL-V7R3M0 5770-WDS A CF03(03 'Exit') A *DS4 WINDOW(7 34 11 60 *NOMSGLIN) A *DS3 WINDOW(7 10 11 60 *NOMSGLIN) A 1 23'Item Information' A DSPATR(HI) A 3 3'Page..............:' A 4 3'Values............:' A 5 5'-' A WSDETAIL1 52A O 5 7DSPATR(HI) A 6 5'-' A WSDETAIL2 52A O 6 7DSPATR(HI) A 7 5'-' A WSDETAIL3 52A O 7 7DSPATR(HI) A 8 5'-' A WSDETAIL4 52A O 8 7DSPATR(HI) A* 9 5'-' A* WSDETAIL5 52A O 9 7DSPATR(HI) A WSPAGE 35A O 3 24DSPATR(HI) A 9 5'-' A WSDETAIL5 52A O 9 7DSPATR(HI) A 11 4'F3=Exit' A COLOR(BLU) A R MAIN2 A*%%TS SD 20210608 093006 REKA REL-V7R3M0 5770-WDS A CF03(03 'Exit') A PAGEDOWN(40 'PageDown') A PAGEUP(41 'PageUP') A CF01(01 'Info') A CF18(18 'Last Page') A CF17(17 'First Page') A RTNCSRLOC(*RECNAME &CSRREC &CSRFLD) A RTNCSRLOC(*MOUSE &CSRROW &CSRCOL) A DSPMOD(*DS3) A CSRLOC(ROWPOS COLPOS) A OVERLAY A PRINT A CSRFLD 10A H A CSRREC 10A H A COLPOS 3S 0H A ROWPOS 3S 0H A CSRROW 3S 0H A CSRCOL 3S 0H A H2LINE 70A O 1 7DSPATR(HI) A D2LINE01 78A O 3 1 A D2LINE02 78A O 4 1 A D2LINE03 78A O 5 1 A D2LINE04 78A O 6 1 A D2LINE05 78A O 7 1 A D2LINE06 78A O 8 1 A D2LINE07 78A O 9 1 A D2LINE08 78A O 10 1 A D2LINE09 78A O 11 1 A D2LINE10 78A O 12 1 A D2LINE11 78A O 13 1 A D2LINE12 78A O 14 1 A D2LINE13 78A O 15 1 A D2LINE14 78A O 16 1 A D2LINE15 78A O 17 1 A D2LINE16 78A O 18 1 A D2LINE17 78A O 19 1 A D2LINE18 78A O 20 1 A D2LINE19 78A O 21 1 A D2LINE20 78A O 22 1 A D2LINE21 78A O 23 1 A Y2DESC 40A O 2 1COLOR(BLU) A F2LINE1 27A O 24 52DSPATR(HI) A 24 1'F1=Item Info' A COLOR(BLU) A 24 15'F3=Exit' A COLOR(BLU) A 24 24'F17=1st Page' A COLOR(BLU) A 24 38'F18=Last Page' A COLOR(BLU) A R ERRSCREEN A*%%TS SD 20210608 135832 REKA REL-V7R3M0 5770-WDS A CF03(03 'Exit') A *DS4 WINDOW(10 46 4 40 *NOMSGLIN) A *DS3 WINDOW(10 20 5 40 *NOMSGLIN *NORSTC- A SR) A 1 15' ERROR! ' A COLOR(RED) A DSPATR(RI) A 3 4' There is no data to display! ' A DSPATR(HI) A DSPATR(RI)
GENCHART#R - Source Code
*================================================================ *šProgram Name:‚GENCHART#R *šAuthor :‚REKA - Pieter Henrico *šDate :‚2021-06-02 *================================================================ *šPurpose of program:‚ * * * * Before compile: * *THIS SOURCE CODE IS PROVIDED AS IS, USE IT AT YOUR OWN RISK! * *================================================================ //== A M E N D M E N T S == //======================================================================= //== DD.MM.YYYY Name Description //== //== //== //== *================================================================ CTL-OPT COPYRIGHT('Pieter Henrico') DATFMT(*ISO) TIMFMT(*HMS:) DFTACTGRP(*NO) OPTIMIZE(*NONE) OPTION(*NODEBUGIO) USRPRF(*USER) TEXT(*SRCMBRTXT) ALWNULL(*USRCTL) CopyNest(128) Thread(*Serialize); *================================================================ *š Declare files here *================================================================ // File Description here dcl-f GENCHART#D workstn indds(Indicators1); *================================================================ *š Copy Programs *================================================================ *======================== *ENTRY ================================ *š Setup *Entry Parameters *================================================================ dcl-pr GENCHART#R extpgm('GENCHART#R '); p_InputDS pointer; p_Heading char(100); p_YLabel char(30); p_TotalItems int(10); p_MaxVal packed(31:2); p_ChartType char(10); p_YCalc char(10); end-pr; dcl-pi GENCHART#R ; p_InputDS pointer; p_Heading char(100); p_YLabel char(30); p_TotalItems int(10); p_MaxVal packed(31:2); p_ChartType char(10); p_YCalc char(10); end-pi; *================================================================ *š Declare data structures and variables here *================================================================ * ------------------------------------------------------------------------ /if not defined(#INDICATORS) /define #INDICATORS dcl-ds Indicators1; InfoRequest ind pos(1) ; ExitPgm ind pos(3) ; FirstPage ind pos(17); LastPage ind pos(18); PageDown ind pos(40) ; PageUp ind pos(41) ; end-ds ; /Endif dcl-s wDetailLine char(130) dim(24); dcl-s wLine int(10); dcl-s wTempLine char(130); dcl-s wColumn int(10); dcl-s wPage int(10); dcl-s wDetailX char(30) dim(140); dcl-s wDetailValue packed(15:2) dim(140); dcl-ds dsData qualified based(wPointer) dim(9999); wXData char(30); wDataItem packed(31:2); end-ds; dcl-s wPointer pointer; dcl-s wMax packed(31:2); dcl-s wCount int(10) inz(0); dcl-s wStrCol int(10) inz(0); dcl-s wDeterminePages ind inz('0'); dcl-s wTotalPages int(10) inz(0); dcl-ds dsPage qualified dim(200); Start int(10); End int(10); Entries int(10); End-Ds; dcl-s wLineStr int(10) inz(0); dcl-s wLastCol int(10) inz(0); dcl-s wScreenLarge ind inz('0'); dcl-c wCol_White const(X'22'); //============================================================== Dcl-PR QsnQryModSup Int(10:0) extProc('QsnQryModSup'); mode Char(1) const; modeAllowed Char(1) options(*OMIT); llhandle Int(10:0) const options(*OMIT); error Char(16) options(*varsize:*OMIT); End-PR; Dcl-C DS4_MODE '4'; Dcl-C MODE_ALLOWED 1; *====================================================================* * Mainline * *====================================================================* wPointer = p_InputDS; wPage = 1; wMax = p_MaxVal; ROWPOS = 0; COLPOS = 0; wScreenLarge = ScreenSizeIs132(); DoU ExitPgm = *On; Reset wDetailLine; Reset wDetailValue; Reset wDetailX; BuildScreen(wPage:wMax:p_TotalItems:p_YLabel:p_ChartType:p_YCalc); If wScreenLarge = *On; hLine = CenterText(%trim(p_Heading):%len(hLine)); If p_TotalItems > 0; exfmt main; Else; write main; exfmt ErrScreen; ExitPgm = *On; EndIf; Else; h2Line = CenterText(%trim(p_Heading):%len(h2Line)); If p_TotalItems > 0; exfmt main2; Else; write main2; exfmt ErrScreen; ExitPgm = *On; EndIf; EndIf; If ExitPgm = *Off; If wScreenLarge = *On; wLastCol = wPage*(130-wLineStr); Else; wLastCol = wPage*(78-wLineStr); EndIf; select; when PageUp = *On and wPage > 1; wPage = wPage - 1; When PageDown = *On and wPage < wTotalPages; wPage = wPage + 1; When FirstPage = *On; wPage = 1; FirstPage = *Off; When LastPage = *On; wPage = wTotalPages; LastPage = *Off; When InfoRequest = *On and CSRCOL >= wLineStr+1 and CSRCol - wLineStr <= dsPage(wPage).Entries; InfoRequest = *Off; If wScreenLarge = *On; wsPage = %trim(FLine1); Else; wsPage = %trim(F2Line1); EndIf; wsDetail1 = 'Heading: ' + %trim(p_Heading); wsDetail2 = 'X-Axis Label: ' + %trim(wDetailX(csrcol):'1'); wsDetail3 = 'X-Value: ' + %trim(%editc(wDetailValue(csrcol) :'1')); wsDetail4 = 'Max Value: ' + %trim(%editc(wMax:'1')); If wPage > 1; wsDetail5 = 'Data point: ' + %trim(%editc(dsPage(wPage-1).End+ csrcol-wLineStr:'1')); Else; wsDetail5 = 'Data point: ' + %trim(%editc(csrcol-wLineStr:'1')); EndIf; exfmt info; ROWPOS = CSRROW; COLPOS = CSRCOL; ExitPgm = *Off; EndSl; EndIf; EndDo; // ================================================================ // Program ends here // ================================================================ *InLR = *On; return; // ================================================================ dcl-proc BuildColumn; dcl-pi BuildColumn; pColumn int(10) value; pMaxValue int(20) value; pValue int(20) value; pXValue char(30) value; end-pi; dcl-s wLoopCount int(10) inz(0); dcl-s wChartValue int(10) inz(0); dcl-s wMaxRows int(10) inz(0); // If wScreenLarge = *On; wMaxRows = 23; Else; wMaxRows = 20; EndIf; wChartValue = %int((pValue/pMaxValue)*wMaxRows); wDetailValue(pColumn) = %dec(pValue:31:2); wDetailX(pColumn) = pXValue; If wChartValue > 0; For wLoopCount = wMaxRows downto (wMaxRows - wChartValue); If wLoopCount > 0; %subst(wDetailLine(wLoopCount):pColumn:1) = '|'; EndIf; EndFor; If wChartValue < wMaxRows; %Subst(wDetailLine(wMaxRows-wChartValue):pColumn:1) = '_'; Else; %Subst(wDetailLine(1):pColumn:1) = '_'; EndIf; EndIf; End-proc; // ================================================================ dcl-proc BuildYLines; dcl-pi BuildYLines int(10); pMaxValue int(20) value; pYType char(10) value; pYLabel char(30) value; pYCalc char(10) value; end-pi; dcl-s wLoopCount int(10) inz(0); dcl-s wDivisor int(10) inz(0); dcl-s wTempValue packed(15:2) inz(0); dcl-s wUnderLine char(130) inz(*all'-'); dcl-s wUnderLine2 char(130) inz(*all'_'); dcl-s wUnderLine3 char(130) inz(*all'='); dcl-s wLength int(10) inz(0); dcl-s wEndOfDesc int(10) inz(0); // yDesc = pYLabel; y2Desc = pYLabel; Select; When pYType = '*PCT' and wScreenLarge = *On; // Y-bar will be percentage wDetailLine(1) = '100% :' + wCol_White + %trim(wUnderLine); wDetailLine(6) = ' 75% :' + wCol_White + %trim(wUnderLine); wDetailLine(12) = ' 50% :' + wCol_White + %trim(wUnderLine); wDetailLine(17) = ' 25% :' + wCol_White + %trim(wUnderLine); wDetailLine(23) = ' 0% :' + wCol_White + %trim(wUnderLine2); wDetailLine(24) = ' ' + %trim(wUnderLine3); For wLine = 1 to 23; %subst(wDetailLine(wLine):7:2) = ':' + wCol_White; Endfor; wEndOfDesc = 8; When pYType = '*NORMAL' and wScreenLarge = *On; // Determine Min/Max/25%/50%/75% select; //1234567890123 when pMaxValue >= 1000000000000 and pYCalc = '*TB'; wDivisor = 1024*1024*1024*1024; yDesc = 'Size in TB'; when pMaxValue >= 1000000000 and pYCalc = '*GB'; wDivisor = 1024*1024*1024; yDesc = 'Size in GB'; when pMaxValue >= 1000000 and pYCalc = '*MB'; yDesc = 'Size in MB'; wDivisor = 1024*1024; when pMaxValue >= 1000 and pYCalc = '*KB'; yDesc = 'Size in KB'; wDivisor = 1024; Other; wDivisor = 1; EndSl; wLength = %len(%trim(FormatNumber(%dec(pMaxValue/wDivisor:31:2)))); wEndOfDesc = wLength + 4; wDetailLine(1) = %trim(FormatNumber(%dec(pMaxValue/wDivisor:31:2))); %subst(wDetailLine(1):wEndOfDesc+1:131-wEndOfDesc-1) = %trim(wUnderLine); wDetailLine(6) = %trim(FormatNumber(%dec(pMaxValue/wDivisor*0.75:31:2))); %subst(wDetailLine(6):wEndOfDesc+1:131-wEndOfDesc-1) = %trim(wUnderLine); wDetailLine(12) = %trim(FormatNumber(%dec(pMaxValue/wDivisor*0.50:31:2))); %subst(wDetailLine(12):wEndOfDesc+1:131-wEndOfDesc-1) = %trim(wUnderLine); wDetailLine(17) = %trim(FormatNumber(%dec(pMaxValue/wDivisor*0.25:31:2))); %subst(wDetailLine(17):wEndOfDesc+1:131-wEndOfDesc-1) = %trim(wUnderLine); wDetailLine(23) = '0'; %subst(wDetailLine(23):wEndOfDesc+1:131-wEndOfDesc-1) = %trim(wUnderLine2); %Subst(wDetailLine(24):wEndOfDesc+1:131-wEndOfDesc-1)= %trim(wUnderLine3); For wLine = 1 to 23; %subst(wDetailLine(wLine):wEndOfDesc-1:2) = ':' + wCol_White; Endfor; When pYType = '*PCT' and wScreenLarge = *Off; // Y-bar will be percentage wDetailLine(1) = '100% : ' + %trim(wUnderLine); wDetailLine(5) = ' 75% : ' + %trim(wUnderLine); wDetailLine(10) = ' 50% : ' + %trim(wUnderLine); wDetailLine(15) = ' 25% : ' + %trim(wUnderLine); wDetailLine(20) = ' 0% : ' + %trim(wUnderLine2); wDetailLine(21) = ' ' + %trim(wUnderLine3); For wLine = 1 to 20; %subst(wDetailLine(wLine):7:2) = ':' + wCol_White; Endfor; wEndOfDesc = 8; When pYType = '*NORMAL' and wScreenLarge = *Off; // Determine Min/Max/25%/50%/75% select; //1234567890123 when pMaxValue >= 1000000000000 and pYCalc = '*TB'; wDivisor = 1024*1024*1024*1024; y2Desc = 'Size in TB'; when pMaxValue >= 1000000000 and pYCalc = '*GB'; wDivisor = 1024*1024*1024; y2Desc = 'Size in GB'; when pMaxValue >= 1000000 and pYCalc = '*MB'; y2Desc = 'Size in MB'; wDivisor = 1024*1024; when pMaxValue >= 1000 and pYCalc = '*KB'; y2Desc = 'Size in KB'; wDivisor = 1024; Other; wDivisor = 1; EndSl; wLength = %len(%trim(FormatNumber(%dec(pMaxValue/wDivisor:31:2)))); wEndOfDesc = wLength + 4; wDetailLine(1) = %trim(FormatNumber(%dec(pMaxValue/wDivisor:31:2))); %subst(wDetailLine(1):wEndOfDesc+1:79-wEndOfDesc-1) = %trim(wUnderLine); wDetailLine(5) = %trim(FormatNumber(%dec(pMaxValue/wDivisor*0.75:31:2))); %subst(wDetailLine(5):wEndOfDesc+1:79-wEndOfDesc-1) = %trim(wUnderLine); wDetailLine(10) = %trim(FormatNumber(%dec(pMaxValue/wDivisor*0.50:31:2))); %subst(wDetailLine(10):wEndOfDesc+1:79-wEndOfDesc-1) = %trim(wUnderLine); wDetailLine(15) = %trim(FormatNumber(%dec(pMaxValue/wDivisor*0.25:31:2))); %subst(wDetailLine(15):wEndOfDesc+1:79-wEndOfDesc-1) = %trim(wUnderLine); wDetailLine(20) = '0'; %subst(wDetailLine(20):wEndOfDesc+1:79-wEndOfDesc-1) = %trim(wUnderLine2); %Subst(wDetailLine(21):wEndOfDesc+1:79-wEndOfDesc-1)= %trim(wUnderLine3); For wLine = 1 to 20; %subst(wDetailLine(wLine):wEndOfDesc-1:2) = ':' + wCol_White; Endfor; EndSl; Return wEndOfDesc; End-proc; // ================================================================ dcl-proc FormatNumber; dcl-pi FormatNumber char(20); pInputValue packed(15:2) value; end-pi; dcl-s wTempValue char(20) inz(' '); // If pInputValue < 1 and pInputValue > 0; wTempValue = '0' + %trim(%editc(pInputValue:'J')); Else; wTempValue = %trim(%editC(pInputValue:'J')); EndIf; Return wTempValue; End-proc; // ================================================================ dcl-proc BuildScreen; dcl-pi BuildScreen; pPage int(10) value; pMaxValue packed(31:2) value; pTotalItems int(10) value; pYLabel char(30) value; pChartType char(10) value; pYCalc char(10) value; end-pi; dcl-s wLineCount int(10) inz(0); dcl-s wTotalColumns int(10) inz(0); dcl-s wPageCount int(10) inz(0); dcl-s wStrCol int(10) inz(0); dcl-s wEndCol int(10) inz(0); dcl-s wTempNum packed(31:2) inz(0); dcl-s wMaxCol int(10) inz(0); If wScreenLarge = *On; wMaxCol = 130; Else; wMaxCol = 78; EndIf; wLineStr = BuildyLines(pMaxValue:pChartType:pYLabel:pYCalc); If wDeterminePages = *Off; wDeterminePages = *On; wTotalColumns = wMaxCol - wLineStr; wTotalPages = %inth(pTotalItems/wTotalColumns); wStrCol = 1; If wTotalPages = 0; wTotalPages = 1; EndIf; For wPageCount = 1 to wTotalPages; dsPage(wPageCount).Start = wStrCol; wEndCol = wStrCol + wTotalColumns - 1; If wEndCol > pTotalItems; wEndCol = pTotalItems; EndIf; dsPage(wPageCount).End = wEndCol; dsPage(wPageCount).Entries = wEndCol - wStrCol + 1; wStrCol = wEndCol + 1; EndFor; EndIf; wStrCol = dsPage(pPage).Start; wEndCol = dsPage(pPage).End; For wLineCount = 0 to (wMaxCol - wLineStr - 1); If dsData(wLineCount+wStrCol).wDataItem < 0; wTempNum = 0; Else; wTempNum = dsData(wLineCount+wStrCol).wDataItem; EndIf; BuildColumn(wLineStr+wLineCount+1:pMaxValue: wTempNum: dsData(wLineCount+wStrCol).wxData); EndFor; BuildDLines(); If wScreenLarge = *On; EvalR FLine1 = 'Page ' + %trim(%editc(wPage:'1')) + ' of ' + %trim(%editc(wTotalPages:'1')) + ' page(s)'; Else; EvalR F2LIne1= 'Page ' + %trim(%editc(wPage:'1')) + ' of ' + %trim(%editc(wTotalPages:'1')) + ' page(s)'; EndIf; End-proc; // ================================================================ // ================================================================ dcl-proc BuildDlines; If wScreenLarge = *On; dline01 = wDetailLine(1); dline02 = wDetailLine(2); dline03 = wDetailLine(3); dline04 = wDetailLine(4); dline05 = wDetailLine(5); dline06 = wDetailLine(6); dline07 = wDetailLine(7); dline08 = wDetailLine(8); dline09 = wDetailLine(9); dline10 = wDetailLine(10); dline11 = wDetailLine(11); dline12 = wDetailLine(12); dline13 = wDetailLine(13); dline14 = wDetailLine(14); dline15 = wDetailLine(15); dline16 = wDetailLine(16); dline17 = wDetailLine(17); dline18 = wDetailLine(18); dline19 = wDetailLine(19); dline20 = wDetailLine(20); dline21 = wDetailLine(21); dline22 = wDetailLine(22); dline23 = wDetailLine(23); dline24 = wDetailLine(24); Else; d2line01 = wDetailLine(1); d2line02 = wDetailLine(2); d2line03 = wDetailLine(3); d2line04 = wDetailLine(4); d2line05 = wDetailLine(5); d2line06 = wDetailLine(6); d2line07 = wDetailLine(7); d2line08 = wDetailLine(8); d2line09 = wDetailLine(9); d2line10 = wDetailLine(10); d2line11 = wDetailLine(11); d2line12 = wDetailLine(12); d2line13 = wDetailLine(13); d2line14 = wDetailLine(14); d2line15 = wDetailLine(15); d2line16 = wDetailLine(16); d2line17 = wDetailLine(17); d2line18 = wDetailLine(18); d2line19 = wDetailLine(19); d2line20 = wDetailLine(20); d2line21 = wDetailLine(21); EndIf; End-proc; // ====================================================================* // Subroutine.... ScreenSizeIs132 * // Description... Check if the screen is configured for 132 Chars * // // Parameters: // // ‚Example: // // šIf ScreenSizeIs132() = *Off; // SndCompMsg('Screen is NOT configured for 132 chars'); // šElse; // SndCompMsg('Object is configured for 132 chars'); // šEndIf; // ====================================================================* Dcl-Proc ScreenSizeIs132 export; Dcl-PI ScreenSizeIs132 ind;// Return Variable End-PI; // Check the screen size now If (QsnQryModSup(DS4_MODE:*OMIT:*OMIT:*OMIT) <> MODE_ALLOWED); Return *Off; Else; Return *On; EndIf; End-Proc; //******************************************************************** // =================================================================================== // Center Text in a string // Parm: Input String varchar(32767) // String Length (untrimmed) // Returns: Output String varchar(32000) // =================================================================================== // EXAMPLE: // wTestString = CenterText(wTestString):%len(wTestString)); // // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ dcl-proc CenterText export; dcl-pi CenterText char(32767); p_InputString char(32767) const OPTIONS(*VARSIZE); p_Stringlength int(10) value; end-pi; // dcl-s wStrPos int(10) inz(0); dcl-s wTempLen int(10) inz(0); dcl-s wOutputString char(32767) inz(' '); wTempLen = %len(%trim(%subst(p_InputString:1:p_StringLength))); wStrPos = ((p_StringLength - wTempLen)/2) + 1; %Subst(wOutputString:wStrPos:wTempLen) = %trim(%subst(p_InputString:1:p_StringLength)); Return wOutputString; end-proc;