• No results found

DATE = ICONV(TD[10,11], ’D’)

In document JofBASEcommaTAFofC (Page 27-36)

7 Tips and tricks: custom data conversion

V. DATE = ICONV(TD[10,11], ’D’)

V.TD = OCONV(V.DATE, ’DY2’) : FMT(OCONV(V.DATE, ’DM’), "R0%2") \ : FMT(OCONV(V.DATE, ’DD’), "R0%2") : V.TIME

R.OUTPUT<V.DATE.TIME> = V.TD

There is a lot of conversion codes (see jBC manual and jBASE knowledgebase). Also there are some special codes – for example, *A9999 shows record size (try the following under jrunT24.cmd):

Another conversion code sample C:\sa-tafc> jrunT24.cmd

jsh ~ --> LIST F.COMPANY *A9999

@ID... *A9999...

GB0010003 2166

SG0010001 2173

EU0010001 2173

GB0010002 2174

GB0010004 2166

GB0010001 2607

6 Records Listed

J of BASE, TAF of C 27 By KZM

7 TIPS AND TRICKS: CUSTOM DATA CONVERSION

If we’re way too suspicious let’t check if the output is correct. To do that we’ll change the program prog1 to output the size of all records in COMPANY application data file rather then their contents.

prog1 - the changes

18

19 * CRT V.KEY : ’ >>> ’ : R.CMP

20 CRT V.KEY : ’ >>> ’ : BYTELEN(R.CMP)

21

Why bytelen() rather that len()? Because if we have a UTF-8 environment (and we do have it, see environment variable JBASE I18N), len() will give us the number of characters rather than the number of bytes in a record.

So - compile, run (jrunT24.cmd again since we need T24 data access), see:

Record sizes checked jsh ~ --> prog1

HELLO

GB0010003 >>> 2166 SG0010001 >>> 2173 EU0010001 >>> 2173 GB0010002 >>> 2174 GB0010004 >>> 2166 GB0010001 >>> 2607

Looks like it works. What have we just done? Achieved the same goal using 2 different methods. Which one to choose? In this case - first (a built-in) one is easier. But it’s not always the same so the final choice in every particular case is yours.

Please note that in this book some examples are run under jrunT24.cmd, some – under jrunSH.cmd etc. Make sure you lanch the same cmd that is shown in an example, otherwise it might not work.

Little more about “A” conversion codes – also known as “A-correlatives”. A*n means

“field n”, so if you don’t have the dictionary file (or too lazy to type field names) you can try the following:

Another conversion code sample C:\sa-tafc> jrunT24.cmd

jsh ~ --> LIST F.COMPANY *A1 *A2 *A3

@ID... *A1... *A2... *A3...

J of BASE, TAF of C 28 By KZM

7 TIPS AND TRICKS: CUSTOM DATA CONVERSION

GB0010003 R11 MF BRANCH R11 MF BRANCH MF2

1 1

SG0010001 R11 LEAD SG CO R11 LEAD SG CO SG1

MPANY MPANY

EU0010001 R11 LEAD CO GE R11 LEAD CO GE EU1

RMANY RMANY

GB0010002 R11 LEAD MF CO R11 LEAD MF CO MF1

MPANY MPANY

GB0010004 R11 MF BRANCH R11 MF BRANCH MF3

2 2

GB0010001 Model Bank 18 Place De Ph BNK ilosophes,

CH 1205 Geneva ,

Switzerland 6 Records Listed

As we saw earlier, A*9999 is a special code, A*9998 also is:

Yet another conversion code sample C:\sa-tafc> jrunT24.cmd

jsh ~ --> LIST F.COMPANY *A9998

@ID... *A9998...

GB0010003 1

SG0010001 2

EU0010001 3

GB0010002 4

GB0010004 5

GB0010001 6

6 Records Listed

No, that’s not record “physical” location number or like as I initially thought – just a sequential number in the output. Change the sequence of records with SSELECT and see:

And yet another conversion code sample C:\sa-tafc> jrunT24.cmd

jsh ~ --> SSELECT F.COMPANY

> LIST F.COMPANY *A9998

@ID... *A9998...

J of BASE, TAF of C 29 By KZM

7 TIPS AND TRICKS: CUSTOM DATA CONVERSION

EU0010001 1

GB0010001 2

GB0010002 3

GB0010003 4

GB0010004 5

SG0010001 6

6 Records Listed

A*n is not limited by actual number of fields (most probably executing something equiv-alent to var = arr<n> ), though there is a limitation (and this number is quite large to terminate the session). To (most probably) get out-of-memory error you might try the following:

Trying to terminate the session C:\sa-tafc> jrunT24.cmd

jsh ~ --> LIST F.COMPANY *A99999999

Session dies and we have a nice new file in our bnk.run directory:

Core dump C:\sa-tafc> jrunT24.cmd

jsh ~ --> LIST . LIKE ...dmp DICT ...

TAFC_coredump-20110707213724386.dmp 1 Records Listed

Something more about solving problems in different ways. There’s an application in T24 called OFS.REQUEST.DETAIL which you most probably already know about. Let’s see its contents. Normally it’s something like:

OFS.REQUEST.DETAIL sample contents C:\sa-tafc> jrunT24.cmd

jsh ~ --> LIST F.OFS.REQUEST.DETAIL

@ID... SCRPT11062000160~I

@ID... SCRPT11062000160~I MESSAGE.KEY... SCRPT11062000160~I

APPLICATION... AA.PRD.DES.PAYMENT.SCHEDULE VERSION...

J of BASE, TAF of C 30 By KZM

7 TIPS AND TRICKS: CUSTOM DATA CONVERSION

FUNCTION... I

TRANS.REFERENCE. NOTICE.ACCOUNT-EUR-20100809 USER.NAME... SUSER1

COMPANY... GB0010001

DATE.TIME.RECD.. 09:08:03:875 10 MAR 2011 DATE.TIME.QUEUE.

DATE.TIME.PROC.. 09:08:03:928 10 MAR 2011 STATUS... PROCESSED

MSG.IN... AA.PRD.DES.PAYMENT.SCHEDULE,/I/PROCESS/1/0/,SUSER1/******/GB001 0001////,NOTICE.ACCOUNT-EUR-20100809/SCRPT11062000160~I,DESCRIPT ION:1:1=Savings Account,PAYMENT.TYPE:1:1=INTEREST.ONLY,PAYMENT.T YPE:2:1=INTEREST.ONLY,PAYMENT.METHOD:1:1=CAPITALISE,PAYMENT.METH OD:2:1=CAPITALISE,PAYMENT.FREQ:1:1=e0Y e1M e0W e0D e0F,PAYMENT.F REQ:2:1=e0Y e1M e0W e0D e0F,PROPERTY:1:1=CRINTEREST,PROPERTY:2:1

=DRINTEREST,DUE.FREQ:1:1=e0Y e1M e0W e0D e0F,DUE.FREQ:2:1=e0Y e1 M e0W e0D e0F,DEFAULT.NEGOTIABLE:1:1=YES,

MSG.OUT... NOTICE.ACCOUNT-EUR-20100809/SCRPT11062000160~I/1,DESCRIPTION:1:

1=Savings Account,PAYMENT.TYPE:1:1=INTEREST.ONLY,PAYMENT.TYPE:2:

1=INTEREST.ONLY,PAYMENT.METHOD:1:1=CAPITALISE,PAYMENT.METHOD:2:1

=CAPITALISE,PAYMENT.FREQ:1:1=e0Y e1M e0W e0D e0F,PAYMENT.FREQ:2:

