In the previous article “Dealing with the Python time module from Rocket MV BASIC” I showed how it is possible to access the python internal time module and convert the python date to string display format, then convert it back into the number of seconds since Epoch.
Python RESULT:
python time= 1418146291
Python RESULT:
python local time= Tue Dec 9 09:31:31 2014
Python RESULT:
python time= 1418146291
While it is possible to write a subroutine to handle the interaction between MV BASIC and Python, you can get more from you subroutine if you write it as a User Defined User Exit.
User exits are the codes used in the ICONV and OCONV functions. In the first article of this series we showed how we can call the u2py.DynArray.iconv and u2py.DynArray.oconv functions to convert display dates into internal format, and then convert back into display format:
python> test = u2py.DynArray("04 Dec 2014")
python> itest = test.iconv("D")
python> itest
<u2py.DynArray value=b'17140'>
python> itest.oconv("D4/")
<u2py.DynArray value=b'12/04/2014'>
The limitation on the MV date conversion is that it only deals with the date. There is a separate conversion code that deals with time. The following user defined user exit calls the python module we worked with in the previous article, and exposes it to the MV Developer as a conversion code that handles timedate values.
pyTimeDate
SUBROUTINE Upytimedate( return_val, STATUS, input_val, TYPE )
***************************************************************
*
* Brief functional description
* Example user exit to deal with Python time module
* Copyright (c) 2020
**************************************************************
*
* Detailed description
*
* Usage, such as return_val = OCONV(input_val,"UpyTimeDate")
*
**************************************************************
* processing code area:
* Arguments:
* return_val = final data to return.
* STATUS = 0 for success, other for failure.
* input_val= data to be converted or processed.
* TYPE: 0 for ICONV, 1 for OCONV.
*
ModuleName = "python_time"
* import the module
pymodule = PyImport(ModuleName)
IF @PYEXCEPTIONTYPE NE '' THEN
return_val = "bad import"
END
IF TYPE THEN
* OCONV
A = input_val+ 0
FuncName = "localtime"
return_val = PyCallFunction(ModuleName, FuncName, A )
IF @PYEXCEPTIONTYPE NE '' THEN
return_val = "bad function call ":FuncName
END
END ELSE
* ICONV
B = input_val
FuncName = "getepoch"
return_val = PyCallFunction(ModuleName, FuncName, B )
IF @PYEXCEPTIONTYPE NE '' THEN
return_val = "bad function call ":FuncName
END
END
RETURN
END
Note that this is a simple example that handles limited formats and does minimal error checking. Yet it allows us to create a display formatted date from the internal python representation, which is the number of seconds from Epoch.
UTEST
TIMEDATE = 1418126116
PRINT "START WITH ":TIMEDATE
OUTDATE = OCONV(TIMEDATE, "UpyTimeDate")
PRINT "OUTDATE = ":OUTDATE
INDATE = ICONV(OUTDATE, "UpyTimeDate")
PRINT "BACK TO INTERNAL ":INDATE
Another benefit of having the code as a user defined user exit is that it works in a dictionary item as well.
SORT DICT PYTEST TYP LOC CONV MNAME FORMAT SM ASSOC BY TYP BY LOC BY @ID 14:03:47 Dec 09 2014 1
@ID............ TYP LOC...... CONV MNAME...... FORMAT SM ASSOC.....
@ID D 0 PYTEST 10L S
RAW D 1 10L S
pyTimeDate D 1 Upytimedate 30L S
3 records listed
LIST PYTEST pyTimeDate RAW 14:06:23 Dec 09 2014 1
PYTEST.... pyTimeDate.................... RAW.......
1 Tue Dec 9 03:55:16 2014 1418126116
3 Thu Dec 11 11:28:36 2014 1418326116
2 Wed Dec 10 07:41:56 2014 1418226116
3 records listed
While this is a simple example, there are countless uses for accessing python modules in this manner. A quick search of python.org will surely show numerous modules that you may want to access to add additional information to your MV Query Reports.
------------------------------
Michael Rajkowski
Rocket Software
------------------------------