Professional Documents
Culture Documents
Hhguide2t24 4
Hhguide2t24 4
c
Hitchhiker’s Guide To
c
jBASE and
c
Edition 4, final. Built at June 12, 2013
c
c b a n V. K a z i m i r ch i k 2011 2012 2013
0.1 What’s new in edition 4
New jBC code parser – different colours are now assigned for keywords, functions and special
variables like @FM. Hope that code became more readable. See comments in the example
below:
* The comment
$INSERT I_COMMON ;* special keyword, default text
$INSERT I_EQUATE
#ifdef DEBUGGING
CRT var_1
#endif
* a label:
DO.IT:
var_1 = @TIME : @FM : TIME() ;* more special keywords (or variables)
RETURN
END
The book was fully revised; some manual formatting was done to achieve a better look.
All jBC code examples were retested (and many of them enhanced); now their style is the
same, including such things like variables naming etc. Some new examples and chapters were
added.
REM Page 2
Contents
0.1 What’s new in edition 4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1 Preface 11
3 jBC 14
3.1 Code compilation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
3.2 Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
3.3 Comments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
3.4 String variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
3.5 Line continuation; several statements on the same line . . . . . . . . . . . . . 18
3.6 String operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
3.7 Comparisons . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
3.8 Numeric variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
3.9 Boolean variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
3.10 Data files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
3.11 File variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
3.12 Dynamic arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
3.13 Differences between emulations . . . . . . . . . . . . . . . . . . . . . . . . . 33
3.14 jBC statements and functions . . . . . . . . . . . . . . . . . . . . . . . . . . 36
3.15 ABORT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
3.16 ASCII() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
3.17 ASSERTEQUALS(), ASSERTTRUE() . . . . . . . . . . . . . . . . . . . . . 37
3.18 BREAK ON/OFF . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
3.19 BYTELEN(), LEN(), CHAR() . . . . . . . . . . . . . . . . . . . . . . . . . . 38
3.20 CALL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
3.21 CALLJ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
3.22 CASE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
3.23 CATS() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
3.24 CHAIN, CLEARINPUT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
3.25 CHANGE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
3.26 CHANGETIMESTAMP(), LOCALDATE() . . . . . . . . . . . . . . . . . . 42
3.27 CHAR() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
3.28 CHDIR() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
3.29 CHECKSUM() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
3.30 CLEAR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
3.31 CLEARCOMMON . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
3.32 CLEARDATA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
3.33 CLEARFILE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
3.34 CLOSE, ASSIGNED() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
3.35 COMMON . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
3.36 CONVERT statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
REM Page 3
3.37 CONVERT() function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
3.38 CREATE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
3.39 CRT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
3.40 DEL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
3.41 DELETE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
3.42 DELETELIST . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
3.43 DELETESEQ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
3.44 DIM, MAT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
3.45 DIR() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
3.46 DIV() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
3.47 DROUND() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
3.48 DTX(), XTD() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
3.49 ENCRYPT() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
3.50 EXECUTE/RTNLIST/CAPTURING, DATA, DCOUNT() . . . . . . . . . . 52
3.51 GETENV() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
3.52 GETLIST, SELECT, READNEXT, OPEN, READ, WRITE . . . . . . . . . 54
3.53 GOSUB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
3.54 GROUPSTORE() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
3.55 FIELD(), COL1(), COL2() . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
3.56 FILEINFO(), NULL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
3.57 FIND, FINDSTR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
3.58 FOLD() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
3.59 FOR...NEXT...STEP...CONTINUE...BREAK . . . . . . . . . . . . . . . . . 58
3.60 ICONV(), OCONV(), FMT() . . . . . . . . . . . . . . . . . . . . . . . . . . 58
3.61 IN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
3.62 INDEX() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
3.63 INMAT() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
3.64 INPUT, DOWNCASE() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
3.65 INSERT() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
3.66 IOCTL() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
3.67 ISCNTRL() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
3.68 ISDIGIT(), ISLOWER(), ISPRINT(), ISSPACE(), ISUPPER() . . . . . . . 65
3.69 ITYPE() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
3.70 JBASECOREDUMP() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
3.71 JBASESubroutineExist() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
3.72 JQLCOMPILE(), JQLEXECUTE(), JQLFETCH(), JQLGETPROPERTY() 70
3.73 KEYIN(), TIMEDATE(), UPCASE() . . . . . . . . . . . . . . . . . . . . . . 71
3.74 LATIN1() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
3.75 LEN(), INT() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
3.76 LOCATE, INS, MINIMUM(), MAXIMUM() . . . . . . . . . . . . . . . . . . 72
3.77 LOWER() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
3.78 MAKETIMESTAMP() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
3.79 MATBUILD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
3.80 MATCH(ES) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
3.81 MATPARSE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
REM Page 4
3.82 MAXIMUM() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
3.83 MOD() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
3.84 MSLEEP() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
3.85 NEGS() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78
3.86 NUM() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78
3.87 OPENSEQ, READSEQ, CLOSESEQ . . . . . . . . . . . . . . . . . . . . . . 79
3.88 OSBREAD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
3.89 OSREAD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
3.90 PRECISION . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
3.91 PRINTERR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
3.92 PROMPT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
3.93 PUTENV . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
3.94 PWR() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
3.95 RAISE() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83
3.96 READBLK . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83
3.97 READL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
3.98 READNEXT combined with READPREV . . . . . . . . . . . . . . . . . . . 84
3.99 READSEQ – platforms compatibility . . . . . . . . . . . . . . . . . . . . . . 85
3.100 READU . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
3.101 READV . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
3.102 RECORDLOCKED() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88
3.103 REGEXP() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89
3.104 RELEASE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89
3.105 REMOVE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
3.106 REPLACE() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
3.107 REUSE(), SUBS() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
3.108 SEEK . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
3.109 SENTENCE() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
3.110 SEQ() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
3.111 SORT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
3.112 SSELECT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
3.113 SSELECTV . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
3.114 STATUS() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
3.115 STATUS statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
3.116 STR() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
3.117 SUM() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
3.118 SYSTEM() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96
3.119 TIME() and @TIME . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98
3.120 TIMESTAMP() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98
3.121 TRANSTART, TRANSEND, TRANSQUERY(), TRANSABORT . . . . . . 99
3.122 TRIM() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
3.123 TRIMBS() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
3.124 TRIMFS() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
3.125 UNASSIGNED() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
3.126 UNIQUEKEY() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
REM Page 5
3.127 UTF8() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
3.128 WEOFSEQ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
3.129 WRITEBLK . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106
3.130 WRITELIST . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108
3.131 WRITESEQ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108
3.132 WRITEU . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
3.133 WRITEV . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110
3.134 XLATE() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110
4 jQL 111
4.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111
4.2 LIST . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111
4.3 SELECT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124
4.4 SSELECT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127
4.5 NSELECT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127
4.6 XSELECT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 128
4.7 BSELECT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 128
4.8 EVAL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130
4.9 Manipulations with lists . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134
4.10 Other jQL stuff . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136
7 JED 147
7.1 Text indentation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147
7.2 Input @VM and @SM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148
7.3 Return where you were last time . . . . . . . . . . . . . . . . . . . . . . . . . 149
8 Debugger 149
8.1 Enter the debugger at program start . . . . . . . . . . . . . . . . . . . . . . 149
8.2 Get call stack information . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149
8.3 List variables using mask . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149
8.4 List a variable with additional information . . . . . . . . . . . . . . . . . . . 149
8.5 Amend a variable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150
8.6 Remove the value altogether . . . . . . . . . . . . . . . . . . . . . . . . . . . 150
8.7 Set variable contents to CHAR(0) . . . . . . . . . . . . . . . . . . . . . . . . . 150
REM Page 6
9 Tools and utilities 150
9.1 jgrep . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150
9.2 jprof - quick tutorial . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151
9.3 LIST-OPEN-FILES . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153
9.4 MW42 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154
9.5 t24version . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154
9.6 SQLUPDATE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154
9.7 telnetd.exe, Transcmd.exe . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155
9.8 WHERE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155
9.9 LOGOFF . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155
9.10 jshelltype . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 156
9.11 SP-NEWTAB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 156
9.12 MSG . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157
10 OFS 157
10.1 Characters substitution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157
10.2 “Replace” option . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 159
10.3 Launch an enquiry . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161
10.4 Prepare complex OFS message using SELECT...SAVING EVAL . . . . . . . 162
REM Page 7
12.11 ENQUIRY/CONVERSION routine . . . . . . . . . . . . . . . . . . . . . . . 178
12.12 NOFILE enquiry . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179
12.13 OFS.SOURCE/IN.MSG.RTN . . . . . . . . . . . . . . . . . . . . . . . . . . 181
12.14 OFS.SOURCE/OUT.MSG.RTN . . . . . . . . . . . . . . . . . . . . . . . . 183
12.15 DE.MAPPING/ROUTINE . . . . . . . . . . . . . . . . . . . . . . . . . . . 184
12.16 DE.DISP.CONTROL/FIELD.NAME . . . . . . . . . . . . . . . . . . . . . . 190
12.17 ACCOUNT.PARAMETER/ACCOUNTING.SUBRTN . . . . . . . . . . . . 192
12.18 EB.FREQUENCY/SPECIAL.ROUTINE . . . . . . . . . . . . . . . . . . . 194
12.19 I-descriptors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 195
14 How-tos 218
14.1 Get rid of speaker beeps in jsh (Windows) . . . . . . . . . . . . . . . . . . . 218
14.2 Get rid of speaker beeps in T24 Classic . . . . . . . . . . . . . . . . . . . . . 219
14.3 Automatically create the new file on target system when using DL.DEFINE 219
14.4 Correct the screen used in “L” function . . . . . . . . . . . . . . . . . . . . . 219
14.5 To see changes in the example given above without necessity to relogin to T24 221
14.6 Overcome “200 pages” ENQUIRY limit set in SPF . . . . . . . . . . . . . . 224
14.7 Avoid hanging of Globus Desktop on DEBUG statement . . . . . . . . . . . . 225
14.8 Place “$” files separately from sources . . . . . . . . . . . . . . . . . . . . . 225
14.9 See last jsh commands issued from the same port number . . . . . . . . . . 226
REM Page 8
14.10 See last jsh and jed commands issued from any port number . . . . . . . . 226
14.11 Correct the error appearing after LIST VOC command . . . . . . . . . . . . 227
14.12 Enter debugger in tSS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 227
14.13 Clean shared memory after installing new release in Unix (example for jBASE5)228
14.14 Install TAFC without admin rights under XP . . . . . . . . . . . . . . . . . 229
14.15 See which files and records took part in T24 transaction . . . . . . . . . . . 229
14.16 Distribute a file . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 230
14.17 Set up transaction journalling . . . . . . . . . . . . . . . . . . . . . . . . . . 234
14.18 Create an online service that is activated at certain periods of time . . . . . 244
14.19 Embed python into jBC code . . . . . . . . . . . . . . . . . . . . . . . . . . 250
14.20 Adapt PuTTY for accepting T24 functional keys F1 ... F7 . . . . . . . . 254
14.21 Run PuTTY in typical T24 environment without using registry . . . . . . . 257
14.22 Create a reverse tunnel so you can log in from Unix server to your local PC 259
14.23 Upload a file to server in one step (SCP) . . . . . . . . . . . . . . . . . . . . 260
14.24 Automate frequently used command on a server (e.g. compile a source) . . . 260
14.25 Login automatically to T24 using Browser client . . . . . . . . . . . . . . . 260
14.26 Execute a program in background . . . . . . . . . . . . . . . . . . . . . . . 261
14.27 Generate a simple temporary text file on the fly . . . . . . . . . . . . . . . . 262
14.28 Create a directory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 262
REM Page 9
18 Source code editing 335
18.1 To highlight jBC code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 335
18.2 Compilation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 342
18.3 Find all CALLs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 344
18.4 Display contents of an insert file under the cursor . . . . . . . . . . . . . . . 345
18.5 Autocomplete jBC/T24 keywords . . . . . . . . . . . . . . . . . . . . . . . . 347
18.6 Code intentation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 348
18.7 Code folding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 349
18.8 Exec Putty . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 355
18.9 Other things . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 356
18.10 Settings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 358
REM Page 10
1 Preface
This is the “copy-and-paste”-friendly book with jBC, jQL and other samples, how-tos etc –
for people who know the ropes but are too lazy to memorize, for example, all parameters of
f.readu or all options of trim() (like I am). I recently added “jBASE and” into the book
title because the more I write, the more the focus shifts from “pure” T24 to other things like
jBC, jQL etc.
Some areas are well-represented, some are populated quite sparsely. That was as much as
I could gather of 100%-tested examples. That’s why many T24 things from my old records
hadn’t found their way here – I either wasn’t able to retest them or just understood that I
did things wrongly then.
Most things here occupy somewhat lower level than T24 does. Main aspect is jBC program-
ming. Other languages (Python, C, Lua) are used quite in an amateur way just to make the
life easier.
When you copy some code including page breaks – page numbers will become comments (to
avoid compilation fail; that’s why they look like “REM Page 2” for jBC and, e.g., “-- Page
150” for Lua code).
The only exception known to me at the moment is that if REM is at the middle of jBC code
lines with continuation – it wouldn’t compile (unlike “*”; but I haven’t found a way to use
asterisk in page number definition). See an example. The following code wouldn’t compile:
utf_line = CHAR(XTD('C3')) \
: CHAR(XTD('9F')) \ ;* c3 9f: LATIN SMALL LETTER SHARP S
REM Page 201
: CHAR(XTD('C3')) \
: CHAR(XTD('9D')) ;* c3 9d: LATIN CAPITAL LETTER Y WITH ACUTE
utf_line = CHAR(XTD('C3')) \
: CHAR(XTD('9F')) \ ;* c3 9f: LATIN SMALL LETTER SHARP S
*REM Page 201
: CHAR(XTD('C3')) \
: CHAR(XTD('9D')) ;* c3 9d: LATIN CAPITAL LETTER Y WITH ACUTE
So the only thing you need to do is search, copy, paste and compile. Most jBC examples
(those that don’t have subroutine statement) can be pasted to a test.b file. (Don’t forget
to press Enter after the last line – compiler wouldn’t be happy otherwise; in some editors
there are settings for this - for example, for SciTE it’s ensure.final.line.end=1.)
When the source code is saved – jcompile test.b; then run it.
If your PDF viewer dooesn’t preserve leading spaces after copy/paste - use JED (in jBC case)
to get them back or see chapter “Source code editing”. (This is optional for Java, C, jBC
and Lua but mandatory for Python.)
REM Page 11
I’ve tested copying the source code from this PDF in different PDF viewers; the best results
were achieved in Sumatra PDF (which is free and remembers current position for each PDF
file as well). Thanks to Sumatra support too for pointing me to LATEX package that allows
to keep single quotes correct after paste (without converting them to Unicode).
Each chapter contains some useful things – definitely not all that are available. (Who needs
the mathematical tangent in T24?)
All financial data in examples is from Temenos Model Bank.
Starting from edition 3 (i.e. from October 2012) I also contribute to “Temenos jBC docu-
mentation” which you can read at:
http://jbc.temenos.com
Examples written by me there and in this book are often the same or similar.
Enjoy!
REM Page 12
2 What I prefer not to use
There are things in T24 area that I don’t use. Reasons for that are not discussed here; I
just supply a replacement suggestion. And – I’m not saying I’m never going to use all that
– someday and to solve a certain task I might have to...
• jBASE secondary indexes. Replacement: T24 application EB.ALTERNATE.KEY.
• CALL DAS(), CALL EB.READLIST(). Replacement: EXECUTE SELECT, Basic SELECT.
• New application template. “Template V3” is good enough for me.
• “=” as comparison in jBC – only for assignment. E.g. “V.VAR = 1”; “IF V.VAR EQ 1”.
• jBC GOTO, “RETURN TO”. I believe that LOOP...REPEAT with a BREAK can bring you wher-
ever you want inside current section; and passing execution to another section with GOTO is
absolute nightmare.
• jBC IF...ELSE without THEN.
• EB.COMPILE. For programs jcompile os OK, for subroutines – BASIC...CATALOG.
• Including I COMMON and I EQUATE isn’t necessary if you don’t use variables declared there.
(Just – if necessary – don’t forget to add “PRECISION 13” statement in this case to match
T24 default.)
• Capturing data to dynamic array if I don’t know the volume of data. After certain size
the performance drops.
• Unnamed COMMON.
• EQU in jBC. Not being able to see actual value in debugger disturbs me.
• I use CALL OFS.GLOBUS.MANAGER() outside T24 transaction boundary – Temenos still
does the same in the core quite extensively. Places where it can be used safely – everywhere
with “VALIDATE” option, in mainline routine or in “Verify” section of “W” template. (Two
last options are also true for CALL JOURNAL.UPDATE.)
• CALL JULDATE() might be considered obsolete – OCONV() with “DJ” code gives you the
number of day in a year.
• Manipulating of such things as T array, T.ENRI, T.LOCREF on-the-fly – often people try to
make, for example, one field NOINPUT depending on a value of another field etc. Sometimes it
works, but more often it doesn’t. Or – which even worse – it stops working after an upgrade
or update.
• Calling core routines which are not listed in “Subroutine guide”. (Some exceptions exist
though – say, TXTINP() but it was there some time ago.) But calling something that is
subject to change or disappear from core – no way.
• CALL EB.ACCOUNTING(). In some legacy code I have to, but the way to go is OFS Clearing.
• EBS.AUTO.FUNCTION application. Instead – SELECT...SAVING EVAL to create OFS
string for each record, then copy/paste to tSS or put the saved list for batch file listener to
proceed.
• Repgens. ENQUIRY is much better though not ideal either.
• Non-zero values for the following environment variables: JBASE ERRMSG DIVIDE BY ZERO,
JBASE ERRMSG ZERO USED and JBASE ERRMSG NON NUMERIC in development environment. It’s
better to see errors than to hide them.
• EB.PHANTOM – it’s really outdated.
• VB scripting – it works only in Desktop.
REM Page 13
• jBC DEFFUN – it doesn’t make any difference to have a function intead of a subroutine.
The only useful thing that comes to my mind is – make the code more compact by writ-
ing something like “V.RET = FUNC1(FUNC2(V.PAR2), FUNC3(V.PAR3))” instead of several
subsequent CALLs...
• LOOP...WHILE, LOOP...UNTIL – left only in legacy code. Just LOOP...REPEAT with con-
ditional BREAKs for all new code.
• Numeric labels. Of course you can compile even the following code but think twice before
doing that...
001 var = 0
002 var += 1
003 IF var LT 5 THEN GOTO 002 ELSE CRT var
3 jBC
3.1 Code compilation
jcompile could be used to compile a program in one step:
jcompile test.b
Don’t forget to add the location of resulting executable and shared library to
PATH environment variable, otherwise COMMON areas wouldn’t be preserved.
For a subroutine (especially T24-type one without “.b” extension) it’s easier to use BASIC...
CATALOG:
REM Page 14
Source file PROG1 compiled successfully
note: COMMON areas wouldn’t be preserved in this case; CHAIN behaviour also differs.
How to look into generated C source:
jcompile -S test.b
note: test.c and test.j files will be generated and that’s it.
See which commands are executed during compilation:
jcompile -v test.b
CATALOG -v . INCR.NUM
INCR.NUM
Object INCR.NUM cataloged successfully
jcompile -Qs C:\home\kzm\v-t24\client\lib\lib0.dll -b 805306368 -fCATALOG_5.TMP
Library C:\home\kzm\v-t24\client\lib\lib0.dll rebuild okay
REM Page 15
Conditional compilation:
the_var = 1
CRT 'Version ':
#ifdef VER1
CRT the_var:
#else
CRT the_var + 1:
#endif
CRT ' finished'
jcompile test.b
test.c
test
Version 2 finished
jshow -c PROG1
Executable: $HOME\bin\PROG1.dll
jBC main() version 11.0 Wed Nov 21 22:03:18 2012
jBC main() source file TEST.BP
Executable (DUP!!): $HOME\bin\PROG1.exe
jBC main() version 11.0 Wed Nov 21 22:03:18 2012
jBC main() source file TEST.BP
3.2 Variables
Visibility and lifetime.
Variable is visible throughout the program or its subroutine (i.e. in the bounds of particu-
lar source code file). (Yes, you’re unable to put several subroutines into same source code
file.) To share a variable between different programs/subroutines pass them as parameters in
CALL statement or use a named or unnamed COMMON. PASSDATA/RTNDATA clauses
REM Page 16
in EXECUTE statement can also help here (and there is also PASSDATA and COLLECT-
DATA statements). All variables (except ones in COMMON areas) are reset (i.e. become
unassigned) upon program end.
Naming.
I’d recommend to use low case with underscores style. Don’t forget that variable names
(as well as jBC keywords and functions) are case-sensitive.
3.3 Comments
* This is a comment
! And this is a comment
REM This is also a comment
// Even this is a comment
CRT '1' ;* this is a comment sharing the same line with some code
CRT '2' // yet another way to define a comment
GOSUB DO.IT
STOP
As you’ve seen above, if you need to have a string delimiter as part of a string, just use other
delimiter. Duplication method doesn’t work; compiler wouldn’t give an error message in this
case:
REM Page 17
3.5 Line continuation; several statements on the same line
* Usual way is a backslash at the end of line
CRT 'QWE' \
: 'RTZ'
CRT STR('QWE', ;* no need in that if the line ends with comma
5)
* several statements together:
CRT 'QWE' ; CRT 'XYZ': ; CRT 'ABC'
CRT 'QWE' ; CRT 'XYZ' ;* comment is also possible here
* as soon as you have a comment, all the rest turns to comments as well:
v_var = 2
v_var-- ;* comment goes to the EOL so no "1" in the output ; CRT v_var
v_var--
CRT v_var ;* 0 will be output
* multi-line conditional statements are also supported:
var_1 = 1 ; var_2 = 2 ; IF var_1 + var_2 EQ 3 THEN
CRT var_1, '+', var_2, '= 3'
END
Its a good idea to move line continuation(s) even more than 3 usual positions to the right,
e.g.:
current_date = DATE()
current_day = OCONV(current_date, 'DD')
current_month = OCONV(current_date, 'DM')
ansi_date = OCONV(current_date, 'DY') : '-' \
: FMT(current_month, 'R0%2' ) : '-' \
: FMT(current_day, 'R0%2' )
CRT ansi_date ;* e.g. 2013-03-08
REM Page 18
3.6 String operations
* concatenate strings
a_line = 'QWE' : 'RT'
CRT a_line ;* QWERT
* unary concatenation
a_line := 'Y'
CRT a_line ;* QWERTY
* extract a substring
CRT a_line[1,2] ;* QW
CRT a_line[2] ;* TY
CRT a_line[-4,2] ;* ER
* add quotes around a string
CRT SQUOTE(a_line[4,999]) ;* 'RTY'
CRT QUOTE(a_line) ;* "QWERTY"
* change case
CRT DOWNCASE(a_line) ;* qwerty
* length of a string
CRT LEN(a_line) ;* 6
* length of i18n string
a_line := CHAR(353)
CRT LEN(a_line) ;* 7
CRT BYTELEN(a_line) ;* 8
* repeat string several times
CRT STR('QWE', 5) ;* QWEQWEQWEQWEQWE
* dynamic array is also a string
dyn_array = 'qwe' : @FM : "rty" : @VM : \xYZ\
dyn_array := @SM : 123
CRT LEN(dyn_array) ;* 15
CRT FMT(UPCASE(dyn_array), 'MCP') ;* QWE^RTY]XYZ\123
* reassign parts of a string
a_string = 'ABC'
a_string[2,1] = 'Q'
CRT a_string ;* AQC
a_string[2,1] = 'WER'
CRT a_string ;* AWERC
* get ASCII value of a character
CRT SEQ(a_string[1,1]) ;* 65 (ASCII code of "A")
* pad a string
CRT '/' : FMT(a_string, '25R') : '/' ;* / AWERC/
* strip spaces...
a_string = ' QWERTZ '
CRT DQUOTE(TRIM(a_string, ' ', 'B')) ;* "QWERTZ"
* ...or other characters, e.g. leading zeroes
CRT '"' : TRIM('000033', '0', 'L') : '"' ;* "33"
* another method of removing zeroes
CRT '"' : '000033' + 0 : '"' ;* "33"
REM Page 19
And more:
a_string = 'AWERC'
* check if there are only alphabetic characters
CRT ISALPHA(a_string) ;* 1
* add number to the end, unary operation (can omit quotes)
a_string := 1 ; CRT a_string ;* AWERC1
* check again if there are only alphabetic characters
CRT ISALPHA(a_string) ;* 0
* check if there are only alphanumeric characters
CRT ISALNUM(a_string) ;* 1
* check a string for control characters
a_string = CHAR(13) : CHAR(10)
CRT ISCNTRL(a_string) ;* 1
a_string := @FM
CRT ISCNTRL(a_string) ;* 1
CHANGE @FM TO ' ' IN a_string
CRT ISCNTRL(a_string) ;* 0
3.7 Comparisons
Strings comparison is done from left to right:
a_string = 'ABC'
char_a = 'A'
char_b = 'B'
CRT a_string GT char_a ;* 1
CRT a_string GT char_b ;* 0
a_char = 'E'
IF a_char # 'A' THEN CRT 'Not an "A"'
IF a_char NE 'B' THEN CRT 'Not a "B"'
IF a_char ! 'C' THEN CRT 'Not even a "C"'
IF a_char <> 'D' THEN CRT 'Surprisingly, but neither a "D"'
REM Page 20
3.8 Numeric variables
v_var= 5 ; CRT v_var ;* 5
CRT ISDIGIT(v_var) ;* 1
v_var= v_var+ 1 ; CRT v_var ;* 6
v_var++ ; CRT v_var ;* 7
v_var += 1 ; CRT v_var ;* 8
v_var -= 1 ; CRT v_var ;* 7
v_var =- 1 ; CRT v_var ;* -1... easy to make a mistake
CRT ISDIGIT(v_var) ;* 0 (we have minus now)
CLEAR
CRT v_var ;* 0
note: ++v var etc isn’t my favourite way; this might help to understand legacy code.
REM Page 21
Examples:
CRT @TRUE ;* 1
CRT @FALSE ;* 0
IF NOT(unassigned_var) THEN CRT 'Unassigned var is false'
true_var = 1 ; false_var = 0
IF true_var THEN CRT '1 is true'
IF NOT(false_var) THEN CRT '0 is false'
a_string = 'YES'
IF a_string THEN CRT 'Non-empty string is true'
IF NOT('0.00') THEN CRT '0.00 is false'
IF NOT('-0.00') THEN CRT '"-0.00" is still false - treated as numeric'
* and this test depends on PRECISION
PRECISION 9
GOSUB TRUE.OR.FALSE
PRECISION 17
GOSUB TRUE.OR.FALSE
STOP
*------------------------------------------------------------------------
TRUE.OR.FALSE:
*
IF NOT('0.00000000000001') THEN CRT '0.00000000000001 is false' \
ELSE CRT '0.00000000000001 is true with PRECISION 17'
RETURN
END
Output:
1
0
Non-numeric value -- ZERO USED ,
Variable 'unassigned_var' , Line 3 , Source test2.b
Unassigned var is false
1 is true
0 is false
Non-empty string is true
0.00 is false
"-0.00" is still false - treated as numeric
0.00000000000001 is false
0.00000000000001 is true with PRECISION 17
Parentheses change the order of evaluations, e.g. in the following example code lines 2, 3 and
4 are the same (except parentheses); only second IF is true:
REM Page 22
3.10 Data files
The most used formats for data files nowadays are “J4” and “JR”. The former has size
limitation (up to 2Gb if OS-level limits allow that) and needs resizing on regular basis though
when it’s properly sized it’s faster. “JR” – “resilient” – doesn’t have size limitation and
doesn’t need resizing.
The following samples can be executed in jshell prompt or (except JED - it makes no sense)
in a jBC program or subroutine (using EXECUTE/PERFORM). In blue colour is what you
type, in black – what system types for you.
Create hashed file (data and dictionary):
DELETE-FILE F.SAMPLE
0001 Field 1
0002 Field 2
0003 Field 3
REM Page 23
Save the record:
Esc FI
LIST F.SAMPLE
F.SAMPLE......
REC1
1 Records Listed
CT F.SAMPLE
REC1
001 Field 1
002 Field 2
003 Field 3
0001 D
0002 1
0003
0004 FIELD 1 HEADER
0005 10L
0006 S
0007
REM Page 24
Save the record.
note: In T24 use application STANDARD.SELECTION to create dictionary entries.
REC1 Field 1
1 Records Listed
No Records Listed
LIST F.SAMPLE
F.SAMPLE......
REC1
0001 PH
0002 @ID FLD1
LIST F.SAMPLE
jstat -v F.SAMPLE
File C:\r11\bnk\bnk.run\F.SAMPLE
Type=J4 , Hash method = 5
REM Page 25
Created at Tue Nov 20 19:38:25 2012
Groups = 101 , Frame size = 4096 bytes , Secondary Record Size = 8192 bytes
Restore re-size parameters : (none)
File size = 417792 bytes , Inode = 29838 , Device = Id 24915
Last Accessed Tue Nov 20 19:50:30 2012 , Last Modified Tue Nov 20 19:50:30 2012
Backup = YES , Log = YES , Rollback = YES , Network = NO
note: 101 – number of groups – was defined when file was created.
Add more records:
1 records copied
jrf -V F.SAMPLE
...
Downsizing skipped from modulo 101 to 3.
Resize it anyway:
...
Downsizing from modulo 101 to 3
jstat -v F.SAMPLE
REM Page 26
File size = 8192, Freespace = 0 frames
Internal Modulo = 3/7/11, External Modulo = 13
Inode no. = 29838, Device no. = 24915
Accessed = Tue Nov 20 19:56:13 2012, Modified = Tue Nov 20 19:56:13 2012
Backup = YES, Log = YES, Rollback = YES, Secure updates = NO
Deallocate pointers : NO Deallocate frames NO
Revision level = 2
Record Bytes = 82, Record Count = 2
Bytes/Record = 41, Bytes/Group = 82
Data Frames = 1, Ptr Frames = 0
OOG Bytes = 0, OOG Frames = 0
Sum Squares = 3362, Std Dev Mean = 41
jchmod +S F.SAMPLE
jstat -v F.SAMPLE
...
Backup = YES, Log = YES, Rollback = YES, Secure updates = YES
...
Delete a record:
1 record(s) deleted.
REM Page 27
Save the record. See that all sections use the same dictionary:
LIST F.SAMPLE,TWO
LIST F.SAMPLE,THREE
No Records Listed
Note that file F.SAMPLE still reports 1 record in it; here’s the difference between having
several data sections and a distributed file. In T24 environment splitting of data into sections
isn’t used.
Folders are treated like data files (type UD); flat files in them – like records. This allows,
for example, use JED to edit source code. Data can be copied transparently between hashed
files and folders. Some examples:
CREATE-FILE DATA TEST.BP TYPE=UD
[ 417 ] File TEST.BP created , type = UD
PROG1
4
Copy data:
REM Page 28
Edit file REC1 in TEST.BP folder with any text editor so it now looks like:
Field 1 - updated
Field 2
Field 3
LIST F.SAMPLE
1 Records Listed
...they are not strings. But – like strings – can be compared with each other:
SUBROUTINE SOME.TEST
* T24 mainline routine
$INSERT I_COMMON
$INSERT I_EQUATE
REM Page 29
Runtime:
note: File variable can also be compared with an empty string to see if file was opened.
Be careful about assigning a file variable to another one. In the following example we’ll use
a dimensioned array to store file variables.
seq_no = 0
DIM files_list(3) ;* array for flat file handles
out_dir = '.'
out_file = 'account-file.csv'
GOSUB INIT.FLAT.FILE
out_file = 'customer-file.csv'
GOSUB INIT.FLAT.FILE
out_file = 'system-file.csv'
GOSUB INIT.FLAT.FILE
STOP
INIT.FLAT.FILE:
seq_no ++
OPENSEQ out_dir, out_file TO f_out THEN
WEOFSEQ f_out ;* truncate the file
END
files_list(seq_no) = f_out
RETURN
WRITE.FLAT.FILE:
WRITESEQ file_type : ') here we are' TO files_list(file_type) ELSE
CRT 'WRITE ERROR'
STOP
END
RETURN
END
3 Records selected
REM Page 30
>CT .
account-file.csv
001 1) here we are
customer-file.csv
001 2) here we are
system-file.csv3ITiDfhyT
001 3) here we are
** Error [ NOT_FILE_VAR ] **
Variable is not an opened file descriptor , Line 28 , Source test.b
Trap from an error message, error message name = NOT_FILE_VAR
REM Page 31
Now amend the program to avoid the reassigning:
seq_no = 0
DIM files_list(3) ;* array for flat file handles
out_dir = '.'
out_file = 'account-file.csv'
GOSUB INIT.FLAT.FILE
out_file = 'customer-file.csv'
GOSUB INIT.FLAT.FILE
out_file = 'system-file.csv'
GOSUB INIT.FLAT.FILE
STOP
INIT.FLAT.FILE:
seq_no ++
// OPENSEQ out_dir, out_file TO f_out THEN
OPENSEQ out_dir, out_file TO files_list(seq_no) THEN
// WEOFSEQ f_out ;* truncate the file
WEOFSEQ files_list(seq_no) ;* truncate the file
END
// files_list(seq_no) = f_out
RETURN
WRITE.FLAT.FILE:
WRITESEQ file_type : ') here we are' TO files_list(file_type) ELSE
CRT 'WRITE ERROR'
STOP
END
RETURN
END
3 Records selected
>CT .
account-file.csv
001 1) here we are
REM Page 32
customer-file.csv
001 2) here we are
system-file.csv
001 3) here we are
dyn_array = 1
dyn_array<2> = 2
dyn_array<-1> = 3
dyn_array := @FM : 4
CRT FMT(dyn_array, 'MCP') ;* 1^2^3^4
“Angle brackets” nesting was discouraged to be used in earlier releases of jBASE; it works
now:
Always be sure that there are commas to indicate positions. Dot will mess it up:
dyn_array = 1 :@FM: 2 :@FM: '3-1' :@VM: '3-2' :@VM: '3-3' :@FM: 4 :@FM: 5
CRT FMT(dyn_array, 'MCP') ;* 1^2^3-1]3-2]3-3^4^5
dyn_array<3,2> = 'new value'
CRT FMT(dyn_array, 'MCP') ;* 1^2^3-1]new value]3-3^4^5
dyn_array<3.2> = 'brand new value'
CRT FMT(dyn_array, 'MCP') ;* 1^2^brand new value^4^5 - the whole
;* field 3 is replaced
REM Page 33
Runtime:
prime
7^7
ros
Non-numeric value -- ZERO USED ,
Variable 'dyn_array' , Line 3 , Source test.b
Trap from an error message, error message name = NON_NUMERIC
More examples:
dir_name = '.'
file_name = 'report.txt'
DELETESEQ dir_name, file_name ELSE NULL
This program outputs “<>” under “prime” and “<0>” under “seq” emulation. In the latter
case there will be zero-sized file report.txt after program terminates. So if, for example,
nothing was written to a report under “prime” emulation (or, in fact, any other except
“seq”), there will be no output file left after that.
note: Setting in Config EMULATE: openseq creates = false|true
And more... The following program outputs 1 under “prime” emulation and 0 under “r83”:
CRT ASSIGNED(var_1)
REM Page 34
note: Setting in Config EMULATE: no extra delimiter = false|true
The following READV example outputs “REC1” (i.e. record key) when is run under “jbase”
emulation and “3” (i.e. fields count) under, e.g., “ap” or “r83”:
CRT in_record
DIMENSION dyn_array(10)
MAT dyn_array = '!'
dyn_array(5) = '?'
FOR i = 1 TO 10
CRT dyn_array(i): ;* output: !!!!?!!!!!
NEXT i
DIM dyn_array(15)
dyn_array(15) = '...'
CRT dyn_array(15)
REM Page 35
note: Setting in Config EMULATE: resize array = false|true
3.15 ABORT
* Open a file with random name (just to make sure that it doesn't exist)
file_name = ''
FOR i = 1 TO 8
random_char_no = RND(26) + 65
file_name := CHAR(random_char_no) ;* A...Z
NEXT i
OPEN file_name TO f_report ELSE ABORT 201, file_name
Sample output:
** Error [ 201 ] **
Unable to open file XCICLJPH
3.16 ASCII()
Create the file test.txt in hex editor containing the following characters (in hex):
C8 85 93 93 96 40 91 C2 C3
Output:
Hello jBC
REM Page 36
3.17 ASSERTEQUALS(), ASSERTTRUE()
Useful for tesing purposes. Example (reflects some items from “known issues” chapter):
INCLUDE JBC.h
a_string = 'ABC->DEF->QWE->XYZ'
exp_result = 'DEF->QWE'
test_result = FIELD(a_string, '->', 2, 2)
ASSERTEQUALS(test_result, exp_result)
abss_result = ABSS(-1:@FM:-2:@FM:-3)
CRT FMT(abss_result, 'MCP')
REM Page 37
Source changed to .\test2.b
0009 MSLEEP(5000)
jBASE debugger->
utf_string = 'ABCDEF' \
: CHAR(353) : CHAR(352) : CHAR(269) : CHAR(268) : CHAR(263) \
: CHAR(262) : CHAR(382) : CHAR(381) : CHAR(273) : CHAR(272)
CRT LEN(utf_string) ;* 16
CRT BYTELEN(utf_string) ;* 26
3.20 CALL
A subroutine:
SUBROUTINE INCR.NUM(P.NUMBER)
* increase the parameter
P.NUMBER ++
RETURN
END
REM Page 38
Program that calls it:
a_subr = 'INCR.NUM'
CALL @a_subr(a_number) ;* can call a subroutine this way
CRT a_number ;* 5
* Dimensioned array is ok as well
DIM V.DIM.ARR(3)
V.DIM.ARR(2) = 'INCR.NUM'
V.I = 2
CALL @V.DIM.ARR(V.I) (a_number)
CRT a_number ;* 6
* Pass by value rather than by reference - variable keeps its value:
CALL INCR.NUM((a_number))
CRT a_number ;* still 6
* Wrong CALL:
CALL INCR.NUM(a_number, 1) ;* ** Error [ SUBROUTINE_PARM_ERROR ] **
3.21 CALLJ
Sample: getting contents of certain URL from the internet and display retrieved HTML in
the default browser.
jBC subroutine calljGetHTTP.b:
the_URL = 'http://www.temenos.com'
CALLJ "gethttp", "getit", the_URL SETTING ret_code ON ERROR CRT 'ERROR:'
CRT ret_code
import java.net.*;
import java.io.*;
// Page 39
public class gethttp {
public String getit(String cURL) throws Exception {
String returnText = "";
URL site = new URL(cURL);
URLConnection uc = site.openConnection();
BufferedReader in = new BufferedReader(
new InputStreamReader(
uc.getInputStream()));
String inputLine;
while ((inputLine = in.readLine()) != null)
returnText += inputLine;
in.close();
return returnText;
}
}
note: JAVA HOME should be set and PATH should contain %JAVA HOME%\bin.
3.22 CASE
a_string = 'B'
GOSUB CHK.IT
a_string = 'ABC'
GOSUB CHK.IT
STOP
*
CHK.IT:
*
BEGIN CASE
CASE a_string EQ 'A'
CRT 'an A'
CASE a_string EQ 'B'
CRT 'a B'
CASE a_string EQ 'C'
CRT 'a C'
CASE 1
CRT 'neither A nor B nor C'
END CASE
RETURN
END
Output:
a B
neither A nor B nor C
Unlike for, e.g., switch...case in Javascript, we don’t need break in the end of each CASE
to pass execution after the END CASE line.
REM Page 40
3.23 CATS()
Concatenate corresponding array elements together.
DO.PROCEED:
the_result = CATS(an_array, another_array)
CRT OCONV(the_result, 'MCP')
RETURN
IF the_login EQ 0 THEN
CLEARINPUT ;* don't take anything in advance
INPUT the_login
CLEARINPUT
HUSH ON
INPUT the_passwd
HUSH OFF
END
DATA the_login
DATA the_passwd
CHAIN 'EX'
STOP
END
REM Page 41
3.25 CHANGE
the_string = 'ABCDEFCDYZ'
CHANGE 'C' TO 'Q' IN the_string
CRT the_string ;* ABQDEFQDYZ
CHANGE 'QD' TO 'nnn' IN the_string
CRT the_string ;* ABnnnEFnnnYZ
* Both types of arrays are OK as well (dynamic ones can be processed in one go)
dyn_array = the_string
dyn_array<2> = the_string
CHANGE 'nnn' TO 'mmm' IN dyn_array
CRT OCONV(dyn_array, 'MCP') ;* ABmmmEFmmmYZ^BmmmEFmmmYZ
DIM dim_array(3)
MAT dim_array = the_string
CHANGE 'nnn' TO 'mmm' IN dim_array(2)
CRT dim_array(2) ;* ABmmmEFmmmYZ
* Funny but numbers can also be processed
the_number = 12345.67
CHANGE 3 TO 9 IN the_number
CRT the_number ;* 12945.67
* Compatibility mode
the_string = CHANGE(the_string, 'YZ', '+-=/')
CRT the_string ;* ABnnnEFnnn+-=/
3.27 CHAR()
EQUATE VM TO CHAR(253) ;* value Mark; defined in I_EQUATE hence the colouring
FOR i = 1 TO 6
CRT CHAR(64 + i): ;* ABCDEF
NEXT i
CRT ''
CRT OCONV(CHAR(353), 'MX') ;* C5A1
CRT CHAR(7) ;* rings a bell
REM Page 42
3.28 CHDIR()
INCLUDE JBC.h
IF GETENV('TAFC_HOME', tafc_home) THEN
IF CHDIR(tafc_home : DIR_DELIM_CH : 'config') ELSE
CRT "TAFC configuration cannot be found"
ABORT
END
END ELSE CRT 'TAFC home can not be found'
note: usage of DIR DELIM CH from JBC.h allows to have cross-platform code.
3.29 CHECKSUM()
Can not provide the reliable result by itself.
CRT CHECKSUM('A') ;* 65
CRT CHECKSUM('AA') ;* 65*1 + 65*2 = 195
CRT CHECKSUM('B') ;* 66
CRT CHECKSUM(CHAR(0) : '!') ;* 0*1 + 33*2 = 66
3.30 CLEAR
COMMON /MY.COMM/ global_var
global_var = 1000
var = 5 ; CRT var ;* 5
var ++ ; CRT var ;* 6
CLEAR
* only regular variables will be cleared
CRT var ;* 0
CRT global_var ;* 1000
3.31 CLEARCOMMON
COMMON /MY.COMM/ global_var
COMMON gl_unnamed
global_var = 1000
gl_unnamed = 1001
CLEARCOMMON
* only unnamed common will be cleared
CRT global_var ;* 1000
CRT gl_unnamed ;* 0
REM Page 43
3.32 CLEARDATA
3.33 CLEARFILE
OPEN 'F.TEMP' TO f_temp THEN
err_code = ''
CLEARFILE f_temp SETTING err_code
IF err_code NE '' THEN
CRT 'ERROR ' : err_code
STOP
END
CRT 'FILE CLEARED'
END ELSE
EXECUTE 'CREATE-FILE DATA F.TEMP 1 101 TYPE=J4'
OPEN 'F.TEMP' TO f_temp ELSE ABORT 201, 'F.TEMP'
END
REM Page 44
3.35 COMMON
COMMON /MY.COMM/ var_1
var_1 = 'YES'
var_2 = 'NO'
the_string = 'ABCCCDEFCDYZ'
CONVERT 'CEY' TO '+-*' IN the_string
CRT the_string ;* AB+++D-F+D*Z
the_string = 'ABCCCDEFCDYZ'
IF jbc_emu = 'prime' THEN
the_result = CONVERT('CEY', '+-*', the_string)
END ELSE
the_result = CONVERT(the_string, 'CEY', '+-*')
END
REM Page 45
3.38 CREATE
INCLUDE JBC.h
out_dir = '.' ; out_file = 'report.txt'
OPENSEQ out_dir, out_file TO f_out THEN
WEOFSEQ f_out
END ELSE
CREATE f_out ELSE CRT 'File create error' ; STOP
CRT 'File created'
END
WRITESEQ 'ABCDEFabcdef' TO f_out ELSE
CRT 'Write error'
STOP
END
CLOSESEQ f_out
OSREAD the_content FROM out_dir : DIR_DELIM_CH : out_file ELSE NULL
CRT the_content ;* ABCDEFabcdef
3.39 CRT
* normal output
var = 5
CRT var
* result of an expression
CRT var > 2 ;* 1
CRT 2 > 1 ;* 1, though compiler gives the warning
;* "Expression always evaluates as TRUE"
* next 6 outputs will appear at the same line (note ":" in CRT command)
FOR i = 1 TO 6
CRT CHAR(64 + i): ;* ABCDEF
NEXT i
* start a new line
CRT ''
* ring a bell
CRT CHAR(7)
* several things together
CRT 'Loop counter is ' : i
* TAB-delimited output
CRT 'Loop counter is', i
* formatted output
CRT i, i+1 "20R" ;* 6 7
* output at specific location
CRT @(-1) ;* clears the screen and homes the cursor
CRT @(40, 12):'Hello' ;* will start output at row 11, column 39
* compatibility note
DISPLAY 'DISPLAY is synonym of CRT'
REM Page 46
3.40 DEL
Delete an element from dynamic array:
dyn_array = ''
dyn_array<-1> = '' ;* element isn't created here...
FOR i = 1 TO 5
dyn_array<-1> = i
NEXT i
dyn_array<-1> = '' ;* ...and here it is
dyn_array<-1> = 'The end'
CRT FMT(dyn_array, 'MCP') ;* 1^2^3^4^5^^The end
DEL dyn_array<1>
CRT FMT(dyn_array, 'MCP') ;* 2^3^4^5^^The end
dyn_array<2,2> = 6
CRT FMT(dyn_array, 'MCP') ;* 2^3]6^4^5^^The end
DEL dyn_array<2,1>
CRT FMT(dyn_array, 'MCP') ;* 2^6^4^5^^The end
DEL dyn_array<2,1,3>
CRT FMT(dyn_array, 'MCP') ;* still 2^6^4^5^^The end - no such element
//
* An element from dimensioned array can't be deleted but
* can be processed as a dynamic array:
DIM dim_array(5)
MAT dim_array = '*' :@VM: '/'
DEL dim_array(3)<1,2>
MATBUILD delim_array FROM dim_array USING ":"
CRT FMT(delim_array, 'MCP') ;* *]/:*]/:*:*]/:*]/
note: ”<-1>” doesn’t add an empty string as the first element of an array.
REM Page 47
3.41 DELETE
LIST F.TEMP
DICT F.TEMP...
REC1
REC3
2 Records Listed
3.42 DELETELIST
Delete a saved list:
REM Page 48
3.43 DELETESEQ
The following example is to be put into file test.b:
DRAW.SCREEN:
CRT @(-1)
FOR i = 1 TO size_x
FOR j = 1 TO size_y
CRT @(i, j) : the_screen(i, j):
NEXT i
MSLEEP(100) ;* 0.1 sec
NEXT j
MSLEEP 5000 ;* this syntax also works
RETURN
END
REM Page 49
Another example:
DIM dim_array(10)
MAT dim_array = '!'
dim_array(5) = '?'
FOR i = 1 TO 10
CRT dim_array(i): ;* output: !!!!?!!!!!
NEXT i
DIM threedim_array(2, 3, 4)
MAT threedim_array = 1
threedim_array(1, 2, 1) *= 2
CRT ''
CRT threedim_array(1, 2, 1) ;* 2
CRT threedim_array(1, 2) ;* still 2
CRT threedim_array(1, 20, 1) ;* runtime error ARRAY_SUBS
3.45 DIR()
Get file information:
3.46 DIV()
CRT DIV(400, 200) ;* 2
CRT DIV(200, 400) ;* 0.5
CRT DIV(200, -400) ;* -0.5
PRECISION 9
CRT DIV(1, 10000000000) ;* 0
PRECISION 17
CRT DIV(1, 10000000000) ;* 0.0000000001
a_zero = 0
zero_div = DIV(1, a_zero) ;* Divide by zero !!
CRT zero_div ;* 0.0nan
REM Page 50
3.47 DROUND()
PRECISION 6 ;* non-dependent on PRECISION setting
FOR i = 0 TO 20
CRT DROUND(3.14159265358979323846, i)
NEXT i
Output:
3
3.1
3.14
3.142
3.1416
3.14159
3.141593
3.1415927
3.14159265
3.141592654
3.1415926536
3.14159265359
3.14159265359
3.1415926535898
3.14159265358979
3.141592653589793
3.1415926535897932
3.14159265358979324
3.141592653589793238
3.1415926535897932385
3.14159265358979323846
note: negative result in line 4 is caused by the first bit of binary result being set.
REM Page 51
3.49 ENCRYPT()
As a sample of usage – encode a text to base64 (useful if you’re going to store hexadecimal
data in a table):
INCLUDE JBC.h
CRT ENCRYPT('This is a test line' : @FM : CHAR(9), '', JBASE_CRYPT_BASE64)
* Output: VGhpcyBpcyBhIHRlc3QgbGluZf4J
LOOP
READNEXT next_id FROM 9 ELSE BREAK
CRT next_id
REPEAT
Several commands (especially when it’s not possible to run them one-by-one):
REM Page 52
Run an external executable or OS command and capture its output:
Sample result:
3.51 GETENV()
IF NOT(GETENV('JBASE_ERRMSG_ZERO_USED', zero_using)) THEN
CRT 'GETENV failed'
STOP
END
IF zero_using NE 0 THEN
CRT 'Please set JBASE_ERRMSG_ZERO_USED to 0'
STOP
END ELSE
CRT "Setting's all right, let's go..."
END
REM Page 53
3.52 GETLIST, SELECT, READNEXT, OPEN, READ, WRITE
* Here we get a list that was saved before; if it wasn't - select a file
* (T24 environment - we need file F.ENQUIRY)
* This is a program hence OPEN...READ instead of T24 style (OPF...F.READ etc)
*----------------------------------------------------------------------------
OPEN 'F.ENQUIRY' TO f_enq ELSE
CRT 'ERROR OPENING F.ENQUIRY'
STOP
END
LOOP
READNEXT enq_id FROM enq_list ELSE BREAK
// Read the record:
READ rec_enq FROM f_enq, enq_id ELSE
CRT 'ERROR READING THE FILE, ID=' : enq_id : ''
STOP
END
REM Page 54
3.53 GOSUB
var_1 = 1 ; var_2 = 2 ; var_3 = 3
GOSUB MAKE.ARRAY
GOSUB OUTPUT ;* -1^-2^-3
var_1 = -1 ; var_2 = -2 ; var_3 = -3
GOSUB MAKE.ARRAY
GOSUB OUTPUT ;* 1^2^3
var_1 = 1 ; var_2 = -2 ; var_3 = 3
GOSUB MAKE.ARRAY
GOSUB OUTPUT ;* -1^2^-3
STOP
*------------------------Subroutines-----------------------------------
MAKE.ARRAY:
dyn_array = NEGS(var_1 :@FM: var_2 :@FM: var_3)
RETURN
*
OUTPUT:
CRT FMT(dyn_array, 'MCP')
RETURN
If you, for example, forget a RETURN in MAKE.ARRAY section the execution will continue
till the next RETURN, i.e. section OUTPUT will be executed 6 times instead of 3.
3.54 GROUPSTORE()
Insert the variable contents into dynamic array (or replace an element in it):
REM Page 55
3.55 FIELD(), COL1(), COL2()
a_string = 'ABC/DEF/QWE/XYZ'
* One field
CRT FIELD(a_string, '/', 2) ;* DEF
CRT COL1() ;* 4 - position right before "DEF"
CRT COL2() ;* 8 - position right after it
CRT FIELD(a_string, '/', -2) ;* ABC - negative doesn't work here
;* so 1st element is returned by default
* Alternate way
CRT a_string[ '/', 2, 1 ] ;* DEF
* More than one field
CRT FIELD(a_string, '/', 2, 2) ;* DEF/QWE
CRT COL1() ;* 4
CRT COL2() ;* 12
CRT a_string[ '/', 2, 3 ] ;* DEF/QWE/XYZ
CRT DQUOTE(FIELD(a_string, '/', 2, 99))
;* "DEF/QWE/XYZ" - all after 1st one
* Delimiter can consist of several characters:
CHANGE '/' TO '->' IN a_string ; CRT a_string ;* ABC->DEF->QWE->XYZ
CRT FIELD(a_string, '->', 2) ;* DEF
CRT FIELD(a_string, '->', 2, 2) ;* >DEF->QWE, should be: DEF->QWE
REM Page 56
3.57 FIND, FINDSTR
dyn_array = 'ABC' \
:@FM: 'DEF' :@VM: '123' :@VM: 'XYZ' :@VM: '456' \
:@FM: '789' \
:@FM: '---' : @SM: 'XYZ'
GOSUB INIT
FIND 'XYZ' IN dyn_array SETTING field_posn, value_posn ELSE NULL
CRT field_posn, value_posn ;* 2 3
GOSUB INIT
FIND 'XYYYZ' IN dyn_array SETTING field_posn, value_posn ELSE NULL
CRT field_posn, value_posn ;* 0 0
GOSUB INIT
FIND 'XYZ' IN dyn_array, 2 SETTING field_posn, value_posn, subval_posn ELSE NULL
CRT field_posn, value_posn, subval_posn ;* 4 1 2
GOSUB INIT
* FIND looks for whole string match, FINDSTR can find a substring
FIND 'XY' IN dyn_array SETTING field_posn, value_posn ELSE NULL
CRT field_posn, value_posn ;* 0 0
GOSUB INIT
FINDSTR 'XY' IN dyn_array SETTING field_posn, value_posn ELSE NULL
CRT field_posn, value_posn ;* 2 3
STOP
INIT:
field_posn = 0 ; value_posn = 0 ; subval_posn = 0
RETURN
3.58 FOLD()
Program:
a_string = 'Lorem ipsum dolor sit amet, consectetur adipisici elit, ' \
: 'sed do eiusmod tempor incididunt ut labore et dolore magna ' \
: 'aliqua. Ut enim ad minim veniam, quis nostrud exercitation ' \
: 'ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis ' \
: 'aute irure dolor in reprehenderit in voluptate velit esse ' \
: 'cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat ' \
: 'cupidatat non proident, sunt in culpa qui officia deserunt ' \
: 'mollit anim id est laborum.'
the_fold = FOLD(a_string, 35)
CHANGE @FM TO CHAR(10) IN the_fold
CRT the_fold
Output:
REM Page 57
exercitation ullamco laboris nisi
ut aliquip ex ea commodo
consequat. Duis aute irure dolor
in reprehenderit in voluptate
velit esse cillum dolore eu fugiat
nulla pariatur. Excepteur sint
occaecat cupidatat non proident,
sunt in culpa qui officia deserunt
mollit anim id est laborum.
3.59 FOR...NEXT...STEP...CONTINUE...BREAK
dyn_array = ''
FOR i = 1 TO 10
IF i EQ 3 THEN CONTINUE
dyn_array<-1> = i
NEXT i
* we can also pass from the end to beginning; step isn't necessarily 1
FOR j = 10 TO 1 STEP -2
IF j EQ 4 THEN BREAK
dyn_array<-1> = j
NEXT j
CRT FMT(dyn_array, 'MCP') ;* 1^2^4^5^6^7^8^9^10^10^8^6
REM Page 58
Strings:
* split a string
the_string = 'LONG STRING TO BE SPLIT'
the_split = FMT(the_string, '10L')
CRT OCONV(the_split, 'MCP') ;* LONG STRIN.G TO BE SP.LIT
* hexadecimal output
CRT OCONV(the_split, 'MX')
* Output:
* 4C4F4E4720535452494EFB4720544F204245205350FB4C495420202020202020
*
* Remove non-alphabetic symbols:
CRT OCONV(the_split, 'MCA') ;* LONGSTRINGTOBESPLIT
* Remove all alphabetic symbols:
CRT OCONV(OCONV(the_split, 'MC/A'), 'MX') ;* 20FB202020FB20202020202020
* Note FB symbols in the output above.. see what's that
CRT OCONV('FB', 'MCXD') ;* 251 a.k.a. @TM
CHANGE @TM TO '->' IN the_split ; CRT the_split ;* LONG STRIN->G TO BE SP->LIT
* Remove non-numeric symbols:
CRT OCONV('another 1 bites the dust', 'MCN') ;* 1
* Remove all numeric symbols:
CRT OCONV('another 1 bites the dust', 'MC/N') ;* another bites the dust
* formatting
CRT SQUOTE(FMT(the_string, '30L')) ;* 'LONG STRING TO BE SPLIT '
CRT SQUOTE(FMT(the_string, '30R')) ;* ' LONG STRING TO BE SPLIT'
* replace some data
CRT OCONV(the_string, 'MCC;STRING;DATA') ;* LONG DATA TO BE SPLIT
* change case
CRT OCONV(the_string, 'MCL') ;* long string to be split
CRT OCONV('do it', 'MCU') ;* DO IT
CRT OCONV(the_string, 'MCT') ;* Long String To Be Split
* extract delimited fields: skip 1 space-delimited word, take 3 from that point
CRT OCONV(the_string, 'G1 3') ;* STRING TO BE
Numbers:
* amounts
amount_fcy = 1234
CRT FMT(amount_fcy, 'R%7') ;* 0001234
amount_fcy += 0.56
CRT FMT(amount_fcy, 'R2*19') ;* ************1234.56
CRT SQUOTE(FMT(amount_fcy, 'L2,#19')) ;* '1,234.56 '
CRT FMT(-amount_fcy, 'R2,C&*$#15') ;* $1,234.56CR
CRT FMT(amount_fcy,'L0') ;* 1235
* phone numbers
CRT FMT(1234567890, 'R((###) ###-###)') ;* (234) 567-890
CRT FMT(74952223355, 'R(+# (#3) #3-#2-#2)') ;* +7 (495) 222-33-55
* FMT() and OCONV() are often interchangeable;
* though it's not the case for next 2 lines...
CRT DQUOTE(FMT(123456.78, 'R2,$#15')) ;* " $123,456.78"
CRT DQUOTE(OCONV(123456.78, 'R2,$#15')) ;* Error in Range Test
REM Page 59
User exits:
Create the date and time stamp in T24 style (what’s used in audit trail field date.time):
date_time = TIMEDATE()
V.TIME = date_time[1,2] : date_time[4,2]
V.DATE = ICONV(date_time[10,11], 'D')
date_time = OCONV(V.DATE, 'DY2') : FMT(OCONV(V.DATE, 'DM'), "R0%2") \
: FMT(OCONV(V.DATE, 'DD'), "R0%2") : V.TIME
CRT date_time ;* e.g. 1305302237
3.61 IN
Receive raw data from keyboard:
LOOP
IN in_key
IF in_key EQ 27 THEN ;* ESC seen
IN in_key_2 FOR 2 THEN ;* Function Key?
IN in_key_3 FOR 2 THEN
CRT ''
BEGIN CASE
CASE in_key_2 EQ 79 AND in_key_3 EQ 80
CRT 'F1 detected'
CASE in_key_2 EQ 79 AND in_key_3 EQ 81
CRT 'F2 detected'
END CASE
END
END ELSE
CRT ''
CRT 'ESC pressed, exiting'
STOP
END
END
REPEAT
REM Page 60
3.62 INDEX()
Find a substring:
3.63 INMAT()
Get the number of elements in dimensioned array.
DIM cust_rec(99)
MAT cust_rec = ''
CRT INMAT(cust_rec) ;* 99
DIM cust_rec(299) ;* array re-dimensioning works not in all emulations
cust_rec(150) = 'Y'
CRT INMAT(cust_rec) ;* 299
CRT INMAT() ;* 0 - no operations like MATREAD occured yet
REM Page 61
3.64 INPUT, DOWNCASE()
Ask user for input for 60 seconds; every 3 seconds update the counter:
time_out = 60
GOSUB UPD.CNT
answer = ''
wait_time = 30 ;* 3 seconds
LOOP
WHILE 1 DO
INPUT answer, 1 : FOR wait_time ELSE
time_out -= 3
IF time_out LE 0 THEN answer = '###'
END
BEGIN CASE
CASE answer EQ '' ; GOSUB UPD.CNT
CASE DOWNCASE(answer) EQ 'b' ; CRT @(-9): 'Wrong... boom!' ; BREAK
CASE DOWNCASE(answer) EQ 'r' ; wait_time = 5 ;* make it faster
CASE answer EQ '###' ; CRT ' Battery low...exit' ; BREAK
CASE 1 ; CRT ' Boom!' ; BREAK
END CASE
REPEAT
STOP
UPD.CNT:
CRT @(0):'Seconds left: ': FMT(time_out, '2R') : ', (r)ed or (b)lue wire':
RETURN
CRT @(-1)
INPUT @(17,2):answer,50,'_..':_
User screen:
? _________________________________________________
3.65 INSERT()
dyn_array = 'Field 1' :@VM: 2 :@VM: 3 :@VM: 5 :@FM: 'Field 2'
out_array = INSERT(dyn_array, 1,4 ; 'Field1Value4')
CRT OCONV(out_array, 'MCP') ;* Field 1]2]3]Field1Value4]5^Field 2
REM Page 62
3.66 IOCTL()
* Program to get the last update time for particular record
INCLUDE JBC.h
the_file = SENTENCE(1)
the_rec = SENTENCE(2)
OPEN the_file TO F.TEST.FILE ELSE ABORT 201, the_file
V.NAME = the_rec
V.STAT = IOCTL(F.TEST.FILE, JIOCTL_COMMAND_FINDRECORD_EXTENDED, V.NAME)
IF V.STAT THEN
date_time = V.NAME<2>
the_date = OCONV(date_time, 'U0ff1') ; the_time = OCONV(date_time, "U0ff0")
CRT OCONV(the_date, 'D4') : ' at ' : OCONV(the_time, \MTS\)
END ELSE
CRT '*** FAILED TO GET RECORD INFO ***'
END
Processing sequential files with long (with more than 1024 characters) lines.
Step 1. Program to create such file:
REM Page 63
Ends of lines in that file look this way:
------1040------1050------1060------1070------1080------1090------1100
------1040------1050------1060------1070------1080------1090------1100
------1040------1050------1060------1070------1080------1090------1100
------1040------1050------1060------1070------1080------1090------1100
------1040------1050------1060------1070------1080------1090------1100
------1040------1050------1060------1070------1080------1090------1100
------1040------1050------1060------1070------1080------1090------1100
------1040------1050------1060------1070------1080------1090------1100
------1040------1050------1060------1070------1080------1090------1100
------1040------1050------1060------1070------1080------1090------1100
READSEQ by default reads lines up to 1024 characters; the rest of such line would be read by
subsequent READSEQ. To override this we can use IOCTL() function.
Step 2. Program to read file:
INCLUDE JBC.h
OPENSEQ '.', 'test.txt' TO f_in THEN NULL
ELSE CRT 'File open error' ; STOP
counter = 0
GOSUB READ.LINE
GOSUB READ.LINE ;* one time isn't enough in this mode
GOSUB READ.LINE
STOP
READ.LINE:
counter ++
READSEQ the_line FROM f_in ELSE CRT 'File read error' ; STOP
CRT counter : ':' : DQUOTE(the_line[1,30] : '...' : the_line[30])
RETURN
END
Program output:
1:"--------10--------20--------30...--1000------1010------1020----"
2:"--1030------1040------1050----...------1080------1090------1100"
3:"--------10--------20--------30...------1080------1090------1100"
REM Page 64
3.67 ISCNTRL()
Check if the expression consists entirely of control characters:
CRT ISDIGIT(123) ;* 1
CRT ISDIGIT(-123) ;* 0
CRT ISDIGIT(123.456) ;* 0
CRT ISLOWER('qwertz') ;* 1
CRT ISLOWER('qweRtz') ;* 0
CRT ISPRINT('abcde') ;* 1
CRT ISPRINT('abcde' : @FM) ;* 0
CRT ISSPACE('') ;* 0
CRT ISSPACE(' ') ;* 1
CRT ISUPPER('QWERTZ') ;* 1
CRT ISUPPER('QWERTZ1') ;* 0
REM Page 65
3.69 ITYPE()
* Data preparation
file_name = 'F.TEMP'
EXECUTE 'DELETE-FILE ' : file_name
EXECUTE 'CREATE-FILE ' : file_name : ' 1 101 TYPE=J4'
OPEN file_name TO f_temp ELSE ABORT 201, file_name
OPEN 'DICT', file_name TO f_temp_dict ELSE ABORT 201, file_name : ']D'
* Field 1 dictionary entry
rec_dict_type_d = ''
rec_dict_type_d<1> = 'D'
rec_dict_type_d<2> = '1'
rec_dict_type_d<5> = '25L'
rec_dict_type_d<6> = 'S'
WRITE rec_dict_type_d TO f_temp_dict, 'FOOTWEAR'
* I-descriptors
fwsize_idesc_name = 'FWSIZE'
rec_dict_type_i = ''
rec_dict_type_i<1> = 'I'
rec_dict_type_i<2> = 'FOOTWEAR[":", 2, 1]'
rec_dict_type_i<4> = fwsize_idesc_name
rec_dict_type_i<5> = '3R'
rec_dict_type_i<6> = 'S'
WRITE rec_dict_type_i TO f_temp_dict, fwsize_idesc_name
fwname_idesc_name = 'FWNAME'
rec_dict_type_i<2> = 'FOOTWEAR[":", 1, 1]'
rec_dict_type_i<4> = fwname_idesc_name
rec_dict_type_i<5> = '12L'
WRITE rec_dict_type_i TO f_temp_dict, fwname_idesc_name
* Data records
rec_data = '' ; rec_data<1> = 'SLIPPERS:8'
WRITE rec_data TO f_temp, 'JIM'
rec_data = '' ; rec_data<1> = 'BOOTS:10'
WRITE rec_data TO f_temp, 'GREG'
rec_data = '' ; rec_data<1> = 'SLIPPERS:5'
WRITE rec_data TO f_temp, 'ALAN'
* Data is prepared; now proceed it
@FILENAME = file_name
READ fwsize_idesc_rec FROM f_temp_dict, fwsize_idesc_name ELSE ABORT
READ fwname_idesc_rec FROM f_temp_dict, fwname_idesc_name ELSE ABORT
SSELECT f_temp TO staff_list
LOOP
READNEXT next_id FROM staff_list ELSE BREAK
@ID = next_id
READ @RECORD FROM f_temp, @ID ELSE ABORT
fw_size = ITYPE(fwsize_idesc_rec) ; fw_name = ITYPE(fwname_idesc_rec)
CRT OCONV(@ID, 'MCT') : ' wears ' : DOWNCASE(fw_name) : ', size: ' : fw_size
REPEAT
REM Page 66
Program output:
GREG BOOTS 10
ALAN SLIPPERS 5
JIM SLIPPERS 8
3.70 JBASECOREDUMP()
Example of usage: get T24 application structure (log in to T24 and log out before running
this program):
$INSERT I_COMMON
$INSERT I_EQUATE
ret_code = JBASECOREDUMP('all-vars.txt', 0)
CALL/GOSUB stack
Backtrace:
#0: jmainfunction.b:7
#1: test.b:7 -> Line 7 , Source jmainfunction.b
Backtrace log:
Program jmainfunction.b, Line 7, Stack level 0
Line 0 , Source jmainfunction.b , Level 0
>>> Program test.b, Line 7, Stack level 1
Line 7 , Source jmainfunction.b
COMMON variables
REM Page 67
003FF278 : T.RETURN.DATA : (V) Integer : 0
003FEF30 : T.CONTROLWORD : (V) Integer : 0
003FF4F8 : F.STATIC.TEXT : (V) Integer : 0
01D93B08 : C$MULTI.BOOK : (V) Integer : 0
01D93BA8 : C$DE.EU.LIST : (V) Integer : 0
003FEBC0 : PGM.TYPE.NEXT : (V) Integer : 0
003FE260 : A : (V) Integer : 0
003FE3C8 : C : (V) Integer : 0
003FF520 : F.FILE.CONTROL : (V) Integer : 0
003FE4B8 : E : (V) Integer : 0
01DA7A68 : F(0) : (V) String : 0 bytes at address 22131690 :
01DA7A90 : F(1) : (V) String : 17 bytes at address 003FD838 : XX.LL.DESCRIPTION
01DA7AB8 : F(2) : (V) String : 17 bytes at address 01D932F8 : XX.LL.SHORT.DESCR
...
01A407E8 : N(1) : (V) String : 4 bytes at address 019C5AA0 : 35.3
01A40810 : N(2) : (V) String : 4 bytes at address 019C5B30 : 15.3
01A40838 : N(3) : (V) String : 5 bytes at address 019C5BC0 : 3.1.C
01A40860 : N(4) : (V) String : 5 bytes at address 019C5C50 : 3.1.C
...
01A5DDF8 : T(1) : (V) String : 1 bytes at address 0181DA68 : A
01A5DE20 : T(2) : (V) String : 1 bytes at address 0181DAB0 : A
01A5DE48 : T(3) : (V) String : 0 bytes at address 22119A4C :
01A5DE70 : T(4) : (V) String : 0 bytes at address 22119A4C :
...
0181C430 : ID.N : (V) Scaled (13) float : 4.2
...
01A28030 : CHECKFILE(1) : (V) String : 0 bytes at address 22119A4C :
01A28058 : CHECKFILE(2) : (V) String : 0 bytes at address 22119A4C :
01A28080 : CHECKFILE(3) : (V) String : 17 bytes at address .. TRANSACTION^1^L.A
01A280A8 : CHECKFILE(4) : (V) String : 17 bytes at address .. TRANSACTION^1^L.A
...
01A31CE0 : CONCATFILE(1) : (V) String : 0 bytes at address 22119A4C :
01A31D08 : CONCATFILE(2) : (V) String : 0 bytes at address 22119A4C :
01A31D30 : CONCATFILE(3) : (V) String : 0 bytes at address 22119A4C :
01A31D58 : CONCATFILE(4) : (V) String : 0 bytes at address 22119A4C :
...
0181C390 : ID.CONCATFILE : (V) String : 2 bytes at address 019C5A10 : AR
...
01DC4FC8 : R.OPF(497) : (V) Integer : 0
01DC4FF0 : R.OPF(498) : (V) Integer : 0
01DC5018 : R.OPF(499) : (V) Integer : 0
01DC5040 : R.OPF(500) : (V) Integer : 0
003FF1D8 : T.OPF : (V) Integer : 0
003FF250 : T.RAT : (V) Integer : 0
01DB1718 : R.NEW(0) : (V) Integer : 0
01DB1740 : R.NEW(1) : (V) Integer : 0
01DB1768 : R.NEW(2) : (V) Integer : 0
01DB1790 : R.NEW(3) : (V) Integer : 0
REM Page 68
01DB17B8 : R.NEW(4) : (V) Integer : 0
...
003FF3E0 : F.FILE$NAU : (V) Integer : 0
003FF3B8 : F.FILE$HIS : (V) Integer : 0
01D92C20 : SPARE.FKEY13 : (V) Integer : 0
01D92C48 : SPARE.FKEY14 : (V) Integer : 0
003FF548 : T.VAL.ASSOC : (V) Integer : 0
01D92C70 : SPARE.FKEY15 : (V) Integer : 0
01D92C98 : SPARE.FKEY16 : (V) Integer : 0
003FF2C8 : T.SUB.ASSOC : (V) Integer : 0
01D93A90 : USING.EBCDIC : (V) Integer : 0
003FE5A8 : V$FUNCTION : (V) String : 4
bytes at address 003FD4E8 : TEST
003FEF08 : CLEAR.SCREEN : (V) Integer : 0
003FF750 : COMI.DEFAULT : (V) Integer : 0
003FECD8 : SCREEN.TITLE : (V) Integer : 0
003FE8A0 : INPUT.BUFFER : (V) Integer : 0
003FF6B0 : F.IDS.LATEST : (V) Integer : 0
003FF0E8 : T.MULTI.PAGE : (V) Integer : 0
003FE378 : AUTH.QUALITY : (V) Integer : 0
003FEA30 : LEVEL.STATUS : (V) Integer : 0
003FE6C0 : ID.CONCATFILE : (V) String : 2
bytes at address 003FD618 : AR
003FF2F0 : BATCH.DETAILS : (V) Integer : 0
003FE990 : OVERRIDE.FLAG : (V) Integer : 0
003FEE90 : R.SPF.SYSTEM : (V) Integer : 0
01D93D60 : F.T24.SESSION : (V) Integer : 0
003FF188 : T.MULTI.TEXT : (V) Integer : 0
STANDARD Variables in SUBROUTINE main()
008DFCCC : PASSED.NO : (V) String : 0 bytes at address 22131690 :
008DFCF4 : PASSED.CHAR : (V) String : 0 bytes at address 22131690 :
008DFD1C : ret_code : (V) String : 0 bytes at address 22131690 :
3.71 JBASESubroutineExist()
Check if a subroutine exists in current environment:
subr_name = 'CDD'
result = CALLC JBASESubroutineExist(subr_name, subr_info)
CRT result ;* 1 (in T24 environment)
subr_name = 'QWERTY'
result = CALLC JBASESubroutineExist(subr_name, subr_info)
CRT result ;* 0
REM Page 69
3.72 JQLCOMPILE(), JQLEXECUTE(), JQLFETCH(), JQLGET-
PROPERTY()
Working with compiled jQL statements.
INCLUDE jQLProperties.h
message = 0
ret_code = JQLCOMPILE(jql_statement, jql_query, 0, message)
IF message NE 0 THEN CRT 'Statement compilation error' ; STOP
select_var = ''
ret_code = JQLEXECUTE(jql_statement, select_var)
IF ret_code NE 0 THEN CRT 'JQLEXECUTE returned', ret_code ; STOP
LOOP
GOSUB GET.NEXT
UNTIL fetch_ret_code NE 1
REPEAT
STOP
GET.NEXT:
fetch_ret_code = JQLFETCH(jql_statement, control_var, data_var)
IF fetch_ret_code NE 1 THEN RETURN
ret_code = JQLGETPROPERTY(property_value, jql_statement, 0, \
STMT_PROPERTY_EXECUTE_COUNT)
CRT '@ID #' : property_value : ':' , data_var<1>
IF ret_code NE 0 THEN CRT 'JQLGETPROPERTY returned', ret_code ; STOP
RETURN
END
Output:
REM Page 70
@ID #488: 80044228
@ID #489: 80044233
@ID #490: 80045024
key_pressed = UPCASE(KEYIN())
IF key_pressed EQ 'Q' THEN BREAK ;* exit if q or Q was pressed
REPEAT
3.74 LATIN1()
utf_line = CHAR(XTD('C3')) \
: CHAR(XTD('9F')) \ ;* c3 9f: LATIN SMALL LETTER SHARP S
: CHAR(XTD('C3')) \
: CHAR(XTD('9D')) ;* c3 9d: LATIN CAPITAL LETTER Y WITH ACUTE
lat_line = LATIN1(utf_line)
CRT lat_line, SEQ(lat_line[1,1]), SEQ(lat_line[2,1])
REM Page 71
3.76 LOCATE, INS, MINIMUM(), MAXIMUM()
I prefer FIND to search an array. But LOCATE can be used for sorting:
dyn_array = ''
FOR i = 1 TO 1000
dyn_array := @FM : RND(1000)
NEXT i
DEL dyn_array<1>
sorted_array = ''
3.77 LOWER()
Convert field, value etc marks to one-level-lower ones:
REM Page 72
3.78 MAKETIMESTAMP()
There are no milliseconds in the output under AIX so I found an appropirate C program
example on the Net and tried to obtain the proper time stamp there:
Step 1. C program nanosec.c:
#include <stdio.h>
#include <sys/time.h>
#include <stdlib.h>
#include <sys/types.h>
void main(){
struct timeval tm;
gettimeofday( &tm, NULL );
printf( "%d.%6d\n", tm.tv_sec, tm.tv_usec );
}
the_time = TIME()
EXECUTE './nanosec' CAPTURING std_out
CRT 'Timestamp (up to nanoseconds) is: ' : std_out
CRT 'Timestamp (up to milliseconds) is: ' \
: FMT(std_out, 'R3')
REM Page 73
Sample output:
3.79 MATBUILD
Build a dynamic array from dimensioned one:
SUBROUTINE SOME.TEST
* T24 input routine
$INSERT I_COMMON
$INSERT I_EQUATE
DIM dim_array(40)
MAT dim_array = 'Element '
FOR i = 1 TO 40
dim_array(i) := i
NEXT i
MATBUILD delim_array FROM dim_array, 3, 7 USING ":"
CRT delim_array ;* Element 3:Element 4:Element 5:Element 6:Element 7
REM Page 74
3.80 MATCH(ES)
* T24 IDs matching
transfer_id = 'FT130172HQJ4'
CRT transfer_id MATCHES "'FT'5N5X" ;* 1
hist_id = 'FT130172HQJ4;1'
CRT hist_id MATCHES "'FT'5N5X" ;* 0
CRT hist_id MATCHES "'FT'5N5X;1N" ;* 1
* date
start_date = '2011-10-25'
CRT start_date MATCHES "4N'-'2N'-'2N" ;* 1
* emulations compatibility
cust_name = 'JOHN DORY'
CRT cust_name MATCH "JOHN..." ;* 1 under prime, 0 under jbase
CRT cust_name MATCH "'JOHN'..." ;* 1 under prime, 0 under jbase
CRT cust_name MATCH "'JOHN'0X" ;* 1 under both
CRT cust_name MATCH "'John'..." ;* 0 under both
* "C" - alphanumeric - isn't supported at all under prime
CRT '2HQJ4' MATCHES "5C" ;* 1 under jbase emulation
* numbers
CRT 9.99 MATCHES "0N'.'2N" ;* 1
CRT '.99' MATCHES "0N'.'2N" ;* 1
* avoid messing up data with patterns (example for prime):
cust_address = '3RD FLOOR, 17A ELM STREET'
CRT cust_address MATCH "...17A..." ;* 0 - 17A means 17 alpha characters
CRT cust_address MATCH "...'17A'..." ;* 1 - here '17A' is a string to search
3.81 MATPARSE
If the dynamic array taken into a dimensioned one has more elements than the dimensioned
does, extra elements will be placed to zero element of target array; if dimensioned array has
2 dimensions - it will be populated “left-to right”.
REM Page 75
Example:
DIM dim_array(100)
dyn_array = '' ; delim_array = ''
FOR i = 1 TO 100
dyn_array<-1> = i
delim_array := i*2 : '-'
NEXT i
* Full copy
MATPARSE dim_array FROM dyn_array
CRT dim_array(1) ;* 1
CRT dim_array(100) ;* 100
* Using different array delimiter
MAT dim_array = 'Default'
MATPARSE dim_array FROM delim_array USING '-'
CRT dim_array(1) ;* 2
CRT dim_array(100) ;* 200
* Partial copy
MAT dim_array = 'Default'
MATPARSE dim_array, 3, 7 FROM dyn_array
CRT dim_array(1) ;* Default
CRT dim_array(3) ;* 1
CRT dim_array(5) ;* 3
CRT dim_array(100) ;* Default
* "Over-copy"
FOR i = 101 TO 103 ;* add 3 elements to dynamic array
dyn_array<-1> = i
NEXT i
MAT dim_array = 'Default'
MATPARSE dim_array FROM dyn_array
CRT dim_array(1) ;* 1
CRT dim_array(100) ;* 100
the_extra = dim_array(0) ;* all excess elements are here
CHANGE @FM TO '>>>' IN the_extra
CRT the_extra ;* 101>>>102>>>103
* 2-dimensioned array population: "left-to-right":
DIM two_dim_array(100,2)
MATPARSE two_dim_array FROM dyn_array
CRT two_dim_array(1,1) ;* 1
CRT two_dim_array(1,2) ;* 2
CRT two_dim_array(2,1) ;* 3
CRT two_dim_array(2,2) ;* 4
CRT two_dim_array(50,2) ;* 100
CRT DQUOTE(two_dim_array(100,1)) ;* ""
REM Page 76
3.82 MAXIMUM()
PRECISION 5
dyn_array = 4.29442 :@AM: -3.60441 :@VM :4.29445 :@AM: 2.00042 \
:@SM: -33.90228
CRT MAXIMUM(dyn_array) ;* 4.29445
* non-numeric elements are ignored
dyn_array<2,1> = '9000,00'
CRT MAXIMUM(dyn_array) ;* still 4.29445
* PRECISION matters
PRECISION 2
CRT MAXIMUM(dyn_array) ;* now 4.29442
3.83 MOD()
In this sample a dot will be output to the screen after every 1000 iterations:
FOR i = 1 TO 100000
IF MOD(i, 1000) EQ 0 THEN
CRT '.':
END
* some processing here
NEXT i
3.84 MSLEEP()
CRT MAKETIMESTAMP(DATE(), TIME(), '') ;* e.g. 1353068005.934
MSLEEP(100) ;* 0.1 sec
CRT MAKETIMESTAMP(DATE(), TIME(), '') ;* e.g. 1353068006.044
MSLEEP(3000) ;* 3 sec
CRT MAKETIMESTAMP(DATE(), TIME(), '') ;* e.g. 1353068009.039
MSLEEP 3000 ;* this syntax also works
CRT MAKETIMESTAMP(DATE(), TIME(), '') ;* e.g. 1353068012.035
* Sleep until the beginning of the next hour
time = OCONV(TIME(), 'MT')
sleep_until = time[1, 2] + 1
IF sleep_until EQ 24 THEN sleep_until = '00'
sleep_until := ':00'
CRT 'Will sleep until ' : sleep_until ;* e.g. Will sleep until 13:00
SLEEP sleep_until
CRT OCONV(TIME(), 'MTS'), ',', "I'm back as promised"
REM Page 77
3.85 NEGS()
dyn_array = 1 :@FM: 2 :@VM :3
GOSUB PROC.IT ;* -1^-2]-3
dyn_array = 1 :@FM: '' :@VM :3
GOSUB PROC.IT ;* -1^0]-3
dyn_array = -1 :@FM: -2 :@VM: -3
GOSUB PROC.IT ;* 1^2]3
dyn_array = 1 :@SM: -2 :@FM: 3
GOSUB PROC.IT ;* -1\2^-3
dyn_array<-1> = 'A text'
GOSUB PROC.IT ;* Non-numeric value -- ZERO USED
;* -1\2^-3^0
STOP
PROC.IT:
CRT FMT(NEGS(dyn_array), 'MCP')
RETURN
3.86 NUM()
It doesn’t check if every character in expression is a numeric (that’s what ISDIGIT is for) –
rather if an expression can be considered as a number:
CRT NUM('') ;* 1
CRT NUM('123334440.12') ;* 1
CRT NUM('1233344.40.12') ;* 0
CRT NUM('1,233,344.40') ;* 0 - thousand delimiters don't do
CRT NUM('1 233 344.40') ;* 0 - neither do spaces
CRT NUM('00012') ;* 1 - leading zeroes are ok
CRT NUM('-123334440.12') ;* 1 - minus is ok...
CRT NUM('123334440.12-') ;* 0 - ...but not everywhere
CRT NUM('+123334440.12') ;* 1
CRT NUM('6.02e23') ;* 0 - E notation doesn't work
CRT NUM('1233Q34440.12') ;* 0 - of course it's not
CRT NUM(2 + 2) ;* 1
CRT NUM('.00') ;* 1
REM Page 78
3.87 OPENSEQ, READSEQ, CLOSESEQ
In this example we read a flat file and proceed it line by line (line length is not limited):
Output:
3.88 OSBREAD
The following program, being put to test.b file, reads its source and outputs it to the screen:
REM Page 79
3.89 OSREAD
Unlike OSBREAD, it reads not a portion but the whole file so take care about file size. Also,
it requires file name rather than file variable.
Example:
lookup = 'the_pi'
GOSUB FIND.IT
lookup = 'longer_pi'
GOSUB FIND.IT
lookup = 'something_wrong'
GOSUB FIND.IT
STOP
FIND.IT:
RETURN
END
REM Page 80
Output:
note: With “PRECISION 10” clause at program start longer pi would be float as well.
3.90 PRECISION
Don’t believe manuals, it can be greater than 9. A little program to illustrate its behaviour:
var_1 = '0.123456789012345678901234567890123456789012345678901234567890'
var_2 = '0.1234567890123456789012345678901234567890123456789012345678901'
PRECISION 13
GOSUB TEST ;* Equal
PRECISION 17
GOSUB TEST ;* Not equal
STOP
TEST:
results = 'Not equal' :@FM: 'Equal'
compare = (var_1 = var_2)
CRT results<compare + 1>
RETURN
END
PRECISION 6
CRT 2 / 3 ;* 0.666666 - truncation, not rounding
PRECISION 8
CRT 2 / 3 ;* 0.66666666
3.91 PRINTERR
PRINTERR 201 : CHAR(254) : "CUSTOMERS"
Output:
** Error [ 201 ] **
Unable to open file CUSTOMERS
REM Page 81
3.92 PROMPT
Change the prompt used in INPUT statement:
3.93 PUTENV
See the impact of JBASE ERRMSG ZERO USED setting:
zero_use = 'JBASE_ERRMSG_ZERO_USED'
IF NOT(PUTENV(zero_use : '=35')) THEN
CRT 'PUTENV failed'
STOP
END
CRT 'See the impact of JBASE_ERRMSG_ZERO_USED'
CRT '=35'
CRT var_1 ;* variable not assigned; nothing is being output
IF NOT(PUTENV(zero_use : '=0')) THEN
CRT 'PUTENV failed'
STOP
END
CRT '=0'
CRT var_1 ;* Invalid or uninitialised variable -- NULL USED ,
;* Var (UNKNOWN) , Line 17 , Source test.b
3.94 PWR()
number = 2
power = 31
CRT "2 GB is " : number ^ power ;* 2 GB is 2147483648
CRT "2 GB is definitely " : PWR(number, power)
;* 2 GB is definitely 2147483648
CRT "-2 GB is " : NEG(number)^power ;* -2 GB is -2147483648
CRT "2 to the power of 31.5 is " : PWR(number, power + 0.5)
;* 2 to the power of 31.5 is 3037000499.9761
CRT "-2 to the power of 31.5 is " : PWR(NEG(number), power + 0.5)
;* -2 to the power of 31.5 is 0.0nan
REM Page 82
3.95 RAISE()
Opposite of LOWER().
3.96 READBLK
IF NOT(GETENV('TAFC_HOME', tafc_home)) THEN
CRT 'TAFC_HOME not defined'
STOP
END
file_in = 'RELEASE'
file_info = DIR(tafc_home : '/' : file_in)
file_size = file_info<1>
OPENSEQ tafc_home, file_in TO f_release ELSE
CRT 'Failed to open', file_in
STOP
END
block_size = MINIMUM(file_size :@FM: 512)
READBLK rel_info FROM f_release, block_size ELSE
CRT 'Failed to read', file_in
STOP
END
CRT rel_info[1, INDEX(rel_info, CHAR(10), 1)] ;* 1st line, e.g.:
;* jBase Release : R11.0.0.0
REM Page 83
3.97 READL
REM Page 84
Output:
NEXT:REC1
NEXT:REC2
PREVIOUS:REC3 ---> expected to be REC1
READPREV 2 FAILED ---> would be true if we had REC1 as expected
PREVIOUS:
READNEXT 3 FAILED ---> expected to be REC1
NEXT:
note: Works as expected under jbase emulation; however we’re under prime in T24.
LINE 1
LINE 2
LINE 3
Step 2. A program:
dir_in = '.'
file_in = 'input-file'
OPENSEQ dir_in, file_in TO f_in ELSE
CRT 'FLAT FILE OPEN ERROR'
STOP
END
LOOP
READSEQ line FROM f_in ELSE BREAK
DEBUG
CRT OCONV(line, 'MX')
REPEAT
CLOSESEQ f_in
REM Page 85
jBASE debugger->S
0011 CRT OCONV(line, 'MX')
jBASE debugger->S
4C494E452031
0012 REPEAT
jBASE debugger->
Step 4. Upload the file input-file in binary mode to Unix server. Run the same program
there:
3.100 READU
In this example a record in the file is opened (or created) and a new field is appended to it.
REM Page 86
Sample output:
F.TEMP........ *A9...........
3.101 READV
Read particular field instead of the whole record:
REM Page 87
3.102 RECORDLOCKED()
SUBROUTINE SOME.TEST
* T24 mainline routine
$INSERT I_COMMON
$INSERT I_EQUATE
RETURN
END
REM Page 88
3.103 REGEXP()
3.104 RELEASE
This program optionally creates file F.TEMP and writes to it a record REC1, on the following
runs it updates that record – puts a new field in it, but only if there’s less than 7 fields;
otherwise we need to release the lock.
REM Page 89
Example:
rec_id = 'REC1'
READU record FROM f_temp, rec_id LOCKED
CRT 'Record locked (' : RECORDLOCKED(f_temp, rec_id) : ')'
STOP
END ELSE NULL
To test “LOCKED” clause run this program at least once (to create the file), then open another
session and run JED there: JED F.TEMP REC1, then return to the first session and try to
execute this program one more time. Output will be:
3.105 REMOVE
Retrieve elements of a dynamic array one by one – and it’s faster than using angle-brackets
notation indicated as “try 4” at the code below (see also the last chapter of this book).
REM Page 90
* This example requires T24 environment
EXECUTE 'SELECT FBNK.ACCOUNT SAMPLE 10' RTNLIST acct_list
* Retrieve @IDs one by one
CRT 'Try 1:'
LOOP
REMOVE acct_id FROM acct_list SETTING status
CRT acct_id
IF status EQ 0 THEN BREAK ;* check the status at the end of the loop
REPEAT ;* otherwise we'll lose the last item
* Alternate method:
CRT 'Try 4:'
count = DCOUNT(acct_list, @FM)
FOR i = 1 TO count
acct_id = acct_list<i>
CRT acct_id
NEXT i
This example shows that current array delimiter can be determined:
record = "Field 1" :@FM: "Field 2" :@SM: " Sub-value" :@VM: "Value"
REMOVE rec_data FROM record SETTING status ; CRT status ;* 2 (FM)
REMOVE rec_data FROM record SETTING status ; CRT status ;* 4 (SM)
REMOVE rec_data FROM record SETTING status ; CRT status ;* 3 (VM)
REMOVE rec_data FROM record SETTING status ; CRT status ;* 0 (end of array)
record = record ;* reset "remove pointer"
REMOVE rec_data FROM record SETTING status ; CRT status ;* 2 (start again)
record := @TM : "Some text"
* data changed; hence we start again...
REMOVE rec_data FROM record SETTING status ; CRT status ;* 2
REMOVE rec_data FROM record SETTING status ; CRT status ;* 4
REMOVE rec_data FROM record SETTING status ; CRT status ;* 3
REMOVE rec_data FROM record SETTING status ; CRT status ;* 5 (text mark)
REMOVE rec_data FROM record SETTING status ; CRT status ;* 0 - that's it...
REM Page 91
3.106 REPLACE()
dyn_array = "Life" :@VM: "is" :@VM: "wonderful" :@FM: '!'
* note semicolon in the next line - quite unusual for jBC...
more_dyn_array = REPLACE(dyn_array, 1, 2; "is really")
* it doesn't mean that some arrays are more dynamic than others... just a name
CRT FMT(dyn_array, 'MCP') ;* Life]is]wonderful^!
CRT FMT(more_dyn_array, 'MCP') ;* Life]is really]wonderful^!
3.108 SEEK
Note that it’s possible to go to position after EOF:
REM Page 92
3.109 SENTENCE()
this_prog = SENTENCE(0) ;* name of this program
phrase_part = 'to understand recursion '
IF SENTENCE(1) EQ '-2' THEN ;* first parameter
CRT TRIM(SENTENCE(2), '"', 'B'): ;* 2nd parameter
CRT phrase_part
END ELSE
CRT phrase_part:
EXECUTE this_prog : ' -2 "you firstly need "'
END
3.110 SEQ()
Opposite to CHAR(). Get character code (and not only ASCII):
CRT SEQ('A') ;* 65
CRT SEQ('AB') ;* still 65 - only one character counts
* Unicode Character 'LATIN SMALL LETTER S WITH CARON' (C5A1)
CRT SEQ(ICONV('C5A1', 'MX')) ;* 353
3.111 SORT
Ascending, left-justified sort of a dynamic array:
REM Page 93
3.112 SSELECT
3.113 SSELECTV
SSELECTV can be used to proceed with a simple sort of dynamic array :
random_list = ''
FOR i = 1 TO 1000
random_list<-1> = FMT(RND(10000), 'R%4') ;* FMT() - for proper sorting
NEXT i
* Sample outputs:
* Got numbers from 3 to 9988
* Got numbers from 7 to 9991
* Got numbers from 12 to 9998
* Got numbers from 6 to 9990
note: As you see, multiplication by 1 strips leading zeroes; trim() could also be used.
REM Page 94
3.114 STATUS()
DELETE not_valid_filevar, 'REC5' SETTING ret_code ON ERROR
CRT 'REC5 - DELETE ERROR'
END
CRT STATUS() ;* -1
CRT ret_code ;* 32768
note: If there’s no data file, values for dictionary part will be displayed.
3.116 STR()
* repeat a variable contents, not necesserily a string
CRT STR('-', 30) ;* ------------------------------
CRT STR('+-', 10) ;* +-+-+-+-+-+-+-+-+-+-
CRT STR(123, 3) ;* 123123123
3.117 SUM()
Results depend on array structure (i.e. set of delimiters):
REM Page 95
3.118 SYSTEM()
Command line parameters and options:
command_line = SYSTEM(1000)
this_prog = command_line<1> ;* name of this program
IF command_line<2> EQ '' THEN
EXECUTE this_prog : ' -Jd par_1 "par 2"'
END ELSE
CRT 'Parameter 1 is:', command_line<2>
CRT 'Parameter 2 is:', command_line<3>
CRT 'Launch option was:', SYSTEM(1001)<2>
END
REM Page 96
Other useful samples:
* get server OS
CRT SYSTEM(1017) ;* WINNT or UNIX
* get program or subroutine name (but not a section)
CRT SYSTEM(40) ;* e.g. test
GOSUB SUB1 ;* output is the same
* get own port number
CRT SYSTEM(18)
* get own PID
CRT SYSTEM(1037)
* get screen size
CRT SYSTEM(2) ;* e.g. 80
CRT SYSTEM(3) ;* e.g. 24
* is there anything in keyboard buffer
CRT SYSTEM(14) ;* 0
* Buffer is not necessarily filled manually
DATA 'QWE'
CRT SYSTEM(14) ;* 4 (includes end-of-line character)
* Prompt...
CRT SYSTEM(26) ;* ? (default one)
PROMPT 'Your choice:'
CRT SYSTEM(26) ;* Your choice:
* Active SELECT
IF NOT(GETENV('TAFC_HOME', tafc_home)) THEN
CRT 'TAFC_HOME not defined'
STOP
END
CLEARDATA ;* otherwise "QWE" will be executed
CRT SYSTEM(11) ;* 0
HUSH ON
EXECUTE 'SELECT ' : tafc_home : '/jbcmessages'
HUSH OFF
CRT SYSTEM(11) ;* 490
STOP
*-----------------------
SUB1:
CRT SYSTEM(40)
RETURN
REM Page 97
3.119 TIME() and @TIME
The former is current time; the latter is program start time:
MSLEEP 3000
CRT @TIME, TIME() ;* e.g. 80557 80560
3.120 TIMESTAMP()
Returns UTC timestamp value:
timestamp = TIMESTAMP()
CRT timestamp ;* e.g. 1370330053.058
CRT (MAKETIMESTAMP(DATE(), TIME(), \
'Europe/Amsterdam') - timestamp) / 3600 ;* -1 or -2 (depending on
CRT (MAKETIMESTAMP(DATE(), TIME(), \ ;* daylight saving)
'Asia/Singapore') - timestamp) / 3600 ;* -8
REM Page 98
3.121 TRANSTART, TRANSEND, TRANSQUERY(), TRANS-
ABORT
Never use that in T24 environment; though it might be useful for some standalone reports.
Example illustrating the parallel write to 2 files.
TRANSTART ELSE
CRT 'ERROR STARTING TXN 1'
STOP
END
CRT SYSTEM(47) ;* 1 - we're inside a transaction
TRANSTART ELSE
CRT 'ERROR STARTING TXN 2'
STOP
END
Output:
REM Page 99
1
TXN 1 WRITTEN
0
TXN 2 ABORTED
1 Records Listed
1 Records Listed
note: REC2 doesn’t exist in both files – transaction was aborted; REC1 is in initial state.
1 Records Listed
No Records Listed
1 Records Listed
Output:
2 Records Listed
3.122 TRIM()
string = ' A string '
* Get rid of leading spaces
CRT '"' : TRIM(string, ' ', 'L') : '"' ;* "A string "
* Get rid of trailing spaces
CRT '"' : TRIM(string, ' ', 'T') : '"' ;* " A string"
* Get rid of leading and trailing spaces
CRT '"' : TRIM(string, ' ', 'B') : '"' ;* "A string"
* Get rid of leading, trailing and redundant spaces
CRT '"' : TRIM(string, ' ', 'R') : '"' ;* "A string"
* Get rid of leading zeroes
CRT '"' : TRIM('000033', '0', 'L') : '"' ;* "33"
3.123 TRIMBS()
TRIM the dynamic array:
dyn_array = ' Use ' :@FM: ' the ' :@VM: ' ' :@FM: 'source Luke ! '
CRT DQUOTE(OCONV(TRIMBS(dyn_array), 'MCP'))
3.124 TRIMFS()
dyn_array = ' Use ' :@FM: ' the ' :@VM: '' :@FM: 'source Luke ! '
CRT DQUOTE(OCONV(TRIMFS(dyn_array), 'MCP'))
* Compare this with TRIMBS()
CRT DQUOTE(OCONV(TRIMBS(dyn_array), 'MCP'))
Output:
3.125 UNASSIGNED()
Opposite of ASSIGNED():
3.126 UNIQUEKEY()
Generates a UUID (Universally Unique Identifier).
the_key = UNIQUEKEY()
CRT the_key ;* e.g. AAADrAAADEy5+H7m
CRT FMT(DOWNCASE(FMT(the_key, 'MX')), \
'L(########-####-####-############)')
* e.g. 41414144-7241-4141-444579352b48
3.128 WEOFSEQ
Truncate the sequential file at the current position.
In this example a flat file is created and written to. If file already exists – ask user to agree
with file recreation. Last 5 bytes of written data will be deleted.
Line 1
Line 2
Line 4
Line 5
Line 6
Li
file_name := '.txt'
etc
file_name := '.txt'
** Error [ NOT_FILE_VAR ] **
Variable is not an opened file descriptor , Line 21 , Source test.b
Trap from an error message, error message name = NOT_FILE_VAR
Source changed to .\test.b
0021 WRITEBLK data TO f_out ELSE
jBASE debugger->
file_name := '.txt'
3.130 WRITELIST
EXECUTE 'SELECT . SAMPLE 5' RTNLIST ret_list
WRITELIST ret_list TO 'SOME-FILES'
GETLIST 'SOME-FILES' TO files_list ELSE NULL
CRT OCONV(files_list, 'MCP') ;* e.g. &COMO&^&COMO&]D^&ED&^&ED&]D^&PH&
3.131 WRITESEQ
Write to sequential file.
out_dir = '.'
out_file = 'report.txt'
OPENSEQ out_dir, out_file TO f_out THEN
SEEK f_out, 0, 2 ELSE ;* go to the end
CRT 'Seek error'
STOP
END
WRITESEQ 'One more line' TO f_out ELSE
CRT 'Write error'
STOP
END
END ELSE
WRITESEQ 'Line 1' TO f_out ELSE
CRT 'Write error'
STOP
END
END
out_dir = '.'
out_file = 'time.log'
OPENSEQ out_dir, out_file TO f_out THEN NULL
WRITESEQ TIMEDATE() APPEND TO f_out ELSE
CRT 'Write error'
STOP
END
3.132 WRITEU
Write a record without releasing the previously applied lock.
3.133 WRITEV
Write the specific field to a record.
3.134 XLATE()
Get data from a file without opening it explicitly:
4.2 LIST
List particular fields:
GB0010003
SG0010001
EU0010001
GB0010002
GB0010004
GB0010001
note: Also can use: LIST F.COMPANY COMPANY.NAME MNEMONIC WITH MNEMONIC EQ "[1"
List depending on a field being empty:
188888
122122
100362
...
41017 1002
46396 1004
41475 1002
41947 1002
42137 1002
47058 1004
...
LIST FBNK.ACCOUNT CATEGORY WITH CATEGORY EQ 1002 1004 AND CURRENCY EQ EUR
@ID................ CATEGORY
No Records Listed
Usage of OR:
LIST FBNK.ACCOUNT CATEGORY CURRENCY WITH CATEGORY EQ 1002 1004 OR CURRENCY EQ EUR
@ID................ CATEGORY CURRENCY
...
EUR141850084 14185 EUR
17531 6001 EUR
41947 1002 USD
EUR141850264 14185 EUR
EUR141250001 14125 EUR
42137 1002 USD
...
Alternate way to do that (though it doesn’t always work – the previous example wouldn’t):
2 Records Listed
Suppress paging:
LIST FBNK.ACCOUNT (N
...
LIST FBNK.ACCOUNT (N PAGE 16275 19:31:57 19 DEC 2011
...
LOCKED.WITH.LIMIT..
LOCK.INC.THIS.MVMT.
Suppress headers:
@ID.................. SYSTEM
@ID.................. SYSTEM
SYSTEM.SPEC.......... SYSTEM
RUN.DATE............. 20110330
SITE.NAME............ R11 Model Bank
OP.MODE.............. O
...
*** 25104974.25
*** 126155.6494
note: Some shortcuts are also available in VOC, see the next screen.
CT VOC F1 F2 F3
F1
001 D
F2
001 D
002 2
003
004
005 13T
006 S
F3
001 D
002 3
003
004
005 13T
006 S
LIST F.COMPANY F1 F2 F3
@ID........ F1............. F2........... F3...........
6 Records Listed
LIST F.COMPANY *A1 FMT "25L" *A2 FMT "25L" *A3 FMT "3R"
@ID........ *A1...................... *A2...................... *A3
LIST F.COMPANY ID.SUPP @ID CNV "ML& ##-###-####" FMT "12L" *A1 FMT "25L"
@ID......... *A1......................
GB-001-0003 MF Branch 1
SG-001-0001 Model Bank - Singapore
EU-001-0001 Model Bank - Europe
GB-001-0001 Model Bank
GB-001-0002 MF Lead Company
GB-001-0004 MF Branch 2
Another CNV example – list only amounts that fall into certain range:
SG0010001 2071
GB0010003 2063
EU0010001 2071
GB0010002 2068
GB0010004 2062
GB0010001 2163
@ID........... AM.MATRIX,HDG
INPUT.ROUTINE. V.BLS.AM.MAT.NEW.AXIS.HDG
@ID........... AM.MATRIX,HDG
INPUT.ROUTINE. V.BLS.AM.MAT.UPD.AXIS.HDG
3 Records Listed
BREAK-ON examples:
42398 100100
42428 100100
42439 100100
...
***
45028 100101
45039 100101
45055 100101
***
47791 100105
...
42398 100100
42428 100100
42439 100100
...
-----------
45028 100101
45039 100101
45055 100101
-----------
47791 100105
...
456014.62 GBP
11448663.27 USD
===================
51 Records Listed
Adding pounds to dollars doesn’t make sense of course. Here we’ll calculate the local amounts
and sum them up (sometimes I wish there would be a line continuation character in jQL – 4
lines’ worth of symbols are to be input in one line of course).
Note: we omit only the empty QUOTATION.CODE support.
*** 30092437288.71
100315.4.1 1 1188250.00 0
100291.1.1 2 959013.27 0
100317.1.1 3 750000.00 0
100344.1.1 4 677000.00 0
120019.1.1 5 563000.00 0
120014.1.1 6 559000.00 0
120016.1.1 7 559000.00 0
120006.1.1 8 530000.00 0
100332.1.1 9 471000.00 0
111419.1.1 10 370000.00 1
6626263.27 ***
100315.6.1 11 365000.00 1
100327.1.1 12 353000.00 1
100361.1.1 13 353000.00 1
100395.1.1 14 306000.00 1
111747.1.1 15 290000.00 1
100396.1.1 16 224000.00 1
120012.1.1 18 165000.00 1
100378.1.1 19 153000.00 1
100805.1.1 20 150000.00 2
2524000 ***
100372.1.1 21 124000.00 2
100310.1.1 22 118000.00 2
100315.9.1 23 117700.00 2
120110.1.1 24 107000.00 2
100272.1.1 25 106000.00 2
100346.1.1 26 106000.00 2
100107.1.1 27 100000.00 2
100283.8.1 28 100000.00 2
100283.9.1 29 100000.00 2
100297.1.1 30 100000.00 3
1078700 ***
...
SORT FBNK.ACCOUNT WITH *A1 NE '' BY *A1 BREAK-ON " 'U' " *A1
@ID................ *A1...........
42398 100100
42428 100100
42439 100100
...
45028 100101
45039 100101
45055 100101
47791 100105
...
SORT FBNK.ACCOUNT WITH *A1 NE '' BY *A1 BREAK-ON " 'U' " *A1 *A9998
@ID................ *A1........... *A9998........
47791 100105 24
48194 100105 25
...
47635 188888 1078
4.3 SELECT
Prepare a list for DL.DEFINE:
Using current SELECT list to select another file, e.g.: see how many T24 accounts have
history:
>SELECT FBNK.ACCOUNT (R
No Records selected
After:
No Records selected
!!! Error message A Select list was required and not supplied.
not found !!!
Result:
155520547050531.030001*28169
155440192725431.090002*45691
155710780457593.020002*34638
155720675739306.000001*14265
157740260025724.000002*47546
155650497154461.020002*46598
155520742538909.170001*USD145550001
...
Result:
155520547050531.030001
28169
155440192725431.090002
45691
155710780457593.020002
34638
155720675739306.000001
note: Then put the saved list to batch file listener input folder or copy/paste to tSS.
Get 10 top balances on accounts. Wrong:
hhhh (((
hhhh
( (( (((
hhhh (
hhh (((
hhhh (( ((((
(
SELECT FBNK.ACCOUNT WITH CURRENCY
( ((EQ
h(h(EUR
h(hhBY.DSND
hhh WORKING.BALANCE SAMPLE 10
(( ( ( hhhh
(( ( hhh
( ( hhhh
>LIST ( ( (((
FBNK.ACCOUNT WORKING.BALANCE hhh
((( hh
@ID................ WORKING.BALANCE....
EURUSD190220006 4000000
40339 14209.92
EUR165050006 5000
14087
46213
53015
EUR150050001
46205 -28351.31
EUR144410001 -54551.98
EUR141570002 -58000
10 Records Listed
10 Records Listed
Sample with BY-EXP-DSND (digits at the end of each list entry represent the value number):
>SAVE.LIST QWE
EDIT.LIST QWE
.P
001 AC.ACCOUNT.OPENING,INPUT.PW.JOINT]1
002 SEC.OPEN.ORDER,MIFID]1
003 SEC.OPEN.ORDER,MIFID.INPUT]1
004 SEC.TRADE,MIFID]1
005 SEC.TRADE,MIFID.INPUT]1
006 SEC.OPEN.ORDER,MIFID.INPUT]2
007 SEC.TRADE,MIFID.INPUT]2
008 EB.LENDING.HP,RETAIL.LENDING]1
...
.EXIT
4.4 SSELECT
What doesn’t make sense since SSELECT sorts by @id:
h ((
BYh
SSELECT F.COMPANY ( (MNEMONIC
h
(h(h(
hh
4.5 NSELECT
Returns records in specified (or default) select list that do not present in a file specified. E.g.:
get unauthorised ACCOUNT records that were never authorised before:
SELECT FBNK.ACCOUNT$NAU
>NSELECT FBNK.ACCOUNT
5 Records selected
>
SELECT FBNK.ACCOUNT$NAU TO 9
6 Records selected
NSELECT FBNK.ACCOUNT
Input list name 9
5 Records selected
>
4.6 XSELECT
“Reverses” a SELECT:
COUNT F.COMPANY
6 Records counted
1 Records selected
>XSELECT F.COMPANY
5 Records selected
>
4.7 BSELECT
Put all fields of a file into SELECT list:
BSELECT FBNK.ACCOUNT
EDIT.LIST QWE
.P
TOP
001 EUR141850743
002 EUR141850743
003
004 14185
005 RECORD.AUTOMATICALLY.OPENED
006 RECORD.AUTOMATICALLY.OPENED
007 RECORD.AUTOMATICALLY.OPENED
008
009 TR
010 EUR
011 1
...
BSELECT FBNK.ACCOUNT (C
...
Processed '500' Selected '500'
Processed '1000' Selected '1000'
...
Processed '1673' Selected '1673'
356505 Records selected
>SAVE.LIST QWE
EDIT.LIST QWE
.P
TOP
001 EUR141850743
002 14185
003 EUR
004 14095
005 1001
006 GBP
4.8 EVAL
Using EVAL as a calculator...
$FT-PART-ALGO 4
1 Records Listed
GBP141850768-200802
GBP141850768-200812
15393-200801
USD140550220-200803
USD140550220-200811
...
Some jBC functions might look redundant but are useful for EVAL:
Another field() example – see at what system date a forward accounting entry was gener-
ated:
@ID.......................... F20110414.15826077544910428
OCONV(@ID[".",2,1][1,5],"D"). 30 APR 2011
@ID.......................... F20110415.15825031964301106
OCONV(@ID[".",2,1][1,5],"D"). 29 APR 2011
...
@ID........................................... SCRPT11062000160-I
FIELD(FIELD(MSG.OUT,"INPUTTER:1:1=",2),",",1). 4964_SEAT.USER_I_INAU_OFS_SEAT
Some comparisons:
@ID........................ C.FIXED.PLACEMENT
PROCESS.STATUS............. COMPLETED SUCESSFULLY
AVAILABLE.DATE............. 20110311
AVAILABLE.DATE EQ 20110311. 1
...
@ID........................ TD.PARENT
PROCESS.STATUS............. COMPLETED SUCESSFULLY
AVAILABLE.DATE............. 20110309
@ID........................ CURRENT.PARENT
PROCESS.STATUS............. COMPLETED SUCESSFULLY
AVAILABLE.DATE............. 20110309
AVAILABLE.DATE EQ 20110311. 0
10497824.8 1998
-958489.37 2007
18248067.18 2008
-15850 2010
-9927303.88 2011
===================
*** 17844248.73
USD140300001 USD
USD141850990 USD
42218 USD
USDCHF140180001 USD
...
8888674688;77481;GUARANTOR
8888512388;77020;GUARANTOR
8888599888;77162;GUARANTOR
8888169488;77261;GUARANTOR
8888574188;77424;CO-SIGNER
8888574188;77435;CO-SIGNER
8888286188;77445;GUARANTOR
8888554888;77641;GUARANTOR
8888599488;77828;GUARANTOR
8888086088;77932;GUARANTOR
8888099688;77127;CO-SIGNER
8888762988;77127;GUARANTOR
8888521888;77142;GUARANTOR
...
8888674688;777446;GUARANTOR]77481;GUARANTOR
8888512388;77020;GUARANTOR
8888599888;779100;GUARANTOR]77162;GUARANTOR]777740;GUARANTOR
8888169488;77261;GUARANTOR]777365;CO-SIGNER
8888574188;777304;GUARANTOR]77424;CO-SIGNER]77435;CO-SIGNER
... so – COMO ON, LIST, COMO OFF, remove COMO header and footer in editor... that’s
it.
>SAVE.LIST AC.TITLE
SORT-LIST AC.TITLE
List 'AC.TITLE' sorted with 915 records
EDIT.LIST AC.TITLE
.jBASE.el.1
TOP
.P
TOP
001 Aa Dep Tax
002 AA Dep Tax
003 Aa Suspense Transactions
004 AA Suspense Transactions
005 Abn Amro Usd Nostro
006 Abu Dhabi National Oil Company
007 Abudhaoil Mg Dd Ac
...
>SAVE.LIST QWE
1673 record(s) saved to list 'QWE'
SORT.LIST QWE (U
List 'QWE' sorted with 239 records
AND-LISTS. Get common part of two lists. E.g. find if any unauthorised record in AC-
COUNT was authorised before:
SELECT FBNK.ACCOUNT$NAU
2 Records selected
>SAVE.LIST LIST1
2 record(s) saved to list 'LIST1'
SELECT FBNK.ACCOUNT
1673 Records selected
>SAVE.LIST LIST2
1673 record(s) saved to list 'LIST1'
XOR-LISTS. Records that present in one list but not in the other and vice versa in the
resulting SELECT.
Copy that record back (e.g. after manual editing) overwriting the target:
LIST &TEMP&
EU0010001
GB0010001
GB0010002
GB0010003
GB0010004
SG0010001
COUNT FBNK.ACCOUNT
Delete records:
DELETE F.OFS.MESSAGE.QUEUE
Record Keys : *
54 record(s) deleted.
LIST &COMO&
QWERTY
tSA_15_20120123_22-28-57
tSA_15_20120123_22-35-41
tSA_54_20120123_22-28-58
tSA_54_20120123_22-35-42
tSA_55_20120123_22-28-59
tSA_55_20120123_22-35-43
>DELETE &COMO&
6 record(s) deleted.
STAT F.COMPANY
Statistics of record length :
total = 13854 average = 2309 count = 6
GB0010003 MF Branch 1
SG0010001 Model Bank - S
ingapore
EU0010001 Model Bank - E
urope
GB0010001 Model Bank
GB0010002 MF Lead Compan
y
GB0010004 MF Branch 2
CUSTOMER D 1 CUSTOMER R 10
5 Environment variables
There are variables that are used by jBASE/T24; some of them are their own, others are
OS-specific.
Warning: some of these variables might be temporary or strictly for internal use. Descriptions
are for your information only!
Windows:
note: If you don’t set JBCBASETMP – “$HOME” directory will be created for this purpose.
Unix/Linux:
export LD_LIBRARY_PATH=$TAFC_HOME/lib:/usr/ccs/lib:/usr/lib:/lib
(Linux)
export LIBPATH=$TAFC_HOME/lib:/usr/ccs/lib:/usr/lib
(AIX)
export SHLIB_PATH=$TAFC_HOME/lib:${SHLIB_PATH:-/usr/lib:/lib}
(HP-UX)
note: For jBASE 5 and earlier use variable JBCRELEASEDIR instead of TAFC HOME.
The following environment variables are sorted alphabetically (excluding underscores).
CLASSPATH
Used in T24 environment to point to multiple extensions written in Java, such as e-mail or
SMS carriers.
DRIVER_HOME
INCLUDE
JAVA_HOME
JBASE_DEBUG_PIPE
JBASE_DISABLE_NEW_PHANTOM
JBASE_DISTRIB_FASTSCAN
JBASE_ERRMSG_DIVIDE_BY_ZERO
Allows to suppress error messages and/or a program entering the debugger when divide by
zero is encountered.
note: My personal recommendation of its value for development: 0.
JBASE_ERRMSG_NON_NUMERIC
Allows to suppress error messages and/or a program entering the debugger when non-numeric
variable is used in an equation.
note: My personal recommendation of its value for development: 0.
JBASE_ERRMSG_ZERO_USED
Allows to suppress error messages and/or a program entering the debugger when uninitialized
variable is used in an equation.
note: My personal recommendation of its value for development: 0.
JBASE_I18N
Being set to 1 means utf-8 environment (requires files conversion when changed).
JBASE_INHIBIT_ZERO_USED
JBASE_JBCOBJECTLIST_DIR
Being set to 1 makes jBASE understand that the folder t24lib contains T24 subroutines
that are distributed into subdirectories.
JBASE_LOCALE
Usually en US.
JBASE_NOCOLLATION
Turns off icu collation handling for compares, locates, sorts etc (according to jBASE Knowl-
edgebase).
JBASE_PATH
Makes jBASE understand that the folder being set in this variable (usually t24bin) contains
T24 programs that are distributed into subdirectories.
JBASE_TIMEZONE
E.g. Europe/London.
JBASE_USE_INTERNAL_TXN_CACHE
JBASE_WARNLEVEL
JBCBASETMP
set JBCBASETMP=%HOME%\tmp_workfile
export JBCBASETMP=$HOME/jBASEWORK/tmp_$TTYNO
JBC_CCOMPILER_PATH, JBC_SHAREDIDE_PATH
Not needed if PATH, INCLUDE and LIB are set properly (not sure about Temenos Toolbox
though).
Being set to 1 causes creation of a core dump when the session crashes.
JBCDEV_BIN
JBCDEV_LIB
JBCEMULATE
JBCGLOBALDIR
JBCJVMLIB
set JBCJVMLIB=%JAVA_HOME%\jre\bin\client\jvm.dll
export JBCJVMLIB=$JAVA_HOME/jre/bin/classic/libjvm.so
JBCLISTFILE
set JBCLISTFILE=%HOME%\^&SAVEDLISTS^&
export JBCLISTFILE=$HOME/\&SAVEDLISTS\&
JBCOBJECTLIST
Where to look for libraries containing compiled subroutines. Could be several entries, e.g.:
set JBCOBJECTLIST=%HOME%\lib;%HOME%\t24lib
export JBCOBJECTLIST=$HOME/lib:$HOME/t24lib
note: If there are duplicates of a subroutine, what’s the earlier gets priority.
JBCPROCDIR
JBCSPOOLERDIR
Where spooler directory is located. It’s a good idea to have a separate directory for each
T24 environment.
JBC_STDERR
Being set to 1 redirects stderr to stdout. Useful to catch errors during COB.
JBC_TELNET_FLAG
Being set to 1 reportedly prevented T24 from committing any transaction from Browser in
Windows environment.
JBC_UNLOCK_LASTCLOSE
Set JBC UNLOCK LASTCLOSE=1 to ensure locks are not released upon subroutine termi-
nation (according to jBASE Knowledgebase).
JDIAG
set JDIAG=trace=JVM,CALLJ
set JDIAG=TRACE=INDEX
JEDI_DISTRIB_DEFOPEN
Being set to 1 prevents all parts of a distributed file to be opened as soon as the stub had
been.
JEDIENABLEQ2Q
JEDIFILENAME_MD
set JEDIFILENAME_SYSTEM=%JBCGLOBALDIR%\src\SYSTEM
export JEDIFILENAME_SYSTEM=$JBCRELEASEDIR/src/SYSTEM
JEDIFILEPATH
Default path to jBASE data files. Doesn’t make much sense under T24 because mainly VOC
pointers are used there.
JEDI_PREFILEOP
set JEDI_PREFILEOP=TYPE=J4
export JEDI_PREFILEOP="SECURE=NO"
The second setting prevents the creation of new JR file with SECURE mode enabled.
JEDI_XMLDB2_SORT_RID_PARTIAL
JQL_TRACE_DEBUG
LDR_CNTRL
Under AIX allows more memory for libraries’ upload, thus avoiding errors “Not enough
space...SUBROUTINE CALL FAIL”, e.g.:
export LDR_CNTRL=MAXDATA=0x60000000
LIB
If sources compilation is to be done – needs to contain lib subfolder of Visual C folder (for
Windows; other platforms have their own folders).
TAFC_MONITORING_STORE
PATH
Needs to contain: bin subfolder of TAFC, bin subfolder of Java home (after TAFC/bin!),
t24bin subfolder of bnk.run, the folder where JBCDEV BIN points, C:\windows\system32
(for Windows), bin subfolder of Visual C folder (for Windows; other platforms have their
own folders, like /usr/vac/bin for AIX).
TERM
001 PA
002 SELECT FBNK.ACCOUNT$NAU
003 SELECT FBNK.ACCOUNT REQUIRE.SELECT (R
004 LIST ONLY FBNK.ACCOUNT$NAU
001 PA
002 ETS
003 DISPLAY PASSWORD?
004 HUSH ON
005 DISPLAY <<ADMIN.PASSWORD>>
006 HUSH OFF
007 EX
008 DATA INPUTT
009 DATA <<ADMIN.PASSWORD>>
010 DATA TSA.SERVICE, I TSM 6 STA
note: If you add 17 in hex mode to the end of the last line, F5 won’t be necessary.
Sample output:
T24 release R11.000 detected
7 JED
7.1 Text indentation
Use indent of 3 characters (default is 4) for jBC source code; format the code (BI command):
After bi command:
Command-> HEX
0001 ABCDEFXYZ
Step 2:
Command->
0001 414243FD444546FC58595A
Step 3:
Command-> HEX
0001 414243FD444546FC58595A
Result:
Command->
0001 ABC]DEF\XYZ
8 Debugger
8.1 Enter the debugger at program start
Use option -Jd in command line:
Backtrace log:
Line 0 , Source UNKNOWN , Level 0
Line 50 , Source EX
Line 153 , Source T.EX
Line 18 , Source INP
COMMON variables
E : 0
ECOMI : Y
ETEXT :
END.ERROR : 0
Output 2:
Output 3:
WHERE
Port Device Account PID Command
*1 ntcon t24 2184 jsh
WHERE
2 ntcon t24 2452 jsh
jprof 2 branch=on:output=t24.output
EXECUTE: 1: ETS
BRANCH: 2: Subroutine Start: From unknown To SUBROUTINE main() Level 1
EXECUTE: 2: EBS.TERMINAL.SELECT EBS-JBASE
BRANCH: 3: Subroutine Start: From unknown To SUBROUTINE main() Level 1
EXIT: 3: EBS.TERMINAL.SELECT
EXIT: 2: para
BRANCH: 1: Subroutine Start: From SUBROUTINE main() To SUBROUTINE
JBASECommandNext Level 2
BRANCH: 1: Subroutine End: From SUBROUTINE JBASECommandNext To SUBROUTINE
main() Level 1
BRANCH: 1: Subroutine Start: From SUBROUTINE main() To SUBROUTINE
JBASECommandNext Level 2
BRANCH: 1: Subroutine End: From SUBROUTINE JBASECommandNext To SUBROUTINE
main() Level 1
BRANCH: 1: Subroutine Start: From SUBROUTINE main() To SUBROUTINE
JBASECommandNext Level 2
TIMESTAMP: time 1322650073
BRANCH: 1: Subroutine End: From SUBROUTINE JBASECommandNext To SUBROUTINE
main() Level 1
EXECUTE: 1: EX
BRANCH: 2: Subroutine Start: From unknown To SUBROUTINE main() Level 1
BRANCH: 2: Subroutine Start: From SUBROUTINE main() To SUBROUTINE OVERLAY.EX
Level 2
BRANCH: 2: Subroutine Start: From SUBROUTINE OVERLAY.EX To SUBROUTINE
T24.INITIALISE Level 3
...
BRANCH: 2: Subroutine End: From SUBROUTINE RUN.APPLICATION To SUBROUTINE
T.EX Level 2
BRANCH: 2: Subroutine Start: From SUBROUTINE T.EX To SUBROUTINE INP Level 3
BRANCH: 2: Subroutine Start: From SUBROUTINE INP To SUBROUTINE T.INP Level 4
BRANCH: 2: Subroutine Start: From SUBROUTINE T.INP To SUBROUTINE CHARX Level 5
BRANCH: 2: Subroutine End: From SUBROUTINE CHARX To SUBROUTINE T.INP Level 4
BRANCH: 2: Subroutine Start: From SUBROUTINE T.INP To SUBROUTINE CHARX Level 5
BRANCH: 2: Subroutine End: From SUBROUTINE CHARX To SUBROUTINE T.INP Level 4
BRANCH: 2: Subroutine Start: From SUBROUTINE T.INP To SUBROUTINE EB.AUTO.LOGOUT
Level 5
BRANCH: 2: Subroutine End: From SUBROUTINE EB.AUTO.LOGOUT To SUBROUTINE T.INP
Level 4
From session 1:
jprof 2 branch=off:memory=on:output=t24.output
MEMORY: -1*-1:
free 01C28030 at jlibBStore.c,548(I_SF.INPUT,134)
MEMORY: -1*-1:
malloc 74 to 01BD9B58 at jlibBStore.c,589(I_SF.INPUT,175)
MEMORY: -1*-1:
malloc 1 to 01BC3A00 at bigdigits.c,1275(I_SF.INPUT,177)
MEMORY: -1*-1:
free 01BC3A00 at bigdigits.c,1295(I_SF.INPUT,177)
MEMORY: -1*-1:
malloc 3 to 01BC3A00 at bigdigits.c,1275(I_SF.INPUT,178)
MEMORY: -1*-1:
free 01BC3A00 at bigdigits.c,1295(I_SF.INPUT,178)
MEMORY: -1*-1:
free 01BD9B58 at jlibBStore.c,55(I_SF.INPUT,179)
MEMORY: -1*-1:
malloc 4096 to 01C2C8E8 at jediHASHR.c,422(VALIDATE.APPLICATION,
276)
MEMORY: -1*-1: malloc 584 to 01B445E0 at jlibFNEWFILE.c,1447(VALIDATE.APPLICATI
ON,276)
...
jprof 2 profile=off
Check memory usage summary (makes sense after memory profiling of the whole program
run):
jfatty t24.output
...
Remaining: 00000027 entries: Total 110592 bytes at jediHASHR.c,1525(OPF,403)
Remaining: 00000027 entries: Total 112104 bytes at jediHASHR.c,1470(OPF,403)
Remaining: 00000027 entries: Total 3456 bytes at jediBase.c,224(OPF,403)
Remaining: 00000027 entries: Total 410 bytes at jediBase.c,297(OPF,403)
Remaining: 00000027 entries: Total 945 bytes at jediBase.c,250(OPF,403)
Remaining: 00000038 entries: Total 23107 bytes at jlibBStore.c,589(System.putCac
he,49)
Remaining: 00000046 entries: Total 2622 bytes at jlibBCONVSFB.c,73(MATRIX.UPDATE,
335)
Remaining: 00000047 entries: Total 5266 bytes at jlibEMATPRS.c,134(LOAD.COMPANY,
180)
Total of 856 free spaces consuming 492441 bytes
9.3 LIST-OPEN-FILES
LIST-OPEN-FILES (V
9.4 MW42
The Answer to the Ultimate Question of Life, the Universe, and Everything...
Parameter: interval between screen refreshes (in seconds, default 5).
Using “A” (or up-arrow) as a toggle, you can see @user.root information in “User” column:
Port User Pid Files Perf Del Read Write Open Mem Cpu Prog
1 7143606 41 (6) 54 5 1758 57 350 16.5M 1.20 1 I /usr/jb..
4UTHORISER-012451872 171 (6) 8 5 711K 475K 253 14.7M 5m 3 I EX (I_S..
* 5LADIMIR.K-010289170 91 (7) 17 17 844 69 209 12.2M 0.00 2 MW42 (mw4..
27 INPUTTER-0 9371854 32 (6) 110 1 9927 202 124 10.5M 1.46 3 SLEEP tSM..
“M” – show “MemF” and “MemU” (memory free and used accordingly); space bar – screen
refresh.
9.5 t24version
Gives more information about libraries than jdiag:
9.6 SQLUPDATE
Mass update of data on low level (no T24 checks, updates of linked tables etc). Use with
extreme caution; I haven’t found much logic in the syntax facing many error messages.
Working sample:
9.8 WHERE
Show jBASE-related processes:
WHERE
Port Device Account PID Command
*1 ntcon t24 436 jsh
WHERE
2 ntcon vladimir.kaz 2928 jsh
9.9 LOGOFF
It’s a good idea to try LOGOFF before (j)kill (especially the one with “-9” option):
MW42
Port User Pid Files Perf Del Read Write Open Mem Cpu Prog
1 t24test9830644 55 (6) 26 51 8.29M 131 309 12.4M 10m 3 I EX (I_SF.INPUT,121)
4 t24test2517600 8 (7) 34 1 117K 39 94 6.38M 8.47 2 I mw42 (mw42.b,221)
5 t24test0158156 32 (6) 80 1 77454 639 134 10.4M 6.69 3 SLEEP tSM (tSM,823)
11 t24test0813568 80 (6) 6 13 469 40 154 12.0M 0.73 3 I EX (UNKNOWN,121)
*19 t24test3041728 76 (7) 8 9 439 28 156 11.6M 0.00 2 MW42 (mw42.b,708)
MW42
Port User Pid Files Perf Del Read Write Open Mem Cpu Prog
5 t24test0158156 32 (6) 80 1 77454 639 134 10.4M 6.69 3 SLEEP tSM (tSM,823)
*19 t24test3041728 76 (7) 10 9 446 30 160 11.6M 0.00 2 MW42 (mw42.b,708)
9.10 jshelltype
Changes jBASE shell type (note the prompt):
jsh-->LIST &TEMP&
DICT &TEMP&...
No Records Listed
jsh-->jshelltype sh
sh-->LIST &TEMP&
No file name could be found for your query
'TEMP' is not recognized as an internal or external command,
operable program or batch file.
9.11 SP-NEWTAB
If JBCSPOOLERDIR environment variable points to non-existing directory, each attempt to
“print” something (even “P” T24 function) will hang the process. To avoid that, when
creating a new environment it’s a good idea to set that variable to, say, %HOME%\jspooler,
create it if it doesn’t exist and run SP-NEWTAB at jsh prompt, e.g.:
SP-NEWTAB
This operation deletes ALL print jobs and print queues, and
re-creates a new spooler with the following criteria:
10 OFS
10.1 Characters substitution
Some characters are considered by OFS as special ones – comma, underscore etc. To put
them into fields you need to substitute them by other ones.
For this test we’ll use a field that has IN2ANY routine attached to it, namely - enq.desc field
of CONTEXT.ENQUIRY application. The easiest way to input an OFS string in Model
Bank – type tSS TAG at jsh prompt, copy/paste the string, when finished type EXIT.
Even if a string is shown at several lines in the following examples – this is only for fitting
into the screen; OFS message is always one line.
Comma is to be replaced by question mark:
CONTEXT.ENQUIRY,/I/PROCESS,INPUTT/123456,ACCOUNT,
ENQ.DESC:1:1=Statement summary? list
Result:
FILE.NAME......... ACCOUNT
------------------------------------------------------------------------------
15. 1. 1 GB ENQ.DESC. Statement summary, list
CONTEXT.ENQUIRY,/I/PROCESS,INPUTT/123456,ACCOUNT,
ENQ.DESC:1:1=Statement |summary| list
Result:
FILE.NAME......... ACCOUNT
------------------------------------------------------------------------------
15. 1. 1 GB ENQ.DESC. Statement "summary" list
CONTEXT.ENQUIRY,/I/PROCESS,INPUTT/123456,ACCOUNT,
ENQ.DESC:1:1=Statement'_'summary'_'list
Result:
FILE.NAME......... ACCOUNT
------------------------------------------------------------------------------
15. 1. 1 GB ENQ.DESC. Statement_summary_list
Delete a subvalue:
CONTEXT.ENQUIRY,/I/PROCESS,INPUTT/123456,ACCOUNT,ENQ.DESC:4:1=-
FILE.NAME......... ACCOUNT
------------------------------------------------------------------------------
15. 3. 1 GB ENQ.DESC. Forward movements
16. 3 AUTO.LAUNCH....
17. 1 VERSION.NAME...
18. 1. 1 GB VER.DESC.
19. 1 SCRIPT.NAME....
20. 1. 1 GB SPT.DESC.
21 RESERVED.6........
22 RESERVED.5........
CONTEXT.ENQUIRY,/D/PROCESS,INPUTT/123456,ACCOUNT
Result:
FILE.NAME......... ACCOUNT
------------------------------------------------------------------------------
15. 3. 1 GB ENQ.DESC. Forward movements
16. 3 AUTO.LAUNCH....
2. 4 ENQUIRY.NAME... STMT.ENT.TODAY Statement Entries Today
3. 4. 1 SEL.FIELD... ACCOUNT.NUMBER
CONTEXT.ENQUIRY,/I/PROCESS//0,INPUTT/123456,ACCOUNT,AUTO.LAUNCH:3:1=I
Result:
FILE.NAME......... ACCOUNT
------------------------------------------------------------------------------
15. 3. 1 GB ENQ.DESC. Forward movements
16. 3 AUTO.LAUNCH.... I
2. 4 ENQUIRY.NAME... STMT.ENT.TODAY Statement Entries Today
3. 4. 1 SEL.FIELD... ACCOUNT.NUMBER
CONTEXT.ENQUIRY,/I/PROCESS//0,INPUTT/123456,ACCOUNT,AUTO.LAUNCH:3:1=NULL
Result:
FILE.NAME......... ACCOUNT
------------------------------------------------------------------------------
15. 3. 1 GB ENQ.DESC. Forward movements
16. 3 AUTO.LAUNCH....
2. 4 ENQUIRY.NAME... STMT.ENT.TODAY Statement Entries Today
3. 4. 1 SEL.FIELD... ACCOUNT.NUMBER
Result:
UNIT.NAME......... TMNS000-TESTDLDEF
------------------------------------------------------------------------------
1. 1. 1 GB DESCRIPTN THE TEST ONE
Step 2:
DL.DEFINE,/I/PROCESS,INPUTT/123456,TESTDLDEF,FILE.NAME:2:=MD.PARAMETER,
RECORD.NAME:2:=GB0010001
Result:
UNIT.NAME......... TMNS000-TESTDLDEF
------------------------------------------------------------------------------
1. 1. 1 GB DESCRIPTN THE TEST ONE
2. 1 GB SHORT.DESC.. TEST
5 OPERATION......... S
9. 1 FILE.NAME...... ACCOUNT.PARAMETER
10. 1 RECO SYSTEM
9. 2 FILE.NAME...... MD.PARAMETER
10. 2 RECO GB0010001
31. 1 DATE.TIME...... 20 DEC 11 19:09
Step 3:
DL.DEFINE,/I/PROCESS,INPUTT/123456,TESTDLDEF,FILE.NAME:1:=LMM.INSTALL.CONDS,
RECORD.NAME:1:=GB0010001
Result:
UNIT.NAME......... TMNS000-TESTDLDEF
------------------------------------------------------------------------------
1. 1. 1 GB DESCRIPTN THE TEST ONE
2. 1 GB SHORT.DESC.. TEST
5 OPERATION......... S
9. 1 FILE.NAME...... LMM.INSTALL.CONDS
10. 1 RECO GB0010001
9. 2 FILE.NAME...... MD.PARAMETER
10. 2 RECO GB0010001
31. 1 DATE.TIME...... 20 DEC 11 19:12
Result:
UNIT.NAME......... TMNS000-TESTDLDEF
------------------------------------------------------------------------------
1. 1. 1 GB DESCRIPTN THE TEST ONE
2. 1 GB SHORT.DESC.. TEST
5 OPERATION......... S
9. 1 FILE.NAME...... LMM.INSTALL.CONDS
10. 1 RECO GB0010001
31. 1 DATE.TIME...... 20 DEC 11 19:14
Result:
note: BUILD routine was executed; it doesn’t for CALL ENQUIRY.DISPLAY – see below.
Result:
DATES,/I/PROCESS//0,INPUTT/123456,GB0010001,BACK.VALUE.MINIMUM::=20110413,
FORW.VALUE.MINIMUM::=20110415,FORW.VALUE.MAXIMUM::="13 JUN 2011"
11.1 F array
Defines field names in application (and such things like associations, single/multi property
etc). See examples for CUSTOMER:
Single field:
F(1) : (V) String : 8 bytes at address 022FFF38 : MNEMONIC
Multi-language field:
F(2) : (V) String : 16 bytes at address 022FF350 : XX.LL.SHORT.NAME
Multivalue field:
F(25) : (V) String : 16 bytes at address 01959290 : XX.OTHER.OFFICER
Multi-valued association:
F(34) : (V) String : 11 bytes at address 0230D2E0 : XX<LEGAL.ID
F(35) : (V) String : 17 bytes at address 0231C068 : XX-LEGAL.DOC.NAME
F(36) : (V) String : 20 bytes at address 0181D1A0 : XX-LEGAL.HOLDER.NAME
F(37) : (V) String : 17 bytes at address 022FFCD0 : XX-LEGAL.ISS.AUTH
F(38) : (V) String : 17 bytes at address 02315C90 : XX-LEGAL.ISS.DATE
F(39) : (V) String : 17 bytes at address 0192B120 : XX>LEGAL.EXP.DATE
Multi- and sub-valued association:
F(10) : (V) String : 16 bytes at address 02317A18 : XX<RELATION.CODE
F(11) : (V) String : 15 bytes at address 023464D8 : XX-REL.CUSTOMER
F(12) : (V) String : 18 bytes at address 02310188 : XX-REVERS.REL.CODE
F(13) : (V) String : 19 bytes at address 019B7F58 : XX-XX<REL.DELIV.OPT
F(14) : (V) String : 10 bytes at address 02302EC0 : XX-XX-ROLE
F(15) : (V) String : 20 bytes at address 019CEE60 : XX-XX-ROLE.MORE.INFO
F(16) : (V) String : 16 bytes at address 02315C48 : XX-XX>ROLE.NOTES
F(17) : (V) String : 14 bytes at address 01A07520 : XX-REL.RESERV6
F(18) : (V) String : 14 bytes at address 019FBC58 : XX-REL.RESERV5
Length more than 18 causes T24 classic to truncate the field name:
CUSTOMER.CODE..... 120018
------------------------------------------------------------------------------
1 MNEMONIC.......... ABCDE
...
14. 1. 1 ROLE........
15. 1. 1 ROLE.MORE.IN
16. 1. 1 ROLE.NOTES..
------------------------------------------------------------------------------
06 DEC 2011 19:36:51 USER (09 AUG) VLADIMIR.K [6492,INPAGE 1 >>14>>>
ACTION
AWAITING PAGE INSTRUCTIONS
11.2 N array
Defines field length in application. See examples for CUSTOMER:
11.3 T array
Defines field type in application. See examples for CUSTOMER:
note: Analogs for @id are called ID.F, ID.N and ID.T respectively.
11.4 LOCAL.REF.FIELD
Local reference field position in application. Useful when you address a local reference only
– you don’t need to include the insert for the application:
SUBROUTINE SOME.TEST
* T24 input routine
$INSERT I_COMMON
$INSERT I_EQUATE
* Local ref fields used here are #1 and #2, though it's better
* to use an insert file and not address them by numbers
RETURN
END
note: Addressing local fields by numbers isn’t recommended – it’s done to simplify code.
Test sample:
------------------------------------------------------------------------------
28 NOV 2011 19:18:08 USER (14 APR) VLADIMIR.K [3018,INPAGE 12
ACTION
11.10 I ENQUIRY.COMMON
• ENQ.ERROR – can be set in “build routine” to cancel enquiry output.
• O.DATA – incoming/outgoing data for “conversion routine”.
12 T24 hooks
12.1 Record types
Description of records that are to be created for certain hooks to work. (@id is always a
routine name.)
• PGM.FILE, record type: “M”.
PROGRAM SOME.TEST
------------------------------------------------------------------------------
1 TYPE.............. M
5 PRODUCT........... EB
PROGRAM SOME.TEST
------------------------------------------------------------------------------
1 TYPE.............. S
5 PRODUCT........... EB
8. 1 APPL.FOR.SUBR.. FUNDS.TRANSFER FUNDS.TRANSFER
KEY............... SOME.TEST
------------------------------------------------------------------------------
2 PROTECTION.LEVEL.. FULL
3 SOURCE.TYPE....... BASIC
12.3 VERSION/ID.RTN
Doesn’t make much sense. Could be useful if we got to it before system checks of @id –
to save typing, for example. And for local application it’s better to incorporate checks to
template.
Uses COMI to check and/or change the @id. ID.NEW is empty at this stage.
12.4 VERSION/CHECK.REC.RTN
In this example we’ll stop user from amending an existing record – only allow to input a new
one.
Step 1. Routine:
SUBROUTINE SOME.TEST
* t24 check.rec.rtn
$INSERT I_COMMON
$INSERT I_EQUATE
PGM.NAME.VERSION.. ACCOUNT,TEST
------------------------------------------------------------------------------
75. 1 CHECK.REC.RTN.. SOME.TEST
------------------------------------------------------------------------------
ACCOUNT.NUMBER.... 60623
------------------------------------------------------------------------------
1 CUSTOMER..........
2 CATEGORY..........
3 ACCOUNT.TITLE.1...
4 ACCOUNT.TITLE.2...
5 SHORT.TITLE.......
6 MNEMONIC..........
7 POSITION.TYPE.....
8 CURRENCY..........
9 CURRENCY.MARKET... 1 Currency Market
10 LIMIT.REF.........
11 ACCOUNT.OFFICER...
12. 1 OTHER.OFFICER..
13 POSTING.RESTRICT..
14 RECONCILE.ACCT....
15 INTEREST.LIQU.ACCT
16 INTEREST.COMP.ACCT
------------------------------------------------------------------------------
17 NOV 2011 22:36:32 USER (09 AUG) VLADIMIR.K [5317,I PAGE 1 >>14>>>
ACTION
12.5 VERSION/AUT.NEW.CONTENT
Auto-populate a field. In the past it was also used to stop user from entering an inappropriate
record. It doesn’t make sense now – CHECK.REC.RTN can be used for that.
SUBROUTINE SOME.TEST
* T24 aut.new.content routine
$INSERT I_COMMON
$INSERT I_EQUATE
PGM.NAME.VERSION.. FUNDS.TRANSFER,TEST
------------------------------------------------------------------------------
50. 1 AUTOM.FIELD.NO. DEBIT.THEIR.REF DEBIT.THEIR.REF
51. 1 AUT.OLD.CONTENT
52. 1 AUT.NEW.CONTENT @SOME.TEST
Run:
Model Bank FUNDS.TRANSFER,TEST INPUT REF FT102210VT31
------------------------------------------------------------------------------
1 TRANSACTION.TYPE..
2 DEBIT.ACCT.NO.....
3 IN.DEBIT.ACCT.NO..
4 CURRENCY.MKT.DR... 1 Currency Market
5 DEBIT.CURRENCY....
6 DEBIT.AMOUNT......
7 DEBIT.VALUE.DATE..
8 IN.DEBIT.VDATE....
9 DEBIT.THEIR.REF... NEW REFERENCE
10 CREDIT.THEIR.REF..
11 CREDIT.ACCT.NO....
12 CURRENCY.MKT.CR... 1 Currency Market
13 CREDIT.CURRENCY...
14 CREDIT.AMOUNT.....
15 CREDIT.VALUE.DATE.
16 TREASURY.RATE.....
------------------------------------------------------------------------------
18 NOV 2011 20:05:24 USER (09 AUG) VLADIMIR.K [1212,INPAGE 1 >>15>>>
ACTION
note: You can populate any field from such routine, not necessarily the “current” one.
SUBROUTINE SOME.TEST
* T24 validation routine
$INSERT I_COMMON
$INSERT I_EQUATE
PGM.NAME.VERSION.. FUNDS.TRANSFER,TEST
------------------------------------------------------------------------------
58. 1 VALIDATION.FLD. DEBIT.THEIR.REF DEBIT.THEIR.REF
59. 1 VALIDATION.RTN. SOME.TEST
PGM.NAME.VERSION.. FUNDS.TRANSFER,TEST
------------------------------------------------------------------------------
13. x FIELD.NO....... DEBIT.THEIR.REF DEBIT.THEIR.REF
...
42. x. 1 ATTRIBS..... HOT.FIELD
Run:
------------------------------------------------------------------------------
1 TRANSACTION.TYPE..
2 DEBIT.ACCT.NO.....
3 IN.DEBIT.ACCT.NO..
4 CURRENCY.MKT.DR... 1 Currency Market
5 DEBIT.CURRENCY....
6 DEBIT.AMOUNT......
12.7 VERSION/INPUT.ROUTINE
Cross-validation of a record. In this example user will be forced to input something to either
debit.their.ref or credit.their.ref.
Step 1. Routine:
SUBROUTINE SOME.TEST
* T24 input routine
$INSERT I_COMMON
$INSERT I_EQUATE
$INSERT I_F.FUNDS.TRANSFER
IF NOT(R.NEW(FT.DEBIT.THEIR.REF)) \
AND NOT(R.NEW(FT.CREDIT.THEIR.REF)) THEN
AF = FT.DEBIT.THEIR.REF
ETEXT = 'ENTER EITHER THIS OR CREDIT REF'
CALL STORE.END.ERROR
AF = FT.CREDIT.THEIR.REF
ETEXT = 'ENTER EITHER THIS OR DEBIT REF'
CALL STORE.END.ERROR
END
RETURN
END
PGM.NAME.VERSION.. FUNDS.TRANSFER,TEST
------------------------------------------------------------------------------
63. 1 INPUT.ROUTINE.. SOME.TEST
------------------------------------------------------------------------------
1 TRANSACTION.TYPE.. AC Account Transfer
2 DEBIT.ACCT.NO..... 13487 Sears Roebuck
3 IN.DEBIT.ACCT.NO..
4 CURRENCY.MKT.DR... 1 Currency Market
5 DEBIT.CURRENCY.... EUR Euro
6 DEBIT.AMOUNT...... 150.00
7 DEBIT.VALUE.DATE.. 09 AUG 2010
8 IN.DEBIT.VDATE....
9 DEBIT.THEIR.REF... ENTER EITHER THIS OR CREDIT REF
10 CREDIT.THEIR.REF.. ENTER EITHER THIS OR DEBIT REF
11 CREDIT.ACCT.NO.... 40827 Jacob Eur Ac
12.8 VERSION/AUTH.ROUTINE
Performs custom checks, update of local tables etc at authorisation stage. In this example
user will not be allowed to authorise any record using this VERSION:
Step 1. Routine:
SUBROUTINE SOME.TEST
* T24 authorisation routine
$INSERT I_COMMON
$INSERT I_EQUATE
RETURN
END
PGM.NAME.VERSION.. FUNDS.TRANSFER,TEST
------------------------------------------------------------------------------
64. 1 AUTH.ROUTINE .. SOME.TEST
------------------------------------------------------------------------------
1 TRANSACTION.TYPE.. AC Account Transfer
2 DEBIT.ACCT.NO..... 13487 Sears Roebuck
4 CURRENCY.MKT.DR... 1 Currency Market
5 DEBIT.CURRENCY.... EUR Euro
6 DEBIT.AMOUNT...... 150.00
7 DEBIT.VALUE.DATE.. 09 AUG 2010
11 CREDIT.ACCT.NO.... 40827 Jacob Eur Ac
12 CURRENCY.MKT.CR... 1 Currency Market
13 CREDIT.CURRENCY... EUR Euro
15 CREDIT.VALUE.DATE. 09 AUG 2010
18 PROCESSING.DATE... 09 AUG 2010
44 CHARGE.COM.DISPLAY
45 COMMISSION.CODE... DEBIT PLUS CHARGES
49 CHARGE.CODE....... DEBIT PLUS CHARGES
55 PROFIT.CENTRE.CUST 100295 Sears Roebuck
57 RETURN.TO.DEPT.... NO
------------------------------------------------------------------------------
18 NOV 2011 22:09:50 USER (09 AUG) VLADIMIR.K [3161,INPAGE 1 >>>3>>>
ACTION USE OTHER VERSION TO AUTHORISE
AWAITING PAGE INSTRUCTIONS
12.10 ENQUIRY/BUILD.ROUTINE
Here we are able to create or amend a selection criteria for an enquiry, as well as to raise an
error. In this example a selection will be required from a user; if it starts with “USER.NAME
LK” then it will be amended to “USER.NAME LK A... D...”
SUBROUTINE SOME.TEST(P.ENQ)
* T24 build routine for ENQUIRY
$INSERT I_COMMON
$INSERT I_EQUATE
$INSERT I_ENQUIRY.COMMON
RETURN
END
ENQUIRY........... USER
------------------------------------------------------------------------------
12. 1 BUILD.ROUTINE.. SOME.TEST
Test case 1:
Return to “AWAITING APPLICATION” prompt; launch enquiry again. Test case 2, screen 1:
Model Bank
List of T24 Users
------------------------------------------------------------------------------
1 ABI1 ABINAN.1 ABINAN.1
2 ACCTEXEC Account Executive ACCTEXEC1
3 AUTHORISER AUTHORISER AUTHOR
4 BUILDUSER279 AUTHORISER GOPIRAM
5 DEALER01 DEALER1 DEALER1
6 DXBO DX Back Office User DXBOUSER
7 DXMO DXMO DXMOUSER
8 DXO DX Front Office User DXOUSER
9 GOPIRAMK AUTHORISER GOPI123
------------------------------------------------------------------------------
17 NOV 2011 23:11:13 USER (09 AUG) VLADIMIR.K [8127,INPAGE 1 >>>1>>>
ACTION
AWAITING PAGE INSTRUCTIONS
SUBROUTINE SOME.TEST
* T24 conversion routine for ENQUIRY
$INSERT I_COMMON
$INSERT I_EQUATE
$INSERT I_ENQUIRY.COMMON
RETURN
END
ENQUIRY........... AC.TEST
------------------------------------------------------------------------------
1 PAGE.SIZE ........ 4,19
2 FILE.NAME......... ACCOUNT
14. 1 FIELD.NAME..... WORKING.BALANCE
15. 1. 1 OPERATION... WORKING.BALANCE
16. 1 COLUMN......... 4
17. 1 LENGTH.MASK.... 19R
18. 1. 1 CONVERSION.. @ SOME.TEST
35. 1 SINGLE.MULTI... S
14. 2 FIELD.NAME..... ID
15. 2. 1 OPERATION... @ID
16. 2 COLUMN......... 25
17. 2 LENGTH.MASK.... 19R
35. 2 SINGLE.MULTI... S
Run enquiry:
Model Bank
------------------------------------------------------------------------------
1 0 CHF141850697
2 0 CHF141850746
3 0 CHF141850786
4 0 CHF141850833
5 CHF141850963
SUBROUTINE NOFILE.TEST(P.LIST)
* T24 nofile enquiry routine
$INSERT I_COMMON
$INSERT I_EQUATE
$INSERT I_ENQUIRY.COMMON
HUSH ON
EXECUTE 'SELECT F.HELPTEXT.MAINMENU' RTNLIST V.LIST.1
EXECUTE 'SELECT F.HELPTEXT.MENU' RTNLIST V.LIST.2
HUSH OFF
RETURN
END
Step 2. SS record:
FILE.NAME......... NOFILE.TEST
Step 3. ENQUIRY:
Model Bank ENQUIRY SEE
ENQUIRY........... MENUTEST
------------------------------------------------------------------------------
1 PAGE.SIZE ........ 4,19
2 FILE.NAME......... NOFILE.TEST
3. 1 FIXED.SELECTION OUTPUT LK ...
14. 1 FIELD.NAME..... SOURCE
15. 1. 1 OPERATION... DATAFLD
16. 1 COLUMN......... 4
17. 1 LENGTH.MASK.... 20L
18. 1. 1 CONVERSION.. F *,1
18. 1. 2 CONVERSION.. SUBSTITUTE 1,HELPTEXT.MAINMENU
18. 1. 3 CONVERSION.. SUBSTITUTE 2,HELPTEXT.MENU
14. 2 FIELD.NAME..... NAME
15. 2. 1 OPERATION... DATAFLD
16. 2 COLUMN......... 26
17. 2 LENGTH.MASK.... 35L
18. 2. 1 CONVERSION.. F *,2
40 PAGE.FIELDS.......
------------------------------------------------------------------------------
18 NOV 2011 18:48:54 USER (09 AUG) VLADIMIR.K [5502,INPAGE 1 >>>2>>>
ACTION
AWAITING PAGE INSTRUCTIONS
Model Bank
------------------------------------------------------------------------------
HELPTEXT.MAINMENU 164
HELPTEXT.MAINMENU 66
HELPTEXT.MAINMENU 501
HELPTEXT.MAINMENU 100
HELPTEXT.MAINMENU 1
HELPTEXT.MAINMENU 500
HELPTEXT.MENU LC.ENQUIRIES
HELPTEXT.MENU RL.AUTH.HOME.PAGE
HELPTEXT.MENU TF.EXLCTRF
HELPTEXT.MENU FOREX.CONFIRM
HELPTEXT.MENU TELLER.DEPOSIT
HELPTEXT.MENU MF.POS.ENQ
HELPTEXT.MENU LI.GRP.MENU
HELPTEXT.MENU CHQ.COLL.HP.AUTH
HELPTEXT.MENU AI.CORP.SWEEP
HELPTEXT.MENU BLOCK.PF.CASH.FO
------------------------------------------------------------------------------
18 NOV 2011 18:50:04 USER (09 AUG) VLADIMIR.K [5502,INPAGE 1 >>>3>>>
ACTION
AWAITING PAGE INSTRUCTIONS
12.13 OFS.SOURCE/IN.MSG.RTN
Receives, optionally amends and returns full incoming OFS message. In this example we set
time restrictions for processing incoming OFS messages and supply default T24 login if it
absents.
SUBROUTINE OFS.IN.RTN(P.MSG)
* T24 OFS in-message routine.
* We don't use I_COMMON and I_EQUATE variables here.
* Set time restriction (in conjunction with OUT.MSG.RTN -
* there's no known way to stop processing so we create
* an erroneous request that we analyse there)
V.TIME = OCONV(TIME(), 'MT')
IF V.TIME GT '18:00' THEN
P.MSG = 'SPF,/I/VALIDATE,INPUTT/123456,' : V.TIME : ',SITE.NAME::=QWERTZ'
RETURN
END
RETURN
END
note: Of course storing the pasword in the source code isn’t the way to go.
SOURCE.NAME....... TAG
------------------------------------------------------------------------------
9 IN.MSG.RTN........ OFS.IN.RTN
Run:
tSS TAG
ACCOUNT//1,DESCRIPTION:1:1=Account Enquiries,ENQUIRY.NAME:1:1=ACCT.STMT.HIST,EN
QUIRY.NAME:2:1=ACCT.BAL.TODAY,ENQUIRY.NAME:3:1=NOSTRO.FWD.BAL,ENQUIRY.NAME:4:1=
STMT.ENT.TODAY,SEL.FIELD:1:1=STMT.ACCOUNT.NO,SEL.FIELD:2:1=ACCOUNT.NUMBER,SEL.F
IELD:3:1=ACCOUNT.ID,SEL.FIELD:4:1=ACCOUNT.NUMBER,CONTEXT.TYPE:1:1=ENQUIRY,CONTE
XT.TYPE:2:1=ENQUIRY,CONTEXT.TYPE:3:1=ENQUIRY,CONTEXT.TYPE:4:1=ENQUIRY,ENQ.DESC:
1:1=Statement "summary" list,ENQ.DESC:2:1=Current balance information,ENQ.DESC:
3:1=Forward_movements,ENQ.DESC:4:1=Entries posted today,RECORD.STATUS:1:1=INAU,
CURR.NO:1:1=2,INPUTTER:1:1=152_INPUTTER__OFS_TAG,DATE.TIME:1:1=1111291754,CO.CO
DE:1:1=GB0010001,DEPT.CODE:1:1=56
tSS TAG
To make this error message more friendly – proceed with the OUT.MSG.RTN below.
12.14 OFS.SOURCE/OUT.MSG.RTN
Step 1. Routine:
SUBROUTINE OFS.OUT.RTN(P.MSG)
* T24 OFS out-message routine.
RETURN
END
SOURCE.NAME....... TAG
------------------------------------------------------------------------------
10 OUT.MSG.RTN....... OFS.OUT.RTN
tSS TAG
Note the value of field FIELD NAME (yes, this application has unusual space in some field
names) and go visit the application DE.MESSAGE where we can get the idea how not to
break the rules assigned to this field:
MESSAGE.TYPE...... 103
------------------------------------------------------------------------------
1. 1 GB DESCRIPTION. CUSTOMER CREDIT TRANSFER
2 COPIES............ Y
3 TRANSLATION....... Y
4 DELETE............ Y
5 TEST.KEY.REQ...... NO
6 APPLICATION.QUEUE.
7. 1 FIELD.NAME..... SENDER REF
8. 1 LENGTH......... 16
9. 1 PRINT.TYPE..... A
10. 1 SINGLE.MULTI... S
11. 1 MANDATORY...... Y
We now know that in so-called “handoff” the SWIFT field 20 corresponds to position “2.2”,
i.e. “record #2, field #2”. To amend it a subroutine must be written. (Note that population
of fields in handoff is in most cases hardcoded in the core so we just amend the existing value
on-the-fly.)
We’re going to add “T24” before FT @id which is usually placed into that field (it will not
exceed the limitation of 16 characters stipulated by DE.MESSAGE):
ID................ 103.FT.1
------------------------------------------------------------------------------
15.45 HEADER.POSITION
15.46 HEADER.POSITION
15.47 HEADER.POSITION
15.48 HEADER.POSITION
15.49 HEADER.POSITION
15.50 HEADER.POSITION
15.51 HEADER.POSITION
15.52 HEADER.POSITION
15.53 HEADER.POSITION
15.54 HEADER.POSITION
15.55 HEADER.POSITION
15.56 HEADER.POSITION
16 ROUTINE........... @EXPAND.FT.REF
17. 1 AC.FIELD.......
------------------------------------------------------------------------------
1 TRANSACTION.TYPE.. OT03 Outward SWIFT Payment
2 DEBIT.ACCT.NO..... 13315 GENERAL MOTORS
4 CURRENCY.MKT.DR... 1 Currency Market
5 DEBIT.CURRENCY.... USD US Dollar
7 DEBIT.VALUE.DATE.. 14 APR 2011
...
80. 2 DELIVERY.OUTREF D20120120024027272702-103.1.1 CABLE TO CUST
DATE.TIME.STAMP... D20120120-02402-72727-02
------------------------------------------------------------------------------
1 MESSAGE TYPE...... 103
3 APPLICATION....... FTOT
4 DISPOSITION....... UNFORMATTED
...
21 TRANSACTION REF... T24FT11104110WY
To format it (and thus form the SWIFT message) we need to start the service SWIFT.OUT
(“debugger mode” was used for this sample).
Step 1:
SERVICE........... TSM
------------------------------------------------------------------------------
1. 1 DESCRIPTION.... TSM Record for running upgrade as service
2. 1 SERVER.NAME....
3. 1 WORK.PROFILE... TSM WORK LOAD PROFILE FOR TSM
4. 1 SERVER.STATUS..
5 USER.............. INPUTTER
6 SERVICE.CONTROL... START
7 REVIEW.TIME.......
8 TIME.OUT..........
Step 2:
SERVICE........... SWIFT.OUT
------------------------------------------------------------------------------
1. 1 DESCRIPTION.... DE FORMATTING SERVICE
2. 1 SERVER.NAME....
3. 1 WORK.PROFILE... DE.FORMATTING.SERVICE USED FOR DE FORMATTING SERVICE
4. 1 SERVER.STATUS..
5 USER.............. INPUTTER
6 SERVICE.CONTROL... START
DATE.TIME.STAMP... D20120120-02402-72727-02
------------------------------------------------------------------------------
1 MESSAGE TYPE...... 103
3 APPLICATION....... FTOT
4 DISPOSITION....... FORMATTED
...
21 TRANSACTION REF... T24FT11104110WY
23 TEST KEY REQ...... NO
25. 1 CARRIER ADDR NO SWIFT.1
...
32. 1 MSG DISPOSITION WACK
And – the message itself. In JED it wouldn’t look very well so:
>CT &TEMP&
Result:
D20120120024027272702.1
001 {1:F01DEMOGBPXAXXX.SN...ISN.}{2:I103BCITIT24XXXXN}{3:{108:xxxxx}}{4:
002 :20:T24FT11104110WY
003 :23B:CRED
004 :32A:110414EUR40000,00
005 :33B:EUR40000,00
006 :50F:/13315
007 1/General Motors
008 2/100 RENAISSANCE CENTRE
009 3/US/DETROIT
010 :53B:/D/EUR-IT-1223354566
011 :59:DREAM REALTY VENTURES INC
012 :70:PAYMENT OF INVOICE NO.23701
013 :71A:SHA
014 -}
ID................ SYSTEM.STATUS
------------------------------------------------------------------------------
...
11 DISP CONTROL...... Y
RETURN.FLAG = 0 ;* OK by default
V.AMT = R.NEW(FT.CREDIT.AMOUNT)
IF NOT(V.AMT) THEN V.AMT = R.NEW(FT.DEBIT.AMOUNT)
V.CCY = HEADER.REC<DE.HDR.CURRENCY>
IF V.CCY NE LCCY THEN
V.LCY.AMT = ''
CALL MIDDLE.RATE.CONV.CHECK(V.AMT, V.CCY, '', 1, V.LCY.AMT, '', '')
END ELSE
V.LCY.AMT = V.AMT
END
RETURN
END
Step 2. Take an FT from the previous example, copy it, make credit amount somewhat less
than 100,000 EUR (which amounts to somewhat more than 100,000 in local currency – USD)
and commit. See result in DE.O.HEADER:
Model Bank OUTWARD DELIVERY HEADER SEE
DATE.TIME.STAMP... D20120123-02177-72009-04
------------------------------------------------------------------------------
Release it manually:
DATE.TIME.STAMP... D20120123-02177-72009-04
------------------------------------------------------------------------------
17 VALUE DATE........ 14 APR 2011
18 CURRENCY.......... EUR
19 AMOUNT............
20 DEPARTMENT........ 1
21 TRANSACTION REF... T24FT11104HQYBV
22 APPLICATION QUEUE.
23 TEST KEY REQ...... NO
24 INWARD PAY TYPE...
25. 1 CARRIER ADDR NO SWIFT.1
26. 1 COPY NUMBER.... 1-100464
27. 1 FRAME NUMBER... 1
28. 1 FORMAT......... 1
29. 1 MSG LANGUAGE... GB
30. 1 MSG PRIORITY... N
31. 1 MSG STATUS..... RELEASE
32. 1 MSG DISPOSITION
------------------------------------------------------------------------------
DATE.TIME.STAMP... D20120123-02177-72009-04
------------------------------------------------------------------------------
1 MESSAGE TYPE...... 103
3 APPLICATION....... FTOT
4 DISPOSITION....... FORMATTED
...
32. 1 MSG DISPOSITION WACK
12.17 ACCOUNT.PARAMETER/ACCOUNTING.SUBRTN
This subroutine is triggered every time when any accounting entry (STMT.ENTRY or
CATEG.ENTRY) is created online. And note that if entries are created during COB –
it isn’t.
In the following example all new accounting entries will be copied to another file.
RETURN
END
KEY............... SYSTEM
------------------------------------------------------------------------------
39 ACCOUNTING.SUBRTN. ACCT.SUBR
LIST ALL.ENTRY
STMT160470490350839.000001
STMT160470490350839.000002
ALL.ENTRY.......... STMT160470490350839.000001
@ID................ STMT160470490350839.000001
STMT.ENTRY.ID...... STMT160470490350839.000001
ACCOUNT.NUMBER..... 20467
COMPANY.CODE....... GB0010001
AMOUNT.LCY......... 7800.00
TRANSACTION.CODE... 258
...
SUBROUTINE FREQ.TEST
* T24 custome frequency routine
$INSERT I_COMMON
$INSERT I_EQUATE
V.DATE = COMI[1,8]
LOOP
CALL CDT('', V.DATE, '+1C')
IF INDEX('02468', V.DATE[8,1], 1) THEN EXIT
REPEAT
COMI = V.DATE : COMI[9,5]
RETURN
END
FREQ.ID........... EVEND
------------------------------------------------------------------------------
1. 1 GB DESCRIPTION. EVEN DAYS ONLY
3 SPECIAL.ROUTINE... FREQ.TEST
Use (force user INPUTTER to change password on every 2nd , 4th , 6th ... etc day of month):
USER.ID........... INPUTTER
------------------------------------------------------------------------------
1 USER.NAME......... Inputter, yes it is
2 SIGN.ON.NAME...... INPUTT
3 CLASSIFICATION.... INT
4 LANGUAGE.......... 1 English
5. 1 COMPANY.CODE... GB0010001 Model Bank
5. 2 COMPANY.CODE... GB0010002 MF Lead Company
5. 3 COMPANY.CODE... GB0010003 MF Branch 1
5. 4 COMPANY.CODE... GB0010004 MF Branch 2
5. 5 COMPANY.CODE... SG0010001 Model Bank - Singapore
5. 6 COMPANY.CODE... EU0010001 Model Bank - Europe
6 DEPARTMENT.CODE... 56 Trade Finance Supervisor
7 PASSWORD.VALIDITY. EVEND
12.19 I-descriptors
Routines can be used in STANDARD.SELECTION fields with usr.type = I. This example
creates an I-descriptor that shows the difference (in work days) between processing date and
the current date for FUNDS.TRANSFER application.
IF TODAY EQ 0 THEN
P.RESULT = '!!!' ;* need to log in and out of T24
RETURN ;* to obtain TODAY value
END
V.PR.DATE = P.PROC.DATE
V.DIFF = 'W' ;* or C for calendar days
CALL CDD('', TODAY, V.PR.DATE, V.DIFF)
P.RESULT = V.DIFF
RETURN
END
Output:
@ID...................... PROC.DIFF
FT11070870KS;1 -13
FILE.NAME......... FUNDS.TRANSFER
------------------------------------------------------------------------------
15. 1 USR.FIELD.NAME. PROC.DIFF
16. 1 USR.TYPE....... I
17. 1. 1 USR.FIELD.NO SUBR('FT.IDESC',PROCESSING.DATE);ABS(@1);
17. 1. 2 USR.FIELD.NO IF @2 LE 5 THEN @2 ELSE @2:' - time to review!'
18. 1. 1 USR.VAL.PROG
19. 1 USR.CONVERSION.
20. 1 USR.DISPLAY.FMT 25L
Result:
@ID...................... PROC.DIFF................
13 T24 API
13.1 CDD()
See I-descriptors sample right above.
SUBROUTINE SOME.TEST
* T24 mainline routine
$INSERT I_COMMON
$INSERT I_EQUATE
V.DATE = TODAY
CALL CDT('', V.DATE, '31W')
RETURN
END
Output:
SUBROUTINE SOME.TEST
$INSERT I_COMMON
$INSERT I_EQUATE
TEXT = TODAY
CALL REM ;* e.g. 20100809
TEXT = TODAY
CALL REM ;* now 20100921
RETURN
END
SUBROUTINE SOME.TEST
* T24 mainline routine
$INSERT I_COMMON
$INSERT I_EQUATE
start_date = '20130514M0617'
GOSUB ROLL.DATE ;* output: 20131017M0617
start_date = '20130517M0617'
GOSUB ROLL.DATE ;* output: 20131117M0617
RETURN
ROLL.DATE:
COMI = start_date
CALL CFQ
TEXT = COMI
CALL REM
RETURN
END
13.4 DISPLAY.MESSAGE()
Output something to predefined position of T24 Classic screen without waiting for user input
(used in core to output “TXN COMPLETE” etc). In this example we construct sort of progress
indicator:
SUBROUTINE SOME.TEST
* T24 mainline rtn
$INSERT I_COMMON
$INSERT I_EQUATE
FOR i = 1 TO 20000
IF MOD(i, 1000) EQ 0 THEN
CALL DISPLAY.MESSAGE('->' : i : '...', 2)
MSLEEP(500) ;* not to be too fast
END
NEXT i
RETURN
END
13.5 DUP()
Checks for duplicates in multi- or subvalued field (in VERSION hooks).
Routine:
SUBROUTINE SOME.TEST
* T24 input routine
$INSERT I_COMMON
$INSERT I_EQUATE
$INSERT I_F.CUSTOMER
RETURN
END
Test case:
CUSTOMER.CODE..... 100112
------------------------------------------------------------------------------
33. 1 TEXT...........
34. 1 LEGAL.ID.......
35. 1 LEGAL.DOC.NAME.
36. 1 LEGA
37. 1 LEGAL.ISS.AUTH.
38. 1 LEGAL.ISS.DATE.
39. 1 LEGAL.EXP.DATE.
40. 1 OFF.PHONE...... (123)456-7890
40. 2 OFF.PHONE...... (123)456-7890 DUPLICATE
41 REVIEW.FREQUENCY..
42 BIRTH.INCORP.DATE.
43 GLOBAL.CUSTOMER...
44 CUSTOMER.LIABILITY
45 LANGUAGE.......... 1 English
46 POSTING.RESTRICT..
47 DISPO.OFFICER.....
------------------------------------------------------------------------------
20 DEC 2011 21:44:31 USER (14 APR) VLADIMIR.K [2002,INPAGE 3 >>12>>>
ACTION
SUBROUTINE SOME.TEST
* T24 mainline routine
$INSERT I_COMMON
$INSERT I_EQUATE
amount = 1234.56
charge_amt = amount * 0.001
currency = LCCY
method = ''
TEXT = 'Default LCCY rounding'
GOSUB DO.IT ;* 1.23
currency = 'JPY'
method = ''
TEXT = 'Default JPY rounding'
GOSUB DO.IT ;* 1
currency = LCCY
method = 1 :FM: 'U'
TEXT = 'LCCY cash rounding (up)'
GOSUB DO.IT ;* 1.24
currency = 'EUR'
method = 1 :FM: 'D'
TEXT = 'EUR cash rounding (down)'
GOSUB DO.IT ;* 1.23
RETURN
DO.IT:
result = charge_amt
CALL EB.ROUND.AMOUNT(currency, result, method, '')
TEXT := ': ' : result
CALL REM
RETURN
END
SUBROUTINE SOME.TEST
* T24 input routine
$INSERT I_COMMON
$INSERT I_EQUATE
RETURN
END
13.8 ENQUIRY.DISPLAY()
Launch ENQUIRY from mainline routine:
SUBROUTINE SOME.TEST
* T24 mainline routine
$INSERT I_COMMON
$INSERT I_EQUATE
dyn_array<1> = 'USER'
dyn_array<2,1> = 'USER.NAME'
dyn_array<3,1> = 'LK'
dyn_array<4,1,1> = 'C...'
CALL ENQUIRY.DISPLAY(dyn_array)
RETURN
END
Run routine from AWAITING APPLICATION level:
Model Bank
List of T24 Users
------------------------------------------------------------------------------
1 CALLCENTRE1 Call Centre Agent CALLCENTRE
2 CHEQUESMANAGER CHEQUES MANAGER RETAILMGR01
3 CHEQUESOFFICER CHEQUES OFFICER RETAILOFF01
4 COMPOFFICER Compliance Officer COMPOFF
5 CORPMANAGER CORPMANAGER CORP.MGR
6 CORPOFFICER CORPOFFICER CORP.OFF
7 CREDITMANAGER CREDIT MANAGER CREDITMGR
8 CREDITMANAGER1 Credit Manager CREDITMANAGER
9 CREDITMGR Credit Manager CREDITMGR1
10 CREDITOFF Credit Officer CREDITOFF1
11 CREDITOFFICER CREDIT OFFICER CREDITOFF
12 CREDITOFFICER1 Credit Officer CREDITOFFICER
13 CSAGENT1 Customer Service Agent CSAGENT
14 CSREP Customer Service Representative CSREP1
15 CSS Customer Service Supervisor CSS123
------------------------------------------------------------------------------
RETURN
END
Runtime:
jsh -->
001 20110414
002 1
003 232650
004 23:26:50:646
005 6572
006
007 GB0010001
008 VLADIMIR.K
009 SOME.TEST
010 1
011
012 VERY SERIOUS ERROR
013
SUBROUTINE SOME.TEST
* T24 mainline rtn
$INSERT I_COMMON
$INSERT I_EQUATE
LOOP
READNEXT acct_id FROM 9 ELSE BREAK
acct_rec = ''
CALL F.READ(acct_file, acct_id, acct_rec, f_acct, '')
IF acct_rec EQ '' THEN
TEXT = 'COULD NOT READ ID=&' :FM: acct_id
CALL REM
END
REPEAT
RETURN
END
note: F.READ() is able to read an account from another company, see the next screen:
SUBROUTINE SOME.TEST
* T24 mainline routine
$INSERT I_COMMON
$INSERT I_EQUATE
$INSERT I_F.ACCOUNT
acct_id = '2000000429'
acct_file = 'F.ACCOUNT' ; f_acct = '' ; CALL OPF(acct_file, f_acct)
CALL F.READ(acct_file, acct_id, acct_rec, f_acct, '')
TEXT = acct_rec<Account_AccountTitle1>
CALL REM ;* AUDIGBPSW3
RETURN
END
SUBROUTINE SOME.TEST
* T24 mainline routine
$INSERT I_COMMON
$INSERT I_EQUATE
GOSUB SET.NEXT.TASK
RETURN
SET.NEXT.TASK:
CALL EB.SET.NEXT.TASK('LOCKING S ' : locking_id)
RETURN
END
Run this routine one or more times; output will be:
KEY............... USER.COUNTER
-------------------------------------
1. 1 CONTENT........ 1
KEY............... USER.COUNTER
-------------------------------------
1. 1 CONTENT........ 1001
13.12 F.DELETE()
In this example the record created in the example right above will be deleted.
SUBROUTINE SOME.TEST
* T24 mainline routine
$INSERT I_COMMON
$INSERT I_EQUATE
locking_id = 'USER.COUNTER'
retry = 'P' ;* Prompt user: record locked by... retry Y/N?
CALL F.READU('F.LOCKING', locking_id, R.LOCKING, F.LOCKING, error_code,
retry)
IF error_code AND error_code NE 'RECORD NOT FOUND' THEN
TEXT = error_code
CALL REM
RETURN
END
RETURN
END
13.13 GET.STANDARD.SELECTION.DETS()
Gets SS record and merges system and user fields. The following example resolves local
references’ names to numbers.
Calling subroutine:
SUBROUTINE SOME.TEST
* T24 mainline routine
$INSERT I_COMMON
$INSERT I_EQUATE
RETURN
END
Makes another company to be the current one and loads its environment:
SUBROUTINE SOME.TEST
* T24 mainline routine
$INSERT I_COMMON
$INSERT I_EQUATE
END
There are many of them – see the appropriate manual; here’s in2d() example:
SUBROUTINE SOME.TEST
* T24 mainline routine
$INSERT I_COMMON
$INSERT I_EQUATE
COMI = '20111231'
GOSUB DO.CHECK ;* 20111231
COMI = '20110229'
GOSUB DO.CHECK ;* EB.RTN.DATE.DOES.NOT.EXIST
COMI = '2011001'
GOSUB DO.CHECK ;* EB.RTN.INVALID.DATE.LENGTH
COMI = '19171108'
GOSUB DO.CHECK ;* EB.RTN.YEAR.CANT.PRECEDE.1950
COMI = '171108'
GOSUB DO.CHECK ;* 20081117
COMI = '20111313'
GOSUB DO.CHECK ;* EB.RTN.MONTH.CAN..11
COMI = '2011/12/31'
GOSUB DO.CHECK ;* 20111231
COMI = '31 MAY 2013'
GOSUB DO.CHECK ;* 20130531
RETURN
DO.CHECK:
CALL IN2D('D', 11)
IF ETEXT THEN TEXT = ETEXT
ELSE TEXT = COMI ;* processed value
CALL REM
RETURN
END
13.16 OFS.GLOBUS.MANAGER()
Synchronous creation of OFS message. Safe to use everywhere with “VALIDATE” option, in
mainline routine and in “Verify” section of “W” template.
SUBROUTINE SOME.TEST
* T24 mainline routine
$INSERT I_COMMON
$INSERT I_EQUATE
ofs_message = 'DL.DEFINE,/I/PROCESS,INPUTT/123456,TESTDLDEF,'
ofs_message := 'DESCRIPTN::=THE TEST ONE,SHORT.DESC::=TEST,'
ofs_message := 'FILE.NAME:1:=ACCOUNT.PARAMETER,RECORD.NAME:1:=SYSTEM'
RETURN
END
Runtime. Screen 1:
------------------------------------------------------------------------------
24 JAN 2012 20:50:23 USER (14 APR) VLADIMIR.K [6413,IN]
ACTION
CONTINUE (Y) TMNS000-TESTDLDEF//1,DESCRIPTN:1:1=THE TEST ONE,SHORT.DESC:1:1=TE
Screen 2:
Model Bank. R11.000 DL.DEFINE SEE
UNIT.NAME......... TMNS000-TESTDLDEF
------------------------------------------------------------------------------
1. 1. 1 GB DESCRIPTN THE TEST ONE
2. 1 GB SHORT.DESC.. TEST
5 OPERATION......... S
9. 1 FILE.NAME...... ACCOUNT.PARAMETER
10. 1 RECO SYSTEM
31. 1 DATE.TIME...... 05 JUN 13 19:40
32 AUTHORISER........ 7265_INPUTTER_OFS_TAG
33 CO.CODE........... GB-001-0001
------------------------------------------------------------------------------
------------------------------------------------------------------------------
05 JUN 2013 19:42:33 USER (14 APR) VLADIMIR.K [4081,IN]
ACTION
CONTINUE (Y) SECURITY VIOLATION DURING SIGN ON PROCESS
You can even specify non-existing OFS.SOURCE record – the only thing that is necessary
is syntax type (OFS or XML) that is supplied in field 2. The following routine updates the
record that was created in the previous example:
SUBROUTINE SOME.TEST
* T24 mainline routine
$INSERT I_COMMON
$INSERT I_EQUATE
ofs_message = 'DL.DEFINE,/I/PROCESS,INPUTT/123456,TESTDLDEF,'
ofs_message := 'FILE.NAME:2:=MD.PARAMETER,'
ofs_message := 'RECORD.NAME:2:=GB0010001'
RETURN
END
Result:
UNIT.NAME......... TMNS000-TESTDLDEF
------------------------------------------------------------------------------
1. 1. 1 GB DESCRIPTN THE TEST ONE
2. 1 GB SHORT.DESC.. TEST
5 OPERATION......... S
9. 1 FILE.NAME...... ACCOUNT.PARAMETER
10. 1 RECO SYSTEM
9. 2 FILE.NAME...... MD.PARAMETER
10. 2 RECO GB0010001
31. 1 DATE.TIME...... 05 JUN 13 19:45
32 AUTHORISER........ 8973_VLADIMIR.K_OFS_DUMMY
13.17 OFS.POST.MESSAGE()
Asynchronous creation of OFS message.
SUBROUTINE SOME.TEST
* T24 mainline routine
$INSERT I_COMMON
$INSERT I_EQUATE
RETURN
END
Result:
CT F.OFS.MESSAGE.QUEUE 160950936835505.00-TAG
160950936835505.00-TAG
001 DL.DEFINE,/I/PROCESS,/,TESTDLDEF,DESCRIPTN::=THE TEST ONE,SHORT.DESC::=TES
T,FILE.NAME:1:=ACCOUNT.PARAMETER,RECORD.NAME:1:=SYSTEM
SUBROUTINE SOME.TEST
* T24 mainline routine
$INSERT I_COMMON
$INSERT I_EQUATE
RETURN
END
SUBROUTINE SOME.TEST
* T24 mainline routine
$INSERT I_COMMON
$INSERT I_EQUATE
GOSUB GET.OPENS
CALL OPF(acct_file, f_acct)
GOSUB GET.OPENS
TEXT = number_of_opens<2> - number_of_opens<1>; CALL REM
RETURN
GET.OPENS:
counter ++
user_stats = @USERSTATS
number_of_opens<counter> = user_stats<18>
RETURN
END
SUBROUTINE SOME.TEST
* T24 mainline routine
$INSERT I_COMMON
$INSERT I_EQUATE
RETURN
END
SUBROUTINE SOME.TEST
* T24 mainline routine
$INSERT I_COMMON
$INSERT I_EQUATE
cword_save = T.CONTROLWORD
T.CONTROLWORD<1> = 'NV'
CALL TXTINP('ENTER PASSWORD', 10, 22, '64', 'ANY')
T.CONTROLWORD = cword_save
RETURN
END
13.19 OVE()
Similar to REM() but adds a choice:
SUBROUTINE SOME.TEST
* T24 mainline routine
$INSERT I_COMMON
$INSERT I_EQUATE
the_score = 100
TEXT = 'GAME OVER. WRITE YOUR SCORE (&) ?' :FM: the_score
CALL OVE
IF TEXT EQ 'Y' THEN
TEXT = 'Will do'
END ELSE
TEXT = 'No probs'
END
CALL REM
RETURN
END
SUBROUTINE SOME.TEST
* T24 mainline routine
$INSERT I_COMMON
$INSERT I_EQUATE
RETURN
END
F.PROTOCOL record:
201201240160580314.00
001 20110414
002 1
003 225834
004 22:58:34:047
005 1605
006
007 GB0010001
008 VLADIMIR.K
009 SOME.TEST
010 1
011
012 A note for audit
013
13.21 STORE.END.ERROR()
See examples in the section “T24 hooks”.
SUBROUTINE SOME.TEST
* T24 input routine
$INSERT I_COMMON
$INSERT I_EQUATE
$INSERT I_F.FUNDS.TRANSFER
RETURN
END
------------------------------------------------------------------------------
112 TOT.REC.COMM.LCL.. 0.00
113 TOT.REC.CHG....... 0
114 TOT.REC.CHG.LCL... 0.00
136 RATE.FIXING....... NO
148 TOT.REC.CHG.CRCCY. 0.00
149 TOT.SND.CHG.CRCCY. 0.00
153 AUTH.DATE......... 14 APR 2011
195. 1 STMT.NOS....... 160600876767533.00
195. 2 STMT.NOS....... 1-2
196. 1 OVERRIDE....... WITHDRAWL MAKES A/C BAL LESS THAN MIN BAL
196. 2 OVERRIDE....... Unauthorised overdraft of USD 14400 on account 40622.
196. 3 OVERRIDE....... CREDIT.THEIR.REF NOT SUPPLIED
198 CURR.NO........... 1
199. 1 INPUTTER....... 1251_VLADIMIR.K
200. 1 DATE.TIME...... 20 DEC 11 22:12
201 AUTHORISER........ 1251_VLADIMIR.K
------------------------------------------------------------------------------
20 DEC 2011 22:12:42 USER (14 APR) VLADIMIR.K [1251,INPAGE 3 >>>4>>>
ACTION
AWAITING PAGE INSTRUCTIONS
------------------------------------------------------------------------------
1 TRANSACTION.TYPE.. AC Account Transfer
2 DEBIT.ACCT.NO..... 40622 Dell Computer
3 IN.DEBIT.ACCT.NO..
4 CURRENCY.MKT.DR... 1 Currency Market
5 DEBIT.CURRENCY.... USD US Dollar
6 DEBIT.AMOUNT......
7 DEBIT.VALUE.DATE.. 14 APR 2011
8 IN.DEBIT.VDATE....
9 DEBIT.THEIR.REF...
10 CREDIT.THEIR.REF.. _ 'NO' REPLIED TO LOCAL OVERRIDE
11 CREDIT.ACCT.NO.... 20467 DELL COMPUTER
12 CURRENCY.MKT.CR... 1 Currency Market
13 CREDIT.CURRENCY... USD US Dollar
14 CREDIT.AMOUNT..... 7,800.00
15 CREDIT.VALUE.DATE. 14 APR 2011
16 TREASURY.RATE.....
------------------------------------------------------------------------------
20 DEC 2011 22:10:42 USER (14 APR) VLADIMIR.K [1251,INPAGE 3 >>>4>>>
ACTION
AWAITING PAGE INSTRUCTIONS
13.23 TXT()
Process a dynamic message.
SUBROUTINE SOME.TEST
* T24 mainline routine
$INSERT I_COMMON
$INSERT I_EQUATE
message = 'READ ERROR, FILE [&], RECORD [&]' :FM: 'FBNK.ACCOUNT' :VM: 999999
CALL TXT(message)
* We don't call REM here since it has the same functionality itself; so:
CRT @(8,22):message
MSLEEP(5000)
RETURN
END
Output:
------------------------------------------------------------------------------
26 JAN 2012 19:49:31 USER (14 APR) VLADIMIR.K [1405,IN]
If we run it being logged in as non-English language user, a new record appears in application
DYNAMIC.TEXT so we can add the translation, authorise that record and next time see
the message in desired language:
USER.ID........... VLADIMIR.K1
------------------------------------------------------------------------------
1 USER.NAME......... V.KAZIMIRCHIK
2 SIGN.ON.NAME...... VLADIMIRK1
3 CLASSIFICATION.... INT
4 LANGUAGE.......... 3 German
BASE.TEXT......... READ.ERROR,.FILE.[&],.RECORD.[&]
------------------------------------------------------------------------------
1 GB TEXT 1 ........ READ ERROR, FILE [&], RECORD [&]
2 FR TEXT 2 ........
3 DE TEXT 3 ........
4 ES TEXT 4 ........
5 ...TEXT 5 ........
6 ...TEXT 6 ........
7 ...TEXT 7 ........
8 ...TEXT 8 ........
9 ...TEXT 9 ........
10 ...TEXT 10 .......
11 ...TEXT 11 .......
12 ...TEXT 12 .......
13 RECORD.STATUS..... INAU INPUT Unauthorised
14 CURR.NO........... 1
15. 1 INPUTTER....... ****SOME.TEST
16. 1 DATE.TIME...... 26 JAN 2012 19:55
------------------------------------------------------------------------------
26 JAN 2012 19:56:11 USER (14 APR) VLADIMIR.K1 [5163,INPAGE 1 >>>2>>>
ACTION
AWAITING PAGE INSTRUCTIONS
BASE.TEXT......... READ.ERROR,.FILE.[&],.RECORD.[&]
------------------------------------------------------------------------------
1 GB TEXT 1 ........ READ ERROR, FILE [&], RECORD [&]
2 FR TEXT 2 ........
Here’s the idea of a dynamic message – we don’t need to do the translation every time when
a new file name and/or record @id appears in a message. Let’s amend the routine:
SUBROUTINE SOME.TEST
* T24 mainline routine
$INSERT I_COMMON
$INSERT I_EQUATE
TEXT = 'READ ERROR, FILE [&], RECORD [&]' :FM: 'FBNK.CUSTOMER' :VM: 12345
CALL REM
RETURN
END
Output:
-- LAST SIGN.ON, DATE: 26 JAN 2012 TIME: 12:02 ATTEMPTS: 0 --------
26 JAN 2012 12:07:29 USER (14 APR) VLADIMIR.K1 [1840,IN]
ACTION
CONTINUE (Y) Lesefehler, Datei [FBNK.CUSTOMER], Rekord [12345]
14 How-tos
14.1 Get rid of speaker beeps in jsh (Windows)
Step 1. Edit file jbase nt.ti in %TAFC HOME%\src directory – comment “bel” setting:
#
# Definiton of the NT console, use by jBASE to give ANSI emulation
#
ntcon|dumb|ansi|NT console emulation,
am, xon,
cols#80, lines#24,
# bel=^G,
blink=\E[5m, bold=\E[1m, cbt=\E[Z,
note: TERM environment variable should match the section header – e.g. ntcon.
TERMINAL.......... EBS-JBASE
------------------------------------------------------------------------------
17. 1 INIT.SEQUENCE.. <027>&oR
17. 2 INIT.SEQUENCE.. <027>[?67h
18. 1 FUNCTION.KEYS.. <27>&f2a1k6d1LRETURN<21>
18. 2 FUNCTION.KEYS.. <27>&f2a2k4d1LBACK<2>
18. 3 FUNCTION.KEYS.. <27>&f2a3k7d1LFORWARD<6>
18. 4 FUNCTION.KEYS.. <27>&f2a4k4d1LLAST<5>
18. 5 FUNCTION.KEYS.. <27>&f2a5k5d1LENTER<22>
18. 6 FUNCTION.KEYS.. <27>&f2a6k4d1LNEXT<23>
18. 7 FUNCTION.KEYS.. <27>&f2a7k4d1LLEFT<29>
18. 8 FUNCTION.KEYS.. <27>&f2a8k5d1LRIGHT<30>
19. 1 INIT.EXECUTES..
20 BELL..............
21 RESET............. <027>[0;1m
22 CURSOR.BACK.......
23 PRINT............. <027>[D
24 PRINT.ECHO........ <027>[C
------------------------------------------------------------------------------
08 DEC 2011 20:12:28 USER (14 APR) VLADIMIR.K [2797,INPAGE 2 >>>5>>>
ACTION
AWAITING PAGE INSTRUCTIONS
14.3 Automatically create the new file on target system when us-
ing DL.DEFINE
Just include FILE.CONTROL record for your application to DL.DEFINE. (If you transfer
records of your application as well, put FILE.CONTROL record before them.)
Model Bank
------------------------------------------------------------------------------
1 100112 ABNAMRO Abn Amro Securities Chief Securities De| N|
2 100369 ABUDHAOIL Abu Dhabi National Oil Company Corporate Loan Supe| U|
3 111706 ADMIN Administrator Of Acorn Engg CompMortgage Dept User 2 U|
4 100396 AIRBOURNE Airbourne Freight Retail Credit Offic| R|
5 111405 AKAI AKAI Trade Finance Offic| J|
ENQUIRY........... %CUSTOMER
------------------------------------------------------------------------------
1 PAGE.SIZE ........ 4,19
After:
Model Bank
------------------------------------------------------------------------------
1 100112 ABNAMRO Abn Amro Securities Chief Securities De| N|
2 100369 ABUDHAOIL Abu Dhabi National Oil Company Corporate Loan Supe| U|
3 111706 ADMIN Administrator Of Acorn Engg CompMortgage Dept User 2 U|
4 100396 AIRBOURNE Airbourne Freight Retail Credit Offic| R|
5 111405 AKAI AKAI Trade Finance Offic| J|
6 111410 AKAIGBP AKAI Trade Finance Offic| J|
7 100349 ALBRECHTT Theo Albrecht Retail Credit Offic| G|
8 111683 ALEX Alex Branch Operations M| U|
9 100600 ALEXFL Alex Call Centre Agent U|
10 100301 ALLEGRA Allegra Corporate Officer U|
11 111421 ALLENG Allen Gerling Customer Service Ag| G|
12 100971 ALLIANCE Alliance Investment Managers Chief Securities De| U|
13 100433 AMEXINDONE American Express Indonesia Trade Finance Offic| I|
14 100435 AMEXPARIS American Express Paris Treasury Dealer F|
15 100436 AMEXSINGAP American Express Singapore Treasury Dealer S|
16 100437 AMEXUK American Express Uk Treasury Dealer G|
------------------------------------------------------------------------------
20 DEC 2011 20:09:34 USER (14 APR) VLADIMIR.K [6409,INPAGE 1 >>>3>>>
ENQUIRY........... %DE.MESSAGE
------------------------------------------------------------------------------
1 PAGE.SIZE ........ 4,99
MessaDescription
------------------------------------------------------------------------------
ENQUIRY........... %DE.MESSAGE
------------------------------------------------------------------------------
1 PAGE.SIZE ........ 4,19
MessaDescription
------------------------------------------------------------------------------
1 1 Complete Message def for AA
2 5 New Arrangement message
3 10 CHEQUE
4 20 CHEQUE ENCLOSURE
5 30 DRAFT
6 40 ADV. OF DRAWING
7 50 DRAFT ENCLOSURE
8 60 BANKERS PAYMENT
9 80 B.A.C.S. PAYMENT
10 100 CUSTOMER TRANSFER
11 101 REQUEST FOR TRANSFER
Step 7. Return to “AWAITING APPLICATION” prompt, wait at least one minute and type
DE.MESSAGE L ←- once again:
MessaDescription
------------------------------------------------------------------------------
1 1 Complete Message def for AA
2 5 New Arrangement message
3 10 CHEQUE
4 20 CHEQUE ENCLOSURE
5 30 DRAFT
6 40 ADV. OF DRAWING
7 50 DRAFT ENCLOSURE
8 60 BANKERS PAYMENT
9 80 B.A.C.S. PAYMENT
10 100 CUSTOMER TRANSFER
11 101 REQUEST FOR TRANSFER
12 102 Multiple Customer Credit Transfer
13 103 CUSTOMER CREDIT TRANSFER
14 110 CHEQUE ADVICE
15 111 REQUEST FOR STOP PAYMENT OF CHEQUE
16 112 STATUS OF MT111
------------------------------------------------------------------------------
20 JAN 2012 22:45:02 USER (14 APR) VLADIMIR.K [7929,INPAGE 1 >>>3>>>
ACTION
AWAITING PAGE INSTRUCTIONS
note: In production don’t set this field (leave empty; value of 0 means “no cache at all”).
KEY............... DOH
------------------------------------------------------------------------------
1. 1 GB DESCRIPTION. FULL DE.O.HEADER
2. 1 ENQUIRY........ %DE.O.HEADER DE.O.HEADER
3. 1. 1 SELECTION...
4. 1. 1 OPERAND.....
5. 1. 1 LIST........
6. 1. 1 SORT........
7 REPORT.CONTROL.... ENQUIRY.PRINT Enquiry screen print
8 STANDARD.HEADING..
Result is being put to &HOLD&. Search it for the last record in the page 200 from the screen
above (D20110419001015270002) and see that here it’s not the last:
// ...
// ...
LIST ETC.BP
SOME.TEST
1 Records Listed
SOME.TEST
BASIC_2.c
Source file SOME.TEST compiled successfully
LIST ETC.BP
SOME.TEST
1 Records Listed
LIST ETC.BP,OBJECT
$SOME.TEST
1 Records Listed
14.9 See last jsh commands issued from the same port number
Ctrl - L
001 where
...
005 jcompile test.b
...
011 CLEAR-FILE F.TEST
012 SELECT VOC
013 CLEARSELECT
...
etc
14.10 See last jsh and jed commands issued from any port number
CT [path_to_TAFC]\tmp\jutil_ctrl
jutil_jed_CONIN_-2
001 .last.
jutil_jsh_CONIN_-34
001 test9
002 build.bat
jutil_jsh_CONIN_-3
001 CT C:\home\kzm\v-t24\tafc201108\tmp\jutil_ctrl
002 where
003 test
004 jcompile test.b
005 LIST C:\home\kzm\v-t24\tafc201108\tmp\jutil_ctrl
006 LIST F.TEST
007 LIST F.TEST
008 jlogdup INPUT set=current terminate=eos OUTPUT set=database
009 SELECT F.LOG WITH PATH LIKE "...'\F.TEST'" AND TYPE EQ 'WRITE'
010 CLEAR-FILE F.TEST
...
note: “-n” at the end of @id is port number – first column of WHERE output.
0001 PH
0002 NAME TYPE
DESC
X X ID.SUP
X
tSS TAG
<tSS version="1.1"><t24version>R10.000</t24version><t24pid>.....
DEBUG
DEBUG statement seen
Line 182 , Source tSS
Backtrace log:
Line 0 , Source jmainfunction.b , Level 0
Line 116 , Source tSS
Shared Memory:
m 0 0x580070b4 --rw-rw-rw- root system root system 1 134217728 192614 237696
m 131073 0x4a414310 --rw-rw-rw- root system root system 3 188 266478 483536 2
m 131074 0x0d00a2f0 --rw-rw-rw- root system root system 14 1440 237818 110204
m 131075 0xffffffff --rw-rw---- root system root system 1 4096 798876 798876
m 4 0x4a414311 --rw-rw-rw- root system root system 3 342616 266478 483536 20:
m 5 0x4a500064 --rw-rw-rw- sairam hdin sairam hdin 3 436504 757986 483538 20:
m 6 0x4a414032 --rw-rw-rw- bhavani hdin bhavani hdin 7 425632 651402 483334 2
m 7 0x4a415032 --rw-rw-rw- sonia hdin sonia hdin 6 351944 659586 483352 20:22
T ID KEY MODE OWNER GROUP CREATOR CGROUP NSEMS OTIME CTIME
Semaphores:
s 262144 0x580070b4 --ra-ra-ra- root system root system 1 22:37:45 22:37:45
s 1 0x440070b4 --ra-ra-ra- root system root system 2 22:37:45 22:37:45
s 131074 0x0100a0bc --ra------- root system root system 1 20:22:14 22:46:54
s 3 0x6200a0c0 --ra-r--r-- root system root system 1 22:38:31 22:38:31
s 4 0x4a414310 --ra-ra-ra- root system root system 61 20:17:54 22:47:23
s 5 0x4a414311 --ra-ra-ra- root system root system 61 16:39:13 22:47:23
ipcrm -m5
note: For jBASE4 address begins from 0x4a4, for TAFC – from 0x24.
14.15 See which files and records took part in T24 transaction
Step 1. Set appropriate spf field:
USER.ID........... INPUTTER
------------------------------------------------------------------------------
1 USER.NAME......... Inputter, yes it is |
2 SIGN.ON.NAME...... INPUTT
3 CLASSIFICATION.... INT
4 LANGUAGE.......... 1 English
5. 1 COMPANY.CODE... GB0010001 Model Bank
5. 2 COMPANY.CODE... GB0010002 MF Lead Company
5. 3 COMPANY.CODE... GB0010003 MF Branch 1
5. 4 COMPANY.CODE... GB0010004 MF Branch 2
5. 5 COMPANY.CODE... SG0010001 Model Bank - Singapore
5. 6 COMPANY.CODE... EU0010001 Model Bank - Europe
6 DEPARTMENT.CODE... 56 Trade Finance Supervisor
7 PASSWORD.VALIDITY. 01 MAY 2012 M0601 01 MAY 2012 Every 6 months on day 1
8 START.DATE.PROFILE 09 APR 2011
9 END.DATE.PROFILE.. 11 APR 2012
10. 1 START.TIME..... 00:01
11. 1 END.TIME....... 23:59
------------------------------------------------------------------------------
30 NOV 2011 19:36:36 USER (14 APR) VLADIMIR.K [1021,INPAGE 1 >>>6>>>
ACTION
1 F.EB.EXTERNAL.
ELETEnput INPUTTER
USER INPUTTER ter, yes it is
NE INPUTTINT1
GB0010001
F.EB.EXTERNAL. GB0010002
USER$NAU INPUT
TER NE
F.USER$NAU INP GB0010003
UTTER WLNE
F.USER INPUTTE GB0010004
R WL
F.SY.PARAMETER SG0010001
SYSTEM
F.SY.PARAMETER EU0010001562
GB0010001 0120501M06012
0110409201204
1112359999
9ALLALL.P
GA 2 B C D E
F H I L P R S
...
BEGIN CASE
CASE ISDIGIT(V.STRT)
P.PARTNO = 1
CASE V.STRT EQ 'D'
P.PARTNO = 2
CASE V.STRT EQ 'S'
P.PARTNO = 3
CASE 1
P.PARTNO = 99
END CASE
RETURN
END
Attach it:
VERIFY-DISTRIB STMT.ENT.DIST
Copy data:
0002 ../bnk.data/ac/STMT.ENT.DIST
0002 ../bnk.data/ac/STMT.ENT.PART1
0002 ../bnk.data/ac/STMT.ENT.PART2
0002 ../bnk.data/ac/STMT.ENT.PART3
0002 ../bnk.data/ac/STMT.ENT.PART99
VERIFY-DISTRIB FBNK.STMT.ENTRY
@ID. 158250319644408.000001
@ID. 158180605551490.020001
@ID. 158210768248728.020001
@ID. 158230320747851.040001
...
@ID. DUMMY.ID502
@ID. DUMMY.ID188
@ID. DUMMY.ID424
@ID. DUMMY.ID226
...
@ID. S!EUR152100001!CR!EUR!SCPL!633!20110407!20110407!!1!!117!20110407
@ID. S!GBPUSD140180001!CR!GBP!AC!130!20110331!!!1!!15!20110331
@ID. S!USDGBP140160001!CR!USD!FT!130!20110414!20110414!!1!!366!20110414
@ID. S!20591!CR!EUR!FT!210!20110414!20110414!!1!!6408!20110414
...
@ID. F20110414.15826077544910414
@ID. F20110415.15825031964301106
@ID. F20110414.15826077544910504
@ID. F20110428.15830060275557004
...
Now you can archive and remove the initial FBNK.STMT.ENTRY file (in my environment it’s
..\bnk.data\ac\FBNK STMT ENTRY).
Use the cursor keys and tab keys to move around the screen.
Define the name (with full path) of the first file in a log set 1, e.g.:
Repeat that step to assign one more file to the set 1. Resulting screen:
Navigate ( →−
−−− ) to menu item “Current switched log set” and set it to 1:
→
Use Ctrl-X to exit. Create stub file to be able to be able to look at the journal:
CT DICT F.LOG
SET
001 A
002 1
003 Set
004
005
006
007
TIME-UTC
001 A
002 6
003 Time]UTC
004
005
006
007
008
009 R
010 12
DATE
001 A
002 6
003 Update]Date
004
005
006
007
008 Uff1]D4
009 L
010 11
...
Log in to and out of T24. See the journal entries (at the beginning there will be entries
related to creation of F.LOG itself so skip them):
LIST F.LOG
...
WRITE vladimir.k F.TERMINAL.USER 19:26:10 09 MAR 2012
WRITE vladimir.k F.TSA.STATUS 19:26:11 09 MAR 2012
WRITE vladimir.k F.T24.SESSION 19:26:11 09 MAR 2012
WRITE vladimir.k F.LOCKING 19:26:11 09 MAR 2012
WRITE vladimir.k F.OS.TOKEN 19:26:11 09 MAR 2012
WRITE vladimir.k F.OS.TOKEN.USE 19:26:11 09 MAR 2012
WRITE vladimir.k F.USER 19:26:11 09 MAR 2012
WRITE vladimir.k F.OS.XML.CACHE 19:26:11 09 MAR 2012
DELETE vladimir.k F.OS.TOKEN 19:26:13 09 MAR 2012
DELETE vladimir.k F.OS.TOKEN.USE 19:26:13 09 MAR 2012
WRITE vladimir.k F.USER 19:26:13 09 MAR 2012
TRANSTART vladimir.k 19:26:13 09 MAR 2012
WRITE vladimir.k F.TSA.STATUS 19:26:13 09 MAR 2012
Set.................... 1
Type................... WRITE
Type................... 2
Update Time............ 19:26:11
Update Date............ 09 MAR 2012
Process ID............. 4020
Port Number............ 3
Total Log Record Size.. 169
File Number............ 0
File Offset............ 5733
Trans.................. 0
Full file path name.... F.TSA.STATUS
Record Key............. OLTP8239
jBASE login............ vladimir.kazimirchik
OS login...............
TTY....................
001 M
002 ID-SUPP SET FILE TYPE TYPENUM TIME DATE PID PORT LOGSIZE FILENO OFFSET
TRANS PATH RECKEY JBNAME OSNAME TTY APPID TRANSID REALTIME TRANSTIME
TRANSCOMP TRANSABORT
Now log in to T24, input an unauthorised ABBREVIATION record and see the impact in
the journal:
jstat -v F.ABBREVIATION
File Path = ..\bnk.data\eb\F_ABBREVIATION
File Type = JR, Hash method = 5, Created = Mon May 19 19:51:57 2008
Frame size = 4096, OOG Threshold = 2048
File size = 94208, Freespace = 1 frames
Internal Modulo = 3/7/19, External Modulo = 31
Inode no. = 145809, Device no. = 24915
Accessed = Fri Mar 09 19:26:00 2012, Modified = Fri Mar 09 19:26:00 2012
Backup = YES, Log = YES , Rollback = YES, Secure updates = YES
Deallocate pointers : NO Deallocate frames NO
Revision level = 1
Record Bytes = 30494, Record Count = 294
Bytes/Record = 103, Bytes/Group = 1452
Data Frames = 21, Ptr Frames = 0
OOG Bytes = 0, OOG Frames = 0
Sum Squares = 3190536, Std Dev Mean = 118
It’s better to switch logging off for certain files to gain some performance (for example, for
F.TERMINAL.USER):
jchmod -L F.TERMINAL.USER
jstat -v F.TERMINAL.USER
...
Backup = YES, Log = NO , Rollback = YES, Secure updates = YES
...
Now let’s try selective journal restore. To avoid over-complicating things let’s not involve
T24 – just create a new file, add some records to it (with logging), then stop logging and
clear the file, then restore the records added earlier. First step will be to create a fresh log
set (#2) and make it active:
LIST F.LOG
Type....... jBASE..... Full file path name................ Update.. Update.....
login Time Date
No Records Listed
CREATE-FILE F.TEST 1 1
[ 417 ] File F.TEST]D created , type = J4
[ 417 ] File F.TEST created , type = J4
Check if this file is being logged (by default it should be, but anyway):
LIST F.LOG
Type....... jBASE..... Full file path name................ Update.. Update.....
login Time Date
2 Records Listed
LIST F.TEST
F.TEST........
F.DX.REVAL.DET.ENHANCED
F.GENERATE.ENTRY.WRK
5 Records Listed
CLEAR-FILE F.TEST
LIST F.TEST
F.TEST........
No Records Listed
Now it’s time to restore the records (logging is yet “INACTIVE” of course):
LIST F.TEST
F.TEST........
F.DX.REVAL.DET.ENHANCED
F.GENERATE.ENTRY.WRK
F.GT.SYSTEM.PARAMETER$NAU
F.RUN.GRP.PERF.TAKEON
F.SA.RATIOS
5 Records Listed
Note that none of log files should ever exceed 2Gb in size (several log sets and their switching
should help here). Many other factors should be taken into consideration for transaction
journalling like online journal replication to another server etc; I believe what was described
here gives a good start to learn it all.
SUBROUTINE SERVICE.TEST(P.NEXT.ID)
*-----------------------------------------------------------------------------
$INSERT I_COMMON
$INSERT I_EQUATE
$INSERT I_SERVICE.TEST.COMMON
*-----------------------------------------------------------------------------
RETURN
END
SUBROUTINE SERVICE.TEST.LOAD
*-----------------------------------------------------------------------------
$INSERT I_COMMON
$INSERT I_EQUATE
$INSERT I_SERVICE.TEST.COMMON
*-----------------------------------------------------------------------------
FN.FT.NAU = 'F.FUNDS.TRANSFER$NAU'
F.FT.NAU = ''
CALL OPF(FN.FT.NAU, F.FT.NAU)
RETURN
END
* Main SELECT
V.SEL.CMD = 'SELECT ' : FN.FT.NAU
HUSH ON
EXECUTE V.SEL.CMD RTNLIST V.FT.LIST
HUSH OFF
RETURN
END
* File: I_SERVICE.TEST.COMMON
COMMON /SERVICE.TEST.COMM/ FN.FT.NAU, F.FT.NAU
Step 2. Create the following records in T24 (applications for two initial screenshots are
PGM.FILE and BATCH respectively):
Model Bank PROGRAM FILE, INPUT
PROGRAM SERVICE.TEST
------------------------------------------------------------------------------
1 TYPE.............. B
2. 1 GB SCREEN.TITLE
3 ADDITIONAL.INFO...
4. 1 BATCH.JOB......
5 PRODUCT........... EB
6 SUB.PRODUCT.......
7. 1 DESCRIPTION....
WORKLOAD.PROFILE.. SERV.TST
------------------------------------------------------------------------------
1 DESCRIPTION....... TEST
2. 1 TIME........... 10:00
3. 1 AGENTS.REQUIRED 2
2. 2 TIME........... 10:05
3. 2 AGENTS.REQUIRED
2. 3 TIME........... 12:00
3. 3 AGENTS.REQUIRED 2
2. 4 TIME........... 12:05
3. 4 AGENTS.REQUIRED
2. 5 TIME........... 14:00
3. 5 AGENTS.REQUIRED 2
2. 6 TIME........... 14:05
3. 6 AGENTS.REQUIRED
2. 7 TIME........... 16:00
3. 7 AGENTS.REQUIRED 2
2. 8 TIME........... 16:05
3. 8 AGENTS.REQUIRED
2. 9 TIME........... 19:00
3. 9 AGENTS.REQUIRED 2
2.10 TIME........... 19:05
3.10 AGENTS.REQUIRED
4 RESERVED.9........
SERVICE........... BNK/SERVICE.TEST
------------------------------------------------------------------------------
1. 1 DESCRIPTION.... TEST
2. 1 SERVER.NAME....
3. 1 WORK.PROFILE... SERV.TST TEST
4. 1 SERVER.STATUS..
5 USER.............. INPUTTER Inputter, yes it is
6 SERVICE.CONTROL... AUTO
7 REVIEW.TIME.......
Now we can put START into field SERVICE.CONTROL of the TSA.SERVICE record TSM and
start tSM (typing START.TSM at jsh prompt). That’s it.
Under this setup 2 agents will be started at specified above moments of time and stopped
after 5 minutes (or after they finish the processing if it takes more than 5 minutes). However,
if they finish fast enough (less that in 5 minutes) they might be triggered again – so take
care not to duplicate the report data or whatever you’re doing.
As it was written above, even if 5 minutes pass and agents are still working, TSM won’t force
them to quit. This makes tempting the idea to specify 0 agents at, say, 19:01 to be sure that
agents will be triggered only once – but since TSM sleeps for 1 minute between its iterations
there might be a slim chance that agents won’t be triggered at all. If you need your service to
run only once a day – use START instead of AUTO for it and agents will definitely be triggered
one time only but then SERVICE.CONTROL value will become STOP and unless you somehow
change it to START before the next day – it will not be started ever again.
set PATH=%PATH%;C:\kzm\tools\python27
set INCLUDE=%INCLUDE%;C:\kzm\tools\python27\include
set LIB=%LIB%;C:\kzm\tools\python27\libs
In this example an Excel file will be created (with different text attributes and a formula),
also SHA1 checksum of a string and md5 checksum of a file will be calculated.
Step 1. C routine PYTOOLS.c:
#include <jsystem.h>
#include <assert.h>
#include <Python.h>
PyObject *pFile, *pModule, *pDict, *pFunc, *pArgs, *pValue;
#ifdef DPSTRUCT_DEF
#define JBASEDP DPSTRUCT *dp,
#else
#define JBASEDP
// Page 250
#endif
/*
* C function called from jBC
*/
VAR *PyCALL(VAR *Result, JBASEDP VAR *VarFile, VAR *VarFunc, VAR *VarArgs)
{
char *cFile, *cFunc, *cArgs;
assert(dp != NULL);
Py_Initialize();
pFile = PyString_FromString(cFile);
pModule = PyImport_Import(pFile);
pDict = PyModule_GetDict(pModule);
pFunc = PyDict_GetItemString(pDict, cFunc);
pArgs = Py_BuildValue("(s)", cArgs);
if (PyCallable_Check(pFunc))
{
pValue = PyObject_CallObject(pFunc, pArgs);
STORE_VBS(Result, PyString_AsString(pValue) );
Py_DECREF(pValue);
Py_DECREF(pFunc);
} else
{
STORE_VBS(Result, "PYerror" );
}
Py_DECREF(pFile);
Py_DECREF(pModule);
Py_DECREF(pDict);
Py_DECREF(pArgs);
Py_Finalize();
return(Result);
}
#!/usr/bin/env python
# Page 251
import hashlib
import xlwt
def createXLS(s_data):
wbk = xlwt.Workbook()
style_normal = xlwt.XFStyle()
font = xlwt.Font()
font.name = 'Calibri'
font.height = 11*20
style_normal.font = font
style_bold = xlwt.XFStyle()
l_data = s_data.split('#')
s_output = l_data[0]
n_len = len(l_data)
for i in range(1, n_len):
s_sheet = l_data[i]
l_sheet = s_sheet.split('^')
s_sh_name = l_sheet[0]
sheet = wbk.add_sheet(s_sh_name)
n_sh_len = len(l_sheet)
for j in range(1, n_sh_len):
l_cell_data = l_sheet[j].split('|')
n_y = int(l_cell_data[0])
n_x = int(l_cell_data[1])
sheet.col(n_x).width = 6500
s_text = l_cell_data[2]
n_text_prop = int(l_cell_data[3])
if n_text_prop == 0:
sheet.write(n_y, n_x, s_text, style_normal)
elif n_text_prop == 1:
sheet.write(n_y, n_x, s_text, style_bold)
else:
sheet.write(n_y, n_x, xlwt.Formula(s_text))
wbk.save(s_output)
# Page 252
return str(j-1) + ' sheet(s) written to ' + s_output
def sha1(s_infile):
f_file_in = open(s_infile, 'rb')
v_text = f_file_in.read()
converted = hashlib.sha1(v_text).hexdigest()
return converted
def md5(s_infile):
f_file_in = open(s_infile, 'rb')
v_text = f_file_in.read()
return hashlib.md5(v_text).hexdigest()
def datesay(s_dummy):
return ctime(time())
def pyecho(s_in):
return s_in
def main():
s_out = 'standard library for jBC'
print s_out
return s_out
if __name__ == '__main__':
main()
note: After copypasting Python code restore line indents exactly as they are shown here!
CRT 'START'
CRT PyCALL('py_function', 'pyecho', 'Python interface is OK, date is:')
CRT PyCALL('py_function', 'datesay', '')
CRT PyCALL('py_function', 'sha1', 'testsha1.txt')
CRT PyCALL('py_function', 'md5', 'C:\\WINDOWS\\system32\\cmd.exe')
START
Python interface is OK, date is:
Thu Jan 19 21:46:51 2012
eb4209cd79d6cdc2443f8d868b50e54dc5c66f16
eeb024f2c81f0d55936fb825d21a91d6
2 sheet(s) written to test001.xls
FINISH
From an experienced C programmer’s view (which I’m not) some of my actions might be
wrong; any comments are welcome. Tested on Windows XP/SP2 using lcc-win32 C com-
piler.
Step 0. Create a directory for this exercise (e.g. C:\putty-workshop).
Step 1. Download PuTTY source code (version 0.60 will do). Extract it to directory
C:\putty-workshop\source directory. In this example I decided not to retain the direc-
tory “putty-0.60” which resided in archive putty-0.60.tar.gz so the full path to, e.g.,
putty.h is: C:\putty-workshop\source\putty.h.
Step 2. Download and install lcc-win32 C compiler and install it to C:\putty-workshop\lcc.
(Note that it’s free for non-commercial use.)
Step 3. To avoid linker error “Invalid resource file putty.res” – download MS resource compiler
and put its files to C:\putty-workshop\lcc\bin. One I have is:
md5:
348493a159d4f2063a62097c41d99b53 lrc.exe
a6060e5c881865daa6f1b406b050bb5a RCDLL.DLL
Step 4. Amend the source code of config.c. Find the following line:
// Page 254
Replace it with:
note: “/* T24” comment will help us to locate all changes later if need be.
Step 5. Amend the source code of putty.h. Find the following code:
enum {
/* Function key types (cfg.funky_type) */
FUNKY_TILDE,
FUNKY_LINUX,
FUNKY_XTERM,
FUNKY_VT400,
FUNKY_VT100P,
FUNKY_SCO
};
enum {
/* Function key types (cfg.funky_type) */
FUNKY_TILDE,
FUNKY_LINUX,
FUNKY_XTERM,
FUNKY_VT400,
FUNKY_VT100P,
FUNKY_SCO,
FUNKY_T24 /* T24 addition */
};
Step 6. Amend the source code of windows\window.c. Find the following line:
// Page 255
case VK_F7: *p++ = '\x14'; break;
}
*p++ = '\n';
return p - output;
} /* T24 addition end */
Step 7. Amend the source code of windows\winstuff.h. Find the following line:
Amend the name of registry entry to avoid collisions with the standard PuTTY, e.g.:
To avoid compilation error “cannot open include file winresrc.h” and to use resource compiler
from MS – find the following line:
Replace it with:
note: Avoid removing TAB or changing it to spaces at the beginning of the line.
Turn compiler optimization off (remove -O in all lines like that). Before:
After:
note: Not all sources are needed for putty.exe but it might be easier to change them all.
// Page 256
Step 9. Create putty-compile.bat in C:\putty-workshop:
cd source\windows
set INCLUDE=C:\putty-workshop\lcc\include;%INCLUDE%
set PATH=C:\putty-workshop\lcc\bin;%PATH%
set LIB=C:\putty-workshop\lcc\lib;%LIB
make -f makefile.lcc putty.exe 2>ERR.TXT
Step 10. Run putty-compile.bat. If you see something like (note “Time:” at the last line):
...
..\windows\winucs.c
lcc -p6 -D_WINDOWS -DNO_MULTIMON -DNO_IPV6 -g -I..\./ -I..\charset/ -I..\w
..\windows\winutils.c
lcc -p6 -D_WINDOWS -DNO_MULTIMON -DNO_IPV6 -g -I..\./ -I..\charset/ -I..\w
..\x11fwd.c
lcclnk -subsystem windows -o putty.exe be_all_s.obj cmdline.obj config.obj
isc.obj ldiscucs.obj logging.obj minibidi.obj misc.obj pinger.ob
putty.res raw.obj rlogin.obj sercfg.obj settings.obj sizetip.obj ssh
sshbn.obj sshcrc.obj sshcrcda.obj sshdes.obj sshdh.obj
j sshrand.obj sshrsa.obj sshsh256.obj sshsh512.obj sshsha.obj ss
.obj timing.obj tree234.obj version.obj wcwidth.obj wildcard.obj wi
obj window.obj winhandl.obj winhelp.obj winmisc.obj winnet.obj
nt.obj winproxy.obj winser.obj winstore.obj wintime.obj winucs.obj
32.lib wsock32.lib ws2_32.lib winspool.lib winmm.lib imm32.lib
Time: 8.987 seconds
...then all is OK and you have putty.exe in source\windows subdirectoty. If not – see file
ERR.TXT located at the same place.
// Page 257
// Set UTF-8 translation as a default:
gpps(sesskey, "LineCodePage", "UTF-8", cfg->line_codepage,
sizeof(cfg->line_codepage));
...
// Screen width=132:
gppi(sesskey, "TermWidth", 132, &cfg->width);
A new parameter (-z "window title") was added (I need it for automatic start from
SciTE, see “Source code editing” chapter). Changes done in cmdline.c, the very end of
cmdline process param function:
Another change – set the colour scheme in command line. See the excerpt from cmdline.c
that is situated right after the previous example:
if (!strcmp(p, "-bkgr_blue")) {
RETURN(1);
SAVEABLE(0);
cfg->colours[2][2] = 128;
}
if (!strcmp(p, "-bkgr_cyan")) {
RETURN(1);
SAVEABLE(0);
cfg->colours[0][0] = 255;
cfg->colours[0][1] = 255;
cfg->colours[0][2] = 255;
cfg->colours[2][1] = 144;
cfg->colours[2][2] = 144;
}
Or:
Or:
14.22 Create a reverse tunnel so you can log in from Unix server
to your local PC
Step 1. Use plink.exe (shipped with PuTTY) on the local machine to create a tunnel:
note: In this example local PC has Telnet (hence port 23) but of course ssh is better
Step 2. Open another session and log in to Unix server in normal way.
Step 3. In that session:
jsh -->bash
bash-3.00$ telnet localhost 19999
Trying...
Connected to loopback.
Escape character is '^]'.
jBASE Telnetd Server Version 3.6.9.1
jsh -->
note: “keepalive” is recommended (not in this sample since I hadn’t the latest plink)
export HOME=$PWD
export TAFC_HOME=/usr/jbc
export PATH=$TAFC_HOME/bin:$HOME/bin:/usr/vacpp/bin:$PATH
export LIBPATH=$TAFC_HOME/lib:/usr/ccs/lib:/usr/lib
export JEDIFILENAME_MD=$HOME/VOC
export JBCEMULATE=prime
export JBASE_I18N=1
export JBCOBJECTLIST=$HOME/lib:$HOME/t24lib
export JEDIENABLEQ2Q=1
jcompile -E -I../T24_BP test.b
http://localhost:9095/BrowserWeb/servlet/BrowserServlet?method=POST
&command=login&requestType=CREATE.SESSION&counter=0&branchAdminLogin=
&signOnName=INPUTT&password=123456
note: Of course this method is recommended only for non-sensitive T24 environments.
LOGOFF 2
INCLUDE JBC.h
*
* Create custom "file.txt".
*
file_path_parent = '..'
file_path = file_path_parent : DIR_DELIM_CH : "file.txt"
file_contents = "";
file_contents<-1> = 'line1'
file_contents<-1> = 'line2'
file_contents<-1> = 'line3'
file_contents<-1> = 'line4'
* ...
OSWRITE file_contents ON file_path
INCLUDE JBC.h
*
file_path_parent = '..'
file_path = file_path_parent : DIR_DELIM_CH : "new_folder"
PERFORM "CREATE-FILE DATA " : file_path : " TYPE=UD" CAPTURING output
15 Performance notes
The main thing to remember is: poorly designed local development can easily bring even the
most powerful T24 server to its proverbial knees.
Some more or less obvious points:
• Minimize the time for keeping a lock. It’s wrong in my opinion to issue one and then let
user to decide something.
• Don’t create local applications with too many fields. There’s a limitation of 500 but it’s
too generous for my liking. Multi- and sub-valuing fields, associating them together adds to
that.
• Don’t create too many local fields for any application. Again, 999 is the limit which is too
big.
16 Known issues
All these issues were reported (though unofficially) and either are in the process of being
corrected or declared to be the natural jBASE behaviour.
LIST FBNK.ACCOUNT CATEGORY CURRENCY WITH CATEGORY EQ 1002 BUT CURRENCY EQ EUR
@ID................ CATEGORY CURRENCY CURRENCY
12 Records Listed
LIST FBNK.ACCOUNT CATEGORY CURRENCY WITH CATEGORY EQ 1002 OR WITH CURRENCY EQ EUR
@ID................ CATEGORY CURRENCY
>SAVE.LIST LIST1
SELECT VOC WITH F1 LIKE F... SAVING EVAL "'COPY FROM ':@ID:' TO &TEMP& ALL'"
>SAVE.LIST LIST2
001 "
002
003 "
004
005 (
006 "
007 !
008 )
009 )
...
CT &SAVEDLISTS& LIST2
$FORD.IN.OUT 1
0
0
CLEARSELECT 0
[526] List '0' is inactive.
SELECT FBNK.ACCOUNT TO 1
No Records selected
CLEARSELECT 1
[528] List '1' cleared.
note: After second SELECT list #1 still contained records but default one didn’t.
SAVE.LIST RESULTS
No default select list is active
LIST &TEMP&
No Records Listed
CT VOC TEST.LOGIN
'TEST.LOGIN' record not found
CT VOC TEST.LOGIN
TEST.LOGIN
001 PA
002 EBS.TERMINAL.SELECT
003 EX
004 EX.INTEGRITY
005 * LO
0001 PA
0002 CT C:\home\kzm\v-t24\r11\tafc <<C2,''>>
SYSF RELEASE
RELEASE
001 jBase Release : R11.0.0.0
002 Create date : Tue Apr 19 14:12:00 2011
003 Patch Level :
004 Change Level : 94295
Step 3. Start another copy of jsh and try to list OPTIONS file:
jsh
SYSF OPTIONS
RELEASE
001 jBase Release : R11.0.0.0
002 Create date : Tue Apr 19 14:12:00 2011
SYSF
RELEASE
001 jBase Release : R11.0.0.0
002 Create date : Tue Apr 19 14:12:00 2011
003 Patch Level :
004 Change Level : 94295
SYSF OPTIONS
OPTIONS
001 #
002 # This file was auto-created at Tue Apr 19 14:12:01 2011
003 # Created from E:\src\TAFC\R11\port\Template\Options.template
004 #
...etc.
17 T24 classic
17.1 What works there (as well as elsewhere)
• Non-tabbed VERSION’s.
• ENQUIRY’s
• OFS.
------------------------------------------------------------------------------
------------------------------------------------------------------------------
16 NOV 2011 19:06:18 USER (09 AUG) VLADIMIR.K [6567,IN]
ACTION
AWAITING APPLICATION
------------------------------------------------------------------------------
Go back ( F1 ):
------------------------------------------------------------------------------
------------------------------------------------------------------------------
16 NOV 2011 19:33:50 USER (09 AUG) VLADIMIR.K [6567,IN]
ACTION
AWAITING APPLICATION
------------------------------------------------------------------------------
List records ( L ←- ):
ID PRINT.ONLY FUNCT.
------------------------------------------------------------------------------
1 AA.ACCRUAL.FREQUENCY,
2 AA.ACCRUAL.FREQUENCY,AA
3 AA.ACCRUAL.FREQUENCY,AA.AUDIT
4 AA.ACCRUAL.FREQUENCY,MB.OFS.AUTH
5 AA.ACTIVITY,
6 AA.ACTIVITY,AA
7 AA.ACTIVITY,AA.AUDIT
8 AA.ACTIVITY,MB.OFS.AUTH
9 AA.ACTIVITY.CLASS,
10 AA.ACTIVITY.CLASS,AA
11 AA.ACTIVITY.CLASS,AA.ACTIONS
12 AA.ACTIVITY.CLASS,AA.AUDIT
13 AA.ACTIVITY.CLASS,AA.BATCH
14 AA.ACTIVITY.CLASS,AA.TYPE
15 AA.ACTIVITY.CLASS,MB.OFS.AUTH
16 AA.ARR.AC.ACCT.GROUP.CONDN,
------------------------------------------------------------------------------
16 NOV 2011 19:35:54 USER (09 AUG) VLADIMIR.K [6567,INPAGE 1 >>>3>>>
ACTION
AWAITING PAGE INSTRUCTIONS
Go forward ( F3 ):
Go to page #5 ( P5 ←- ):
ID PRINT.ONLY FUNCT.
------------------------------------------------------------------------------
1 AA.ARR.CHANGE.PRODUCT,
2 AA.ARR.CHANGE.PRODUCT,AA
3 AA.ARR.CHANGE.PRODUCT,AA.CONTROL
4 AA.ARR.CHANGE.PRODUCT,AA.MORTGAGE
5 AA.ARR.CHANGE.PRODUCT,AA.NOINPUT
6 AA.ARR.CHANGE.PRODUCT,AA.SIMPLE
7 AA.ARR.CHARGE,
8 AA.ARR.CHARGE,AA
9 AA.ARR.CHARGE,AA.CALCULATED
10 AA.ARR.CHARGE,AA.CALCULATED.PA
11 AA.ARR.CHARGE,AA.CONTROL
12 AA.ARR.CHARGE,AA.FIXED
13 AA.ARR.CHARGE,AA.FIXED.PA
14 AA.ARR.CHARGE,AA.NOINPUT
15 AA.ARR.CHARGE,MB.OFS.AUTH
16 AA.ARR.CHARGE.OVERRIDE,
------------------------------------------------------------------------------
16 NOV 2011 19:37:35 USER (09 AUG) VLADIMIR.K [6567,INPAGE 5 >>>7>>>
ID PRINT.ONLY FUNCT.
------------------------------------------------------------------------------
1 AA.ARR.ALERTS,AA.NR
2 AA.ARR.ALERTS,MB.OFS.AUTH
3 AA.ARR.AZ.ACCOUNTING,
4 AA.ARR.AZ.CR.CARD,
5 AA.ARR.AZ.DEPOSIT,
6 AA.ARR.AZ.LOAN,
7 AA.ARR.AZ.SAVINGS,
8 AA.ARR.BALANCE.AVAILABILITY,AA
9 AA.ARR.BALANCE.MAINTENANCE,
10 AA.ARR.BALANCE.MAINTENANCE,AA
11 AA.ARR.BALANCE.MAINTENANCE,AA.ADJ.BALS
12 AA.ARR.BALANCE.MAINTENANCE,AA.ADJ.BILLS
13 AA.ARR.BALANCE.MAINTENANCE,AA.BALS
14 AA.ARR.BALANCE.MAINTENANCE,AA.BILLS
15 AA.ARR.BALANCE.MAINTENANCE,AA.NOINPUT
16 AA.ARR.BALANCE.MAINTENANCE,MB.OFS.AUTH
------------------------------------------------------------------------------
16 NOV 2011 19:37:35 USER (09 AUG) VLADIMIR.K [6567,INPAGE 4 >>>7>>>
ACTION
AWAITING PAGE INSTRUCTIONS
Go one level up ( F1 ):
------------------------------------------------------------------------------
PGM.NAME.VERSION.. FUNDS.TRANSFER,AC
------------------------------------------------------------------------------
note: Several records can be marked at the same time; functions can be different:
PGM.NAME.VERSION.. FUNDS.TRANSFER,AC
------------------------------------------------------------------------------
99 RESERVED.3........
100 RESERVED.2........
101. 1 OVERRIDE.......
102 RECORD.STATUS.....
103 CURR.NO........... 2
104. 1 INPUTTER....... 1_DIM
105. 1 DATE.TIME...... 10 MAR 11 05:33
105. 2 DATE.TIME...... 10 MAR 11 05:32
106 AUTHORISER........ 495_INPUTTER_OFS_MB.OFS.AUTH
107 CO.CODE........... GB-001-0001 Model Bank
108 DEPT.CODE......... 1 Implementation
109 AUDITOR.CODE......
110 AUDIT.DATE.TIME...
------------------------------------------------------------------------------
16 NOV 2011 19:48:39 USER (09 AUG) VLADIMIR.K [6567,I PAGE 42
ACTION
AWAITING PAGE INSTRUCTIONS
PGM.NAME.VERSION.. FUNDS.TRANSFER,AC
------------------------------------------------------------------------------
83 COMPANY.ACCESS....
84 BUSINESS.DAY......
85 AUTO.COMP.CHANGE..
86 SYS.MSG.SUPPRESS..
87. 1 ATTRIBUTES..... NO.HEADER.TAB
88 D.SLIP.STYLE.SHEET
89 WEB.VAL.RTN.......
90 CONFIRM.VERSION...
91 PREVIEW.VERSION...
92 BROWSER.TOOLBAR...
93 EXPOSE............
94. 1 SERVICE........
PGM.NAME.VERSION.. FUNDS.TRANSFER,AC
------------------------------------------------------------------------------
83 COMPANY.ACCESS....
84 BUSINESS.DAY......
85 AUTO.COMP.CHANGE..
86 SYS.MSG.SUPPRESS..
87. 1 ATTRIBUTES..... N O.HEADER.TAB
88 D.SLIP.STYLE.SHEET
89 WEB.VAL.RTN.......
90 CONFIRM.VERSION...
91 PREVIEW.VERSION...
92 BROWSER.TOOLBAR...
93 EXPOSE............
94. 1 SERVICE........
95 ACTIVITY..........
96 FUNCT.............
97 EXPOSE.DESC.......
------------------------------------------------------------------------------
16 NOV 2011 19:50:31 USER (09 AUG) VLADIMIR.K [6567,I PAGE 41 >>42>>>
ACTION
Expand it ( < ←- ):
PGM.NAME.VERSION.. FUNDS.TRANSFER,AC
------------------------------------------------------------------------------
83 COMPANY.ACCESS....
84 BUSINESS.DAY......
85 AUTO.COMP.CHANGE..
86 SYS.MSG.SUPPRESS..
87. 1 ATTRIBUTES.....
87. 2 ATTRIBUTES..... NO.HEADER.TAB
PGM.NAME.VERSION.. FUNDS.TRANSFER,AC
------------------------------------------------------------------------------
83 COMPANY.ACCESS....
84 BUSINESS.DAY......
85 AUTO.COMP.CHANGE..
86 SYS.MSG.SUPPRESS..
87. 1 ATTRIBUTES.....
87. 2 ATTRIBUTES..... NO.HEADER.TAB
88 D.SLIP.STYLE.SHEET
89 WEB.VAL.RTN.......
90 CONFIRM.VERSION...
91 PREVIEW.VERSION...
92 BROWSER.TOOLBAR...
93 EXPOSE............
94. 1 SERVICE........
95 ACTIVITY..........
96 FUNCT.............
97 EXPOSE.DESC.......
------------------------------------------------------------------------------
16 NOV 2011 20:10:24 USER (09 AUG) VLADIMIR.K [6567,I PAGE 41 >>42>>>
ACTION
PROPOSAL 'NO.HEADER.TAB' OK. (Y, NO, _)
------------------------------------------------------------------------------
16 NOV 2011 20:10:24 USER (09 AUG) VLADIMIR.K [6567,I PAGE 41 >>42>>>
PGM.NAME.VERSION.. FUNDS.TRANSFER,AC
------------------------------------------------------------------------------
83 COMPANY.ACCESS....
84 BUSINESS.DAY......
85 AUTO.COMP.CHANGE..
86 SYS.MSG.SUPPRESS..
87. 1 ATTRIBUTES..... SHOW.NULL.FIELDS
87. 2 ATTRIBUTES..... N O.HEADER.TAB
88 D.SLIP.STYLE.SHEET
89 WEB.VAL.RTN.......
90 CONFIRM.VERSION...
91 PREVIEW.VERSION...
92 BROWSER.TOOLBAR...
93 EXPOSE............
94. 1 SERVICE........
95 ACTIVITY..........
96 FUNCT.............
97 EXPOSE.DESC.......
------------------------------------------------------------------------------
16 NOV 2011 20:10:24 USER (09 AUG) VLADIMIR.K [6567,I PAGE 41 >>42>>>
ACTION
PGM.NAME.VERSION.. FUNDS.TRANSFER,AC
------------------------------------------------------------------------------
83 COMPANY.ACCESS....
84 BUSINESS.DAY......
85 AUTO.COMP.CHANGE..
86 SYS.MSG.SUPPRESS..
87. 1 ATTRIBUTES..... SHOW.NULL.FIELDS
87. 2 ATTRIBUTES..... NO.HEADER.TAB
88 D.SLIP.STYLE.SHEET
89 WEB.VAL.RTN.......
ID = PGM.NAME.VERSION
------------------------------------------------------------------------------
Enables the specific Version of an application to be
uniquely identified.
Example:
. Customer,1
. Customer,99
. Customer,abc
------------------------------------------------------------------------------
16 NOV 2011 20:16:25 USER (09 AUG) VLADIMIR.K [6567,I PAGE 1 >>>3>>>
ACTION
AWAITING PAGE INSTRUCTIONS
Go to next page ( F3 ):
ID = PGM.NAME.VERSION
------------------------------------------------------------------------------
__________________________________________________
PGM.NAME.VERSION.. FUNDS.TRANSFER,AC
------------------------------------------------------------------------------
83 COMPANY.ACCESS....
84 BUSINESS.DAY......
85 AUTO.COMP.CHANGE..
86 SYS.MSG.SUPPRESS..
87. 1 ATTRIBUTES..... N O.HEADER.TAB
88 D.SLIP.STYLE.SHEET
89 WEB.VAL.RTN.......
90 CONFIRM.VERSION...
91 PREVIEW.VERSION...
92 BROWSER.TOOLBAR...
93 EXPOSE............
94. 1 SERVICE........
95 ACTIVITY..........
96 FUNCT.............
97 EXPOSE.DESC.......
98 CHALL.RESP........
------------------------------------------------------------------------------
16 NOV 2011 20:21:43 USER (09 AUG) VLADIMIR.K [6567,I PAGE 41 >>42>>>
ACTION
FIELD NO 17 = TEXT
------------------------------------------------------------------------------
Indicates the Text that User wants to define for the
field specified in FIELD NO (Field 13). This is a
sub-value field which can be expanded by itself to
allow the Text to be entered in the various languages
defined in Language code field.
Go back to command line ( F1 ) and then to the field #17 that’s not on the screen ( 17.1.1
←- ):
PGM.NAME.VERSION.. FUNDS.TRANSFER,AC
------------------------------------------------------------------------------
17. 1. 1 TEXT........ # Debit Account
18. 1. 1 TXT.040..078
19. 1. 1 TXT.079..117
20. 1. 1 TXT.118..132
21. 1 ENRICHM.CHAR... 25
22. 1 TABLE.COLUMN... 170
23. 1 TABLE.LINE..... 0
24. 1 ENRI.COL.......
25. 1 PROMPT.COL.....
26. 1 RESERVED05.....
27. 1 RESERVED04.....
28. 1 RESERVED03.....
29. 1 RESERVED02.....
note: Just 17 or 17.1 won’t work – field has values and subvalues.
Expand a sub-value ( ( ←- ):
PGM.NAME.VERSION.. FUNDS.TRANSFER,AC
------------------------------------------------------------------------------
17. 1. 1 TEXT........
18. 1. 1 TXT.040..078
19. 1. 1 TXT.079..117
20. 1. 1 TXT.118..132
17. 1. 2 TEXT........ # Debit Account
18. 1. 2 TXT.040..078
19. 1. 2 TXT.079..117
20. 1. 2 TXT.118..132
21. 1 ENRICHM.CHAR... 25
22. 1 TABLE.COLUMN... 170
23. 1 TABLE.LINE..... 0
24. 1 ENRI.COL.......
25. 1 PROMPT.COL.....
26. 1 RESERVED05.....
27. 1 RESERVED04.....
28. 1 RESERVED03.....
------------------------------------------------------------------------------
16 NOV 2011 21:50:47 USER (09 AUG) VLADIMIR.K [6567,I PAGE 2 >>43>>>
ACTION
note: See that group of fields was added – that’s what is called associated fields.
PGM.NAME.VERSION.. FUNDS.TRANSFER,AC
------------------------------------------------------------------------------
17. 1. 1 TEXT........ # Debit Account
PGM.NAME.VERSION.. FUNDS.TRANSFER,AC
------------------------------------------------------------------------------
17. 1. 1 TEXT........ # D e bit Account |
18. 1. 1 TXT.040..078
19. 1. 1 TXT.079..117
20. 1. 1 TXT.118..132
21. 1 ENRICHM.CHAR... 25
22. 1 TABLE.COLUMN... 170
23. 1 TABLE.LINE..... 0
24. 1 ENRI.COL.......
25. 1 PROMPT.COL.....
26. 1 RESERVED05.....
27. 1 RESERVED04.....
28. 1 RESERVED03.....
29. 1 RESERVED02.....
30. 1 RESERVED01.....
31. 1. 1 P
32. 1. 1 TOOL.TIP.... A/c being debited in respect of the transfer
------------------------------------------------------------------------------
16 NOV 2011 21:55:24 USER (09 AUG) VLADIMIR.K [6567,I PAGE 2 >>42>>>
ACTION
PGM.NAME.VERSION.. FUNDS.TRANSFER,AC
------------------------------------------------------------------------------
17. 1. 1 TEXT........ # DEBIIT A ccount |
18. 1. 1 TXT.040..078
19. 1. 1 TXT.079..117
20. 1. 1 TXT.118..132
21. 1 ENRICHM.CHAR... 25
22. 1 TABLE.COLUMN... 170
23. 1 TABLE.LINE..... 0
24. 1 ENRI.COL.......
25. 1 PROMPT.COL.....
26. 1 RESERVED05.....
27. 1 RESERVED04.....
28. 1 RESERVED03.....
29. 1 RESERVED02.....
30. 1 RESERVED01.....
31. 1. 1 P
32. 1. 1 TOOL.TIP.... A/c being debited in respect of the transfer
------------------------------------------------------------------------------
16 NOV 2011 21:55:24 USER (09 AUG) VLADIMIR.K [6567,I PAGE 2 >>42>>>
ACTION
note: If you type a symbol not appropriate for field type – e.g.“{” – it won’t show up.
PGM.NAME.VERSION.. FUNDS.TRANSFER,AC
------------------------------------------------------------------------------
17. 1. 1 TEXT........ # DEBI I TAccount |
18. 1. 1 TXT.040..078
19. 1. 1 TXT.079..117
20. 1. 1 TXT.118..132
21. 1 ENRICHM.CHAR... 25
22. 1 TABLE.COLUMN... 170
23. 1 TABLE.LINE..... 0
24. 1 ENRI.COL.......
25. 1 PROMPT.COL.....
26. 1 RESERVED05.....
27. 1 RESERVED04.....
PGM.NAME.VERSION.. FUNDS.TRANSFER,AC
------------------------------------------------------------------------------
17. 1. 1 TEXT........ # DEBI T Account |
18. 1. 1 TXT.040..078
19. 1. 1 TXT.079..117
20. 1. 1 TXT.118..132
21. 1 ENRICHM.CHAR... 25
22. 1 TABLE.COLUMN... 170
23. 1 TABLE.LINE..... 0
24. 1 ENRI.COL.......
25. 1 PROMPT.COL.....
26. 1 RESERVED05.....
27. 1 RESERVED04.....
28. 1 RESERVED03.....
29. 1 RESERVED02.....
30. 1 RESERVED01.....
31. 1. 1 P
32. 1. 1 TOOL.TIP.... A/c being debited in respect of the transfer
------------------------------------------------------------------------------
16 NOV 2011 22:09:18 USER (09 AUG) VLADIMIR.K [6567,I PAGE 2 >>42>>>
ACTION
Get the space back – move forward ( F3 ), toggle insert/overwrite ( F6 ), type space:
PGM.NAME.VERSION.. FUNDS.TRANSFER,AC
------------------------------------------------------------------------------
17. 1. 1 TEXT........ # DEBIT A ccount |
18. 1. 1 TXT.040..078
19. 1. 1 TXT.079..117
20. 1. 1 TXT.118..132
21. 1 ENRICHM.CHAR... 25
PGM.NAME.VERSION.. FUNDS.TRANSFER,AC
------------------------------------------------------------------------------
17. 1. 1 TEXT........ # DEBIT Account
18. 1. 1 TXT.040..078
19. 1. 1 TXT.079..117
20. 1. 1 TXT.118..132
21. 1 ENRICHM.CHAR... 25
22. 1 TABLE.COLUMN... 170
23. 1 TABLE.LINE..... 0
24. 1 ENRI.COL.......
25. 1 PROMPT.COL.....
26. 1 RESERVED05.....
27. 1 RESERVED04.....
28. 1 RESERVED03.....
29. 1 RESERVED02.....
30. 1 RESERVED01.....
31. 1. 1 P
32. 1. 1 TOOL.TIP.... A/c being debited in respect of the transfer
------------------------------------------------------------------------------
16 NOV 2011 22:09:18 USER (09 AUG) VLADIMIR.K [6567,I PAGE 2 >>42>>>
ACTION
Copy contents of one field to another – type source field number ( 32.1.1 )...
PGM.NAME.VERSION.. FUNDS.TRANSFER,AC
------------------------------------------------------------------------------
...and press F7 :
PGM.NAME.VERSION.. FUNDS.TRANSFER,AC
------------------------------------------------------------------------------
17. 1. 1 TEXT........ # DEBIT Account
18. 1. 1 TXT.040..078 A /c being debited in respect of the tra|
19. 1. 1 TXT.079..117
20. 1. 1 TXT.118..132
21. 1 ENRICHM.CHAR... 25
22. 1 TABLE.COLUMN... 170
23. 1 TABLE.LINE..... 0
24. 1 ENRI.COL.......
25. 1 PROMPT.COL.....
26. 1 RESERVED05.....
27. 1 RESERVED04.....
28. 1 RESERVED03.....
29. 1 RESERVED02.....
30. 1 RESERVED01.....
31. 1. 1 P
32. 1. 1 TOOL.TIP.... A/c being debited in respect of the transfer
------------------------------------------------------------------------------
16 NOV 2011 22:31:43 USER (09 AUG) VLADIMIR.K [6567,I PAGE 2 >>42>>>
ACTION
note: Field is too short to hold the new content; pipe indicates truncation point.
PGM.NAME.VERSION.. FUNDS.TRANSFER,AC
------------------------------------------------------------------------------
17. 1. 1 TEXT........ # DEBIT Account
18. 1. 1 TXT.040..078
19. 1. 1 TXT.079..117
20. 1. 1 TXT.118..132
21. 1 ENRICHM.CHAR... 25
22. 1 TABLE.COLUMN... 170
23. 1 TABLE.LINE..... 0
24. 1 ENRI.COL.......
25. 1 PROMPT.COL.....
26. 1 RESERVED05.....
27. 1 RESERVED04.....
28. 1 RESERVED03.....
29. 1 RESERVED02.....
30. 1 RESERVED01.....
31. 1. 1 P
32. 1. 1 TOOL.TIP.... A/c being debited in respect of the transfer
------------------------------------------------------------------------------
16 NOV 2011 22:31:43 USER (09 AUG) VLADIMIR.K [6567,I PAGE 2 >>42>>>
ACTION
Commit changes ( F5 ):
PGM.NAME.VERSION.. FUNDS.TRANSFER,AC
------------------------------------------------------------------------------
------------------------------------------------------------------------------
------------------------------------------------------------------------------
16 NOV 2011 23:11:24 USER (09 AUG) VLADIMIR.K [6567,IN]
ACTION
AWAITING APPLICATION
PGM.NAME.VERSION.. FUNDS.TRANSFER,AC
------------------------------------------------------------------------------
2 RECORDS.PER.PAGE.. 1
3 FIELDS.PER.LINE... MULTI
4. 1 LANGUAGE.CODE.. 1 English
5. 1 HDR.1.001..039. Transfer Between Accounts
13. 1 FIELD.NO....... DEBIT.ACCT.NO DEBIT.ACCT.NO
14. 1 COLUMN......... 1
16. 1 TEXT.CHAR.MAX.. 25
note: Record isn’t authorised so changes are shown in the field 17.1.1.
PGM.NAME.VERSION.. FUNDS.TRANSFER,AC
------------------------------------------------------------------------------
65 REPORT.LOCKS...... YES
67. 1 GB D Transfer Between Accounts
68. 1 ASSOC.VERSION.. FUNDS.TRANSFER,AUDIT Audit
73 EXC.INC.RTN....... YES
87. 1 ATTRIBUTES..... NO.HEADER.TAB
102 RECORD.STATUS..... INAU INPUT Unauthorised
103 CURR.NO........... 3
104. 1 INPUTTER....... 6567_VLADIMIR.K_I_INAU
105. 1 DATE.TIME...... 16 NOV 11 22:32
107 CO.CODE........... GB-001-0001
108 DEPT.CODE......... 1
------------------------------------------------------------------------------
16 NOV 2011 23:31:36 USER (09 AUG) VLADIMIR.K [6567,I PAGE 12
ACTION
AWAITING PAGE INSTRUCTIONS
Go two levels up ( F1 F1 ):
------------------------------------------------------------------------------
16 NOV 2011 23:35:15 USER (09 AUG) VLADIMIR.K [6567,IN]
ACTION
AWAITING APPLICATION
------------------------------------------------------------------------------
------------------------------------------------------------------------------
16 NOV 2011 23:35:15 USER (09 AUG) VLADIMIR.K [6567,IN]
------------------------------------------------------------------------------
------------------------------------------------------------------------------
16 NOV 2011 23:35:15 USER (09 AUG) VLADIMIR.K [6567,IN]
ACTION VERSION D FT,AC |
AWAITING APPLICATION
PGM.NAME.VERSION.. FUNDS.TRANSFER,AC
------------------------------------------------------------------------------
2 RECORDS.PER.PAGE.. 1
3 FIELDS.PER.LINE... MULTI
4. 1 LANGUAGE.CODE.. 1 English
5. 1 HDR.1.001..039. Transfer Between Accounts
13. 1 FIELD.NO....... DEBIT.ACCT.NO DEBIT.ACCT.NO
14. 1 COLUMN......... 1
16. 1 TEXT.CHAR.MAX.. 25
17. 1. 1 TEXT........ # DEBIT Account
# Debit Account
21. 1 ENRICHM.CHAR... 25
------------------------------------------------------------------------------
16 NOV 2011 23:44:17 USER (09 AUG) VLADIMIR.K [6567,IN]
ACTION
note: “@” is used to navigate to the upmost level before issuing the command.
Model Bank
Go to page #200 – that’s the limit set in SPF ( P200 ←- ; might also need F3 to draw
the screen):
Model Bank
Press F3 :
------------------------------------------------------------------------------
17 NOV 2011 18:33:49 USER (09 AUG) VLADIMIR.K [8141,INPAGE 200 >200>>>
ACTION THIS IS THE LAST PAGE
AWAITING PAGE INSTRUCTIONS
------------------------------------------------------------------------------
17 NOV 2011 18:40:55 USER (09 AUG) VLADIMIR.K [8141,INPAGE 49
ACTION
AWAITING PAGE INSTRUCTIONS
------------------------------------------------------------------------------
SELECTION FIELDS - LIVE FILE [EQ NE LT GT LE GE RG NR LK UL]
-------------------------------------------------------------------------------
0.. @ID 0A. ENQUIRY 1.. PAGE.SIZE
2.. FILE.NAME 3.. FIXED.SELECTION 4.. FIXED.SORT
5.. OPEN.BRACKET 6.. SELECTION.FLDS 7.. SEL.LABEL
8.. SEL.FLD.OPER 9.. REQUIRED.SEL 10. CLOSE.BRACKET
11. REL.NEXT.FIELD 12. BUILD.ROUTINE 13. K.HEADER
13A HEADER 14. FIELD.NAME 15. OPERATION
16. K.COLUMN 16A COLUMN 17. LENGTH.MASK
18. K.CONVERSION 18A CONVERSION 19. COMMENTS
20. K.TYPE 20A TYPE 21. DISPLAY.BREAK
22. FIELD.LBL 23. FIELD.DISP.TYPE 24. SECTION
Press F5 to proceed:
Model Bank
------------------------------------------------------------------------------
17 NOV 2011 18:51:53 USER (09 AUG) VLADIMIR.K [8141,INPAGE 1 >>>1>>>
ACTION
AWAITING PAGE INSTRUCTIONS
ENQUIRY........... USER
------------------------------------------------------------------------------
1 PAGE.SIZE ........ 4,19
2 FILE.NAME......... USER
6. 1 SELECTION.FLDS. APPLICATION
7. 1. 1 GB SEL.LABEL User Group
ENQUIRY........... USER
------------------------------------------------------------------------------
------------------------------------------------------------------------------
17 NOV 2011 18:55:35 USER (09 AUG) VLADIMIR.K [8141,I
ACTION
AWAITING ID
ENQUIRY........... USER2
------------------------------------------------------------------------------
------------------------------------------------------------------------------
17 NOV 2011 18:57:12 USER (09 AUG) VLADIMIR.K [8141,I TXN COMPLETE
See unauthorised records ( E ←- ); also you can use search of unauthorised records (E E –
just like L L example several pages above):
ID STATUS FUNCT.
------------------------------------------------------------------------------
1 USER2 CHLD
------------------------------------------------------------------------------
17 NOV 2011 18:59:21 USER (09 AUG) VLADIMIR.K [8141,INPAGE 1 >>>1>>>
ACTION
AWAITING PAGE INSTRUCTIONS
note: STATUS is CHLD rather than IHLD; avoid using ’IHLD’ to check record status!
------------------------------------------------------------------------------
ENQUIRY........... USER2
------------------------------------------------------------------------------
1 PAGE.SIZE ........ 4,19
2 FILE.NAME......... USER
3. 1 FIXED.SELECTION
4. 1 FIXED.SORT.....
5. 1 OPEN.BRACKET...
6. 1 SELECTION.FLDS. APPLICATION
7. 1. 1 GB SEL.LABEL User Group
8. 1 SEL.FLD.OPER...
9. 1 REQUIRED.SEL...
10. 1 CLOSE.BRACKET..
11. 1 REL.NEXT.FIELD.
5. 2 OPEN.BRACKET...
6. 2 SELECTION.FLDS. USER.NAME
7. 2. 1 GB SEL.LABEL User Name
8. 2 SEL.FLD.OPER...
9. 2 REQUIRED.SEL...
------------------------------------------------------------------------------
17 NOV 2011 19:04:27 USER (09 AUG) VLADIMIR.K [8141,INPAGE 1 >>20>>>
ACTION
AWAITING PAGE INSTRUCTIONS
Go to field #57 ( 57 ←- ):
ENQUIRY........... USER2
ENQUIRY........... USER2
------------------------------------------------------------------------------
Model Bank PRODUCT CONTROL FILE
------------------------------------------------------------------------------
------------------------------------------------------------------------------
17 NOV 2011 19:11:40 USER (09 AUG) VLADIMIR.K [8141,I
ACTION
ENQUIRY........... USER2
------------------------------------------------------------------------------
Model Bank EB.PRODUCT - Default List
------------------------------------------------------------------------------
43 BREAK.FIELDS...... 0
44 PROCESS.BREAKS.... 0
45 TOTAL.FIELDS...... 0
46 NEXT.LVL.FLDS..... 1 2
47 LINES.OSIDE.PAGE..
48 SMS.APPLICATION...
49 SMS.ID............
50 SMS.ABORT.........
51 USE.FIELD.NUMBERS.
52 CUSTOMER.NO.FLD...
53 ACCOUNT.NO.FLD....
Commit changes ( F5 ), then edit the record again – change field #57 back to “EB”,
commit changes, then edit again – change field #57 to “ST”, commit it, go to “AWAITING
APPLICATION” level, then search the history ( ENQUIRY L ; L ←- ):
------------------------------------------------------------------------------
SELECTION FIELDS - HISTORY FILE [EQ NE LT GT LE GE RG NR LK UL]
-------------------------------------------------------------------------------
0.. @ID 0A. ENQUIRY 1.. PAGE.SIZE
2.. FILE.NAME 3.. FIXED.SELECTION 4.. FIXED.SORT
5.. OPEN.BRACKET 6.. SELECTION.FLDS 7.. SEL.LABEL
8.. SEL.FLD.OPER 9.. REQUIRED.SEL 10. CLOSE.BRACKET
11. REL.NEXT.FIELD 12. BUILD.ROUTINE 13. K.HEADER
13A HEADER 14. FIELD.NAME 15. OPERATION
16. K.COLUMN 16A COLUMN 17. LENGTH.MASK
18. K.CONVERSION 18A CONVERSION 19. COMMENTS
20. K.TYPE 20A TYPE 21. DISPLAY.BREAK
22. FIELD.LBL 23. FIELD.DISP.TYPE 24. SECTION
25. ATTRIBS 26. TARGET.FIELD 27. COL.WIDTH
28. RESERVED7 29. RESERVED6 30. RESERVED5
31. RESERVED4 32. RESERVED3 33. RESERVED2
34. RESERVED1 35. SINGLE.MULTI 36. ENQUIRY.NAME
------------------------------------------------------------------------------
17 NOV 2011 19:22:12 USER (09 AUG) VLADIMIR.K [8141,IN]PAGE 1 >>3>>>
ACTION EB.RTN.INVALID.SELECTION.FLD.1
ENTER SELECTION (eg CUST EQ 123456) , <F5> TO EXECUTE LIST
------------------------------------------------------------------------------
SELECTION FIELDS - HISTORY FILE [EQ NE LT GT LE GE RG NR LK UL]
-------------------------------------------------------------------------------
And then F5 :
Model Bank
------------------------------------------------------------------------------
17 NOV 2011 19:35:42 USER (09 AUG) VLADIMIR.K [8141,INPAGE 1 >>>1>>>
ACTION
AWAITING PAGE INSTRUCTIONS
ENQUIRY........... USER2
------------------------------------------------------------------------------
45 TOTAL.FIELDS...... 0
46 NEXT.LVL.FLDS..... 1 2
56. 1 ATTRIBUTES..... NO.SELECTION
57 PRODUCT........... ST System Tables
58. 1 GB SHORT.DESC.. List of System Users
77 CURR.NO........... 3
78. 1 INPUTTER....... 8141_VLADIMIR.K_I_INAU
79. 1 DATE.TIME...... 17 NOV 11 19:33
79. 2 DATE.TIME...... 17 NOV 11 19:33
80 AUTHORISER........ 8141_VLADIMIR.K
81 CO.CODE........... GB-001-0001
82 DEPT.CODE......... 1
------------------------------------------------------------------------------
17 NOV 2011 19:44:33 USER (09 AUG) VLADIMIR.K [8141,INPAGE 6
ACTION
AWAITING PAGE INSTRUCTIONS
ENQUIRY........... USER2 ;
------------------------------------------------------------------------------
45 TOTAL.FIELDS...... 0
46 NEXT.LVL.FLDS..... 1 2
56. 1 ATTRIBUTES..... NO.SELECTION
57 PRODUCT........... ST System Tables
EB System Core
58. 1 GB SHORT.DESC.. List of System Users
77 CURR.NO........... 3
78. 1 INPUTTER....... 8141_VLADIMIR.K_I_INAU
79. 1 DATE.TIME...... 17 NOV 11 19:33
79. 2 DATE.TIME...... 17 NOV 11 19:33
------------------------------------------------------------------------------
17 NOV 2011 19:47:13 USER (09 AUG) VLADIMIR.K [8141,INPAGE 6
ACTION
AWAITING PAGE INSTRUCTIONS
ENQUIRY........... USER2 ; 2
------------------------------------------------------------------------------
45 TOTAL.FIELDS...... 0
46 NEXT.LVL.FLDS..... 1 2
56. 1 ATTRIBUTES..... NO.SELECTION
57 PRODUCT........... EB System Core
AC Accounts
58. 1 GB SHORT.DESC.. List of System Users
77 CURR.NO........... 2
78. 1 INPUTTER....... 8141_VLADIMIR.K_I_INAU
79. 1 DATE.TIME...... 17 NOV 11 19:22
79. 2 DATE.TIME...... 17 NOV 11 19:22
80 AUTHORISER........ 8141_VLADIMIR.K
81 CO.CODE........... GB-001-0001
82 DEPT.CODE......... 1
------------------------------------------------------------------------------
17 NOV 2011 19:51:04 USER (09 AUG) VLADIMIR.K [8141,INPAGE 6
ACTION
AWAITING PAGE INSTRUCTIONS
ENQUIRY........... USER2
------------------------------------------------------------------------------
See “exceptions” ( E ←- ):
ID STATUS FUNCT.
------------------------------------------------------------------------------
1 USER2 RNAU
------------------------------------------------------------------------------
17 NOV 2011 19:58:50 USER (09 AUG) VLADIMIR.K [8141,INPAGE 1 >>>1>>>
ACTION
AWAITING PAGE INSTRUCTIONS
ENQUIRY........... USER2
------------------------------------------------------------------------------
------------------------------------------------------------------------------
17 NOV 2011 20:02:45 USER (09 AUG) VLADIMIR.K1 [3625,INTXN COMPLETE
ACTION
AWAITING ID
ENQUIRY........... USER2 ; 4
------------------------------------------------------------------------------
1 PAGE.SIZE ........ 4,19
2 FILE.NAME......... USER
6. 1 SELECTION.FLDS. APPLICATION
7. 1. 1 GB SEL.LABEL User Group
6. 2 SELECTION.FLDS. USER.NAME
7. 2. 1 GB SEL.LABEL User Name
6. 3 SELECTION.FLDS. START.DATE.PROFILE
7. 3. 1 GB SEL.LABEL Start Date
6. 4 SELECTION.FLDS. END.DATE.PROFILE
7. 4. 1 GB SEL.LABEL End Date
6. 5 SELECTION.FLDS. DEPARTMENT.CODE
7. 5. 1 GB SEL.LABEL Department Code
Go to the end:
ENQUIRY........... USER2 ; 4
------------------------------------------------------------------------------
45 TOTAL.FIELDS...... 0
46 NEXT.LVL.FLDS..... 1 2
56. 1 ATTRIBUTES..... NO.SELECTION
57 PRODUCT........... ST System Tables
58. 1 GB SHORT.DESC.. List of System Users
76 RECORD.STATUS..... REVE REVERSE Reversed
77 CURR.NO........... 4
78. 1 INPUTTER....... 8141_VLADIMIR.K_R_RNAU
79. 1 DATE.TIME...... 17 NOV 11 20:02
79. 2 DATE.TIME...... 17 NOV 11 19:56
80 AUTHORISER........ 3625_VLADIMIR.K1
81 CO.CODE........... GB-001-0001 Model Bank
82 DEPT.CODE......... 1 Implementation
------------------------------------------------------------------------------
17 NOV 2011 20:06:05 USER (09 AUG) VLADIMIR.K1 [3625,I PAGE 6
ACTION
AWAITING PAGE INSTRUCTIONS
Try to input the record again – go to “AWAITING APPLICATION” level, then (ENQUIRY I
USER2):
------------------------------------------------------------------------------
Here “history restore” comes along ( H USER2 ←- ), then F5 ; status will become HNAU.
After authorisation we have our record back and – finally – we can run the enquiry from
“AWAITING APPLICATION” level ( ENQ USER2 ←- ):
F5 :
Model Bank
List of T24 Users
------------------------------------------------------------------------------
1 ACCTEXEC Account Executive ACCTEXEC1 Eng
2 ARCUSER GENERIC USER FOR ARC IB ARCUSER01 Eng
3 AUTHORISER AUTHORISER AUTHOR Eng
4 BALA BALA PANDIAN Eng
5 BASEAUTH BAUTH BUSER2 Eng
6 BASEUSER BUSER BUSER1 Eng
7 BRANCHMANAGER1 Branch Manager BRANCHMANAGER Eng
8 BTOOLSUSER BUSINESS TOOLS USER BTOOLS Eng
9 BU007 BU007 ARUSER2 Eng
10 BU008 BU008 ARUSER1 Eng
11 BUILDUSER00 BUILDUSER00 KAILASH3 Eng
12 BUILDUSER0001 BUILDUSER0001 INMAIT Eng
13 BUILDUSER0002 BUILDUSER0002 TGMAIT Eng
14 BUILDUSER0003 BUILDUSER0003 MAITIN Eng
15 BUILDUSER001 BUILDUSER001 SHAR123 Eng
16 BUILDUSER002 BUILDUSER002 SHAR456 Eng
------------------------------------------------------------------------------
17 NOV 2011 20:14:35 USER (09 AUG) VLADIMIR.K [7480,INPAGE 1 >>>3>>>
ACTION
AWAITING PAGE INSTRUCTIONS
Current page can be printed (type PRINT ←- for that; we’ll see the printout in the next
lesson).
------------------------------------------------------------------------------
KEY............... JOURNAL.SUMMARY
------------------------------------------------------------------------------
1. 1 GB DESCRIPTION. JOURNAL SUMMARY
2. 1 ENQUIRY........ JOURNAL.CHECK EB.JOURNAL.SUMMARY
3. 1. 1 SELECTION... COMP.CODE
4. 1. 1 OPERAND..... EQ
5. 1. 1 LIST........ !COMPANY
3. 1. 2 SELECTION... SYS.DATE
4. 1. 2 OPERAND..... EQ
5. 1. 2 LIST........ !TODAY-1W
6. 1. 1 SORT........
7 REPORT.CONTROL.... JOURNAL.SUMMARY SUMMARY JNL
8 STANDARD.HEADING.. 80
9. 1 ADDI
10. 1 GB REPORT.HDR..
11 OUTPUT.FORMAT.....
12 RESERVED.13.......
13 RESERVED.12.......
------------------------------------------------------------------------------
24 NOV 2011 19:22:57 USER (09 AUG) VLADIMIR.K [8445,INPAGE 1 >>>3>>>
ACTION
AWAITING PAGE INSTRUCTIONS
------------------------------------------------------------------------------
24 NOV 2011 19:22:57 USER (09 AUG) VLADIMIR.K [8445,IN
ACTION 1 file(s) copied.
AWAITING ID
------------------------------------------------------------------------------
1 BNK JOURNAL.SUMMARY 24 NOV 2011 19:23 No 16034084453382100
2 BNK ENQUIRY.PRINT 17 NOV 2011 20:14 No 15780013442341701
3 BNK TT.DEAL.SLIP 12 MAR 2011 09:11 No 15777047623306300
4 BNK P.FUNCTION 21 JUL 2011 12:48 No 15908082054613400
5 BNK NEW.FILES.CREA| 15 MAR 2011 07:06 No 15780032782560100
6 BNK NEW.FILES.CREA| 15 MAR 2011 07:06 No 15780032782560200
7 BNK NEW.FILES.CREA| 15 MAR 2011 07:06 No 15780032782560300
8 BNK NEW.FILES.CREA| 15 MAR 2011 07:06 No 15780032782560301
9 BNK NEW.FILES.CREA| 15 MAR 2011 07:06 No 15780032782560400
10 BNK NEW.FILES.CREA| 15 MAR 2011 07:06 No 15780032782560401
11 BNK NEW.FILES.CREA| 15 MAR 2011 06:57 No 15780077082506400
12 BNK NEW.FILES.CREA| 15 MAR 2011 06:56 No 15780079962499700
13 BNK NEW.FILES.CREA| 15 MAR 2011 06:30 No 15780013442341100
14 BNK NEW.FILES.CREA| 15 MAR 2011 06:30 No 15780013442341500
15 BNK NEW.FILES.CREA| 15 MAR 2011 06:30 No 15780013442341600
16 BNK NEW.FILES.CREA| 15 MAR 2011 06:30 No 15780013442341601
------------------------------------------------------------------------------
24 NOV 2011 19:25:17 USER (09 AUG) VLADIMIR.K [8445,INPAGE 1 >>>3>>>
ACTION
AWAITING PAGE INSTRUCTIONS
If you’re curious how records are selected and sorted – type SELECTION ←- :
------------------------------------------------------------------------------
note: SSELECT doesn’t make any sense here since custom sort is applied.
Then go back – type REFRESH ←- or use any navigation command (like F3). Now see the
report ( 1 ←- , then S F5 ):
------------------------------------------------------------------------------
------------------------------------------------------------------------------
24 NOV 2011 19:25:17 USER (09 AUG) VLADIMIR.K [8445,INPAGE 1 >>>5>>>
ACTION LINE 16 >>>1>>>
AWAITING PAGE INSTRUCTIONS + Pnnn, Lnnn, Reprint, Screen width
------------------------------------------------------------------------------
JOURNAL.CHECK Model Bank 09 AUG 10 Page 1
Area Implementation No 1 Printed at 24 NOV 2011 19:23:41
To Implementation Implementation
Non ContingentJournal
Currency : USD Company : GB0010
Date : 06 AUG 2010
Back to list of reports. Entry #2 appeared after printing a page from enquiry USER2 during
the previous lesson:
------------------------------------------------------------------------------
ENQUIRY Model Bank 14 APR 11 PRINT USER2 Page 1
Area Implementation No 1 Printed at 17 NOV 2011 20:14:55
To Implementation Implementation
REQUESTED SCREEN PRINT FROM PAGE 1 TO 1
--------------------------------------------------------------------------------
------------------------------------------------------------------------------
24 NOV 2011 19:33:02 USER (09 AUG) VLADIMIR.K [8445,INPAGE 1
ACTION
AWAITING PAGE INSTRUCTIONS
------------------------------------------------------------------------------
24 NOV 2011 19:33:47 USER (09 AUG) VLADIMIR.K [8445,INPAGE 1
ACTION
AWAITING PAGE INSTRUCTIONS
Select “Customer” ( 1 ←- ):
NO. DESCRIPTION
------------------------------------------------------------------------------
1 Individual Customer
2 Corporate Customer
3 Create Prospect
4 Activate Customer
5 Amend Customer
6 Unauthorised Customer
7 Authorise/Delete Customer
8 Create/Amend Routing Instructions
9 Authorise/Delete Routing Instructions
10 Additional Address of Customer
11 Amend Customer Charge
12 Authorise/Delete Customer Charge
13 Set/Remove Posting Restrict
14 Authorise/Delete Posting Restrict
15 Capture External Arrangement
16 Authorise/Delete External Arrangement
------------------------------------------------------------------------------
24 NOV 2011 19:35:51 USER (09 AUG) VLADIMIR.K [8445,INPAGE 1 >>>2>>>
------------------------------------------------------------------------------
------------------------------------------------------------------------------
24 NOV 2011 19:38:17 USER (09 AUG) VLADIMIR.K [8445,IN]
ACTION F 3 TOO FEW MNEMONIC CHAR.
AWAITING ID
Full Name...............
Full Name-2..............
Short Name............... Mnemonic.................
Gender................... Marital Status...........
Account Officer..........
Go back to “AWAITING APPLICATION” level; see our path along menus ( HELPTEXT.MAINMENU
S 1 ←- ):
ACTION.CODE....... 1
------------------------------------------------------------------------------
1. 1 GB TITLE....... Universal Model Bank
2. 1 ID.OF.HELP.MENU USER.MENU
3. 1. 1 GB DESCRIPT. User Menu
2. 2 ID.OF.HELP.MENU ADMIN.MENU
3. 2. 1 GB DESCRIPT. Admin Menu
2. 3 ID.OF.HELP.MENU HOME.PAGE
3. 3. 1 GB DESCRIPT. Role Based Home Pages
6 CURR.NO........... 19
7. 1 INPUTTER....... 224_BUILDUSER85__OFS_BROWSERTC
8. 1 DATE.TIME...... 27 AUG 10 05:50
9 AUTHORISER........ 224_BUILDUSER85_OFS_BROWSERTC
10 CO.CODE........... GB-001-0001 Model Bank
11 DEPT.CODE......... 74 PWM Relationship Manager
------------------------------------------------------------------------------
24 NOV 2011 19:42:56 USER (09 AUG) VLADIMIR.K [8445,INPAGE 1
ACTION
AWAITING PAGE INSTRUCTIONS
Following this chain finally we can see the command that gave us an error before:
MENU.NAME......... CUST.MENU
------------------------------------------------------------------------------
1. 1 APPL CUSTOMER,INPUT I F3
2. 1. 1 GB DESCRIPT. Individual Customer
1. 2 APPL CUSTOMER,CORP I F3
2. 2. 1 GB DESCRIPT. Corporate Customer
1. 3 APPL CUSTOMER,PROSPECT I F3
2. 3. 1 GB DESCRIPT. Create Prospect
1. 4 APPL COS ACTIVATE.CUSTOMER
2. 4. 1 GB DESCRIPT. Activate Customer
1. 5 APPL COS CUST.AMEND
2. 5. 1 GB DESCRIPT. Amend Customer
1. 6 APPL COS CUSTOMER.NAU.AMEND
2. 6. 1 GB DESCRIPT. Unauthorised Customer
1. 7 APPL COS CUSTOMER.NAU
2. 7. 1 GB DESCRIPT. Authorise/Delete Customer
1. 8 APPL COS CUST.AGENCY
2. 8. 1 GB DESCRIPT. Create/Amend Routing Instructions
------------------------------------------------------------------------------
24 NOV 2011 19:49:57 USER (09 AUG) VLADIMIR.K [8445,INPAGE 1 >>>3>>>
------------------------------------------------------------------------------
1 TRANSACTION.TYPE..
2 DEBIT.ACCT.NO.....
3 IN.DEBIT.ACCT.NO..
4 CURRENCY.MKT.DR... 1 Currency Market
5 DEBIT.CURRENCY....
6 DEBIT.AMOUNT......
7 DEBIT.VALUE.DATE..
8 IN.DEBIT.VDATE....
9 DEBIT.THEIR.REF...
10 CREDIT.THEIR.REF..
11 CREDIT.ACCT.NO....
12 CURRENCY.MKT.CR... 1 Currency Market
13 CREDIT.CURRENCY...
14 CREDIT.AMOUNT.....
15 CREDIT.VALUE.DATE.
16 TREASURY.RATE.....
------------------------------------------------------------------------------
24 NOV 2011 20:00:05 USER (09 AUG) VLADIMIR.K [8445,INPAGE 1 >>15>>>
ACTION
We can input function at “AWAITING ID” level as well. What if @id looks like a function?
Example of such application - INTEREST.BASIS:
1 ←- S F5 takes us to authorisation:
------------------------------------------------------------------------------
INTEREST.BASIS.... A
------------------------------------------------------------------------------
1. 1 GB DESCRIPTION. 360/360
2 INT.BASIS......... 360/360
9 CURR.NO........... 1
10. 1 INPUTTER....... 1_G6.0.05
11. 1 DATE.TIME...... 24 OCT 95 11:44
12 AUTHORISER........ 54_INPUTTER
13 CO.CODE........... GB-001-0001 Model Bank
14 DEPT.CODE......... 1 Implementation
------------------------------------------------------------------------------
24 NOV 2011 20:10:10 USER (09 AUG) VLADIMIR.K [8445,INPAGE 1
ACTION
AWAITING PAGE INSTRUCTIONS
INTEREST.BASIS.... A1
------------------------------------------------------------------------------
1. 1 GB DESCRIPTION. 360/360
2 INT.BASIS......... 360/360
9 CURR.NO........... 1
10. 1 INPUTTER....... 1_G7.2.01
11. 1 DATE.TIME...... 01 MAY 97 13:43
12 AUTHORISER........ 46_INPUTTER
13 CO.CODE........... GB-001-0001 Model Bank
14 DEPT.CODE......... 1 Implementation
------------------------------------------------------------------------------
24 NOV 2011 20:12:08 USER (09 AUG) VLADIMIR.K [8445,INPAGE 1
ACTION
AWAITING PAGE INSTRUCTIONS
INTEREST.BASIS.... A2
------------------------------------------------------------------------------
1. 1 GB DESCRIPTION. 30/360
2 INT.BASIS......... 30/360
9 CURR.NO........... 1
10. 1 INPUTTER....... 1_G6.0.05
11. 1 DATE.TIME...... 24 OCT 95 11:44
12 AUTHORISER........ 54_INPUTTER
13 CO.CODE........... GB-001-0001 Model Bank
14 DEPT.CODE......... 1 Implementation
INTEREST.BASIS.... A3
------------------------------------------------------------------------------
1. 1 GB DESCRIPTION. 30/360
2 INT.BASIS......... 30/360
9 CURR.NO........... 1
10. 1 INPUTTER....... 35_AUTHORISER
11. 1 DATE.TIME...... 03 AUG 07 12:39
12 AUTHORISER........ 35_INPUTTER
13 CO.CODE........... GB-001-0001 Model Bank
14 DEPT.CODE......... 1 Implementation
------------------------------------------------------------------------------
24 NOV 2011 20:12:52 USER (09 AUG) VLADIMIR.K [8445,INPAGE 1
ACTION
AWAITING PAGE INSTRUCTIONS
Last but not least – there’s a navigation help that can be accessed at “AWAITING FUNCTION”
level ( ? ←- ):
To see a chapter enter its number like we did before for application records but use “?”
instead of a function, e.g. 2 ←- ? F5 :
FUNCTION = '('CHARACTER
------------------------------------------------------------------------------
This command will expand a sub-value, or sub-value set, within a
multivalue field.
Certain fields within the GLOBUS database are defined as being multivalue,
which means that the field can be expanded to accommodate different
values. Some multivalue fields have the additional facility of having
sub-values within each multivalue element.
NO. REFERENCE NO. TRANS. REF MSG TYPE STATUS PRIORITY FUNCT.
------------------------------------------------------------------------------
1 D20110420-049754593400.1 FX1107036479 202 HOLD
2 D20110420-049754593807.1 FX1107001307 202 HOLD
DATE.TIME.STAMP... D20110420-04975-45934-00
------------------------------------------------------------------------------
1 MESSAGE TYPE...... 202
3 APPLICATION....... FX
4 DISPOSITION....... UNFORMATTED
6 PRIORITY.......... N
10 ACCOUNT NUMBER.... 23752
11. 1 CUSTOMER NUMBER 100492
12 CUS. COMPANY...... GB0010001
13 COMPANY CODE...... GB0010001
16 LANGUAGE.......... GB
17 VALUE DATE........ 15 MAR 2011
18 CURRENCY.......... USD
19 AMOUNT............ 304000.00
20 DEPARTMENT........ 5
21 TRANSACTION REF... FX1107036479
23 TEST KEY REQ...... Y
25. 1 CARRIER ADDR NO SWIFT.1
------------------------------------------------------------------------------
01 MAR 2012 19:23:55 USER (14 APR) VLADIMIR.K [1596,I PAGE 1 >>>2>>>
ACTION
AWAITING PAGE INSTRUCTIONS
You can use F2 , F3 and F4 to navigate the record; F1 pressed twice takes you back
to records list (and you are positioned on the next record):
NO. REFERENCE NO. TRANS. REF MSG TYPE STATUS PRIORITY FUNCT.
------------------------------------------------------------------------------
1 D20110420-049754593400.1 FX1107036479 202 HOLD
2 D20110420-049754593807.1 FX1107001307 202 HOLD
F1 – back to queues list. To view a resulting document we need to choose some queue that
has formatted records, e.g. “FORMATTED - PRINT (ADVICE)” (11 ←- ):
NO. REFERENCE NO. TRANS. REF MSG TYPE STATUS PRIORITY FUNCT.
------------------------------------------------------------------------------
1 D20110411-023435075003.1 FT11070NRKBC 910
2 D20110411-072784681604.1 FT11070MB903 910
3 D20110415-055532794904.1 FT11070Z06ZQ 910
4 D20110504-086292907601.1 FT11104XY3W6 910
5 D20110428-065424049704.1 FT11097F3PJS 910
6 D20110411-000293919305.1 SCTRSC1107066YJK 518
7 D20110411-000294308805.1 SCTRSC11070HDBNF 518
8 D20110411-046934187805.1 SCTRSC11070X51KY 518
9 D20110411-046934189204.1 SCTRSC11070DL8S3 518
10 D20110411-046934192004.1 SCTRSC11070DYLK6 518
11 D20110411-046934193604.1 SCTRSC11070FPZ7W 518
12 D20110411-046934198400.1 SCTRSC11070Q7B00 518
13 D20110411-046934200004.1 SCTRSC11070SQBLS 518
14 D20110411-046935146705.1 SCTRSC110708LN5G 518
15 D20110419-001015232502.1 SCTRSC11070C9XC5 518
16 D20110419-001015251502.1 SCTRSC11070DPNLJ 518
------------------------------------------------------------------------------
01 MAR 2012 19:27:02 USER (14 APR) VLADIMIR.K [1596,I PAGE 1 >>>330>>>
ACTION
AWAITING FUNCTION
------------------------------------------------------------------------------
Do you want to display or print the message
Enter D (Display), P (Print) or <RETURN> to end
D ←- :
REFERENCE......... D20110428-065424049704.1
------------------------------------------------------------------------------
********************************************************************************
PAGE 1 PAGE 1 PAGE 1 PAGE 1 PAGE
********************************************************************************
REFERENCE......... D20110428-065424049704.1
------------------------------------------------------------------------------
WE HAVE TODAY RECEIVED THE FOLLOWING ACCOUNT TRANSFER INSTRUCTION FOR
VALUE 07 APRIL 2011
BY ORDER OF : YOURSELVES
IF YOU HAVE ANY QUERIES REGARDING THE ABOVE DETAILS, PLEASE CONTACT
US AS SOON AS POSSIBLE QUOTING OUR TRANSACTION NUMBER.
------------------------------------------------------------------------------
01 MAR 2012 19:27:02 USER (14 APR) VLADIMIR.K [1596,I PAGE 1
ACTION
AWAITING FUNCTION
Similarly for SWIFT (the following example is from inward REPAIR queue):
REF......... R20110419-045402954102
------------------------------------------------------------------------------
{1:F01DEMOGBPXAXXX.SN...ISN.}{2:I300AEIBSGSGXXXXN}{3:{108:xxxxx}}{4:
:15A/Sequence Identi :
:20/TRANSACTION REFE : FX1107008005
:21/Related Referenc : NEW
:22A/Type of Operati : NEWT
:22C/Common Referenc : DEMOPX3125AEIBSG
:82A/PARTY A : AEIBSGS
:87A/RECEIVER/DELIVE : DEMOGBPX
:15B/Sequence Identi :
:30T/Trade Date : 20110311
:30V/Value Date : 20110315
:36/EXCHANGE RATE : 0,703125
:32B/Currency Code, : GBP6400,00
:57A/Account with Ba : BARCGB22
:33B/Currency, Amoun : USD4500,00
function Set(list)
local set = {}
for _, l in ipairs(list) do set[l] = true end
return set
end
function string.starts(String,Start)
return string.sub(String,1,string.len(Start))==Start
end
---------------------------
function get_jbc_kwords(n_set)
if n_set == 1 then
return {
'$INSERT', '@FM', '@VM', '@SM', '@TM', '@AM', '@ID', '@RECORD',
'@FILENAME',
'ABS', 'ACOS', 'ADDS', 'ALPHA', 'AND', 'ANDS', 'APPEND',
'APPENDING', 'ARG', 'ASCII', 'ASIN',
'ASSIGNED', 'AT', 'ATAN', 'ATKEY', 'ATVARBEFORE',
'BEFORE', 'BEGIN', 'BFUNC', 'BITAND', 'BITCHANGE', 'BITCHECK',
'BITLOAD', 'BITNOT', 'BITOR', 'BITRESET', 'BITSET', 'BITXOR',
'BLOB', 'BREAK', 'BY', 'BYTELEN',
'CAPTURING', 'CASE', 'CATS', 'CE', 'CFUNC', 'CHANGE', 'CHAR',
'CHARS', 'CHDIR', 'CHECKSUM', 'CLEAR', 'CLEARCOMMON', 'CLEARDATA',
'CLEARFILE', 'CLEARINPUT', 'CLEARSELECT', 'CLOSE', 'CLOSESEQ', 'CREATE',
'COL1', 'COL2', 'COLLECTDATA', 'COMMON', 'COMPARE', 'CONTINUE',
'CONVERT', 'COS', 'COUNT', 'CRC', 'CRT', 'CTYPE', 'DATA', 'DATE',
'DCOUNT', 'DE', 'DEBUG', 'DECLARE', 'DECRYPT', 'DEFB', 'DEFC',
'DEFCPP', 'DEFFUN', 'DEL', 'DELETE', 'DELETELIST', 'DELETESEQ',
'DICT', 'DIM', 'DIR', 'DISPLAY', 'DIVS', 'DO', 'DOWNCASE',
-- Page 335
'DQUOTE', 'DTX', 'EBCDIC', 'ECHO', 'EDYN', 'ELSE', 'ENCRYPT',
'END', 'ENVFUNC', 'EOL', 'EQ', 'EQU', 'EQUATE', 'ERROR', 'ERRTEXT',
'EXISTING',
'EXP', 'EXTRACT', 'FADD', 'FCMP', 'FDIV', 'FFIX', 'FFLT', 'FIELD',
'FIELDS', 'FILEINFO', 'FILELOCK', 'FIND', 'FINDSTR', 'FLOAT',
'FMT', 'FMUL', 'FOLD', 'FOOTING', 'FOR', 'FORMLIST', 'FROM',
'FSUB', 'FUNCTION', 'GE', 'GES', 'GET', 'GETCWD', 'GETENV',
'GETLIST', 'GETX', 'GROUP', 'GROUPSTORE', 'GT', 'HEADING', 'HUSH',
'ICONV', 'IF', 'IN', 'INCLUDE', 'INDEX', 'INDICES', 'INMAT',
'INPUT', 'INPUTCLEAR', 'INPUTERR', 'INPUTNULL', 'INPUTTRAP',
'INS', 'INSERT', 'INT', 'IOCTL', 'ISALPHA', 'ISALNUM', 'ISDIGIT',
'ITYPE',
'JBASECOREDUMP', 'JBASESubroutineExist',
'KEY', 'KEYIN',
'LATIN1', 'LE', 'LEN', 'LN', 'LOCATE', 'LOCK', 'LOCKED', 'LOOP',
'LOWCASE', 'LOWER', 'LP', 'LT',
'MAKETIMESTAMP',
'MAT', 'MATBUILD', 'MATCHES', 'MATCHFIELD', 'MATPARSE', 'MATREAD',
'MATREADU', 'MATVAR', 'MATWRITE', 'MATWRITEU', 'MAXIMUM', 'ME',
'MINIMUM', 'MM', 'MOD', 'MSG', 'MSLEEP', 'MULS', 'NE', 'NEG',
'NEGS', 'NEXT', 'NOT', 'NULL', 'NUM', 'OBJEXCALLBACK', 'OCONV',
'OFF', 'ON', 'ONGOSUB', 'ONGOTO', 'OPEN', 'OPENDEV', 'OPENINDEX',
'OPENPATH', 'OPENSEQ', 'OPENSER', 'OR', 'ORS', 'OSBREAD',
'OSBWRITE', 'OSCLOSE', 'OSDELETE', 'OSOPEN', 'OSREAD', 'OSWRITE',
'OUT', 'PAGE', 'PASSDATA', 'PASSLIST', 'PAUSE', 'PE', 'PERROR',
'POSCUR', 'PP', 'PRECISION', 'PRINT', 'PRINTER', 'PRINTERR',
'PROCREAD', 'PROCWRITE', 'PROGRAM', 'PROMPT', 'PUTENV', 'PWR',
'QUOTE',
'RAISE', 'READ', 'READLIST', 'READNEXT', 'READONLY', 'READPREV',
'READSEQ', 'READT', 'READTX',
'READU', 'READV', 'READVU', 'READX', 'READXU', 'RECORDLOCKE',
'RECORDLOCKU', 'REGEXP', 'RELEASE', 'RECORDLOCKED', 'REMOVE',
'REPEAT', 'REPLACE', 'REUSE', 'REWIND', 'RND', 'RTNDATA',
'RTNLIST',
'SADD', 'SCMP', 'SDIV', 'SDYN', 'SECTION', 'SELECT', 'SELECTE',
'SELECTINDEX', 'SELECTINFO', 'SEND', 'SENDX', 'SENTENCE', 'SEQ',
'SETTING', 'SIN', 'SLEEP', 'SMUL', 'SORT', 'SOUNDEX', 'SPACE',
'SPLICE', 'SPOOLER', 'SQL', 'SQRT', 'SQUOTE', 'SSUB', 'SSELECT',
'SSELECTN', 'SSELECTV', 'STATIC', 'STATUS', 'STEP', 'STR',
'STRING', 'SUBR', 'SUBROUTINE', 'SUBS', 'SUBSTRINGS', 'SUM',
'SUMMATION', 'SWAP', 'SYNC', 'SYSTEM',
'System.getUserVariables',
'TA', 'TABLE', 'TAN', 'TE',
'THEN', 'TIME', 'TIMEDATE', 'TO', 'TRANS', 'TRANSABORT',
'TRANSEND', 'TRANSQUERY', 'TRANSTART', 'TRIM', 'TRIMB', 'TRIMF',
'UNASSIGNED', 'UNFILTERED', 'UNLOCK', 'UNTIL', 'UPCASE', 'USING',
'UTF8', 'VAR', 'VARCHAR', 'WAITING', 'WAKE', 'WEOF', 'WEOFSEQ',
'WHILE', 'WITH', 'WRITE', 'WRITEBLK', 'WRITELIST', 'WRITEP',
'WRITEPU', 'WRITESEQ', 'WRITESEQF', 'WRITET', 'WRITETX', 'WRITEU',
'WRITEV', 'WRITEVU', 'WRITEX', 'WRITEXU',
'XLATE', 'XTD'
}
end
-- Page 336
if n_set == 2 then
return {
'ABORT', 'CALL', 'CALLC', 'CALLJ', 'CHAIN', 'ENTER', 'EXEC',
'EXECUTE', 'EXIT', 'GO', 'GOSUB', 'GOTO', 'PERFORM', 'STOP', 'RETURN'
}
end
end
---------------------------
function OnStyle(styler)
-- config:
-- lexer.*.b=script_b
-- style.script_b.0=fore:#000000
-- style.script_b.1=fore:#98280C
-- style.script_b.2=fore:#0000FF
-- style.script_b.3=fore:#757877
-- style.script_b.4=fore:#FF0000
-- style.script_b.5=fore:#DF7401
-- style.script_b.6=fore:#DF01A5
-- style.script_b.7=fore:#088C4B
S_DEFAULT = 0
S_STRING = 1
S_KEYWORD = 2
S_COMMENT = 3
S_FORK = 4
S_LABEL = 5
S_T24_KWORD = 6
S_NUMBER = 7
-- 1,2 for COL1 (2), other digits - for labels and numbers
-- SAVED local kw_characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890.@$_"
local kw_characters =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890.@$_abcdefghijklmnopqrstuvwxyz"
-- Page 337
'C$.UNIVERSE.RELEASE', 'C$.USE.CCY.CACHE', 'C.U', 'C.B',
'C.F', 'C.E', 'C.V', 'C.W', 'C.T', 'C.PRINT', 'CACHE.OFF',
'CACHE.TEXT.TABLE', 'CHARSX', 'CHARX', 'CHECKFILE',
'CLEAR.SCREEN', 'CMD$STACK', 'COMI', 'COMI.DEFAULT',
'COMI.ENRI', 'CONCATFILE', 'CONTROL.MODULO', 'CONTROLWORD.OK',
'E', 'ECOMI', 'END.ERROR', 'ETEXT',
'F', 'F.ACTIVITY', 'F.CURRENCY', 'F.DYNAMIC.TEXT', 'F.FILE',
'F.FILE$HIS', 'F.FILE$NAU', 'F.FILE.CONTROL', 'F.IDS.LATEST',
'F.JOURNAL', 'F.LOCKING', 'F.PROTOCOL', 'F.SPF',
'F.STATIC.TEXT', 'F.T24.SESSION', 'FILE.CLASS', 'FILE.TYPE',
'FM', 'FULL.FNAME', 'G.SPARE1', 'G.SPARE2', 'G.SPARE3',
'G.SPARE4', 'G.SPARE5', 'G.SPARE6', 'G.SPARE7', 'G.SPARE8',
'G.SPARE9', 'G.SPARE10', 'G.SPARE11', 'G.SPARE12',
'G.SPARE13', 'G.SPARE14', 'G.SPARE15', 'G.SPARE16',
'G.SPARE17', 'G.SPARE18', 'G.SPARE19', 'G.SPARE20',
'G.SPARE21',
'HIST.NO',
'ID.ALL', 'ID.AUT', 'ID.CHECKFILE', 'ID.COMPANY',
'ID.CONCATFILE', 'ID.ENRI', 'ID.ETEXT', 'ID.F', 'ID.N',
'ID.NEW', 'ID.NEW.LAST', 'ID.OLD', 'ID.POINTER', 'ID.R',
'ID.T', 'INPUT.BUFFER',
'JOURNAL.BYPASS',
'L', 'L.MULTI', 'L1ST', 'LANG.NO', 'LASTA', 'LASTL.MULTI',
'LASTP', 'LCCY', 'LEVEL.NO', 'LEVEL.STATUS',
'LEVELS.NOT.ALLOWED', 'LIMIT.NETTING.IND', 'LINK.DATA',
'LIVE.RECORD.MANDATORY', 'LNGG', 'LOCAL.REF.FIELD',
'LOCAL1', 'LOCAL2', 'LOCAL3', 'LOCAL4', 'LOCAL5', 'LOCAL6',
'LOCAL7', 'LOCAL8',
'MESSAGE', 'MULTI.POSSIBLE', 'MTHPOS',
'N', 'NOTNUMERIC', 'NUMERIC',
'OPERATOR', 'OPF.NO', 'OTHERWISE', 'OVERRIDE.FLAG',
'P', 'PGM.TYPE', 'PGM.TYPE.NEXT', 'PGM.VERSION', 'PHNO',
'PREFIX', 'PRT.PARAMS', 'PRINTER.STATUS', 'R',
'R.ACCOUNT.PARAMETER', 'R.BANK.RETURN.PARAMS', 'R.COMPANY',
'R.DATES', 'R.INTERCO.PARAMETER', 'R.NEW', 'R.NEW.LAST',
'R.OLD', 'R.OPF', 'R.SPF.SYSTEM', 'R.USER', 'R.VERSION',
'RCOL', 'RLIN', 'RTXT', 'RELN', 'RFLN', 'RETURN.COMI',
'RUNNING.IN.JBASE', 'RUNNING.IN.UTF8', 'RUNNING.UNDER.BATCH',
'SCREEN.MODE', 'SCREEN.TITLE', 'SENSITIVITY', 'SEQSX', 'SEQX',
'SM', 'SPARE.FKEY8', 'SPARE.FKEY9', 'SPARE.FKEY10',
'SPARE.FKEY11', 'SPARE.FKEY12', 'SPARE.FKEY13',
'SPARE.FKEY14', 'SPARE.FKEY15', 'SPARE.FKEY16',
'T', 'T.AUTH.PAGE', 'T.CAT', 'T.CCY', 'T.CONTROLWORD',
'T.DEF.BASE', 'T.DEF.BASE.TARGET', 'T.ENRI', 'T.ETEXT',
'T.FIELDNO', 'T.FUNCTION', 'T.LANGUAGE', 'T.LOCREF', 'T.MTH',
'T.MTH.DAY', 'T.MULTI.PAGE', 'T.MULTI.TEXT', 'T.OPF',
'T.OPF.FC', 'T.OPF.FN', 'T.OPF.MAX', 'T.OV.CLASS', 'T.PWD',
'T.PWP', 'T.RAT', 'T.REMTEXT', 'T.RETURN.DATA', 'T.SELECT',
'T.SEQU', 'T.SUB.ASSOC', 'T.VAL.ASSOC', 'TEXT', 'TIME.STAMP',
'TNO', 'TODAY', 'TTYPE', 'USER.DATE.FORMAT', 'USING.EBCDIC',
'V', 'V$ACTION', 'V$DISPLAY', 'V$FUNCTION',
'VAL.TEXT', 'VM',
'WRITE.CACHE',
-- Page 338
'Z',
'O.DATA' -- the most used one from I_ENQUIRY.COMMON as well
}
cur_sym = styler:Current()
-- comments
-- string constants
-- Page 339
-- line (or statement) end
-- keywords
-- we can move only forward so we try to assemble all keyword here
if cur_word == ''
and kw_characters:find(cur_sym, 1, true) then
cur_word = cur_sym -- new word started
while styler:More() do
styler:Forward()
cur_sym = styler:Current()
if jbc_kw[cur_word] then
styler:ChangeState(S_KEYWORD)
-- Page 340
elseif cur_word == 'REM'
and string.starts(compressed_line, 'REM ') then
styler:ChangeState(S_COMMENT)
cur_word = ''
end
break
end
end
end
if styler:State() ~= S_COMMENT and styler:State() ~= S_LABEL then
styler:SetState(S_DEFAULT)
end
end
----------------------
styler:Forward()
end
styler:EndStyling()
end
-- Page 341
Result:
18.2 Compilation
jBC programs can be compiled and executed in one step. Press F5...
-- Page 342
T24 subroutines are triggered from T24 itself so they are only compiled. See the local
compilation on the next screen:
-- Page 343
18.3 Find all CALLs
function list_all_calls()
local n_init
local n_posn
local n_line
local line
local n_eol_posn
n_init = editor.CurrentPos
editor:GotoPos(0)
print('--------- list of calls ----------')
editor:MarkerDeleteAll(1)
while true do
editor:SearchAnchor()
n_posn = editor:SearchNext(0, 'CALL ')
if editor.StyleAt[n_posn] == 4 then
-- S_FORK doesn't work sometimes.. supposed to be global?
n_line = editor:LineFromPosition(n_posn)
n_posn = n_posn + 1
editor:GotoPos(n_posn)
end
editor:GotoPos(n_init)
end
-- Page 344
Crtl-Alt-C:
-- Page 345
local n_posn_line_start = editor:PositionFromLine(n_line_start)
local cur_line = editor:GetCurLine()
end
Crtl-Alt-I:
-- Page 346
18.5 Autocomplete jBC/T24 keywords
function jbc_auto_complete()
local jbc_kw = get_jbc_kwords(1)
local jbc_kw_fork = get_jbc_kwords(2)
local k,v
for k,v in pairs(jbc_kw_fork) do table.insert(jbc_kw, v) end
-- sort resulting list, otherwise we'll not find "RETURN" which is in the
-- second list
table.sort(jbc_kw)
editor:AutoCShow(editor.CurrentPos - n_start, table.concat(jbc_kw, " "))
end
Crtl-Alt-A:
-- Page 347
18.6 Code intentation
And again another part of kzm-lib.lua – see ”function cure indents()” code in the next
sub-chapter.
Let’s take an example from this book and copy/paste it to the editor (suppose pdf viewer
doesn’t preserve leading spaces while copying):
Crtl-Alt-U:
-- Page 348
Besides helping to improve the code readability, it might be useful to detect incomplete code
structures. Here END after line 27 is missing – and the code after it is shifted to the right:
-------------------------------------
function cure_indents()
-- needs setting where trailing spaces are not saved
-- BEGIN.CASE...CASE...END.CASE are on the same level to save space
-- $INSERTs start from the beginning of line
editor:BeginUndoAction()
local lines_qty = editor.LineCount
local line, n_start, n_indent, n_current, n_line_cont = '', 3, 3, 3, 6
local is_line_cont, is_comment
local is_case = false
local count, n_line
local n_fold_header, n_fold_body, n_fold_deflt = 9216, 1028, 1024
local n_fold_level = 0
local n_level_shift = 0
-- Page 349
line = editor:GetLine(n_line)
if line == nil then break end
line = string.gsub(line, '\n', '')
line = string.gsub(line, '\r', '')
line = string.gsub(line, "^%s*", "")
elseif string.sub(line, -5) == ' THEN' then -- THEN after OPENSEQ etc
-- Page 350
n_current = n_current + n_indent
-- labels
elseif string.sub(line, -1) == ':'
and string.gsub(line, '[A-Z,0-9,%.,:]', "") == '' then
editor.LineIndentation[n_line] = 0
end
-- Page 351
if is_comment == false and string.sub(line, -1) == ',' then
is_line_cont = true
end
if line == 'END'
or string.find(string.gsub(line, " ",""), 'END;%*', 1) ~= nil
or line == 'REPEAT'
or (string.find(string.gsub(line, " ",""), 'REPEAT;%*', 1) ~= nil
and string.sub(line, 1, 7) == 'REPEAT ')
or string.sub(line, -7) == ' REPEAT'
or string.sub(line, 1, 5) == 'NEXT '
or line == 'NEXT'
or line == 'END CASE'
or string.find(string.gsub(line, " ",""), 'ENDCASE;%*', 1) ~= nil
then
n_level_shift = -1
end
end
-- Page 352
editor.FoldLevel[n_line] = n_fold_deflt
end
-- Page 353
Screen after Ctrl-Alt-U:
If you like other indent size – it’s easy to set up. For example, to have initial indent of 6, the
subsequent indents of 4 and additional indentation for line continuation of 2 – change one
line in Lua function cure indents():
-- Page 354
See the result:
function exec_putty()
-- format env:ip:header
local line = editor:GetCurLine()
local n_posn = string.find(line, ':', 1)
if n_posn == nil then return end
local c_env = string.sub(line, 1, n_posn - 1)
line = string.sub(line, n_posn + 1)
n_posn = string.find(line, ':', 1)
if n_posn == nil then return end
Password for environment is “name of env123” – just for this sample only! Omit password
in command line for anything sensitive.
If you use the standard PuTTY, get rid of “-z” parameter.
-- Page 355
Step 1:
Ctrl-Alt-P:
-- Page 356
Lua code:
function ins_time_stamp()
editor:AddText('// '..os.date('%A, %d %b %Y, %H:%M:%S'))
end
After:
-- Page 357
Press Ctrl-Q once more – and code becomes uncommented again.
Dark colour scheme for SciTE which looks like the title page of this book.
18.10 Settings
Here are all settings that are in my SciTEUser.properties; though not all of them are
mandatory for the described samples to work:
font.base=font:Courier,size:12
font.comment=font:Courier,size:12
font.monospace=font:Courier,size:12
font.smaller=font:Courier,size:10
check.if.already.open
save.session=1
save.recent=1
strip.trailing.spaces=1
line.margin.visible=1
view.indentation.guides=1
view.indentation.examine=3
# Page 358
fold=1
fold.compact=1
fold.flags=16
fold.symbols=3
fold.on.open=0
fold.comment=1
fold.preprocessor=1
split.vertical=1
output.initial.hide=1
output.horizontal.size=420
output.magnification=1
output.wrap=1
clear.before.execute=1
caret.fore=#FF0000
caret.width=4
caret.line.back=#FFFED8
caret.line.back.alpha=73
edge.mode=1
edge.column=80
ensure.final.line.end=1
virtual.space=3
eol.mode=LF
# opens a file open dialog in the same directory where the current file is
open.dialog.in.file.directory=1
# after opening an insert file Crtl-Tab will bring you right back
buffers.zorder.switching=1
backspace.unindents=0
# lua startup
ext.lua.startup.script=$(SciteUserHome)/lualib/kzm-lib.lua
command.name.11.*=Fix indentation
command.11.*=cure_indents
command.subsystem.11.*=3
command.mode.11.*=savebefore:no
command.shortcut.11.*=Ctrl+Alt+U
# Page 359
command.subsystem.12.*=3
command.mode.12.*=savebefore:no
command.shortcut.12.*=Ctrl+Alt+A
command.name.13.*=Insert timestamp
command.13.*=ins_time_stamp
command.subsystem.13.*=3
command.mode.13.*=savebefore:no
command.shortcut.13.*=Ctrl+Alt+D
command.name.18.*=Exec Putty
command.18.*=exec_putty()
command.subsystem.18.*=3
command.mode.18.*=savebefore:no
command.shortcut.18.*=Ctrl+Alt+P
command.go.$(file.patterns.jbc)=$(SciteUserHome)/jbc-compile-program.cmd \
"$(FilePath)" "$(FileNameExt)" "$(FileName)"
file.patterns.t24=*.t24
lexer.$(file.patterns.t24)=script_b
# Page 360
command.go.$(file.patterns.t24)=$(SciteUserHome)/jbc-compile-t24-sub.cmd \
"$(FileNameExt)" "$(FileName)"
command.build.$(file.patterns.t24)=$(SciteUserHome)/jbc-upload-t24-sub.cmd \
"$(FilePath)" $(FileName) "$(SciteUserHome)"
@echo off
rem %1: file with full path
rem %2: file name and extension
rem %3: file name (for run)
set ROOT=C:\home\kzm\v-t24
copy %1 %ROOT%\r11\BATfiles
cd %ROOT%\r11\BATfiles
set TAFC_HOME=%ROOT%\r11\tafc
set JBCRELEASEDIR=%TAFC_HOME%
set PATH=%TAFC_HOME%\bin;%ROOT%\msvc\bin;%PATH%
set JBCEMULATE=prime
set INCLUDE=%ROOT%\msvc\include;%INCLUDE%
set LIB=%ROOT%\msvc\lib;%LIB%
set JBCBASETMP=%TEMP%\tmp_workfile
set JBASE_ERRMSG_DIVIDE_BY_ZERO=0
set JBASE_ERRMSG_NON_NUMERIC=0
set JBASE_ERRMSG_ZERO_USED=0
set JBCSPOOLERDIR=%ROOT%\r11\BATfiles\jspooler
jcompile -E %2
if errorlevel 1 goto error
%3
goto exitt
:error
echo "error"
:exitt
jbc-compile-t24-sub.cmd:
@echo off
rem %1 - file with full path, %2 - file name
rem (extension is .t24 - we don't need it)
set ROOT=C:\home\kzm\v-t24
set HOME=%ROOT%\r11\bnk\bnk.run
copy %1 %HOME%\ETC.BP\%2
cd %HOME%
set TAFC_HOME=%ROOT%\r11\tafc
set JBCRELEASEDIR=%TAFC_HOME%
set PATH=%TAFC_HOME%\bin;%ROOT%\msvc\bin;%PATH%
set JBCEMULATE=prime
set INCLUDE=%ROOT%\msvc\include;%INCLUDE%
set LIB=%ROOT%\msvc\lib;%LIB%
set JBCBASETMP=%TEMP%\tmp_workfile
jbc-upload-t24-sub.cmd (you’ll need programs winscp and plink here; amend the [PATH]
to them; also replace [USER], [PASSWORD] and [SERVER IP] to your data; last but not
least – replace KZM.BP with your BP directory name):
@echo off
rem %1 - file with full path, %2 - file name, %3 -user home
rem (extension is .t24 - we don't need it)
copy %1 %3\tmp\%2
[PATH]\WinSCP.com /script=%3\tmp\winscp.cmds
File cmd-template.conf that is used in that CMD file contains settings necessary for com-
pilation, e.g.:
export HOME=$PWD
export TAFC_HOME=/usr/jbc
export PATH=/usr/vac/bin:$TAFC_HOME/bin:$HOME/bin:$PATH
export JBASE_PATH=$HOME/t24bin
export LIBPATH=$TAFC_HOME/lib:/usr/ccs/lib:/usr/lib
export JEDIFILENAME_MD=$HOME/VOC
export JEDIFILENAME_SYSTEM=$TAFC_HOME/src/SYSTEM
export JBCEMULATE=prime
export JBASE_I18N=1
export JBCOBJECTLIST=$HOME/lib:$HOME/t24lib
export JEDIENABLEQ2Q=1
export JBASE_ERRMSG_DIVIDE_BY_ZERO=0
export JBASE_ERRMSG_ZERO_USED=0
19 Useful programs
Here you can find some of my tools that might be useful in everyday life (or add a little fun
to it).
CALL TXTINP('Input list name or ENTER to cancel', 10, 22, '64', 'ANY')
IF COMI EQ '' THEN
TEXT = 'Cancelled' ; CALL REM ; RETURN
END
list_name = COMI
GETLIST list_name TO ofs_list SETTING total_qty ELSE
TEXT = 'List not found' ; CALL REM ; RETURN
END
TEXT = 'Found & messages. Continue?' :FM: total_qty
CALL OVE
IF TEXT NE 'Y' THEN RETURN
GOSUB INIT.LOG
LOOP
READNEXT ofs_msg FROM ofs_list ELSE BREAK
CALL OFS.GLOBUS.MANAGER('TAG', ofs_msg)
log_message = ofs_msg
log_message<-1> = '----------------------------------------------------'
GOSUB ADD.LOG.REC
REPEAT
GOSUB FINISH.LOG ; TEXT = 'Finished' ; CALL REM
RETURN
* ------------- standard logging subroutines
INIT.LOG:
log_name = 'OFS.Paste.Log.'
log_contents = 'Started at: ' : TIMEDATE()
log_lines_counter = 1
RETURN
ADD.LOG.REC:
no_of_lines = DCOUNT(log_message, @FM) ;* can use an array to speed up
log_lines_counter += no_of_lines
log_contents<-1> = log_message
IF log_lines_counter GT 10000 THEN ;* start a new log
log_contents<-1> = 'To be continued...'
GOSUB FLUSH.LOG
log_contents = '...continued at ' : TIMEDATE()
log_lines_counter = no_of_lines + 1
END
RETURN
FLUSH.LOG:
WRITELIST log_contents TO log_name : TIMESTAMP() ;* write to &SAVEDLISTS&
RETURN ;* (with unique name)
FINISH.LOG:
log_contents<-1> = 'Finished at ' : TIMEDATE() ; GOSUB FLUSH.LOG
RETURN
* ---------------------------------------------------------------------------
END
Use this list name in the routine; after it finishes the contents of log file (in my case
OFS.Paste.Log.1370460034.2958) would be like:
PROGRAM FOMQ.COUNT3
* Counts F.OFS.MESSAGE.QUEUE at regular time intervals --------|
* and outputs the performance and estimated finish time. |
* By V.Kazimirchik, 20101222; last change 20110111. |
* 20110121, KZM: added number of running agents. |
* 2012-0405 (FOMQ.COUNT2) additional filter for FOMQ counting. |
* 2012-0711 additional '---' every 5 iterations |
* Tuesday, 17 Jul 2012, 10:20:31 KZM cleanup |
* Friday, 09 Nov 2012, 10:03:15 KZM: changed logic for number |
* of running agents. |
* Saturday, 09 Feb 2013, 12:02:29: New name (.3)
* If parameter is 'FT' or 'ft' then apply the filter automatically
* If something else - ask.
* No parameters - act as FOMQ.COUNT.
* New output format (more compact).
*--------------------------------------------------------------|
first_param = DOWNCASE(SENTENCE(1))
BEGIN CASE
END CASE
V.REC.QTY.SAVED = ''
V.TIME = ''
LOOP
GOSUB COUNT.Q
IF V.REC.QTY EQ 'ERROR' THEN
CRT 'SYSTEM ERROR'
STOP
END
IF V.REC.QTY EQ 0 THEN
CRT 'Upload finished'
STOP
END
BEGIN CASE
CASE V.DAYS.QTY EQ 0
V.DAYS.OUT = 'today'
CASE V.DAYS.QTY EQ 1
V.DAYS.OUT = @(-13) : 'tomorrow' : @(-14) ;* REVERSE
CASE 1
V.DAYS.OUT = @(-13) : 'in ' : V.DAYS.QTY : ' days' : @(-14)
END CASE
END ELSE
* reverse output for next 2 lines
IF V.SPEED EQ 0 THEN V.FINI.TIME.OUTP = @(-13) : 'never' : @(-14)
ELSE V.FINI.TIME.OUTP = @(-13) : '??? (file is growing)' : @(-14)
END
GOSUB GET.AGENTS.QTY
END ELSE
V.TIME = TIME()
V.REC.QTY.SAVED = V.REC.QTY
END
V.LOOP.TIME = 0
LOOP
V.BUFF = SYSTEM(14)
IF V.BUFF NE 0 THEN
V.KEY = KEYIN()
IF UPCASE(V.KEY) EQ 'Q' THEN
CRT ''
CRT 'EXITING'
STOP
END
END
MSLEEP 100
V.LOOP.TIME += 100
IF V.LOOP.TIME GE 10000 THEN BREAK
REPEAT
REPEAT
STOP
V.REC.QTY = 'ERROR'
FOR V.I = 1 TO V.LINES.QTY
V.LINE = V.OUTPUT<V.I>
RETURN
*-----------------------------------------------------------------
GET.AGENTS.QTY:
V.AGENTS.QTY = 0
REPEAT
RETURN
*-----------------------------------------------------------------
END
V.YR = 2012
V.MTH = 5
GOSUB YEAR.START
FOR V.H = 1 TO 7
GOSUB CREATE.CAL
* add additional empty lines to improve the resulting picture
* but not too much - otherwise everything wouldn't fit
IF V.H NE 7 THEN V.DISPL<-1> = ''
NEXT V.H
GOSUB DISPL.CAL
STOP
*----------------------------------------------------------------------------
INIT:
V.DISPL = ''
V.WDAYS.LINE = ''
FOR V.I = 1 TO 4
V.WDAYS.LINE := 'Mon Tue Wed Thu Fri Sat Sun '
NEXT V.I
DIM V.DAYS.L(4)
V.DAYQTY.L = 31 :@FM: 28 :@FM: 31 :@FM: 30 :@FM: 31 :@FM: 30 :@FM: 31 \
:@FM: 31 :@FM: 30 :@FM: 31 :@FM: 30 :@FM: 31
RETURN
*----------------------------------------------------------------------------
YEAR.START:
IF OCONV(ICONV(V.YR : '1231', 'D4'), 'DJ') EQ 366 THEN V.DAYQTY.L<2> = 29
ELSE V.DAYQTY.L<2> = 28
V.DISPL<-1> = STR(' ', 55) : V.YR[1,1] : ' ' : V.YR[2,1] : ' ': V.YR[3,1] \
: ' ' : V.YR[1]
RETURN
IF V.MTH GT 12 THEN
V.MTH = 1
V.YR ++
GOSUB YEAR.START
END
FOR V.I = 1 TO 4
V.LEN = LEN(V.M.NAME)
V.OFF.L = INT((27 - V.LEN) / 2)
V.OFF.R = 27 - V.LEN - V.OFF.L
V.MTH.LINE := STR(' ', V.OFF.L) : V.M.NAME : STR(' ', V.OFF.R) : ' '
V.DAY1.DOW = OCONV(ICONV(V.DAY.1, 'D4'), 'DW')
V.DAY = 0
V.WEEKNO = 0
LOOP
V.WEEKNO ++
FOR V.J = 1 TO 7
V.DAY ++
IF V.DAY GT V.DAYQTY.L<V.MTH> THEN BREAK
V.MTH ++
NEXT V.I
V.DISPL<-1> = V.MTH.LINE
V.DISPL<-1> = V.WDAYS.LINE
RETURN
*----------------------------------------------------------------------------
DISPL.CAL:
CRT @(-1)
V.QTY = DCOUNT(V.DISPL, @FM)
FOR V.I = 1 TO V.QTY
CRT STR(' ', 20) : V.DISPL<V.I>
NEXT V.I
RETURN
*----------------------------------------------------------------------------
END
Result:
By the way, these screenshots were obtained with the following Python script:
"""
Screen grabbing utility
"""
from PIL import ImageGrab
import time
V.FILE.IN = SENTENCE(1)
IF V.FILE.IN EQ '' THEN
CRT 'Usage: BF.RUN <file>'
CRT 'See sample below (created not by me)'
CRT '(Fibonacci numbers sequence in the range from 1 to 100):'
V.SRC = '+++++++++++' \
: '>+>>>>++++++++++++++++++++++++++++++++++++++++++++' \
: '>++++++++++++++++++++++++++++++++<<<<<<[>[>>>>>>+>' \
: '+<<<<<<<-]>>>>>>>[<<<<<<<+>>>>>>>-]<[>++++++++++[-' \
: '<-[>>+>+<<<-]>>>[<<<+>>>-]+<[>[-]<[-]]>[<<[>>>+<<<' \
: '-]>>[-]]<<]>>>[>>+>+<<<-]>>>[<<<+>>>-]+<[>[-]<[-]]' \
: '>[<<+>>[-]]<<<<<<<]>>>>>[+++++++++++++++++++++++++' \
: '+++++++++++++++++++++++.[-]]++++++++++<[->-<]>++++' \
: '++++++++++++++++++++++++++++++++++++++++++++.[-]<<' \
: '<<<<<<<<<<[>>>+>+<<<<-]>>>>[<<<<+>>>>-]<-[>>.>.<<<' \
: '[-]]<<[>>+>+<<<-]>>>[<<<+>>>-]<<[<+>-]>[<+>-]<<<-]'
CRT V.SRC
CRT ''
CRT 'is interpreted as:'
CRT ''
END
V.CNT ++
IF V.CNT GT V.VOLUME THEN STOP
BEGIN CASE
CASE V.INSTR EQ '>'
V.POINTER ++
IF V.POINTER GT 30000 THEN V.POINTER = 30000
V.CURR.VAL = V.VALUES(V.POINTER)
IF V.CURR.VAL GT 0 AND V.CURR.VAL LT 256 THEN CRT CHAR(V.CURR.VAL):
ECHO OFF
V.KEY = KEYIN()
ECHO ON
V.VALUES(V.POINTER) = SEQ(V.KEY)
V.CNT = V.RIGHT.BRACKETS<V.POSN>
IF V.CNT EQ 0 THEN
CRT 'STRUCTURE ERROR AT POSITION ' : V.CNT
STOP
END
V.CNT = V.LEFT.BRACKETS<V.POSN>
END CASE
REPEAT
STOP
END
V.KEY = KEYIN()
BEGIN CASE
V.KEY.2 = KEYIN() ;* ]
V.KEY.3 = KEYIN()
FIND 0 IN V.BOARD SETTING V.ZERO.POSN ELSE
CRT 'FATAL ERROR 1'
BREAK
END
BEGIN CASE
CASE V.KEY.3 EQ 'C' AND MOD(V.ZERO.POSN, 4) NE 1 ;* right
V.POSN.ZERO.NEW = V.ZERO.POSN - 1
GOSUB SWAP.PIECES
END CASE
CASE 1
V.KEY = UPCASE(V.KEY)
IF V.KEY EQ 'Q' THEN BREAK
END CASE
REPEAT
*------------------------------------------------------------------------------
SWAP.PIECES:
V.BOARD<V.ZERO.POSN> = V.BOARD<V.POSN.ZERO.NEW>
V.BOARD<V.POSN.ZERO.NEW> = 0
V.PIECE = V.POSN.ZERO.NEW
GOSUB DRAW.PIECE
V.PIECE = V.ZERO.POSN
GOSUB DRAW.PIECE
RETURN
*------------------------------------------------------------------------------
DRAW.BORDER:
FOR V.I = 4 TO 19
CRT @(22,V.I):'|':
CRT @(57,V.I):'|':
NEXT V.I
RETURN
*------------------------------------------------------------------------------
DRAW.PIECE:
V.X = MOD(V.PIECE+3, 4) * 8 + 24
V.Y = (INT((V.PIECE-1) / 4) + 1) * 4
V.NUMBER = V.BOARD<V.PIECE>
IF V.NUMBER EQ 0 THEN
CRT @(V.X+1,V.Y):' ':
CRT @(V.X,V.Y+1):' ':
CRT @(V.X,V.Y+2):' ':
CRT @(V.X,V.Y+3):' ':
END ELSE
CRT @(V.X+1,V.Y):'______':
CRT @(V.X,V.Y+1):'| |':
CRT @(V.X,V.Y+2):'| ':FMT(V.NUMBER,"2R"):' |':
CRT @(V.X,V.Y+3):'|______|':
END
CRT @(8,22):
RETURN
*------------------------------------------------------------------------------
DRAW.FIELD:
GOSUB CLEAR.FIELD
GOSUB DRAW.BORDER
FOR V.PIECE = 1 TO 16
GOSUB DRAW.PIECE
NEXT V.PIECE
CRT @(25,0):SYSTEM(40):@(-4):
CRT @(8,22):
RETURN
GOSUB DRAW.FIELD
RETURN
*------------------------------------------------------------------------------
END
GOSUB build_gfx
time = 0
loop:
GOSUB refresh
FOR iy = 0 TO height-1
y = 2.0 * iy / height - 1.0
FOR ix = 0 TO width-1
x = 2.0 * (ix - width/2) / width
u = x * zdiv
v = y * zdiv
ch = " "
IF (iu >= 0) AND (iu < width) AND (iv >= 0) AND (iv < height) THEN
ch = M(iv)[iu + 1, 1]
END
S(iy)[ix + 1, 1] = ch
NEXT
NEXT
GOTO loop
STOP
refresh:
CRT @(-2)
FOR I = 0 TO 23
build_gfx:
M( 0) = " "
M( 1) = " "
M( 2) = " XXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXX "
M( 3) = " XXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXX "
M( 4) = " XXX XXX XXX "
M( 5) = " XXX XXX XXX "
M( 6) = " XXX XXX XXX "
M( 7) = " XXX XXX XXX "
M( 8) = " XXX XXX XXX XXX "
M( 9) = " XXX XXX XXX XXX "
M(10) = " XXX XXX XXX "
M(11) = " XXXXXXXXXXXXXXXXXXXXX XXX "
M(12) = " XXX XXXXXXXXXXXXXXXXXXXXX XXX "
M(13) = " XXX XXX XXX XXX "
M(14) = " XXX XXX XXX XXX "
M(15) = " XXX XXX XXX XXXXXX "
M(16) = " XXX XXX XXX XXXXXX "
M(17) = " XXXXXX XXXXXX XXX XXXXXX "
M(18) = " XXXXXX XXXXXX XXX XXXXXX "
M(19) = " XXXXXX XXXXXX XXX XXXXXX "
M(20) = " XXXXXX XXXXXX XXX XXXXXX "
M(21) = " XXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXX "
M(22) = " XXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXX "
M(23) = " "
RETURN
Page 35
h hhhhh ((((
EVAL "FIELD(@ID;';',1)"
(((( hhhh "FIELD(@ID,';',1)"
((
( h
Page 107
note: And the result is opposite - REMOVE is faster... sorry for misleading.
Page 130
Regarding rnd() call with parameter 1000: