Showing posts with label envision statements. Show all posts
Showing posts with label envision statements. Show all posts

Wednesday, September 6, 2017

Record markers to ASCII (and vice versa)

Credits to Thomas Mantooth.

The UniData delimiters are in reverse order of their hierarchy. So, going in the other direction...

@RM (Record mark) = CHAR(255)
@FM (Field mark) = CHAR(254)
@VM (Value mark) = CHAR(253)
@SM (Sub-value mark) = CHAR(252)
@TM (Text mark) = CHAR(251)

One neat trick you can make use of with this comes into play when you use the REMOVE command. It assigns a value that indicates what type of delimiter it returns. Most of the time, you don't care what the specific delimiter is - you're just looking to see if it's zero, which is returned at the end when there's no delimiter. However, if you're dealing with something that can have multiple delimiters, you can use REMOVE and the delimiter value to build a new dynamic array with the same delimiters very simply.

LOOP
    REMOVE X.VALUE FROM XL.ARRAY SETTING X.DELIMITER
    * Do something to manipulate the data
    XL.NEW.ARRAY := X.VALUE
UNTIL NOT(X,DELIM) DO
    XL.NEW.ARRAY := CHAR(256 - X.DELIMITER)
REPEAT

Wednesday, July 1, 2015

Notes on S.EXECUTE subroutine

S.EXECUTE will execute a sentence to perform operations, such as a select statement against the database. This is Datatel's version of the Unibasic EXECUTE command (you can type HELP EXECUTE at the colon prompt for additional information about EXECUTE). Since EXECUTE only works for Unidata clients, we encourage people to use S.EXECUTE in its place.

UniQuery-syntax statements can be used with S.EXECUTE on any underlying database. These statements, when used with S.EXECUTE, will be converted by Datatel's underlying MIO components to the native database query language for executing the select statement.

There is only one argument for this subroutine:
A.STMT Input only The statement to execute; the format of this statement should be:
[<options>] <command> [<arguments>]

<options> are optional; it is a list of zero or more options that are separated by spaces, each of which begins with a dash ('-') character. Valid options are:

-H = Hush the output that may be generated by the command being executed; for example, the 'n records selected' message when a select statement is executed
-NM = Do not map SELECT/SSELECT commands to MIOSEL/MIOSELS; this option is NOT recommended for use unless you are certain the file being selected exists on the application server AND you are certain that the -NM option is necessary
-C = Capture output from the command in the CAPTURED.OUTPUT common variable
-DB = Force debug mode ON for execution of S.EXECUTE; same effect as entering S.EXECUTE in UTDB screen
-DH = Only valid on Distributed UniData deployments; Execute command on database server ('datahome')

<command> is a query language command such as SELECT

<arguments> are optional; is a string that contains arguments for the command (if applicable)

Example:
X.STMT = 'MIOSEL PERSON WITH LAST.NAME = 'Smith''
CALL S.EXECUTE (X.STMT)
FOR_EACH SELECTED ID
<code>
END_EACH SELECTED ID

The X.STMT line sets up the 'sentence' to execute. The next line that calls S.EXECUTE executes the statement. We now have an active list of PERSON records, of which we can use in the following FOR_EACH loop.

Thursday, July 31, 2014

Mistakes to watch out for with NULL in lists

The main thing to watch out for is the usage of the <1,-1> code for accessing/updating a list. When you insert a NULL using <1,-1>, it doesn’t really do anything.

In this case, we had three lists that were being used like an association, trying to be retrieve data from a record:

*Stores each field we care about from STUDENT.ACAD.CRED record in lists. The intention is that these lists are associated.
FOR_EACH REFERENCED SECONDARY PST.STUDENT.ACAD.CRED
  XL.STC.CMPL.CRED<1,-1> = V.STC.CMPL.CRED
  XL.STC.STATUS<1,-1> = VL.STC.STATUS<1,1>
  XL.STC.END.DATE<1,-1> = V.STC.END.DATE
END_EACH PST.STUDENT.ACAD.CRED

The issue arises when you consider how assigning NULLs work in UniData. Since a NULL, in Envision, is not actually a character but an empty string, assigning a null to a list doesn’t actually update the list, so when we hit a NULL value in the assignment the positions of the three lists went wrong. If our starting data was like this:

Record #1:
V.STC.CMPL.CRED = NULL
VL.STC.STATUS<1,1> = ‘N’
V.STC.END.DATE = ‘7/11/2014’

Record #2:
V.STC.CMPL.CRED = ‘3.00’
VL.STC.STATUS<1,1> = ‘N’
V.STC.END.DATE = ‘7/12/2014’

Our ending lists would look like this, based on our code above:

STC.CMPL.CRED
STC.STATUS
STC.END.DATE
1
3.00
N
7/11/2014
2
NULL
N
7/12/2014

In record 1, V.STC.CMPL.CRED was NULL, so it actually did not create a delimiter in the XL.STC.CMPL.CRED in position 1; we merely set the tail of the list equal to NULL, so it didn’t actually do anything. The next record then sticks ‘3.00’ into the tail of the list, which is in position 1. Since position 2 is never set, our three lists are going to look like:

XL.STC.COMPLE.CRED = ‘3.00’
XL.STC.STATUS = ‘N’:@VM:’N’
XL.STC.END.DATE = ‘7/11/2014’:@VM:’ 7/12/2014’

Example of the issue using <1,-1>:

XL.LIST<1,-1> = ‘’
XL.LIST<1,-1> = ‘’
XL.LIST<1,-1> = ‘’
XL.LIST<1,-1> = ‘’
XL.LIST<1,-1> = ‘’
XL.LIST<1,-1> = ‘TEST’

In this case, XL.LIST is now equal to ‘TEST’ with no delimiters. In order to make this work, what you actually need to do is explicitely define the positions:

XL.LIST<1,1> = ‘’
XL.LIST<1,2> = ‘’
XL.LIST<1,3> = ‘’
XL.LIST<1,4> = ‘’
XL.LIST<1,5> = ‘’
XL.LIST<1,6> = ‘TEST’

Now XL.LIST is equal to ‘’:@VM:’’:@VM:’’:@VM:’’:@VM:’’:@VM:’TEST’ with @VM as the delimiter.

In order to fix the original code, I replaced

FOR_EACH REFERENCED SECONDARY PST.STUDENT.ACAD.CRED
  XL.STC.CMPL.CRED<1,-1> = V.STC.CMPL.CRED
  XL.STC.STATUS<1,-1> = VL.STC.STATUS<1,1>
  XL.STC.END.DATE<1,-1> = V.STC.END.DATE
END_EACH PST.STUDENT.ACAD.CRED

With

X.ACAD.COUNTER = ‘1’
FOR_EACH REFERENCED SECONDARY PST.STUDENT.ACAD.CRED
  XL.STC.CMPL.CRED<1,X.ACAD.COUNTER> = V.STC.CMPL.CRED
  XL.STC.STATUS<1,X.ACAD.COUNTER > = VL.STC.STATUS<1,1>
  XL.STC.END.DATE<1,X.ACAD.COUNTER> = V.STC.END.DATE
  X.ACAD.COUNTER = X.ACAD.COUNTER + 1

END_EACH PST.STUDENT.ACAD.CRED


* Cited from Trevyn Bowden.

Thursday, April 10, 2014

Changing the print option on procedure

To change the print option of a procedure, change/create the printer definition of it in PDEF.

For example, in the UI form Procedure Hook, when a process is called via a procedure statement

  PROCEDURE STMT 'SAVE.LIST ':V.JSPARAMS.ID
  PROCEDURE OUTPUT 'XPROC123'
  PROCEDURE STMT 'GET.LIST ':V.JSPARAMS.ID

Go to PDEF, change/create the printer XPROC123 to set the defaults, such as Output Device, Page Width, Page Length, etc.

Wednesday, March 12, 2014

Display Error Message

Use S.ARG.ERROR.MESSAGE(ARG1, ARG2, ARG3, ARG4)

ARG1: Set this to "1" to display an error message
ARG2: Set this to "1" or to a text strings that will become buttons in the warning message
ARG3: Set this argument equal to a text string or the key identifying a shared error message
ARG4: Set this argument equal to a list of arguments, delimited by values marks, for the error message

Use this with PROCESS.END = 1 and RECORD.CANCEL = 2 to get desired result.