1=e0Y e1M e0W e0D e0F,PROPERTY:1:1=CRINTEREST,PROPERTY:2:1=DRINT EREST,DUE.FREQ:1:1=e0Y e1M e0W e0D e0F,DUE.FREQ:2:1=e0Y e1M e0W e0D e0F,DEFAULT.NEGOTIABLE:1:1=YES,ID.COMP.1:1:1=NOTICE.ACCOUNT,

As we know, in OFS messages comma is a delimiter. Imagine we’d like to see each part of the message at a different line. What can we do here? Possible choices are:

• Create an ENQUIRY with some special processing using ENQUIRY field conversion ...and build a web service based on that enquiry... no, forget a web service – we’re aiming to low level rather than adding more and more wrappers. In general, it looks feasible but showing a single-valued field in several lines (like a multi-valued) might be a little tricky in ENQUIRY.

• Create an I-descriptor with user routine and then display the output either in EN-QUIRY or in jsh. Good idea but let’t go deeper and try “not to harm any animal”... sorry, I meant “keep T24 intact”.

• Create what in jBASE (and not only here but in all “multi-valued” world) is called

“user exit”. This technique is described in details in jBASE knowledgebase; let’t take an example from there and amend it to cater our needs.

J of BASE, TAF of C 31 By KZM

7 TIPS AND TRICKS: CUSTOM DATA CONVERSION

There are two methods to create a custom conversion code (read: user exit) - create one routine per each new code or to put everything into one routine with standard name JBCUserConversions. In this example we’ll use the second one.

Our chosen name for a conversion code will be “XZ”. So then the source of the routine JBCUserConversions will look like:

JBCUserConversions - amended

1 * Amended by KZM

2 SUBROUTINE JBCUserConversions (result, source, code, type, error)

3

4 BEGIN CASE

5 CASE code EQ "XZ"

6 IF type THEN

7 * result = source : " was OCONV"

8 result = source

9 CHANGE ’,’ TO @VM IN result

16 END CASE

17

18 RETURN

19

20 END

21

Some code was commented by me but retained to give you the better idea of this method.

Now let’s compile it (for reasons yet unknown to me I wasn’t able to compile any sub-routine using jcompile so here’s good old BASIC and CATALOG). But firstly we need to add some environment variables to jrunSH.cmd:

New variables in jrunSH.cmd

29

30 set JBCOBJECTLIST=%HOME%\lib

31 set JBCDEV_LIB=%HOME%\lib

32

Here goes compilation:

Compilation of JBCUserConversions C:\sa-tafc> jrunSH.cmd

jsh ~ --> BASIC . JBCUserConversions

J of BASE, TAF of C 32 By KZM

7 TIPS AND TRICKS: CUSTOM DATA CONVERSION

JBCUserConversions BASIC_1.c

Source file JBCUserConversions compiled successfully jsh ~ --> CATALOG . JBCUserConversions

JBCUserConversions

Object JBCUserConversions cataloged successfully

mt -nologo -manifest C:\sa-tafc\lib\lib0.dll.manifest -outputresource:

C:\sa-tafc\lib\lib0.dll;2 failed , command returned a code of -1 Library C:\sa-tafc\lib\lib0.dll rebuild okay

jsh ~ -->

We can see that the file $JBCUserConversions appeared in sa-tafc (we can delete it), the directory sa-tafc\lib was automatically created and – what matters for us – in it we have the new file lib0.dll where the compiled routine is supposedly been placed; in any case, jshow will let us know if it is so:

Check of JBCUserConversions jsh ~ --> jshow -c JBCUserConversions

Subroutine: C:\sa-tafc\lib\lib0.dll

jBC JBCUserConversions version 201014.0 Mon Jun 20 09:58:23 2011 jBC JBCUserConversions source file .

jsh ~ -->

As soon as we’re going to apply our new conversion code“XZ”to T24 data file, we need our conversion subroutine to be visible for work in T24 environment. To achieve that we need to add the directory with our lib0.dll here:

