Difference between revisions of "Green-screen Chart/Graph"
Line 1: | Line 1: | ||
− | =Green-screen Chart/Graph | + | =Green-screen Chart/Graph= |
==Background== | ==Background== | ||
Line 138: | Line 138: | ||
GenChart(%addr(TestDs):'ASP Information':'Size in GB':wRecCount: | GenChart(%addr(TestDs):'ASP Information':'Size in GB':wRecCount: | ||
wMaxValue:'*NORMAL':'*NONE'); | 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 * | ||
+ | *====================================================================* | ||
+ | *================================================================ | ||
+ | *šCheck if the data files are available | ||
+ | *================================================================ | ||
+ | |||
+ | 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); | ||
+ | // ' ' + %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(23):wLength+3:1) = ':'; | ||
+ | //wDetailLine(23) = %trim(wDetailLine(23)) + ' '+%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); | ||
+ | // ' ' + %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; |
Revision as of 07:37, 9 June 2021
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 * *====================================================================* *================================================================ *šCheck if the data files are available *================================================================
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); // ' ' + %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(23):wLength+3:1) = ':'; //wDetailLine(23) = %trim(wDetailLine(23)) + ' '+%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); // ' ' + %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;