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.

Check to see if a date is already converted to internal format

IF NOT(NUM(A.DATE)) THEN
      * date is not in internal format, needs converting
      A.DATE = ICONV(A.DATE,X.SN.DATE2)

END

Useful for input validation of dates on things like subroutines and ELF

* 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.

Wednesday, October 9, 2013

Outputting date using OCONV

X.TEXT = OCONV(DATE(), "D") 09 Oct 2013
X.TEXT = OCONV(DATE(), "DDMY") 09 10 2013
X.TEXT = OCONV(DATE(), "DMDYA") October 09 2013
X.TEXT = OCONV(DATE(), "DMDYA3") Oct 09 2013
X.TEXT = OCONV(DATE(), "D4/") 10/09/2013
X.TEXT = OCONV(DATE(), "DWA") Wednesday
X.TEXT = OCONV(DATE(), "DD") 09 
X.TEXT = OCONV(DATE(), "DM") 10
X.TEXT = OCONV(DATE(), "DW") 3 (this is quarter)
X.TEXT = OCONV(DATE(), "DDMY,A,Z4") 09 October 2013


Monday, October 7, 2013

Found this gem in Ellucian's documentation: 2909: Explanation of Rules and Connectives

Colleague
Mnemonic RLDE

The internal documentation on the RLDE Rule Definition screen offers these connectives:

1: WITH With
2: AND And
3: EVERY and every
4: OR Or
5: OREVERY Or every
6: ORWITH Or with
7: OWE Or with every
8: WE With every

Explanation of each connective:

1. WITH
WITH works as a parenthetical AND to start a new true/false condition.

2. AND
AND works with the previous line to determine true or false. The AND statement does *not* start a new parenthetical.

3. EVERY
The EVERY connector evaluates every value within a multi-valued field. Each value in the multi-valued field must equal the defined condition for a true result.

4. OR
OR works with the previous line to determine true or false. The OR connective does *not* start a new parenthetical.

5. OREVERY
Combines the OR and EVERY connectives. As such, it does not start a new parenthetical but works with the previous line to determine true or false. Each value in the multi-valued field must equal the defined condition for a true result.

6. ORWITH
ORWITH begins a new parenthetical to establish a true or false condition. This is in contrast to the WITH connective which is inclusive (AND) whereas ORWITH is exclusive (OR).

7. OWE (ORWITHEVERY)
OWE functions just like ORWITH except that it is used to evaluate multi-valued fields. OWE begins a new exclusive parenthetical and every value in the multi-valued field being evaluated must be equal to the defined condition for a true result.

8. WE (WITHEVERY)
WE combines the WITH and EVERY connectives. As such, it *does* start a new parenthetical. Each value in the multi-valued field being evaluated must be equal to the defined condition for a true result.


To properly build a rule with combinations of OR/AND, keep these facts in mind:

1. The syntax processor within UniData will process AND and OR in the order it finds them from left to right of your sentence. A and B or C or D and E won't necessarily produce the results you expect. For example, if your criteria are as follows:
WITH LAST.NAME EQ 'Smith'
AND STATE EQ 'Virginia'
OR STATE EQ 'Maryland'
OR STATE EQ 'Pennsylvania'
AND FIRST.NAME EQ 'William'

Your result set would consist of persons with last name Smith that live in Virginia and first name William, OR people who live in Maryland or Pennsylvania with first name of William.

2. In the table above, #1 WITH and #2 AND are NOT synonymous and cannot be used inter-changably. They are only inter-changable in a simplest case like A and B and C and D. Here WITH A AND B AND C AND D is the same as WITH A WITH B WITH C WITH D. The key point to remember is that WITH *does* start a new parenthetical while AND does *not* start a new parenthetical.

3. Putting 2 values on the right-hand side of an expression acts as an implied OR. If you want everyone in the states of New York and New Jersey, you can write it as STATE = 'NY','NJ'. This translates as 'with state equal New York OR New Jersey. Note that a comma must be placed between the right-hand side values, which is different than the normal query structure.

4. The best method to get the syntax accurate is to write what you want as a query sentence, being careful to use the word WITH as parentheses around groups. Then use the examples below to create the rule. The second column shows every possible variation of OR and AND with 4 variables. The third column repeats the 2nd, but only uses parentheses when they are necessary to keep the logic accurate.

1 (A and B) and (C and D) A and B and C and D
2 (A and B) and (C or D) A and B and (C or D)
3 (A and B) or (C and D) (A and B) or (C and D)
4 (A and B) or (C or D) (A and B) or C or D
5 (A or B) and (C and D) (A or B) and C and D
6 (A or B) or (C and D) A or B or (C and D)
7 (A or B) or (C or D) A or B or C or D

Here's how the rules should look for each case:
1 A and B and C and D
1st choice 2nd choice (synonymous)
WITH A WITH A
AND B WITH B
AND C WITH C
AND D WITH D

2 A and B and (C or D)
WITH A
AND B
WITH C
OR D

3 (A and B) or (C and D)
WITH A
AND B
ORWITH C
AND D

4 (A and B) or C or D
WITH A
AND B
OR C
OR D

5 (A or B) and C and D
WITH A
OR B
WITH C
AND D

6 A or B or (C and D)
WITH A
OR B
ORWITH C
AND D

7 A or B or C or D
1st choice If you want several values of one variable, use
WITH A WITH variable = 'A' , 'B' , 'C' , 'D'
OR B
OR C
OR D