Correction of jrunT24.cmd

37 set JBCOBJECTLIST=%T24_HOME%\lib;%T24_HOME%\t24lib;%HOME%\lib

Now try to see the results. After toying a little with output width finally we can see something more readable (the full command didn’t fit here properly and of course should be entered in one line):

Results of customization of JBCUserConversions C:\sa-tafc> jrunT24.cmd

jsh ~ --> LIST F.OFS.REQUEST.DETAIL ID-SUPP EVAL "@ID[1,20]"

EVAL "OCONV(MSG.IN, ’XZ’)" EVAL "OCONV(MSG.OUT, ’XZ’)"

@ID[1,20

. OCONV(MSG.IN, "XZ")... OCONV(MSG.OUT, "XZ")...

J of BASE, TAF of C 33 By KZM

7 TIPS AND TRICKS: CUSTOM DATA CONVERSION

SCRPT11062 AA.PRD.DES.PAYMENT.SCHEDULE NOTICE.ACCOUNT-EUR-20100809/SC

000160~I RPT11062000160~I/1

/I/PROCESS/1/0/ DESCRIPTION:1:1=Savings Accoun

t

SUSER1/******/GB0010001//// PAYMENT.TYPE:1:1=INTEREST.ONLY NOTICE.ACCOUNT-EUR-20100809/SC PAYMENT.TYPE:2:1=INTEREST.ONLY RPT11062000160~I

DESCRIPTION:1:1=Savings Accoun PAYMENT.METHOD:1:1=CAPITALISE t

PAYMENT.TYPE:1:1=INTEREST.ONLY PAYMENT.METHOD:2:1=CAPITALISE PAYMENT.TYPE:2:1=INTEREST.ONLY PAYMENT.FREQ:1:1=e0Y e1M e0W e

0D e0F

PAYMENT.METHOD:1:1=CAPITALISE PAYMENT.FREQ:2:1=e0Y e1M e0W e 0D e0F

PAYMENT.METHOD:2:1=CAPITALISE PROPERTY:1:1=CRINTEREST PAYMENT.FREQ:1:1=e0Y e1M e0W e PROPERTY:2:1=DRINTEREST 0D e0F

PAYMENT.FREQ:2:1=e0Y e1M e0W e DUE.FREQ:1:1=e0Y e1M e0W e0D e

0D e0F 0F

PROPERTY:1:1=CRINTEREST DUE.FREQ:2:1=e0Y e1M e0W e0D e 0F

PROPERTY:2:1=DRINTEREST DEFAULT.NEGOTIABLE:1:1=YES DUE.FREQ:1:1=e0Y e1M e0W e0D e ID.COMP.1:1:1=NOTICE.ACCOUNT 0F

DUE.FREQ:2:1=e0Y e1M e0W e0D e ID.COMP.2:1:1=EUR 0F

Note ID-SUPP keyword suppressing the output of @id since default display parameter for it is too big to fit all we need into screen width.

If we hadn’t included our lib directory to JBCOBJECTLIST, we would have got the following error:

Error message Error in named attribute XZ

Unknown conversion code.

J of BASE, TAF of C 34 By KZM

7 TIPS AND TRICKS: CUSTOM DATA CONVERSION

This conversion code now also can be used in ENQUIRY field conversion. Of course to make your custom conversion code generally available you need the compiled subroutine JBCUserConversions to be visible for all T24 users, whether it’s Classic or Browser (in latter case it’s environment.vars or whichever file used in jBoss or TCServer is to be amended).

The template for an individual routine for each custom conversion you can find going to TAFC home directory, then to subdirectory src. It’s named jBASE UserExit.

J of BASE, TAF of C 35 By KZM

8 SOME PERFORMANCE TRICKS – DYNAMIC ARRAY POPULATION, SUBSTRING SEARCH

8 Some performance tricks – dynamic array

In document JofBASEcommaTAFofC (Page 27-36)