Back to Main Page

NPR Report Writing Info


** No Warranty is Expressed or Implied with the accuracy of the below data **



UPDATED: 9/3/10
Quick HTML Guide

Browse Manuals

DO Loops
ECB/ECE
Fragmets
Footnotes
Hard Code Selection List
Horizontal Multiples
Line Attributes
Lookup Features
Looping with + / -
Looping with @Next/@Prev/@First
Looping Through Indexes
Macros
MV Arrays
Nursing Module Specifics
Operators
Variables - Report
Rule to start report
Variables - System
Troubleshooting

Z Routines


Useful Reports, Reports Using Advanced Techniques and Tricks


Do Loops   Main NPR Menu

Note: Because the DO loops use @Next, please see the Looping with @Next info for more detail.
Format: DO{@Next(subscript) @desired field}
Or as Joe Cucuzzo (Iatric Systems) describes DO{while_this_is_true do_stuff}
Example 1: Do loop on Pha Room & Bed Index - By Joe Cucuzzo
Example 2: Do Loop in ED patient room history


Example 1 - Pha room/bed index    Main NPR Menu
The below code was presented at MUSE International 2004 by Joe Cucuzzo as a way to generate a "index" of all inpatients from the PHA module room and bed index
""^PHA.PAT.room^PHA.PAT.bed,
DO{@Next(PHA.PAT.room,PHA.PAT.room.bed.x) 1,
DO{@Next(PHA.PAT.bed,PHA.PAT.room.bed.x) 1,
1^/PAT[@PHA.PAT.room.bed.x.]}}
Note: Internal name of room bed index in PHA.PAT is room.bed.x

Example 2 Look through ED room history for patient and see first time not in room    Main NPR Menu
%Z.time.out(IF{"X"^XX,
DO{@Next(room.hx.q) 1,
IF{"X"=XX IF{'@room.hx.room @room.hx.start.time^XX}}},XX})
Report DPM EDM.PAT Detail Segment edm.pat.edm.data
The @room.hx.start.time is stored in the child segment edm.pat.room.history. The subscripts of that segment are: urn,room.hx.q. The urn is provided by the detail segment. Therefore, we do a DO loop on the subscript room.hx.q. The variable XX is set to "X". As long as the variable is X, the loop. If one of the @room.hx.room is nil, that start time is sent to XX. Next process in the loop, XX is now a time not "X", so it stops.




ECB/ECE   Main NPR Menu

ECB - Extra Code Beginning - quick facts
- Inserts code at the beginning of a report line
- Evaluated prior to the line check.
ECE - Extra Code End - quick facts
- Inserts code at the end of a report line
- Often used with ECB to insert a control structure (such as DO loops) into the program.

Reports

Report Examples:
ECE-ECB1-PHA.RX.zcus.hab.ingredients.ece.ecb.html   Full Report    Back to ECB/ECE Start
Uses ECE/ECB to list ingredents.
ECB=@med^PHA.DRUG.mnemonic,    *** (PHA.RX.med=PHA.DRUG.mnemonic)**
ECB=DO{@Next(PHA.DRUG.drug.ingredient,@PHA.DRUG.ingredients) .,
ECE=.},

@Next format: @Next(subscript) or @Next(subscript,segment.name)
In this case, subscript is in segment name PHA.DRUG.dict.ingredients. Name of field
(subscript is: drug.ingredient. Under internal name - it states "ingredients". Add that
to the DPM and name is inteneral is PHA.DRUG.ingredients.

DO structure: DO{condition statment}
The ( .,) represents the "then"/statement portion of a control structure.
DO control structure: DO{condition statement}
The period acts as a space holder.

ECE-ALON.PP.PAY.zcus.hab.foundation.donat.info.html   Full Report   Back to ECB/ECE Start
This report goes through PP.PAY and produces a date when the withholding was first withheld, within the date range for the report. The AL D checks to see if DATE has a value. If not, it knows it is the first date and puts the value into DATE. The ECE which works at the end of the line, then puts "" into Date. "" is not equal to 'DATE and subsequent values do not print.2
 Footnote:AL D IF{'DATE @pay.date^DATE} 
 Computed field: xx.first.date       
                 DAT=DATE       
                 LEN=8       
                 VAL=DATE     
 Line attribute on the line with the computed field:  ECE=""^DATE


OE.ORD.zcus.hab.order.activity.pt.date Back to ECB/ECE Start
Detail Segment: Main    Index File: pt.ord.x
ECB=""^QUE,DO{+pha.pcs.dose.instructions[urn,QUE]^QUE .,
ECE=.},


Using ECB/ECE to list child segment of different segmentBack to ECB/ECE Start

Report Name: RXM.RX.zcus.hab.print.fax.audit.hard
DPM: RXM.RX SEGMENT: rxm.medications Subscripts of segment: urn
The print audit trail is in a sibling segment: rxm.rx.print.audit.trail.
The subscripts of audit trail segment are:
[print.audit.urn,print.audit.date,print.audit.time,print.audit.seq]
The subscript urn contains the same data (is a link) to the subscript print.audit.urn
Therefore, the ECB code sets the @urn to first subset, nills out the next one and then starts looping. Note before each subscript, the value is nilled. The 1st subscript is set, the 3 remaining are looped.
This code is entered in a line check

ECB=@urn^print.audit.urn,""^print.audit.date,DO{@Next(print.audit.date) 1,
ECB=""^print.audit.time,DO{@Next(print.audit.time) ""^print.audit.seq,
ECB=DO{@Next(print.audit.seq) .,
ECE=.}}},

On the line where this attribute exist (in this case detail), simply list the fields you wish to see on the report.



Using ECB/ECE to list user selected LI input when report started Back to ECB/ECE Start
If a LI operator is used in a report, it is helpful to list items user selected. This example is for SCH.APPT. The field the user is selecting on is @resource. One or several entries could be selected. A Line Check is entered in the HR region with the following code:
ECB=""^XXX,DO{+c.resource[XXX]^XXX .,
ECE=.},
Note A "+" is used and c.resource (no @)
A computed field is also needed. It is placed on the same picture (Same HR line as the line check)
xx.resource: DAT=FREE, FJY=L, LEN=15, VAL=XXX



Fragments   Main NPR Menu

Basics   Top of Fragments   Main NPR Menu


Types of Fragments   Top of Fragments   Main NPR Menu
Joel Berman's Classification: 3 Types of fragments. Click on each fragement type to see examples.

Type 1 - Retrieve Data    Back to Fragment Types   Top of Fragments   Main NPR Menu
This type of fragment stores data into a variable and returns the data to the main report.

Report Examples
  1. ADM.PAT.zcus.jfb.ss02.frag.1
  2. Payroll - report
  3. MIS.USER.zcus.hab.access.by.module.fast Uses method for faster fragments


Fragment Type 1 - Example 1 - Retreive data - ADM.PAT.zcus.jfb.ss02.frag.1
Three Reports: 1 Main & 2 fragments:
Frag Type 1 -Example 1 - Main Report - Retrieve Data    ABS frag    BAR frag    Top of Fragments    Main NPR Menu

Fragment Type 1 - Example 1 - ABS Fragment: Retrieves Data Fields    Main Report-Type 1 Frag    BAR frag    Top of Fragments    Main NPR Menu

Frag Type 1 - Example 1 - BAR Fragment: - Retrieves Multiple Data Fields    Main Report-Type 1 Frag    ABS frag    Top of Fragments    Main NPR Menu


Fragment Type 1 - Example 2 - Retreive data NAME OF REPORT:

Fragment Type 1 - Example 3 - Retreive data - Fast
MIS.USER.zcus.hab.access.by.module.fast

This report puts the data into an array and then goes to the fragment only once. Much more efficient
Macro Below is the macro code. The check on the XX means this only runs once.
IF{XX;
   1^XX,
   %Z.rw.fragment("PP.PER.zcus.hab.frag.mis.user.fast.R","PP.NCH")}
Note: The report also needs to be modified. It has an extra select and custom field xx.flag
DAT=YN
JFY=L
LEN=1
VAL=IF{1^/R.INIT[@initials],"Y"}
The field in the brackets [@initials], is the field you pass to the fragment.
Selects on page 2
xx.flag             EQ
    "Y"
Note- Fragment report select contains a LI !!
1  xx.emp.initials       LI
        /R.INIT
Macro in fragment - The values are then stored into a value that is subscripted. @sort.name^/R.FRAG.VAL[@cd.response["MIS.USER"],"NAME"]
Computed fields on main report
The fields are then also subscripted.
VAL=/R.FRAG.VAL[@initials,"PPJOB"]
The fast way of doing this works well as long as the field being retrieved isn't a multiple.

Fragment Type 2 - Show/Print Data    Back to Fragment Types   Top of Fragments   Main NPR Menu
This type of fragment prints data. Easy to write. Sends detail lines from fragment to main report.

Report Examples
  1. ADM.PAT.zcus.jfb.ss02.frag.2


Frag Type 2 - Example 1 - Print Data (1 main, 2 frags)

Frag Type 2 -Example 1 - Main Report Info - Print/Output Data    BAR frag    ABS frag    Top of Fragments    Main NPR Menu


Frag Type 2 - Example 1 - BAR Fragment - Print/Output Data    Main Report-Type 2 Frag    ABS frag    Top of Fragments    Main NPR Menu

Frag Type 2 - Example 1 - ABS Fragment - Print/Output Data    Main Report-Type 2 Frag    BAR frag    Top of Fragments    Main NPR Menu



Fragment Type 3 - Sorting and Selecting Data    Back to Fragment Types   Top of Fragments   Main NPR Menu


Report Examples
  1. ABS.DRG.zcus.jfb.ss02.top.ten
  2. Add More Here
ABS.DRG.zcus.jfb.ss02.top.ten (2 reports - Main and Frag
Frag Type 3 - Example 1 - Main Report - Sorting and Selecting Data    ABS frag    Top of Fragments    Main NPR Menu
Frag Type 3 - Example 1 - ABS Fragment - Sorting and Selecing Data    Main Report-Type 3 Frag    Top of Fragments    Main NPR Menu









Footnotes    Main NPR Menu
Footnotes are used to execute code at a specific point in the report's compile process.
Format: {footnote}{space}{expression}
Footnote Function
AL The AL footnote is used to incorporate logic into report object code at a point specified by a keyword. Format: {footnote}{space}{keyword}{space}{expression}
RC The RC footnote is used to specify a condition which must be met in order for a record to be printed on the report. This works similar to a select condition.
Example 1: PBR.MPI.VIS.zcus.hab.dup.visits  Full Report
This report checks to see if a patient appears on a list more than once.
It uses the code: xx.select EQ 1 and a footnote: RC /PT[@mpi.urn].
xx.select=VAL=IF{'/PAT[@mpi.urn] 1^/PAT[@mpi.urn];1^/PT[@mpi.urn];1}
Example 2: NUR.RAI.zcus.hab.frag.last.mds.sch. Since client server, report not uploaded
Report loops through all the patient's MDS reports. However, it returns the last one that meets the specified criteria. In this case, the last one that is not any of the values listed below.
xx.last
VAL=IF{""^AA8AF^AA8BF,@aa8a.primary.reason^AA8AF,
VAL=@aa8b.special.code.reason^AA8BF=8 1;
VAL=(AA8AF=4)!(AA8AF=6)!(AA8AF=7)!(AA8AF=8)!(AA8AF=9)!(AA8AF=10) 1;
VAL=urn^/PAT[patient],1}
urn is the MDS specific #. The code keeps looping through and replacing the urn value for the /PAT[patient]
In the Selects, xx.last EQ 1 (Based on code, all patients return a value of 1). However, the footnote has a record check: RC urn=/PAT[patient] Therefore, the line only prints if the urn is the same as the last urn processed which was stored in the variable (met the criteria).
Key points for example 2
1) The sort order must be changed. It can not be the index default sort order. This causes the report writer to process all the records before it starts to print.
2) The xx.last can not be placed on the detail line.

Example 3: BAR.PAT.zcus.hab.hab.frag.ins.cov.dates.mds
This report looks and find the last date that is less than the user inputed dated (brought from another report as /R.DATE
xx.keep: VAL=IF{@zcus.l.ic.eff.date'>/R.DATE zcus.l.ic.eff.date^/DATE[account],1;1}
Footnote: RC zcus.l.ic.eff.date=/DATE[account]
Select: xx.keep EQ 1
If the date (zcus.l.ic.eff.date) is less than or equal to the /R.DATE, then put the date into an array with the account number as the subscript. Then output a value of 1. If the date isn't less, output a value of 1. Key point, the array is continually being overwritten by the next date that meets the criteria. If a patient does not meet the criteria, then the date isn't stored into the array. The RC in the footnote checks what is stored.
The select is xx.keep EQ 1 is a way to keep the field and not print it on the report.
The RC reads: if the zcus.l.ic.eff.date is the one that is stored in the array, print.

EFF The EFF footnote is used to suppress the ending form feed on a report. This is used when downloading a report. The default is YES. Using EFF NO will suppress the formfeed.
SFF The SFF footnote is used to suppress the starting form feed on a report. This is used when downloading a report. The default is YES. Using SFF NO will suppress the formfeed. The starting form feed can also be suppressed for all reports by setting N in the R/W STARTING FF parameter within MIS.
RL The RL footnote is used set the record length on a report. This is used when downloading a report in conjunction with the new line (NL) line attribute. Allows for record lengths longer than the standard 200 CPL limit within NPR Report Writer.
FD The FD footnote is used to define a field delimiter when downloading a report whose records are of variable length. The expression is the numeric value associated with the ASCII character. FD 59 will produce a record in which each field is delimited by a semi-colon.
MSEL The MSEL footnote is used to specify select criteria for a multiple (a field from a child segment of the detail segment). Format:{footnote}{space}{data field}{space}{keyword}.
See MEDITECH KB#4628
Footnote Format: MSEL @child.segment.field test.method.keyword Example: MSEL @allergy NONE
Choices for keywords are either: ANY, NONE, ALL
In the selects on page 2, the same field as after MSEL would appear (i.e. @allergy EQ "WORK"
ANY - the parent record is selected if ANY of its child records pass. - Any have work
NONE - the parent record is selected if NONE of its child records pass. - Non have work
ALL - The parent record is selected if ALL of its child records pass.
GR The GR footnote is used to establish a graphics template for the report. This footnote is not needed as graphics are defined within the line attributes.



Keywords for use with the AL Footnote
The AL footnote is used to execute a line(s) of code at a specific point in the report's compile process. The KEYWORD specifies the point in the object code in which the code will be inserted. Most often this technique is used to incorporate a report macro into your NPR Report. The format of this footnote is as follows:

AL KEYWORD macro.name
AL KEYWORD line.of.code

Keyword Where Macro Code is Inserted
START At the beginning of the program, prior to any selections being performed.
PRINT After the printer has been opened. Must be at the 4.6 release and have NPR Change 89.
SKn (e.g. SK1 = Sort Key 1) After the looping code has been generated for the specified sort key. Note the difference between HKn (region.name) and SKn. With HKn, if no detail records are found for a sort key, the HKn region is not printed and the macro logic is not performed. Alternatively, with SKn, the macro logic is performed for every occurrence of the sort key, regardless of whether any detail records exist.
AFTER.GET.MAIN After the detail segment has been processed, but before multiples have been processed.
BEFORE.PRINT After all data has been gathered, records have been selected and multiples have been processed.
region.name (e.g. D, HK1, TR, etc.) Just before the lines in the associated region are printed.
AFTER.region.name (e.g. AFTER.D, AFTER.HK1, AFTER.TR, etc.) After the lines in the associated region are printed.
CLOSE.UP After the report has been printed, but before Z.rw.close.up has been executed, and the prefixes are closed.









Hard Code Selection List   Main NPR Menu
Example; PBR.BCH.zcus.hab.proc.codes.health.maint

1) In footnotes, enter footnote: AL START buildlist
(AL stands for algorhythm), START tells computer where to do this.

2) Go to macro, create macro, same name as above. ie- buildlist
1^/LST["2EAST"],
1^/LST["2WEST"],
1^/LST["FC"]
(The reason use 1^/LST - is we "need to create something in mailbox. If no value, MEDITECH will not create.)
** Every line has a comma EXCEPT last line is blank

Then go to Select (page 2) - enter field selecting
Example:
@location         LI
/LST


Horizontal Multiples   Main NPR Menu

Reference: MEDITECH MIX - April 2002
Goal: Print multiples horizontally instead of vertically.
Method: Concatenating values into a local variable.
Problem: Line length. If concatenated list does not fit on one line, data is lost
Solution: Build array and print values on separate line.

Method 1: When concatenation does not cause line overflow (easy method)

Method 2: When concatention exceeds line length (using array)



Method 1: When concatenation does not cause line overflow (easy method)    Back to Horizontal Multiples    Main NPR Menu

Example 1 (MEDITECH - CDS)      Example 2 (PHA.RX)      Example 3 (BAR.PAT - Double Loop)   

EXAMPLE 1   Back to Method 1  Back to Horizontal Multiples
Plan: Print mnemonic responses from a CDS that is a multiple (MEDITECH example).
Query name: FLUSYMP
Description
Create a custom field - in this case - xx.flu
DAT=FREE
LEN=30
VAL=IF{"FLUSYMP"^cd.query,""^cdm.seq.no^FLU,DO{@Next(cdm.seq.no) FLU_", "_
VAL=@cdm.response^FLU},FLU%1}
Explanation:
The field xx.flu loops through the multiple query responses for the query FLUSYMP. This query is a group response type query and stores a mnemonic of a flue sympton. The VAL statement starts by identifying what query will be looped ("FLUSYMP^cd.query).

Next, clear out the looping variable. Key point: This is the subscript of the segment that stores all of the responses. we also clear out the variable FLU. This varible will hold the output string of all the symptoms (""^cdm.seq.no^FLU)

With the query defined, and both the looping variable and the output variable initialized we then can start to loop through all of the responses. The DO control structure loops on the cdm.seq.no subscript and concatenates the variable FLU with a comma and a space and then concatenates the response to the query. This is done for each response and the ending value of FLU is all responses with a comma and a space between them. We then output this value. Since FLU was nil during the first iteration of the loop, the value of FLU starts with a comma and a space. To remove the beginning comma and space, we use string extraction to start printing at the first response.


EXAMPLE 2  Back to Method 1  Back to Horizontal Multiples
Report Title pha.rx.zcus.hab.test.horz.mul
Detail DPM PHA.RX     Detail Segment pha.rx.file
Index DPM PHA.RX     Index File pha.rx.start.date.x

Method Create a custom field - in this case - xx.additive
DAT=FREE
JFY=L
LEN=70
VAL=IF{""^IVADD^additive.q,
VAL=DO{@Next(additive.q) IVADD_" "_@additive_" "^IVADD},
VAL=IVADD%1}
Place field on detail line. Multiples print across page.

EXAMPLE 3  Back to Method 1  Back to Horizontal Multiples
Report Title: BAR.PAT.zcus.rsg.avatar.survey.1.mt
Detail DPM BAR.PAT     Detail Segment bar.acct
Index DPM BAR.PAT     Index File bar.acct.discharge.date.index

Method Create a custom field - in this case - xx.rev.coe
DAT=FREE
JFY=L
LEN=120
VAL=IF{""^OUT^bill.no,DO{@Next(bill.no) ""^chg.cat,DO{@Next(chg.cat)
VAL= OUT_(chg.cat$3)^OUT}},OUT}

Note: This example's final goal is the grandchild segment. Example 2 above Pha.rx went to additive, child segment. When going to a grand child segment, two DO loops are needed. One to first sort through the child segment, other one to loop through grandchild segment.
Hierarchy of BAR.PAT
. bar.acct
.. bar.acct.bills
... bar.acct.bills.chg.categories




Method 2: When concatention exceeds line length (using array)     Back to Horizonal Multiples     Main NPR Menu

Two Examples: "Example 1- CDS group name"      Example 2 - IV additives
Live examples:
BAR.PROC.zcus.hab.test.med.nec.diag.horz.90
PHA.RX.zcus.hab.test.horz.mult.array

Example 1- CDS group name Back to Horizonal Multiples    Main NPR Menu
Plan: Print mnemonic responses from a CDS that is a multiple.
Query name: FLUSYMP
Query Name Group Response: FLUSYMPT

Because we are printing the complete group name, it exceeds the original 40 characters. Therefore an array is used.

Description
Create a custom field - in this case - xx.flu
DAT=FREE
LEN=30
VAL=IF{"FLUSYMP"^cd.query,""^cdm.seq.no^FLU,DO{@Next(cdm.seq.no) FLU_", "_
VAL=@MIS.GROUP.RESP.element.response["FLUSYMPT",@cdm.response]^FLU},FLU%1}
Explanation:
Above code pulls the name, not mnemonic, of the flu symptom. Build an array to generate multiple lines of text.
Array: Consist of variable name and a subscript whose value will be equal to a string of responses.

Macro which generates multiple lines of text
; ; nil out our /FLU array so we don't carry over values from one record to the next.
DO{+/FLU[SUB]^SUB ""^/FLU[SUB]},
;set the value of the query, nil out the cdm.seq.no, set one to our array subscript.
"FLUSYMP"^CD.QUERY,
""^cdm.seq.no,
1^CT,
; loop on the query response multiple
DO{@Next(cdm.seq.no) @SET}

*** extra note - notice no semi colon - needs a space before SET SET
; load the name associated with the query response intot he variable RSP
@MIS.GROUP.RESP.element.response["FLUSYMPT",@cdm.response]^RSP,
;
;Check the length of our current array value concantenated with a comma,
;a space and the current response.
;If the length of this new value has less than 32 characters, then concatenate a comma,
;a space and the response to the current array value
;
IF{L(/FLU[CT]_", "_RSP)<32 /FLU[CT]_", "_RSP^/FLU[CT];
;
;If the value is 32 or maore characters in length, place a comma at the end of the current
; array value and increment our array subscript to build a new value into the array
;
/FLU[CT]_","^/FLU[CT],
1+CT^CT,/FLU[CT]_", "_RSP^/FLU[CT]}
;end of macro

Note: MEDITECH's website does not mention the footnote.
A footnote needs to be added to invoke the macro. Therefore, if the macro's name is "get", the footnote is AL D get

For Sally Smith's record, the macro above builds an array which looks like:

/FLU[1]=, COUGH, RUNNY NOSE, FEVER,
/FLU[2]=, ACHES AND PAINS, WATERY EYES,
/FLU[3]=, CONGESTION, CHILLS

To print the first line of the array, we build a computed field which prints on the first detail line. The computed field above will print the first line of the array. /FLU[1] contains , COUGH, RUNNY NOSE, FEVER. We want to remove the comma and space from the front. We do this via the string extraction statement /FLU[1]%1. A comma is concatenated to the end if there is a value in the second array to provide a better appearance to the output. The next thing we need to do is to print the rest of the array. To do this, we use a second detail line and add ECB and ECE line attributes to loop through our array. We set our looping variable of QUE to 1 so that the first iteration of the DO loop will cause QUE to become 2 (we already printed the first line of the array so we want to start printing at the second line). The DO loop will loop through the array until the value of QUE becomes nil. For Sally Smith's record, the loop will be performed two times to process lines 2 and three of the array.

xx.flu Note: Needs to be changed from above. Macro now pulls data. Field's purpose now is to print array.
DAT=FREE
JFY=L
LEN=30
VAL=/FLU[1]%1

Example of page 3 of report
D     name___________ xx.flu_________________________
D                                    xx.flu2________________________

One the 2nd detail line, we needed to put in a ECB line attribute
Edit Line Attribute
ECB=1^QUE,DO{+/FLU[QUE]^QUE .,
ECE=.},


Last step - Create xx.flu2 field.
xx.flu2
DAT=FREE
JFY=L
LEN=30
VAL=/FLU[QUE]%1
The above code will print the value of the array for the QUE variable which gets set in the ECB and ECE line attribute.


Example 2 - IV additives   Back to Horizonal Multiples    Main NPR Menu

Report name: PHA.RX.zcus.hab.test.horz.mult.array
Detail DPM PHA.RX     Detail Segment pha.rx.file
Index DPM PHA.RX     Index File pha.rx.start.date.x

Steps:
  1. Create footnote: AL D ivadd - this footnote will call the macro
  2. create macro

    Enter/Edit Macro Logic: PHA.RX.zcus.hab.test.horz.mult.array.M.ivadd
    ; nil out our /IVADD array so we don't carry over values from one record to the next.
    DO{+/IVADD[SUB]^SUB ""^/IVADD[SUB]},
    ;set the value of the query, nil out the additive.q, set one to our array subscript.
    ""^additive.q,
    1^CT,
    ; loop on the query response multiple
    DO{@Next(additive.q) @SET}

    SET
    ; load the additive into the variable RSP
    @PHA.RX.additive^RSP,
    ;
    ;Check the length of our current array value concantenated with a comma,
    ;a space and the current response.
    ;If the length of this new value has less than 70 characters, then concatenate a comma,
    ;a space and the response to the current array value
    ;
    ;If the value is 70 or maore characters in length, place a comma at the end of the
    ;current array value and increment our array subscript to build a new value
    ; into the array
    IF{L(/IVADD[CT]_", "_RSP)<70 /IVADD[CT]_", "_RSP^/IVADD[CT];
    /IVADD[CT]_","^/IVADD[CT],
    1+CT^CT,/IVADD[CT]_", "_RSP^/IVADD[CT]}
    ;end of macro

  3. Create fields

  4. Put fields on report - See below. Notice how xx.add2 is directly below xx.additive.

    D       patient's.name________________ number_____ med_______
    D         xx.additive___________________________________________________________
    D   *    xx.add2_______________________________________________________________

  5. Enter line attribute Line: xx.add2
    ECB=1^QUE,DO{+/IVADD[QUE]^QUE .,
    ECE=.},




Line Attributes    Main NPR Menu
Functional Attributes    Back to Attributes Menu    Main NPR Menu
AttributeDescriptionFunction Format
LC Line Check Conditional Printing of Line LC=expression
LCR Line Check Range Conditional Printing of Range of Lines LCR=expression
LS Line Space Generate Blank Line(s) LS=number of blank lines (1-50)
NL New Line Suppresses the Generation of a New Line NL=NO
PG Page Break Generates a Page Break when the number is greater than the number of lines left on the page PG=number
MCON Multiple Condition Conditional Printing of Multiples MCON=segment,expression
If all multiple data fields exist in the same segment, an asterisk (*) can be used for the segment. Otherwise, the internal name of the segment should be specified.
MWM Multiples-Within-Multiples Allows the Printing of Multiples from Grandchild Segments MWM=data field from grandchild multiple
ECB Extra Code Beginning Inserts a Line of Code Before the Printing of a Line ECB=expression
ECE Extra Code End Inserts a Line of Code After the Printing of a Line ECE=expression
MV MV Array Used in the Printing of Values from a /MV Array MV=mv name
The mv name is the first subscript of the MV array


Display Attributes   Back to Attributes Menu    Main NPR Menu
BX Box Draws Boxes Around Portions of the Report BX=argument
The arguments are W - WHITE, G - GRAY and END. The box will begin in the middle of the line it is placed and therefore should be placed on a blank line. Boxes begin one character to the left of the left margin and end one character to the right of the right margin. If you begin a second box without ending the current box, the current box is automatically closed before the new box begins.
FF Field Font Defines the Font in which Data Fields Print FF=font type
The font types are:
b - bold B - underscored bold
i - italic I - underscored italic
n - normal U - underscore
GB Gray Bar Establishes Alternating Gray Bars on a single report picture line. GB=first color
The colors are W - WHITE and G - GRAY
GBR Gray Bar Range Establishes Alternating Gray Bars for a Range of Lines GBR=first color
The colors are W - WHITE and G - GRAY. END is also valid to end the gray bar range
GH Gray Highlights Highlights a Portion of a Report Line GH=Bn,Dn,column,length,Bn,Dn,column,length,...
Bn Defines a border box of density n (integer) around the highlighted area. This argument is optional and should only be defined if you want a border.
Dn Defines the density of the highlighted area. n is a number from 1 to 100 where 1 is the lightest and 100 is black. The default is 10. This argument is optional and should only be defined if you want to change the density.
column The starting column of the highlight. (decimals are valid - 1.5 starts halfway between the first and second columns)
length The length of the highlight
HL Horizontal Line Draws a Horizontal Line Across the Report HL=density (an integer, 1 being the thinnest)
PF Prompt Font Defines the Font in which Free Text Prints PF=font type
The font types are:
b - bold B - underscored bold
i - italic I - underscored italic
n - normal U - underscore
US Underscore Underscores a Portion of a Report Line US=column,length,column,length
column The starting column of the underscore. This value is an integer.
length The length of the underscore
VL Vertical Line Draws a Vertical Line(s) VL=density,column,column,....
density (an integer, 1 being the thinnest), the columns define where the vertical line will be placed (decimals are allowed). This attribute can only be used if a BX attribute is defined on the same line. VL=END is used to end the vertical line.


Field Attributes   Back to Attributes Menu    Main NPR Menu

Formatting Field Attributes
Field Attributes Description Function
DAT Data Type Defines the output format of the field.
DEC Decimal Overrides the default number of decimal places of the Data Type.
JFY Justify Indicates the justification within the field length (L, R, or C).
LEN Length Defines the length of the field's output.
FONT Font Graphics Defines the graphic font (bold, italic, etc.) of the field's output.
MEDITECH Standards: B (bold underlined), b (bold), I (italics underlined), i (italics), N (normal underlined), n (normal)

Note The values B, b I, i, are variables. User can overwrite those variables or make own variable. The key is the system knows when user puts FONT=b, It is interpreted as /R.F["b"]
Example - Print medication schedule as bold if med's control schedule = 2
DAT=FREE
FONT=BOLD
LEN=4
VAL=IF{@med's.schedule="2" /R.F["b"]^/R.F["BOLD"],@med's.schedule;
VAL=/R.F["n"]^/R.F["BOLD"],@med's.schedule}
In this example. FONT=BOLD is a variable. If the med's schedule = 2, then /R.F["b"] is written into the variable BOLD, otherwise the normal font is written into the variable BOLD.
SIZE Font Size Defines the characters per inch in which the field is displayed.
COMMA Comma Adds commas to numeric fields: COMMA=Y
TRUNC Truncate Useful if have limited space on picture, but need to squeeze in more text. Example:
DAT=FREE
JFY=R
LEN=58
SIZE=0.6
TRUNC=NO
VAL=/REPORTNAME_" "_/INTERVENTION
In this case, the variable report name + variable intervention are about 80 characters. One can "fool" the report writer into printing all 80 characters. If I did not use TRUNC, even though the size it 0.6, it would still stop printing after 56 characters.



Content Field Attributes
Field Attribute Description Function
CON Condition Defines a condition which must be met in order for the fields value to print.
FNC Function Specifies the function of the field.
Function Description
LST Last Value - Very useful when have a series of values arranged by date (price updates) and you want the last entry Attribute: FNC=LST
AVG Mean Average
CNT Count Entries
MOD Mode
TOT Numeric Total
MED Median Value
MAX Maximum Value
SD Standard Deviation
MIN Minimum Value
VAR Variance
FST First Value
RLOG Report Logic Used to perform logic at the time a standard field is retrieved from the database.
VAL Value A computed/virtual field's output value.
WITH With Changes the region in which a statistical field gets evaluated.
Example 1 PBR.MPI.VIS.zcus.hab.charges.by.visit.type.no.d Full Report
DAT=SMONEY, FNC=TOT, JFY=R, LEN=10
VAL=IF{0^TOT,""^vt.urn,DO{@Next(vt.urn) @vt.total.amount+TOT^TOT},TOT}
WITH=D
Example 2 LAB.L.SPEC.zcus.hab.glucose.er.sdc.rad Full Report
This report looks glucose lab results > 160. However, it only counts 1 per person (even if they had multiple results >160).
Uses WITH=HK2 because the 2nd sort is patient's.name. Note FNC=TOT
FLD=xx.patients, DSP=xx.pa ,DAT=INT, FNC=TOT, JFY=R, LEN=7, VAL=1, WITH=HK2
PRT Print (Y/N) Used to suppress the printing of a computed field on a report: PRT=N
GRP MIS Group ResponseGives the ability to use a MIS group response to limit possible entries a user can enter.
Computed field: xx.room.bed - This field compares patient room to users desired room. Also see select
DAT=FREE
GRP=ROOM.BED   (This is from the MIS Group Response Dictionary. In that dictionary each room is listed as a mnemonic: 203-1, 204-1)
JFY=L
LEN=10
VAL=@patient's.room.bed

Select
xx.room.bed                                LI
     Room-bed (Example: 203-1)

When user runs report, they can press the F9 key and get a lookup of all rooms and beds that were make in the MIS Group Response Dictionary.



Lookup Features    Main NPR Menu

Meditech has several ways of looking up information on fields and segments.

For Use In Any Standard Field Area
S\ and pressing <Lookup> will open up a viewer to see segment report is written. Example: DPM = PHA.RX, common segment: pha.rx.file. S\ would show the child segments of that segment. It does not show grand child segments. For that reason,it is somewhat limited.

S\DPM Example: S\PHA.RX and pressing <Lookup> will open a viewer for the DPM named PHA.RX. Key point: This view shows the complete hierarchy. You can see parent, child and granchild segments. Therefore, the S\ is much more useful when user specifies the DPM. Note: Even though report is in PHA.RX, user could type S\ADM.PAT press lookup and view the DPM.

For Use In Computed Fields Only
* User must be in a computed field and press the <Lookup> button before entering below lookups.
X\ = Enhanced lookup of segments and DPMs where the report is written - Similar toS\DPM above.
X\DMP= Enhanced lookup of segments and DPMs of the specified DPM (can be any DPM in system)

In addition, user can lookup general information about a DPM. Again, user must be in a computed field.
D\DPM/I> = DPM Information lookup (display only)
Example: D\PHA.RX/I <Lookup> This will produce a lookup. Other DPM will also be alphabetically sorted after the typed DPM.

element/I - Element Information Lookup
Example: If looking for field info on the field @user, from a lookup box, type in "user/I" and press <Lookup>. A popup box will appear of selections to choose.

Lookups When Choosing Detail Segment Or Index File
A<Lookup> This will look at all the segments or index files in the DPM. Not just those the report writer selects automatically.

Using Special Function Key When Selecting A Segment Or Index File.
In MAGIC only. When performing a lookup for a detail segment or an index file, the user can enter the number associated with the segment or file and they press Enter, they can press the Special Function Key (Right Control Key). This will display specific info regarding the segment or index file. This is very useful to see the subscripts of an index file.



Looping with + / -   Main NPR Menu

Report Examples:
Using + PHA.GENERIC.zcus.hab.not.used.in.pha.drug   Full Report
Using - BAR.PROC.zcus.hab.proc.exploded.chgs.by.mnemonic (Finds last effective charge date)

Macro: %Z.zcus.hab.M.paint.skin.1.doc Looks at 1st value of built array

+ Steps forward through data structure (Logical Next), - Steps backwards through data structure
*** Need to use "internal name" ***


Structure: +data structure variable^variable - Often used in control structure.
Examples:
/temp[X]^X

Report: PHA.GENERIC.zcus.hab.not.used.in.pha.drug Full Report
Report to check to see if a generic mnemonic in the generic dictionary is used by the pha drug. Key point: @PHA.DRUG.generic.x is the internal segement name of index in PHA.DRUG.
PHA.DRUG index info
Index Name/Internal Name/Detail Seg   Physical Base/Subscripts/Detail Segment Internal Name
------------------------------------  ---------------------------------------------------
pha.drug.dict.generic.index           &TFG[tdg,tf] = active
generic.x                             [generic,mnemonic]
pha.drug.dictionary                   main

Code:
VAL=IF{+@PHA.DRUG.generic.x[mnemonic,XXX] "Y"}

Important:  The [mnemonic] above is referencing the Generic Name mnemonic in PHA.GENERIC dictionary
(mnemonic in PHA.Generic = generic in PHA.DRUG).
mnemonic                      10 FREE      L                  tdg
It is being used to seed the [generic,mnemonic] subscripts in the pha.drug.dict.generic.index. 
Report: BAR.PROC.zcus.hab.proc.exploded.chgs.by.mnemonic
Two Examples Note report is written in detail segment replace codes. Once it finds a replace code, it looks up the code (in the parent segment) to determine last date and charge
Last Effective date: VAL=-std.effective.dates[@replace.code,@.today+1]
Last Effective Charge: VAL=@std.effective.date.charge[@replace.code,
                                       VAL=-std.effective.dates[@replace.code,@.today+1]]

Data Structure for Detail segment SUBSCRIPTS: [mnemonic,replace.code]
Data Structure for Charge Info SUBSCRIPTS: [mnemonic,std.effective.date], INTERNAL NAME: std.effective.dates
In the above example, we are using the replace code as the mnemonic subscript and then telling it to look at the date which would come after today (would always be the last one). The "-" basically steps back through the structure.


Report: BAR.PROC.zcus.hab.proc.exploded.chgs.by.mnemonic
Looping at an Array built in Macro Macro: %Z.zcus.hab.M.paint.skin.1.doc
Looks at 1st value of built array in EDM macro. Then get's 1st value. Example of stepping through structure but not doing a DO loop.
Array is built by:
 IF{FND3 FND3^/EDM[3,EDM.PAT.ta.date,EDM.PAT.ta.time]}

Finding 1st result: basically put in each subscript. Uses +/EDM, but NOT DO{+/EDM...
+/EDM[1,""]^DATE,
+/EDM[1,DATE,""]^TIME,
IF{/EDM[1,DATE,TIME] "EDM: "_%Z.date.out(DATE)_" "_/EDM[1,DATE,TIME]^EDM1},
Looping with @Next/@Prev/@First   Main NPR Menu

Report Examples: - @Next 4 Examples
Report Examples: - @Prev 2 Examples
Report Examples: - @First 3 Examples

@Next examples
Example #1: Report:
PBR.MPI.VIS.zcus.hab.charges.by.visit.type.no.d   Full Report
Detail Segment: pbr.mpi.vis.visits
Information desired: in child segment: pbr.mpi.vis.transactions. Did not wish to list all transactions
Subscripts: [mpi.urn,visit.urn,vt.urn]
Current detail segment gave subscripts of mpi.urn and visit.urn.
Format: DO{@Next(subscript) @desired field}
Note: Do statement is in an If Statement. Full code below
DAT=SMONEY
FNC=TOT
JFY=R
LEN=10
VAL=IF{0^TOT,""^vt.urn,DO{@Next(vt.urn) @vt.total.amount+TOT^TOT},TOT}
WITH=D

@Next example
Example #2 This report starts in PHA.RX and checks to see if the user who entered the order is a RPh.
It does this by looking in the PHA.ACCESS
Report Name: PHA.RX.zcus.hab.test.user.rph
Detail Segment: PHA.RX.pha.rx.file
Detail Segment where pharmacist specified: PHA.ACCESS.pha.access.dict.users (internal name: users, Subscripts [mnemonic,user])
Note: This is a child segment of PHA.ACCESS.pha.access.dictionary (internal name: main, Subscript: [mnemonic])
Uses AL D macro and returns value of @pharmacist to variable "P". Macro info below
IF{@enter.user^EU,""^PHA.ACCESS.mnemonic^P,
   DO{@Next(PHA.ACCESS.mnemonic,PHA.ACCESS.main) ""^PHA.ACCESS.user,
                                                 DO{@Next(PHA.ACCESS.user,PHA.ACCESS.users) 1,
IF{@PHA.ACCESS.user=EU @PHA.ACCESS.pharmacist^P}}},P}
Above is formated as macro editor format places text.
Interpretation: @enter.user is person entering order. Need to first loop through the access dictionary mnemonics. Therefore, nil out the subscript for the first segment.
Format: DO{@Next(subscript,segment internal name)>BR? Note: need to specify PHA.ACCESS because it is in a different DPM.
Once first loop finds an item, it proceeds to 2nd loop - though the child segment
Subscript of 2nd segment is niled out. Same format as above. Note how internal name is used for segment.
Once it finds a user, it checks it to the variable, if so the field data is stored in variable P


@Next example
Example #3 - Report: MRI.ICR.zcus.hab.completed.date.user
Report determines what records were completed for specific date and then loops through audit trail to determine who and when completed. Sorts by time completed determined from audit trail.
Detail Segment mri.incomplete.records = Subscripts: [prefix,record,acct]
Index File mri.icr.date.completed.index = Subscripts: [prefix,date.complete,record,acct]
Segment for audit trail: mri.icr.audit.trail = 4 Subscripts: [audit.prefix,audit.record,audit.acct,audit.queue]
Note: First 3 subscripts are same as detail segments subscripts. Different names, but same values. Therefore, only need to loop on last value.
xx.check VAL=IF{""^AU,DO{@Next(audit.queue) IF{@audit.act="CP"&
VAL=(@audit.date=@date.complete)&(@audit.user=@.user) 1,
VAL=@audit.time^AU}},AU}
In Selects have xx.check NE ""

The RESULT of an IF control statement is always the value of the last expression evaluated.
The RESULT of a DO control structure is always nil.
- Therefore, needs to be put into a variable



Example #4 - Report: EDM.PAT.zcus.hab.ped.patient.reviewer
Report loops through the documentation to pull back the lastest query results for certain queriers.
Detail Segment: edm.pat.edm.data
Used main data segment because only wanted it to print the patient once. Any lower, would have added lines to each documentation.
Data Structure - with subscripts
.edm.pat.edm.data [urn]
.. edm.pat.interventions [urn,ta.intervention]
... edm.pat.intervention.doc [urn,ta.intervention,ta.date,ta.time,ta.ctr]
.... edm.pat.intervention.results [urn,ta.intervention,ta.date,ta.time,ta.ctr,ta.query]

Queries were identified to report. Therefore, had to loop through to get to correct area
Below is the code. - When formatted, the spacing is different
Key Points:
1) Patient was identified. Therefore no need to loop on edm.pat.edm.data
2) Before each loop, the subscript to be looped is set to nil
3) Must loop on each detail segment and work way down.
4) Once to correct detail segment, setup if/then to determine what data is outputted.
5) Notice, when pulling user, I could only 3 loops instead of 4 (up one level), since only needed one static value
6) Variables are then pulled in by computed fields
""^PSC^IMM^DCVS^DCPS^DCRN^DCMD^DCUN^DCVS^TRRN^TRANS,
IF{""^ta.intervention,
   DO{@Next(ta.intervention) 1,
    ""^ta.date,DO{@Next(ta.date) 1,
    ""^ta.time,DO{@Next(ta.time) 1,
    ""^ta.ctr,DO{@Next(ta.ctr) 1,
""^ta.query,DO{@Next(ta.query) IF{ta.query="EDMPS" @ta.value^PSC;
ta.query="EDMIMM" @ta.value^IMM;
ta.query="NURT" "T:"_@ta.value^DCVS;
ta.query="NURBP" DCVS_" BP:"_@ta.value^DCVS;
ta.query="NURP" DCVS_" P:"_@ta.value^DCVS;
ta.query="NURSAO2" DCVS_" O2:"_@ta.value^DCVS;
ta.query="EDMDCPAINS" @ta.value^DCPS;
ta.query="EDMINSTRN" @ta.value^DCRN;
ta.query="EDMINSTMD" @ta.value^DCMD;
ta.query="EDMINSTUN" @ta.value^DCUN;
ta.query="EDMNDCTRA" @ta.value^TRANS}}}}}}},
IF{"AATRIAGE4"^ta.intervention,
   ""^ta.date,DO{@Next(ta.date) 1,
   ""^ta.time,DO{@Next(ta.time) 1,
   ""^ta.ctr,DO{@Next(ta.ctr) @MIS.USER.name[@ta.user]^TRRN}}}}


@Prev examples
Example 1 Report: BAR.PROC.zcus.ncnrc.conversion.report
 Detail DPM      BAR.PROC                    Detail Segment  bar.proc.dict
 Index DPM       BAR.PROC                    Index File      bar.proc.dict.dept.index

VAL=IF{@.today+1^std.effective.date,@Prev(std.effective.date),
VAL=@std.effective.date.charge}
Note: @std.effective.date and @std.effective.date.charge are multiples in a child segment of bar.proc.dict
SEGMENT: bar.proc.dict.std.eff.dates
SUBSCRIPTS: [mnemonic,std.effective.date]

@Prev Example 2 
VAL=IF{"CPT-W/MOD"^alt.code.type,@.today+1^alt.code.eff.date,@Prev
VAL=(alt.code.eff.date),@alt.code}

Same report as above, however, this code looks into a grandchild segment:
   SEGMENT: bar.proc.dict.alt.cd.eff.dates
SUBSCRIPTS: [mnemonic,alt.code.type,alt.code.eff.date]
Seeding is done with "CPT-W/MOD" - for the 2nd subscript (mnemonic is in the sort fields) Date is also seeded (to look for the most recent date).


@First Example 1
Report: PHA.RX.zcus.hab.frag.pom.txns.by.provider
Detail DPM      PHA.RX                      Detail Segment  pha.rx.file
Index DPM       PHA.RX                      Index File      pha.rx.start.date.x

Data desired is in Child segment:
   SEGMENT: pha.rx.transactions
SUBSCRIPTS: [urn,txn.date,txn.q]

VAL=IF{@First(txn.date)^txn.date,@First(txn.q)^txn.q,@txn.type.out}
(Field pulls the txn type name for 1st rx txn)
@First Example 2
PHA dose ranges. Is a multiple located in a child segment of PHA.DRUG
VAL=IF{@First(dose.range)^dose.range,dose.range} - Pulls mnemonic
VAL=IF{@First(dose.range)^dose.range,@PHA.DR.name[dose.range]} - Pulls 1st range's name
Format: @First(subscript)^to internal variable,desired field}

@First Example 3 BAR.PAT.zcus.hab.pts.with.spec.proc.by.payor
Report in BAR looks for 1st insurance.
Detail Segment: bar.acct.transactions Insurance information is located in the segment: bar.acct.ins.order
SUBSCRIPTS: [account,insurance.order] INTERNAL NAME: ins.order CodeVAL=IF{@First(insurance.order)^insurance.order,@ins.mnemonic}
Format: @First(subscript)^to internal variable,desired field}

Looping Through Indexes   Main NPR Menu

Key Point #1: See Data structure of Index, resulting values.
Key Point #2: May need to change prefix.
example: @Chg.prefix(ADM.PAT,:,*),

Examples:
adm.pat.room.bed.index [facility,room,bed] = urn
Notice the value of the index is "urn". Therefore we can do a "Next Get".
DO{>(ADM.PAT.room.bed.index[".",SUB],URN)^SUB 1^/PAT[URN]}

adm.pat.discharge.index [facility,discharge.date,discharge.time,urn]
Notice urn is a subscript, not the value of the index. BTW… this indexes value is always 1. We have to loop each subscript in order to get the urns.
In this example, user is putting in a from and thru date: c.xx.from.dis and c.xx.thru.dis
DISCHARGES
"."^ADM.PAT.facility,
c.xx.from.dis^ADM.PAT.discharge.date,
@Prev(ADM.PAT.discharge.date,ADM.PAT.discharge.index),
""^STOP,
DO{@Next(ADM.PAT.discharge.date,ADM.PAT.discharge.index)&('STOP) .,
IF{ADM.PAT.discharge.date' ""^ADM.PAT.discharge.time,
DO{@Next(ADM.PAT.discharge.time,ADM.PAT.discharge.index) ""^ADM.PAT.urn,
DO{@Next(ADM.PAT.urn,ADM.PAT.discharge.index) 1^/PAT[ADM.PAT.urn]}}}
Index Name/Internal Name/Detail Seg   Physical Base/Subscripts/Detail Segment Internal Name
adm.pat.discharge.index               :AADI[gqb,aaDDT,aaDTM,aa] = 1
     discharge.index                       [facility,discharge.date,discharge.time,urn]
     adm.patient.file                      main


Other Info: Looking at the physical base, some indexes are already link to ADM. Example: oe.adm.room.bed.index
Index Name/Internal Name/Detail Seg   Physical Base/Subscripts/Detail Segment Internal Name
oe.adm.room.bed.index                 *AARB[gqb,ggr,hrmB] = patient
     adm.room.bed.index                    [facility,room,bed]
Notice the "*" before AARB Because both the OE index and the adm.pat database has a "*",In that case, we can create a report with different index and detail segments.
Detail DPM      NUR.PC.WORK                 Detail Segment  nur.pc.work.activity
Index DPM       OE.ORD                      Index File      oe.adm.room.bed.index
Below is an example of looping through OE room and bed index to build patient's list of names.
Note: Report written in OE.ORD. Just want to look at current inpatients, but do not want to use the oe.adm.room.bed.index in main report.

Below is used in a start macro: Report (OE.ORD.zcus.hab.frag.inr.warf.report.M.Start)
;Note: If looping through Index, use format: DO{@Next(subscript,internal name)
Subscript for index are: [facility,room,bed] Below is example - First seed the facility subscript with ".", then nil, the room, loop the room, then nil the bed and loop the bed. "."^facility,
""^room
DO{@Next(room,adm.room.bed.index) ""^bed,
DO{@Next(bed,adm.room.bed.index) 1^/OEPAT[@adm.room.bed.index]}} ;clearing out bed. ** Key point - Because this index has a value = Patient (*AARB[gqb,ggr,hrmB] = Patient), actually use the internal name of the index as the field name! @adm.pat.room.bed.index. most indexes do not equal a urn. most indexes equal a value of 1.



Macros    Main NPR Menu
Basics    Incorporating macros    Nursing Macros    ED Macros

Macro Basics   Top of Macros
Rules for Entering    Local Macros    Syntax Checker   

Rules for Entering   Back to Macro Basics
  • To comment macro code, begin line with semi-colon
  • Separate each MAGIC expression by a comma
  • Maximum of 256 translated characters per line
  • A new line can begin after any comma that separates expressions.
  • Semi-colon is appropriate to end a line if it is contained with in a MAGIC Control Structure (IF/DO)
  • No limit to the number of lines

Local Macros   Back to Macro Basics
  • Subroutines within a macro (a.k.a. Functions)
  • Provide the ability to define a macro first in general terms, then expand the details within each general area
  • Repetitive functions can be defiend once in a local macro
  • Only accessible from within the macro the are defined
  • Use at least 3 uppercase alpha/numeric characters for naming convention
  • Last line should not end with a comma or semi-colon
Example
If{@other.locations[urn,"RAD"];
   @other.locations[urn,"LAB"];
   @other.locations[urn,"ER"];
   @other.locations[urn,"OT"]}^FOUND,
IF {FOUND CNT+1^CNT};


Syntax Checker   Back to Macro Basics
The syntax checker displays an error message dispays if any of the following character sequences are in the macro
^@,   ^%,   ^$,   ^?,   ^:,   ^*,   ^\,   ^[,   ^&
K(,   $K(,   F(,   V(,   O(,   $SEG,   $DIR



Incorporating macros   Top of Macros
Using Footnotes   As a Separate Program

Incorporating Macros Using Footnotes   Back to Incorporating Macros
The AL footnote stands for algorithm.
FormatAL KEYWORD macro.name
ExampleAL START get.info.
The KEYWORD (ie START) specifies the point in the object code in which the macro will be inserted.

Macros can be called either from the same report, or from other reports.
Example:
Report Name: BAR.PAT.zcus.status.rpt
Macro Name: get.info
Complete Macro Name BAR.PAT.zcus.status.rpt.M.get.info
If using the macro with in the report, all that is needed: AL START get info
If using the macro in another report, need the full name: AL START BAR.PAT.zcus.status.rpt.M.get.info

Calling Macro from Footnotes: Key Points
  • Incorporates macro's object code into the report's object code
  • Report must be translated after macro changes
  • Local variables can be passed back and forth between report and macro
  • The Report Writer automatically places a comma at the end of the macro's code
  • The last lineof the macro cannot end with a comma or semi-colon
  • Each KEYWORD may only be referenced once.

KeywordWhere macro is inserted
START At the beginning of the program, prior to any slections being performed.
PRINT After the printer has been opened.
SKn (e.g., Sort Key 1) After the looping code has been generated for the specified sort key.

Note the difference between HKn (region.name) and SKn. With HKn, if no detail records are found for the sort key, the HKn region is not printed and the macro logic isnot performed. Alternatively, the SKn, the macro logic is performed for every occurrence of the sort key, regardless of whether any detail records exist.
AFTER.GET.MAIN After the detail segment ahs been processed, but before multiples have been processed.
BEFORE.PRINT After all daata has been gathered, records have been selected and multiples have been processed.
region.name (e.g., D, HK1, TR, etc.) Just before the lines in that region are printed.
AFTER.region.name
CLOSE.UP After the report has been printed, but before Z.rw.close up has been executed, and the prefixes are closed.


Separate Program   Back to Incorporating Macros
When called as a program the object code of the macro is separated from that of the report. The object code of the report contains only a program call to the macro. Because of this, it is necessary to end your macro with semi-colon(;), the same character used to end all MAGIC program.

Calling Macros as a Program: Key Points

Format: %DPM.zcus.report.name.M.macro.name("")

Passing Arguments to Macros
Eample: Macro called as a program: (From ADM.PAT Report)
%ADM.PAT.zcus.report.M.macro(urn,c.location)
                                                         ||         ||
                                                        A        B
In the Macro editor:
@discharge.date[A];
        OR A^urn,
@discharge.date;
Note: The above code shows how a macro is called as a stand aloneprogram. Local vaariables establed by the report arenot accessible within the macro. Therefore, in order for the macro to access data fields properly, it becomes necessary to pass argumetns (field values) from the report ot the macro. Thisis exactly the same as passing arguments toa Z program. Most often you will be passing hte subscripts of your detail segemnt, to enable you to access data from this segment. If you don't require that arguments be passed to your macro, the nil value must be entered as an argument 9""). This process is performed during the intitial program call.

NOTE: If you receive a "MAGIC syntax error" after setting up yourmacro call within a computed field, and the syntax of your computed field is correct, the syntax error is actually within your macro. This could include; the macro not ending with a semi-colon or, a mismatch of braces in the macro code. It it necessary to first correct this error prior to filing your computed field.

Once within the macro, the arguments that are passed from the report are accessible by the variables: A,B,C etc. As shownin the above code, the first argument passed to the macro is stored in the variable A, the second variable is stored in the variable B, etc.

These variables can then be passed back into the stand field's local variable (if one should exist) or can be utilized simply as a variablein the macro.

If looking at the above code, the variable A has sbeen assigned the value of urn. Within the macro this variable can now be utilized in one of two ways
  1. As a subscribt to access a data field(i.e. @discharge.date[A])
  2. Assign the value of A back to field's local variable (i.e. a^urn,@discharge.date). This method will allow you to access any field from the main segment without having to enter the variable A as a subscript.

Info about Calling Macros as Programs
  • New symbol table is established
  • Local variables established within macro are not accessible within report (and vice-versa)
  • Slash(/) variables established wtihin macro are accessible within report (and vice-versa)
  • Value of the macro is the value of the last expression within the macro
  • Report doees not need to be translated after macro edits.
  • It is possible to call a macro, as a program from a footnote
  • When calling a macro from a computed field, if a syntax error is received, it may be there is an error within the macro
    • - Mismatch of braces
    • - Missing semi-colon as ending character
    • - It is necessary to first correct this error before the computed field can be poperly filed.


Examples:
Line Attributes, Field Attributes and Macros (e.g. - using a footnote)
  • Line Attributes (Line Check)   Back to Examples of Calling Macros as Programs
    • Field name: xx.line.ch
    • Field Attributes: DAT=FREE, LE=10, VAL=DIS.LC
    • line Attribute: LC=%ADM.PAT.zcus.zadv.demo.unit2.M.program(urn)^DIS.LC,1
    • Macro Editor:A^urn,
                              IF{@discharge.date "DISCHARGED"};

  • Field Attributes / Computed field    Back to Examples of Calling Macros as Programs
    • Field name: xx.footnote
    • Field Attributes: DAT=FREE, LEN=10, VAL=%ADM.PAT.zcus.zadv.demo.unit2.M.program(urn)
    • Macro Editor:A^urn,
                              IF{@discharge.date "DISCHARGED"};
      ** Note: Macro Editor is same for Line Check and Field Check

    Another Example: - Find records where after performing calculations the result is less than 30
    Report name: RXM.RX.zcus.hab.fax.pending
    Written in detail segment: rxm.rx.fax
    SUBSCRIPTS: [urn,fax.spool.urn]
    The field xx.keep is used in page 2 as a select
    Field: xx.keep
    DAT=PINT
    VAL=%RXM.RX.zcus.hab.fax.pending.M.select(@urn,@fax.spool.urn)
    Macro select Note:A and B are the subscripts, they are sent in the program call
    This macro figures out the minutes have passed from when the rx was submitted to now.
    A^urn,
    B^fax.spool.urn,
    IF{%Z.elapsed.time(@.today,@.now,%Z.date.clin.to.npr(@fax.submit.time),%Z.time.out(@fax.submit.time),"hh.mm")^ELAPSE,
    ELAPSE#"0:"^HRS*60^MIN1,ELAPSE#"1:"^MIN2,MIN1+MIN2};
    Note Ends in Semi colon


  • Macros/Footnotes    Back to Examples of Calling Macros as Programs
    • Field name: xx.footnote
    • Field Attributes: DAT=FREE, LEN=10, VAL=DIS.FN
    • Footnote: AL D footnote
    • Macro Editor: ""^DIS.FN,
                              IF{@discharge.date "DISCHARGED"^DIS.FN}


now is the next line






  • Field Attributes
  • Line Attributes
  • Macros

Font Attributes Bolding part of line Printing more Characters than 1/1





NUR Module Macros   Top of Macros

Sample Macros   O2 Charging O2 Charging
Looks to see if a charge query (specific query) has a "Y" for the documentation date. If not, sets the field to "Y" if user answers "ON" to the oxygen query.
Data as of 4/16/10
Screen used: NUROXYGEN.1
Intervention: Oxygen Therapy 3320 0005160
Query Info:
4 NURO21 6 1 ~Oxygen Therapy: SAME 18
5 NURO2CHARG 7 1 Daily O2 Charge: SAME 18
Called by:
REQI=IF{"NURO21"=/S.LAST.QUERY ., REQI=%Z.zcus.hab.M.o2.charge(ANS,"NURO21",@.response,"NURO2CHARG"),1}
Notes: Use an REQI, versus FCL, in case person enters "ON" and the charge is applied, then changes it to nil. FCL not executed, REQI is executed.
; 4/15/10 Herb Bromenshenkel
;================================================
; o2 charging on Intervention: 0005160    Oxygen Therapy
;================================================
; A = ANS
; B = CURRENT QUERY
; C = RESPONSE
; D = O2 charge query
;================================================
@INITIALIZE,
@QUERY.POSITIONS,
@CHK,
@CLEAN.UP,
@PAINT,
END;

INITIALIZE
A%0^ANS,
B^CURRENT,
C^VAL,
VAL^/[ANS,CURRENT]|0,
;pulls the date out
ANS#2S^DOCDATE,
""^OUT,
/["aa"]^PAT

QUERY.POSITIONS
K[""](/QUERY),
""^ROW,
DO{+/G.MSE.CDS[ROW]^ROW ""^COL,
                        DO{+(/G.MSE.CDS[ROW,COL],DATA)^COL .,
Q(ROW,COL,DATA|0-COL)^/QUERY[DATA|1]}}

CHK
;Need to go through nursing data to see if been done
PAT^NUR.PC.WORK.patient,
"0005160"^NUR.PC.WORK.int.base,
""^NUR.PC.WORK.int.urn,
DO{@Next(NUR.PC.WORK.int.urn) ""^NUR.PC.WORK.td.act.date,
                              DO{@Prev(NUR.PC.WORK.td.act.date)
IF{'CHG IF{@NUR.PC.WORK.td.act.date=DOCDATE ""^NUR.PC.WORK.td.act.time,
DO{@Next(NUR.PC.WORK.td.act.time) ""^NUR.PC.WORK.td.act.ctr,
DO{@Next(NUR.PC.WORK.td.act.ctr) IF{CHG;@UNDONE;@EDITED;@GET.RESPONSES}}}}}}}

UNDONE
@NUR.PC.WORK.activity[,,,,,NUR.PC.WORK.td.act.ctr:0D_.99]

EDITED
@NUR.PC.WORK.activity[,,,,,NUR.PC.WORK.td.act.ctr+.01]

GET.RESPONSES
IF{"Y"=@NUR.PC.WORK.td.value["NURO2CHARG"] 1^CHG}

PAINT
IF{'CHG&(VAL="ON") "Y"^VAL;""^VAL},
/QUERY[D]|0^r,
/QUERY[D]|1^s,
/QUERY[D]|2^l,
;"Y"^VAL,
"VAL:"_l_"TL"^COMMAND,
P(r,s,V[""](COMMAND))^#,
VAL^/[ANS,D]|0

CLEAN.UP
""^NUR.PC.WORK.int.base^NUR.PC.WORK.int.urn,
""^NUR.PC.WORK.td.act.date^NUR.PC.WORK.td.act.time^NUR.PC.WORK.td.act.ctr
ED Module Macros   Top of Macros

Below macro is only PART of Z.zcus.hab.M.paint.skin.1.doc
It contains the part of looping through intervention and finding data. Note: Submacro of GET.EDM.DATA. Should have been able to subscript @EDM.PAT.ta.value[QU1]^FND1. It did not work. Once set QU1 to the subscript - worked: QU1^EDM.PAT.ta.query

Note: When checking undo's and Edits - Checking EDM.PAT.edm.pat.intervention.doc is the report writer segment where undo's and edit's held (.99 or add .01)

Note: The last line listed
IF{FND1 FND1^/EDM[1,EDM.PAT.ta.date,EDM.PAT.ta.time]},

puts the value FND1 into an array, The 1 = query #, date, time. Later the array is looked at and first value pulled.
Example: - Pulls the very 1st result in array - Notice it has +/EDM versus DO{+/EDM
GET.FIRST.EDM
+/EDM[1,""]^DATE,
+/EDM[1,DATE,""]^TIME,
IF{/EDM[1,DATE,TIME] "EDM: "_%Z.date.out(DATE)_" "_/EDM[1,DATE,TIME]^EDM1},
Below is more of macro
CHK.EDM
/["aa"]^EDM.PAT.urn,
""^EDM.PAT.ta.intervention,
DO{@Next(EDM.PAT.ta.intervention) ""^EDM.PAT.ta.date,
DO{@Next(EDM.PAT.ta.date) ""^EDM.PAT.ta.time,
DO{@Next(EDM.PAT.ta.time) ""^EDM.PAT.ta.ctr,
DO{@Next(EDM.PAT.ta.ctr) IF{@EDM.UNDONE;@EDM.EDITED;@GET.EDM.DATA}}}}}

EDM.UNDONE
@EDM.PAT.edm.data.intervention.doc[,,,,EDM.PAT.ta.ctr#"0."_".99"]

EDM.EDITED
@EDM.PAT.edm.data.intervention.doc[,,,,EDM.PAT.ta.ctr+.01]

GET.EDM.DATA
QU1^EDM.PAT.ta.query,
@EDM.PAT.ta.value^FND1,
IF{@MIS.GROUP.RESP.element.response[QU1GR,FND1];FND1}^FND1,
IF{FND1 FND1^/EDM[1,EDM.PAT.ta.date,EDM.PAT.ta.time]},

/MV Arrays   Main NPR Menu

MV arrays are structures that store data.
Parts of an MV Array
/MV[mv.name,sort.field,field.num]
  1. mv.name Name of array. Often report region where /MV array prints.
  2. sort.field A unique value used to sort data within the array. Must be unique or integrity of data will be loss.
  3. field.num The field number (on page 3 of NPR report writer)
Incorporating /MV arrays into reports - 3 Places
  1. Macros - Where /MV array is created
  2. Footnotes - Instructs report where to macro in inserted in object code
  3. Line Attribue Details where to print data within report
Uses of /MV Arrays
  • Reprocessing (Resorting) existing multiples
  • Sorting data in a way not stored by system - Example - top 10 DRGs. DRGs are stored by number not frequency
  • Creating lables - 3 accross
Example 1 - Find Drugs with same Trade Name and Dispense form. Show only those with > 8
Report Name RXM.DRUG.zcus.hab.test.array

Page 2
   Sort Field                                 Order  Header  Traile
1  xx.name.form                                ASC    NONE      Y
2  mnemonic                                    ASC    NONE      N
Page 3
TK1  L  xx.name.form______________________________________nt: count
TR
TR   L    xx.name_______________________     xx.cou
TR   L    xx.name_______________________     xx.cou
Line Checks
1 LC=""
3 LC=1^NUM
  MV=TR
4 LC=NUM+1^NUM'>100

Explanation: Line 1, keeps the TK1 from printing, therefore only sorted summary prints
Line 3 - Setting up name of MV array (TR)
Line 4 - Limiting to 100 items (top 100)
Fields
Field #1 xx.name.form DAT=FREE JFY=L LEN=50 VAL=@name_" "_@dispense.form
Field #2 Z.count
Field #3 xx.name DAT=FREE JFY=L LEN=30 VAL=1
Field #4 xx.count DAT=FREE JFY=L LEN=6 VAL=1
Note - Line 3 and 4 appear as if multiples.

Footnote AL TK1 sort

Macro - sort
IF{/V[2]>5 /V[2]^COUNT,
           999999-COUNT_@name_@dispense.form^SRT,
           /V[1]^/MV["TR",SRT,3],
           COUNT^/MV["TR",SRT,4];""}
Macro Explanation:/V[2] is the 2nd field in the report (Z.count) The code says if count >5, then proceed with rest of MV array, or else no data is processed in the MV array. This works nice if you only want to see items that meet certain criteria. The 999999-COUNT is a way of sorting from descending (highest to lowest) This number will cause the sort. However, in case two drugs have the same Z.count, the data overwrites. Therefore, concatonating data to make it unique is necessary. This unique value is store in SRT.
After that, it's just a matter of assigning the data into the correct field #. The ^/MV["TR",SRT,3] means into the MV array named TR, sort by SRT value and put into the 3rd field of report (xx.name).


Nursing Module Specifics   Main NPR Menu

Information from Iatrics Newsletter: Sept 2008
Undos and Edits
When you edit documentation, MEDITECH increments the @act.ctr and @td.act.ctr subscripts with a tie breaking value. If the initial time documented as @act.ctr = 1, the first edit has @act.ctr = 1.01 and the second has @act.ctr = 1.02 so on.
When you undo documentation, MEDITECH adds a ".99" to the @act.ctr (and makes an entry in the @activity segment only, no entry is made in the @times.done segment).
Excluding Undo Add select to your report xx.ck.undo EQ 1 xx.ck.undo
DAT=FREE
LEN=1
VAL=IF{@activity[@patient,@int.base,@int.urn,@act.date,@act.time,@td.act.ctr#"0."_".99] "";1}
You can use a translator trick and use commas to hold a spot for each subscript and save some typing like this:
VAL=IF{@activity[,,,,,@td.act.ctr#"0."_".99"] "";1}

Excluding Edits
To exclude entries with a subsequent edit, you can look ahead to the next "td.act.ctr" for the special ".01", ".02" flag.
Add select to your report xx.ck.edit EQ 1
xx.ck.edit
DAT=FREE
LEN=1
VAL=IF{@td.act.ctr^SAVE,@Next(td.act.ctr),td.act.ctr#"0."=(SAVE#"0.") 1,
VAL=SAVE^td.act.ctr,"";
VAL=SAVE^td.act.ctr,1}

Most Recent, Post Edit, Skip Undo For "most recent" reports, we usually create a macro to which we pass all the subscripts of the current record. The macro contains code to loop thru all the documentation for that patient and intervention to determine if the current record is indeed the most recent. For such reports, you can create a computed select field as follows:
xx.ck EQ 1 And create a computed field xx.ck
DAT=FREE
LEN=1
VAL=%NUR.PC.WORK.zcus.is.nur.util.M.last(@patient,@int.base,@int.urn,@td.act.date,@td.act.time,@td.act.ctr)
This creates some duplicate processing, but since you loop through a relatively small number of records, there isn't a significant performance issue. The code to pick the most recent, not undone, post edit entry is shown below. You can upload the sample report from our library and use the macro in any of your NUR reports that need to select only:



Operators    Main NPR Menu Arithmetic Operators   Back to All Operators    Main NPR Menu
+ Addition
- Subtraction
* Multiplication
/ Division
\ Remainder of Division
    5\3 = 2, 5/3 = 1 with 2 left over
   10\3 = 1 10/3 = 3 with 1 left over
The number of decimal places in your result is determined by the operator. The values on each side of the operator are operands.
Addition and Subtraction - the number of decimal places returned will be the same as the operand with the greatest number of decimal places.
Multiplication - the number of decimal places returned will be the sum of the decimal places of the operands.
Division - the number of decimal places returned will be the difference in the number of decimal places of the numerator (operand to the left) and denominator (operand to the right).
Remainder - value returned is an integer (no decimal places)
Note: If either operand is non-numeric, the arithmetic operation yields unpredictable results.

Examples ResultsExplanation
3+5.2 8.28.2 returned because 5.2 has most decimal places
3.0-4.00 -1.00 1.00 returned because 4.00 has most decimal places
5.1*3.3 16.83 2 places returned because each had decimal point
6.2/1.3 4 6.2 (1 place)/1.3(1 place) (1-1) = answer to 0 places (4)
6.200/1.3 4.76 6.200(3 places)/1.3 (1 place) (3-1)= answer to 2 places (4.76)
10\3 1 10/3 =3 With 1 left over


Boolean Operators   Back to All Operators    Main NPR Menu
The boolean operators (&, !) are used to return the minimum/maximum of two expressions as well as applying boolean logic functions.
Format: {expression}{operator}{expression}
The expressions can be numbers, literals, MAGIC expressions and/or data elements. The operators are listed below.
Operator Function
& Minumum (logical AND)
! Maximum (logical OR)
The & returns the minimum value of its two operands. The ! returns the maximum of its two operands.
Note: The minimum and maximum values are based on the MAGIC collating sequence which is based on the ASCII alpha sequence. Numbers which precede alpha characters are collated in numeric order.
Example Result
1&2 1
1!2 2
An expression is considered true if it returns any value and is considered false if it returns nil. The Boolean operators will return the logical AND and OR based on these conditions.

For the expression A&B, the boolean logic tables are:
A B Logical Value Logical Result Physical Value Physical Result
value value true&true true value&value minimum value
value nil true&false false value&nil nil
nil value false&true false nil&value nil
nil nil false&false false nil&nil nil

For the A!B, the boolean logic tables are:
A B Logical Value Logical Result Physical Value Physical Result
value value true!true true value!value maximum value
value nil true!false true value!nil value
nil value false!true true nil!value value
nil nil false!false false nil!nil nil


Example:
IF{A=1!(A=2)!(A=3) expression1;expression2}
If A equals 1 or A equals 2 or A equals 3 then expression1 is executed. If all three relationships are false then expression2 is executed.
Note: Use parentheses around each subsequent relationship in order to correctly evaluate the expression correctly.

Relational Operators    Back to All Operators    Main NPR Menu
The relational operators (>, <, =) are used to create a condition which compares two values.
Format: {expression}{operator}{expression}
The expressions can be numbers, literals, MAGIC expressions and/or data elements. The operators are listed below.
Operator Function
< Less Than
'< Not Less Than (greater than or equal to)
> Greater Than
'> Not Greater Than (less than or equal to)
= Equal to
'= Not Equal to

If the condition represented by the relational operator is:
True: The value on the left of the operator is returned as the value of the expression.
False: The nil value is returned as the value of the expression.
Note: If the value on the left of the relational operator is nil, it is impossible to distinguish between a true and false relation. In this case, nil is always returned as the value of the expression.
Example Result Explanation
1<2 1 The relationship is true since 1 is less than 2.
""<2 "" (nil) Nil on the left always returns nil
2'<1 2 The relationship is true since 2 is greater than or equal to 1.
1'<2 "" The relationship is false since1 is less than 2.
"B">"A" B The relationship is true since B is greater than A


String Extraction   Back to All Operators   Main NPR Menu
$ = Left of, but not including indicated position
% = Right of, but not including indicated position
# = at
'$= Right of and including the indicated position
'% = Left of and including the indicated position
'# = Left and right of the indicated position, but does not include indicated position
_ = concantonate
' = not (urnary operator)
To find things in strings:
              01234567
Assume MEDITECH^XX
L(XX) = Length = 8
L(XX,"D") = Find "D" in MEDITECH = position 2
L(XX,"E")= 1, finds first E and stops
L(XX,"J")=8 - No J, goes to 8th sopt and stops
L(XX,"J")=L(XX) - a way to find if J is in any code, If not, will match and be true.
@dx'#L(@dx,".") - Will return everything in DRG except period.
the L(@dx,".") - finds where the period is.
the @dx'# - says return everything but that spot.
Other example:
@balance'#L(@balance,".") - pulls period from balance
Using Character Delimiter "JONES,ANN"#""1," = ANN - First Unit
"JONES,ANN"#""0," = JONES - Zero Unit
"ADM IN"#"1 " = IN - The first unit delited by a space
LC="MEDITECH IS THE SOFTWARE WE USE - IT WORKS - IT SHARES"^XXX
VAL=XXX#"3 " = SOFTWARE
VAL=XXX#"1-" = IT WORKS
VAL=XXX#"2-" = IT SHARES
VAL=XXX$"1-" = MEDITECH IS THE SOFTWARE WE USE -
VAL=XXX%"1-" = - IT SHARES
VAL=XXX$"0-" = ""
VAL=XXX%"0-"- IT WORKS - IT SHARES

Pattern Match Operators   Back to All Operators    Main NPR Menu
The pattern match operator is the question mark (?) and is used to test the conformity of a value to a specified pattern. The patterns are specified by numbers and code letters which correspond to certain categories of patterns.
Format: {expression}{operator}{code}
The expressions can be numbers, literals, MAGIC expressions and/or data elements. The codes are listed below.
Code Definition
A Alphabetic characters (upper case A-Z and lower case a-z)
N Numeric characters (0-9)
P Punctuation characters (neither a letter nor a number)
M Money (one or more digits followed by a decimal point and two digits)
D Decimal number (a string with at least one digit and no non-digits except minus sign and decimal point)
I Same as N except the number that forms part of the pattern is a maximum
The "pattern" consists of one or more code letters each optionally preceded by a number. If no number is included, zero is assumed. The first code of the pattern MUST be preceded by a number.
Intrepretation:
The number zero followed by a code letter will match ANY number of characters of the expression that fall into the category represented by the code letter.
Any other number followed by a code letter with match exactly that number of charaters in the expression that fall into the category represented by the code letter with the exception of "I", "M" and "D". For "I", "M" and "D", the number within the pattern is a maximum meaning that the pattern will match up to and including that number of characters.
When the pattern contains more than one code letter, the code letters are considered individually in the order that they appear. If the first pattern does not specify the number of characters to match, the maximum number of characters that fall into the category are matched.
The result of the pattern match operator is that of a relational operator. If the pattern is matched, the value on the left is returned. If the pattern does not match, nil is returned.

Example Result Explanation
123?3N 123 123 has 3 digits and is being matched to 3 digits. Condition is true.
123?4N "" (nil) 123 has 3 digits and is being matched to 4 digits. Condition is false.
123?0N 123 123 is made up of only digits and is being matched to digits. Condition is true.
123.45?6M 123.45 123.45 has 6 characters in the money format and is being matched to 6 characters in the money format. Condition is true.
123.45?6A "" (nil) 123.45 has 6 characters in the money format and is being matched to alphabetic characters. Condition is true.
123.?4D 123. 123. has 4 characters in decimal format and is being matched to 4 characters in decimal format. Condition is true.
"-123.45"?7D -123.45 -123.45 has 7 characters in decimal format and is being matched to 7 characters in decimal format. Condition is true.
123.45?2NM 123.45 123.45 has 6 characters in money format and matches 2 digits followed by any number of characters in money format. Condition is true.
123.45?0NM "" (nil) 123.45 has 6 characters in money format is being matched to all digits followed by any number of characters in money format. After the pattern matches all digits, it does not leave any characters in money format. Condition is false.


Format Operators   Back to All Operators    Main NPR Menu
The colon ( : ) is used to format character strings into common formats.
Format: {expression}{operator}{code}
The expressions can be numbers, literals, MAGIC expressions and/or data elements. The codes are listed below. The letter n signifies a whole number.
Code Definition
n Repeat the left operand n times
nR Right justify the left operand in a field of n spaces
nL Left justify the left operand in a field of n spaces
nC Center the left operand in a field of n spaces
nT Truncate the left operand to n characters
nM If the length of the left-hand operand is less than three, append leading zeroes to make the length equal to three. Then insert a decimal point before the right-most two characters and right-justify the result in a field of n spaces.
nD Round a numeric value to n decimal places (if the value has greater than n decimal places) or append n decimal places to a numeric value (if the value has less than n decimal places).
nP Round a numeric value to n significant digits (if the value has greater than n significant digits) or append a decimal point and n significant digits to a numeric value (if the value has less than n significant digits). Leading zeroes are not significant digits. Trailing zeroes are significant digits if there is a decimal point.
S Strip the leading and trailing spaces from the left operand
X Replace any non-printing characters (e.g., controls characters) found in the left operand with spaces.
nA Add commas to a numeric value where appropriate. If the value is negative, move the negative sign to the right of the value. Right justify the field in n spaces.


In the following examples, the lower-case "b" represents a blank space

Example Result Explanation
123:3 123123123 123 is repeated three times.
123:4R b123 123 is right justified in a field of 4 characters.
123:4L 123b 123 is left justified in a field of 4 characters.
1234567:5T 12345 1234567 is truncated to 5 characters.
12345:7M b123.45 12345 is transformed to a money format and right justified in a field of 7 characters.
123:5C b123b 123 is centered in a field of 5 characters.
123:4D 123.0000 123 is transformed to include four decimal places.
12345:4P 12350 12345 is transformed to include four significant digits and is rounded accordingly.
" 123 ":"S" 123 The leading and trailing spaces are removed.
^&A[1]A:"X" 3A 1 A The embedded control characters are transformed into spaces.
1234.56:10A b1,234.56b A comma is added as well as a blank space at the end. The number is right justified in a field of 10 characters.
-1234.56:10A b1,234.56- A comma is added and the minus sign is moved to the right of the number. The number is right justified in a field of 10 characters.


Selection Operators   Back to All Operators    Main NPR Menu
Select Operator Function Special properties: Used primarily with a prompt
EQ Equal to
NE Not Equal to
IG Ignore Does not affect select conditions. *
GE Greater than or equal to
LE Less than or equal to
GT Greater than
LT Less than
LI List Select based on a value from a list.
Note To see an example how to list user selects on a report see ECE/ECBs
*
NL Not in List *
RL Range List Select based on a list of ranges, enter the name of the prompt and the FROM and THRU will automatically default on the screen. *
CO Contains Used to select records if the value is contained within the data field.
NC Not Contains
CL Contains List *
FS First value greater than or equal to
LS Last value less than or equal to






Report Variables    Main NPR Menu
Variable Explanation
/R.CPI The characters per inch defined on page one of the Enter/Edit Report routine.
/R.LPI The lines per inch defined on page one of the Enter/Edit Report routine.
/R.CPL The characters per line defined on page one of the Enter/Edit Report routine.
/R.PS The page size defined on page one of the Enter/Edit Report routine.
/R.DATE The date the user began running the report.
/R.TIME The time the user began running the report.
/R.FOUND This variable will have a value of one if the current record passed the report select criteria.
/R.HOSP The application database report title as defined in the MIS Toolbox configuration.
/R.NEW.PAGE.PGM The name of the new page program associated with the report. (.RP suffix on report name).
/R.PAGE.NUM The current page number.
/R.TITLE The report title defined on page one of the Enter/Edit Report routine.
/RW.URN The name of the report. (Only set up on reports run from Report writer.)
/R.FRAGMENT This variable will have a value of one if the report is being executed as a report fragment.
/temp The temporary sort array based on user defined sort criteria.


Rules - Using rules to run report    Main NPR Menu
Although this is primarily a rule item, the NPR report information is specific to send back to a rule. For more info see Meditech's knowledge base: # 12805 & 12811
Report: PHA.RX.zcus.hab.frag.rule.edm.dup.mnem Full Report
Rule: ED.DUP.MED (see below)
Purpose of report:When orders are being entered in PHA on an ED patient, checks all of patient's meds to see if same med has been entered on the patient. If the same med has been entered on patient (probably by er doc), it flags the user to see about debiting the order instead of entering a new order.
General Concepts
1) Rule puts the med into a slash variable (/ZRPT.MED) and sends it to the report.
2) The report goes through the patient's meds and at each detail line runs a macro (meds). The macro basically checks the current med in the rule against the med in the detail line. If there is a match, a message is setup in a variable.
3) A line check (LC="") needs to be on the report to keep the report from printing
4) When the report is done, a CLOSE.UP macro (setup.msg) sends the information back to the rule.
5) The information back to the rule is stored in a variable called /RX.WIN. This is the standard variable Meditech uses to store the rule's [f rx win init], [f rx win add], and [f rx win disp].
6) Note In this example, since the [f rx win init] is used, something must be sent back. If "" is sent back the rule crashes.
PHA RULE: ED.DUP.MED - Data fields from RX, evaluate at MED
IF{[f pt location]="ER"&([f pt status]="REG ER") 1,
IF{[f z user mis office]="INFO SYS"!([f z user mis office]="PHARMACY") 1,
[f rx win init],
[f z chk.med.mnem.dup],
[f rx win disp],1;[f rx ok]};1};

 Custom Keyword: 
{@Z.rpt.fragment}^SV.F,{1}^{@Z.rpt.fragment},
@PHA.DRUG.mnemonic^/ZRPT.MED,
%PHA.RX.zcus.hab.frag.rule.edm.dup.mnem.R("")X,
""^/ZRPT.MED,
SV.F^{@Z.rpt.fragment},""^SV.F
System Variables    Main NPR Menu
@.appl /.APPL Name of Application
@.country /.CNTRY Country of MIS (US, CANADA, OTHER)
@.db /.DB Name of Application Database
@.device /.DEV User's Input Terminal
@.dir /.DIR Current Directory
@.facility /.FAC Current Facility in Multi-Facility System
@.job /.JOB Job Number of Process
@.logical.device /.LOC Location of User's Terminal
@.lookup /.LK # of Entries to Display in Lookup
@.menu.arg /.MENU.ARG Used by Menus to Pass Arguments
@.mis /.MIS Name of MIS Database
@.now %Z.time.out(S(0)) Current Time in HHMM Format.
@.mri.pfx /.MPX Medical Records Prefix
@.on.device /.PRT Last Response to "ON DEVICE" Prompt
@.today /.DAT Current Date in YYYYMMDD Format
@.user /.USR User's Mnemonic






Troubleshooting    Main NPR Menu
$DDC - MAGIC Debugging utility. Can be inserted any place code can be entered.
Syntax $DDC("string") - User can enter any value for string. Usually where DDC is located.
Example:AL D $DDC("DETAIL")

Viewing Data
  • DDT string? LCN (user can enter variables)
  • DDT string? ;/R.TITLE - (semicolon followed by name of slash variable)
  • DDT string? > - returns the # of bytes used and remaining. Max 1024
  • DDT string? ?? - Names and values of variables in symbol tables
  • DDT string? ;expression - A semicolon followed by a MAGIC expression will execute the expression as it in direct mode. If expression invalid - crash. Example: AL D IF{JOHN+1^JOHN<5 $DDC("DETAIL")}
  • DDT string? ;$G(^/MV) (The ^ stands for "name of". Identifying the "name of" the data structure to be viewed. The $G stands for a utility which dispalys data.
    • DDT string? ;$G("") - After this, select output device such as "S" - Will display data structures on screen
    • After prompt, can specify Nodes
      • / - Will list all variables and structures that exist in the / prefix.
      • /MV - Disply values in /MV array
      • /MV["D" - List values in the /MV structure that have a "D" as the first subscript
      • /MV["D","DR-BOB" - list values in /MV that match criteria.
Conditional Calling IF{@.user="MEDITECH" $DDC(10)}






Z Routines    Main NPR Menu Age Related     Top of Z Routines  Main NPR Menu


Z.age    Back to Z Routine Age Related Header  Main NPR Menu
Syntax: %Z.age(A,B)
Description: Returns an age based on two dates
Arguments A = birthdate (YYYMMDD)
B = Base Date (YYYYMMDD) OPTIONAL: excepts date field, used to find age as of a specific date. If left blank program uses (@.today).
Returns: Age in years, months, days. For example:
Under 1 Year nM dD
Under 5 years: nY nM,
5 and over: nn

Z.age.ck    Back to Z Routine Age Related Header  Main NPR Menu
Syntax: %Z.age.ck(A)
Description checks age for proper format: nnY nnM nnD
Arguments:
A = age in Z.age format
B= not nill if "weeks gestational age" allowed
Example: nnn or nnY nnM nnD
no months/days are allowed if > 5Y
no days are allowed if >= 1Y
Returns : User input if valid, nil if not valid
Example Call:
%Z.age.ck(@age) returns @age
%Z.age.ck("4Y 11M") returns 4Y 11M
%Z.age.ck("6Y 11M") returns (bad format)

Z.age.format    Back to Z Routine Age Related Header  Main NPR Menu
Syntax" %Z.age.format(A)
Description puts age into standardized format for ease of making greater than/less than comparisons Arguments: A =an age - Standard MEDITECh age format
Returns either nn (years if nn>5)
nY nnM (if n'=0)
OY nnM nnD
0Y 00M 00D nnWG (weeks gestation)
Example call
%Z.age.format(@age) returns nY mmM
%Z.age.format("1M22D") returns 0Y 01M 22D

Z.age.format.strip    Back to Z Routine Age Related Header  Main NPR Menu
Syntax: %Z.age.format.strip(A)
Description Takes a formatted age (from %Z.age.format) and strips leading zeros or unnecessary characters from age
Arguments; A= a formatted age (e.g. 2Y 00M)
Returns a stripped age (e.g. 2)
Example Call: %Z.age.format.strip("1Y 01M") returns "1Y 1M"

Z.age.in.years    Back to Z Routine Age Related Header  Main NPR Menu
Syntax: %Z.age.in.years(A,B)
Description Calculates an age in years as of base date
Arguments:
A = birthdate YYYYMMDD
B = base.date YYYYMMDD
Returns Integer value of age. If <1 returns 0
Example Call: %Z.age.in.years(19580101,20000101) Returns 42

Z.age.to.birthdate - From Iatric's web site    Back to Z Routine Age Related Header  Main NPR Menu
Description: Converts an age to a computed birthdate
Arguments:
A = Age (For example: 32, 3Y 6M, 2M 15D)
B = Base Date (Age A was recorded on this date; Generally today or admission date) YYYYMMDD format.
Returns: Computed birthdate in YYYYMMDD format
Example Call: %Z.age.to.birthdate(42,20000422) returns 19580422

Z.age.with.years    Back to Z Routine Age Related Header  Main NPR Menu
Description: Allows compiled reports to compare ages
Arguments:
A = birthdate
B = OPTIONAL base date (e.g., admission date) Program use IF{B;@.today)
Returns: Age in years, months,days. If the age is less than one year, "0Y" is returned in front of the number of months and days.
Examples: 32, 3Y 10M, 0Y 0M 21D
Example Call: %Z.age.with.years(20000101,20000421) returns 0Y 03M 20D

Date/Time    Back to all Z Routines  Main NPR Menu



Z.bdate.in    Back to Z Routine Date/Time Header  Main NPR Menu
Syntax %Z.date.in(A)
Description Converts external dates into an internal format
Arguments A = a date in external form (MM/DD/YY) in US, (DD/MM/YY) in Canada
Returns A date in internal form (YYYYMMDD)
Example Call: %Z.date.in("04/02/00") Returns 20000402

Z.date.add    Back to Z Routine Date/Time Header  Main NPR Menu
Syntax: %Z.date.add(A,B)
Description: Adds a number of days to a date in internal format
Arguments:
A = date in internal format (YYYYMMDD)
B = integer (number of days to add to A) For negative, use (0-N)or "-N"
Returns A date in internal format N days from A
Example Call: %Z.date.add(20000101,90) returns 20000331
** For Dates in NPR reports **
Often the user wants to specific a report to run from T-2 through T-1. (@.today-2) doesn't always work. The user can use: (%Z.date.add(@.today,0-2)).

Z.date.clin.to.out    Back to Z Routine Date/Time Header  Main NPR Menu
Arguments: A = clinical date or S(0) (days since 3/1/1980)
Returns: External Date (MM/DD/YY US, DD/MM/YY Canada).
This yields the same results as: %Z.date.out(%Z.date.in.magic(input))
Example Call: %Z.date.clin.to.out(S(0)) (on 04/21/00) returns 04/21/00
%Z.date.clin.to.out(7356) returns 04/21/00

Z.date.clin.to.text    Back to Z Routine Date/Time Header  Main NPR Menu
Procedure: Z.date.clin.to.text
Description: This program takes a clinical date and returns a 'text' form of it.
Arguments:
A = date (days since 3/1/1980 or S(0))
B = format indicator: Use M, m, N, n, D, d, Y, y.
(Capital letter means long form; Small letter means abbreviated form)
(All other characters are taken literally.)
Examples:
September 03, 1990 "M D, Y"
September 3, 90 "M d, y"
Sep 03, 1990 "m D, Y"
03Sep90 "Dmy"
3 Sep 90 "d m y"
3-Sep-90 "d-m-y"
09/03/90 "N/D/Y"
[For text month only:]
C = "I" to print month with inital capital only, e.g, September or Sep.= "A" to print month with all capitals, e.g., SEPTEMBER or SEP
DEFAULTS:
B = "m d, Y" \_____ Sep 3, 1990
C = "I" /
Example Call %Z.date.clin.to.text(7356, M D, Y ) returns April 21, 2000
NOTE: Meditech's description: - NOTE: Meditech doc says: %Z.date.text
Procedure Z.date.text
Syntax %Z.date.text(A,B,C)
Description Formats a date in text format
Arguments A = date in internal or external format
B = format indicator: Use M, m, N, n, D, d, Y, y (Capital letter means long form; Small letter means abbreviated form, all other characters are taken literally. N or n signifies numeric month).
C = "I" to print month with initial capital only. "A" to print month with all capitals


Z.date.clinical    Back to Z Routine Date/Time Header  Main NPR Menu
Syntax %Z.date.clinical(A)
Description Takes an internal NPR date (YYYYMMDD) and converts it into an integer date format used by the Magic Clinical Products
Arguments: A = Internal Date YYYYMMDD
Returns: Clinical Date (Number of days since 3/1/1980
If the A is not eight characters, A is returned.
Example Call: %Z.date.clinical(7356) returns 20000421

Z.date.in    Back to Z Routine Date/Time Header  Main NPR Menu
Syntax %Z.day.in(A)
Description Converts a three letter mnemonic for a day(ie. "MON") into an integer corresponding to the day of the week 1-7

Z.date.clin.to.npr    Back to Z Routine Date/Time Header  Main NPR Menu
Syntax: %Z.date.clin.to.npr(A)
Description Takes an integer date of the format used by the Magic Clinical Products(ie. with March 1, 1980 equal to 0), and converts it into an NPR internal date (YYYYMMDD)
Arguments A is a clinical date equal to the number of days elapsed since 03/01/80
Returns An NPR internal date (YYYYMMDD)
(NOTE: Do not see this Iatrics page. However, they have one called: Z.date.in.magic - see below

Z.date.in.magic    Back to Z Routine Date/Time Header  Main NPR Menu
Procedure: Z.date.in.magic
Arguments: A = S(0) or @.sd or clinical date
Returns: YYYYMMDD
Example Call: %Z.date.in.magic(7356) Returns 20000421

Z.date.julian    Back to Z Routine Date/Time Header  Main NPR Menu
Syntax %Z.date.julian(A)
Description Converts a date in internal form to julian form
Arguments A = a date in internal format (YYYYMMD
Returns Date in Julian format (YYJJJ) where:
YY = year (93) and JJJ = day of the year (359 = 359th day of 1993)
Iatric's info:
Arguments: A = YYYYMMDD
Returns: YYJJJ The Julian date.
Example call: %Z.date.julian(20000421) returns 00112

Z.date.julian.to.in    Back to Z Routine Date/Time Header  Main NPR Menu
Arguments: A = YYJJJ
Returns: YYYYMMDD
Example call: %Z.date.julian.to.in("00112") returns 20000421

Z.date.out    Back to Z Routine Date/Time Header  Main NPR Menu
Syntax %Z.date.out(A)
Description Converts internal dates into external format
Arguments A = a date in internal form (YYYYMMDD)
Returns A date in external form (MM/DD/YY) in US or (DD/MM/YY) in Canada
Iatric's info:
Arguments:
A = internal date YYYYMMDD
B = if non-nil, return A if format checks fail
C = 5 return MM/DD or DD/MM
C = 10 return MM/DD/YYYY or DD/MM/YYYY
Returns: MM/DD/YY or MMDDYYYY depending on system century or argument C
Example Call:
%Z.date.out(20000421) returns 04/21/00
%Z.date.out(20000421,"",5) returns 04/21
%Z.date.out(20000421,"",10) returns 04/21/2000

Z.date.out.long    Back to Z Routine Date/Time Header  Main NPR Menu
Argument: A = YYYYMMDD
Returns: MM/DD/YYYY (US format only)
Example Call %Z.date.out.long(20000421) Returns 04/21/2000

Z.date.sub    Back to Z Routine Date/Time Header  Main NPR Menu
Syntax %Z.date.sub(A,B)
Description Subtracts the second date from the first date and returns the number of days between the two.
Arguments:
A = later date in internal format
B = earlier date in internal format
Returns An integer number of days corresponding to A-B, (Should work to calculate age)
Iatric's Info:
Arguments:
A = more recent date
B = older date
Returns: Number of days between B and A (If A or B are nil, returns nil)
Example Call: %Z.date.sub(20000415,20000101) returns 105
Z.date.text    Back to Z Routine Date/Time Header  Main NPR Menu
This program takes a date and returns a 'text' form of it.
Arguments: A date in (YYYYMMDD or MM/DD/YY or MM/DD/YYYY)
B = format indicator: Use M, m, N, n, D, d, Y, y.
Capital letter means long form; Small letter means abbreviated form)(All other characters are taken literally.)
Examples:
September 03, 1990 "M D, Y"
September 3, 90 "M d, y"
Sep 03, 1990 "m D, Y"
03Sep90 "Dmy"
3 Sep 90 "d m y"
3-Sep-90 "d-m-y"
09/03/90 "N/D/Y"
[For text month only:]
C = "I" to print month with inital capital only, e.g, September or Sep.
C = "A" to print month with all capitals, e.g., SEPTEMBER or SEP
DEFAULTS:
B = "m d, Y" \_____ Sep 3, 1990
C = "I" /
Returns EXAMPLES:
A B C RESULT
19970903 "M D, Y" "I" September 03, 1997
19970903 "M d, y" "A" SEPTEMBER 3, 97
19970903 "m D, Y" "I" Sep 03, 1997
19970903 "Dmy" "A" 03SEP97
19970903 "d m y" "I" 3 Sep 97
19970903 "d-m-y" "I" 3-Sep-97
19970903 "N/D/y" nil 09/03/97
DEFAULTS:
19970903 "m d, Y" "I" Sep 3, 1997

Z.day.from.date    Back to Z Routine Date/Time Header  Main NPR Menu
Syntax %Z.day.from.date(A)
Description Converts a date in internal format(YYYYMMDD) into an integer corresponding to the day of the week 1-7
Arguments A date in internal format(YYYYMMDD)
Returns 1 = Sunday)
%Z.day.from.date(20000421) Returns 6

Z.day.in    Back to Z Routine Date/Time Header  Main NPR Menu
Converts a three-letter mnemonic (ex. "MON") for a day into a number (ex. 2).
Arguments: Three letter day mnemonic ex: SUN, MON, TUE, WED..
Returns: Day of the week (SUN = 1)
Example Call: %Z.day.in( FRI ) returns 6

Z.day.out    Back to Z Routine Date/Time Header  Main NPR Menu
Syntax %Z.day.out(A)
Description Converts an integer corresponding to the day of the week 1-7into an external three letter mnemonic (i.e., "MON")
Z.month.in    Back to Z Routine Date/Time Header  Main NPR Menu
Procedure: Z.month.in From Iatric's web site, not on MEDITECH's
Arguments: A = Three letter mnemonic for Month
Returns: Number of month
Example Call: %Z.month.in("APR")returns 4

Z.month.out    Back to Z Routine Date/Time Header  Main NPR Menu
Syntax %Z.month.out(A)
Description Converts an internal month in integer form(1-12) into an external three character mnemonic.
Example Call: %Z.month.out(1) returns "JAN"
Example for BAR - Includes Year: VAL="(*"_%Z.month.out(@txn.ser.date$6%3)_" "_(@txn.ser.date$4)_" *)"

Z.time.add    Back to Z Routine Date/Time Header  Main NPR Menu
Syntax %Z.time.add(A,B,C)
Description Takes date and time and adds a number of minutes to return new date and time.
Arguments A = internal date (YYYYMMDD)
B = time (HHMM)
C = number of minutes to add (may be negative)
Returns New date and time
Returns: Q(new.date,new.time) new.date = YYMMDD new.time = HHMM
Example:
A = 19910103
B = 0700
C = "-600" (i.e., subtract 10 hours)
Returns: Q(19910102,2100)
Example Call: Z.time.add(20000421,1200,60*24*3) returns 20000424 1200

Z.time.in    Back to Z Routine Date/Time Header  Main NPR Menu
Arguments: A HHMM time
Returns: S(0) time
Example Call %Z.time.in(1300) returns 46800

Z.time.lapse    Back to Z Routine Date/Time Header  Main NPR Menu
Arguments: S(0) time or HH:MM:SS time
Returns: the alternative format
Example call %Z.time.lapse(46800) returns 13:00:00
%Z.time.lapse( 13:00:00 ) returns 46800
Note: Do not use S(0) or @sd directly, convert to internal time first as follows:
%Z.time.lapse(%Z.time.in(HHMM)) or %Z.time.lapse(S(0)\86400)
The internal time is the remainder on division (\) of S(0) and 86400
because there are 86400 seconds in a day.

Z.time.out    Back to Z Routine Date/Time Header  Main NPR Menu
Argument: Time in S(0) format or HHMM or HH:MM
Returns: HHMM unless already HH:MM, then HH:MM returned
Example call: %Z.time.out(S(0)) returns the current time in HHMM format
In task Plus, to get HR only
TSK.TASK.zcus.hab.task.enter.time
VAL=%Z.time.out(@first.activity.time)$2_"00"
(if entered at 9:45, first part converts and does string extraction, second part adds 00 (09 + 00) = 0900

Z.time.sub    Back to Z Routine Date/Time Header  Main NPR Menu
Syntax %Z.time.sub(A,B)
Description Returns number of minutes between two times
Arguments:
A = thru time in HHMM format
B = from time in HHMM format
Returns The number of minutes between A and B
Iatric's info:
Argument:
A = end time HHMM
B = start time HHMM
Returns: minutes between B and A
Example call: %Z.time.sub(2400,1200) returns 12

Z.time.text    Back to Z Routine Date/Time Header  Main NPR Menu
Syntax %Z.time.text(A,B,C,D)
Description Formats a time in text format
Arguments A = time (HHMM or NNNNN*)
B = format string: (use H, h, M, m A, a, N
(Capital letter means keep lead zero; Small letter means don't)
(Use 'A' or 'a' for AM/PM. 'A' means use 'AM' or 'PM'; 'a' = 'A' or 'P')
(N = military time)
(All other characters are taken literally)
H - Hour (09)
h - hour w/o leading zero (9)
M - Minute (05)
m - Minute w/o leading zero (5)
A - AM/PM Flag (AM or PM)
a - Abbreviated AM/PM Flag (A or P)
N - Military Time (2355)
(all other characters are taken literally)
C = Value of "C" for Capital Letters On the AM/PM Flag or "S" for Lower Cases Letters
D = 1 to indicate that argument A is in NNNNN format
* NNNNN = seconds after midnight, this will be converted to HHMM format if D=1
Returns EXAMPLES:
ARG A ARG B ARG C RESULT
2108 "HMA" "S" 09:08pm
210 "h m a" "C" 9:8 P
2108 "h M A" "S" 9:08 pm
2108 "HM A" "S" 0908 pm
2108 "N" nil 2108
DEFAULTS:
B = "h:MA" eg. 9:08pm
C = "S"
Example call: %Z.time.text(1300,"h:mmA","C") Returns 1:00PM

Z.elapsed.time    Back to Z Routine Date/Time Header   Main NPR Menu
Syntax %Z.elapsed.time(A,B,C,D,E)
Description Computes the elapsed time between one date and time and another date and time, printing this time in a user defined format.
Arguments A = end date (internal format) - YYYYMMDD ** Must be that format**
B = end time (HHMM format) ** MUST be in HHMM format ** If in TIME format,
call %Z.time.out. to convert them to HHMM
C = start date (internal format)
D = start time (HHMM format)
E = format of output
Argument E is used to determine the output format. It is entered as a quoted string, (eg. "hh HRS"). The string will be interpreted for three keywords, and will make substitutions for those keywords. All other text in the string will be outputted as entered. The keywords are:
"hh" - number of hours
"mm" - number of minutes (can not just have mm, must have hh.mm)
"hh.hh" - number of hours to decimal point
Returns Format Output
Format Output
hh Hrs mm Mins" 11 Hrs 35 Mins
"hh.hh Hours" 11.6 Hours
"hh/mm" 11/35
"hh hours" 12 hours
"hh.mm" 11:35
Notes:
If "hh.hh" is entered, do not also enter "hh" or "mm"
If "hh" is used without "mm", "hh" will be rounded to nearest hour
If "hh.mm" is found in the format string, "hh:mm" is substitutedv Example call:
%Z.elapsed.time(20000101,1300,19991231,1200, hh.hh ) returns 25.00
%Z.elapsed.time(20000101,1300,19991231,1230, hh.mm ) returns 24:30
%Z.elapsed.time(20000101,1300,19991231,1230, hh.hh ) returns 24.50
When adding elapsed times to compute averages, use hh.hh , adding hours and minutes as if they were decimals will produce inaccurate results.

Misc. Z Routines
    Back to all Z Routines   Main NPR Menu


Z.amount.in.words    Back to Misc. Z Routines   Main NPR Menu
Syntax %Z.amount.in.words(A,B)
Arguments A = money value between 0.00 and 999999.99
B = OPTIONAL: sets maximum length for the output string, if exceeded, message printed instead of amount.
Returns: String indicating the amount in words, cents are returned as digits.
C\100^C,
A null string if amount is > than 99999999.99, and a an error message is written to the screen. If string exceeds maximum length the result will be truncated and an error message will be written to the screen.

Z.convert.name    Back to Misc. Z Routines   Main NPR Menu
Syntax %Z.convert.name(A)
Uses $NM.STRIP translate string to UPPER CASE names and strip punctuation and numbers. It discards any middle name. Translated names are used in some ID programs to find possible matches for the name entered.
Arguments
A is a name
Returns: Converts name to upper case, strips all punctuation, and drops middle name.
Example: Q(lastname,firstname)
Example call %Z.convert.name(Berman,Joel F ) returns |0 = BERMAN |1 = JOEL

Z.convert.to.mixed.case    Back to Misc. Z Routines   Main NPR Menu
Not available prior to release 4.7
Converts a string from all upper case to initial caps.
Arguments:
A = string to be converted
B = if true, treat as a name, convert to lastfirst
Examples:
%Z.convert.to.mixed.case("GRAND RAPIDS") = Grand Rapids
%Z.convert.to.mixed.case("TOM SAWYER",1) = Sawyer,Tom
%Z.convert.to.mixed.case("TOM SAWYER") = Tom Sawyer
%Z.convert.to.mixed.case( THE RAIN IN SPAIN FALLS MAINLY IN THE PLAIN )
The Rain In Spain Falls Mainly In The Plain

Z.link    Back to Misc. Z RoutinesMain NPR Menu
Links to other module without having to use Fragment. Note: Must use Correct Prefixes!! The prefixes for modules vary. Below are examples. Note: even PHA Dict (pha drug) vs PHA data (rx data) has different prefixes
Originally learned at MUSE
Note: Used in Med Recon Report

Example: In Computed field
Going from ABS to MRI.PAT (ABS.PAT.zcus.hab.test.link.to.mri)
VAL=IF{%Z.link("?","MRI","%.MRI.data","MRI.NCH")^OLD.QM,
VAL=@mri.urn^MRI.DRC.medical.record,
VAL=@MRI.DRC.patient.address.out^TEMP,
VAL=ZZ%O(?,OLD.QM),TEMP}

Example: In Macro
Going from RXM to PHA Dictionary
IF{%Z.link("&","PHA","%.PHA.dic","PHA.NCH.N")^OLD.QM,
MED^PHA.DRUG.mnemonic,
@PHA.GENERIC.name[@PHA.DRUG.generic]^/TEMPGEN,
ZZ%O(&,OLD.QM)}

**Note - Other method, from consultant**
Comments (12/21/06) - I think Z.link returns the old value of the prefex, which you are storing and reopening to.Rather than depend on that, I just close and stack before calling Z.link and do a close and unstack at the end. That gets you back to where you started with the prefix open to whatever it was open to before you used Z.link.

Example
To PHA Drug from RXM
C(&S),
IF{%Z.link("&","PHA","%.PHA.dic","PHA.NCH.N"),
@med^PHA.DRUG.mnemonic,
@PHA.GENERIC.name[@PHA.DRUG.generic]^/GEN},
C(&U)

To PHA rx file from RXM
C(?S),
IF{%Z.link("?","PHA","%.PHA.data","PHA.NCH.N"),
@pha.urn^PHA.RX.urn,
@PHA.RX.sig^/SIG},
C(?U)
** Notice how before Z.link is there is a command to close and stack and then close and unstack.

Below is an email from Marvin Johson (Capita Solutions) - using in a macro.>
DPM’s can be divided into two main categories: “data” and “dic”.
For example, ADM.PAT is “data” while “MIS.USER” is “dic”.

Now let’s look at PHA.RX. It is of course “data”. Notice most segments use “?” and the indexes use “:”.
This means we will want to open these two prefixes to the “data” file.


OPEN.PHA
C(:S),                                         #start by closing and stacking the :
%Z.link(":","PHA","%.PHA.data","PHA.NCH")),    # link the : to the data file of database PHA.NCH.
O[""](?S,:)                                    # open ? to the : prefix and stack it. 
	                                         : is already open to the data file.
                                                 In other words, this is opens ? to the data file as well.

CLOSE.PHA
C(:U,?U)                                      # close and unstack the prefixes.
                                             This restores them to the way the where before we started. 


Also, it does not matter the order in which you link or open the prefix for the segments and indexes. 
This will work also:
OPEN.PHA
C(?S),                                                                    
%Z.link("?","PHA","%.PHA.data","PHA."_(@.db#"1.")),                                 
O[""](:S,?)  

You can also close them in any order
C(?U,:U)
---------------------- END OF EMAIL -------------------------------------
Example of Nursing CDS to Lab to get last Glucose or last Glucose POC
Macro's name: LAB.L.SPEC.zcus.hab.macros.M.gl.string.time
;9/2/10 Herb Bromenshenkel
;Pulls last glucose based on time parameter - string because it is text- not value only
;used in Surgical Check list   CDS: NURSURGCHECK.4
;------------------------------
;A = ANS
;B = Time to look back in minutes
;
;--------------------------------------------------
@INITIALIZE,
@QUERY.POSITIONS,
@OPEN.LAB,
@GET.GLUCOSE,
@CLOSE.LAB,
@PAINT,
END;

INITIALIZE
A%0^ANS,
/["aa"]^PAT,
0-B^MIN,
%Z.time.add(@.today,@.now,MIN)^FROM,
FROM#1S^FDATE,
FROM#2S^FTIME,
FDATE_FTIME^FROM5,
1

QUERY.POSITIONS
K[""](/QUERY),
""^ROW,
DO{+/G.MSE.CDS[ROW]^ROW ""^COL,
DO{+(/G.MSE.CDS[ROW,COL],DATA)^COL .,
Q(ROW,COL,DATA|0-COL)^/QUERY[DATA|1]}}

OPEN.LAB
C(:S),
%Z.link(":","LAB","%.LAB.data","LAB.NCH"),
O[""](?S,:)
GET.GLUCOSE
PAT^LAB.L.SPEC.patient,
999999999^collection.date,
DO{@Prev(LAB.L.SPEC.collection.date,patient.x) IF{'OUT&(FDATE'>collection.date) 1,
9999^collection.time,
IF{DO{@Prev(LAB.L.SPEC.collection.time,patient.x) 1,
IF{'OUT collection.date_collection.time^COL,
collection.date_collection.time^COL.SAMP,
IF{FROM5'>COL.SAMP 1,
"C"^prefix,""^number.part,
999999^number.part,
DO{@Prev(LAB.L.SPEC.number.part,patient.x) IF{'OUT @number.part^NUMB.PART,
patient.x^URN,
@GLUCOSE}}}}}}}}

GLUCOSE
"100.2400"^GLU,
"100.2940"^POC,
URN^LAB.L.SPEC.urn,
IF{@result[GLU]&("COMP"=@status!("RES"=@status)) @result[GLU]_" "_@abnormal.flag[GLU]^GLUR},
IF{@result[POC]&("COMP"=@status!("RES"=@status)) @result[POC]_" "_@abnormal.flag[POC]^GLU2R},
IF{GLUR!GLU2R 1^GOT,@PULL}

PULL
IF{GLUR "GLU: "_GLUR_" "_%Z.date.out(collection.date)_" "_collection.time^OUT;
   "GLUPOC: "_GLU2R_" "_%Z.date.out(collection.date)_" "_collection.time^OUT}

CLOSE.LAB
C(:U,?U)

PAINT
"NURSSGLU"^QRY,
/QUERY[QRY]|0^r,
/QUERY[QRY]|1^s,
/QUERY[QRY]|2^l,
P(r,s," ":l)^#,
P(r,s,OUT)^#,
OUT^/[ANS,QRY]|0


Z.money.ck    Back to Misc. Z RoutinesMain NPR Menu
Checks validity of MONEY, SMONEY & PMONEY data types, and adds decimals on if appropriate. Returns 2 decimal number if OK, else nil

Z.name.inversion    Back to Misc. Z Routines   Main NPR Menu
Syntax %Z.name.inversion(A)
Description Takes A as "lastname,rest of name" and returns "title first.name middle.name last.name qualifiers"
Arguments Name field in the form lastname,rest of name
Returns SMITH,DR WILLIAM JOHN JR becomes DR WILLIAM JOHN SMITH, JR
Example Call: %Z.name.inversion("Berman,Joel F III MD") returns
Joel F Berman, III, MD
I believe 4.7 has an MIS title dictionary to allow a site to tweak this program.

Z.phone.ck    Back to Misc. Z Routines   Main NPR Menu
Formats phone numbers according to MIS parameter.
Arguments:
A is input
B is # of max columns in field
C suppresses messages to screen

Z.phone.format    Back to Misc. Z Routines   Main NPR Menu
Formats phone numbers according to MIS parameter. This is identical to phone.ck except it does not prompt the user to accept a non standard format. Instead it uses arguement C to decide whether to accept it.
Arguments:
A is input
B is # of max columns in field
C if true accept a format which does not match the standard format

Z.split.text    Back to Misc. Z Routines   Main NPR Menu
Arguments:
A input string, or 'name of' input string (see E)
B - break characters, eg, " ;,."
C - length of desired piece
D - number of desired pieces
E - if present, A is 'name of' input string; else, A is input string

Z.zero.fill    Back to Misc. Z Routines   Main NPR Menu
Arguments:
A - number to zero fill
B - length of resulting field
C - number of implied decimal points
If input is Result is:
A               B        C
123.56        7        2        0012356
123.00        7        2        0012300
123.56        7       0        0000124
123.00        7        0        0000123
-123.45      7        2       -012345
123456.78    7       2        12345678 (This is an error)

Z.zip.code.ck    Back to Misc. Z Routines   Main NPR Menu
This program checks for legal zip codes and postal codes. A legal zip code is either: nnnnn or nnnnn-nnnn. A legal postal code is: ana nan (02141 or 02141-1234) (A1B 2K3)
Arguments:
A = user's entry
B = Y or N (allow user to override a bad entry, after a warning)
C = Z, P, or nil Z=only allow zip code form,
P=only allow postal code form,
nil=allow both)
RETURNS: TRUE if there is an error.

Z.percent    Back to Misc. Z Routines   Main NPR Menu
Syntax %Z.percent(A,B)
Description Calculates the percentage of argument A to B
Arguments A and B are numeric values in integer or decimal form
Returns Percent calculated out to two decimal places

Z.square.root    Back to Misc. Z Routines   Main NPR Menu
Syntax %Z.square.root(A)
Description Returns the square root of a number
Arguments A= any number
Returns Square root or A out to 5 decimal places

Z.rw.fragment    Back to Misc. Z Routines   Main NPR Menu
Syntax %Z.rw.fragment(A,B)
Description Allows the user to call a report fragment.
Arguments
Returns The Z.rw.fragment program does not return any value

Z.count    Back to Misc. Z Routines   Main NPR Menu
Produces a count of the number of detail records selected by the report. Define this field in the fields section on page three and place the field on a TKn or TR region

Z.record.limit    Back to Misc. Z Routines   Main NPR Menu
This field is used as a select field to limit the amount of records selected before the report prints. For instance, if you have a report which finds many records and takes time to run, you can set up Z.record.limit as a select field and set this value equal to 10


Useful Reports    Main NPR Menu
This section contains reports that use a variety of different useful techniques. Behind each report is a description how it works

Reports/Techniques




ADM.PAT.zcus.hab.test.rx   Back to Top of Useful Reports      Main NPR Menu
This report starts in ADM.PAT, calls a macro which loops through pharmacy to see which of the inpatients are on warfarin. If they are on warfarin, flag is returned. For any patient with a flag returned, system then starts a macro to pull pharmacy info. After pharmacy info is returned, lab info is gathered.

Report specifics 4 reports -


**ADM.PAT.zcus.hab.rx.test - Main Report    Back to top of ADM.PAT.ZCUS.HAB.RX.TEST      Back to Top of Useful Reports      Main NPR Menu

Important fields
  • xx.flag VAL=%ADM.PAT.zcus.hab.rx.test.M.chk.rx(@urn) (Macro to if on specific med)
    Very important: Notice this field is called as a program. The "%" sign - means program. The "M.chk.rx" means this is a macro that is running. (This macro actually starts the fragment program: PHA.RX.zcus.hab.frag.chk.rx - See Below
  • Selects - Page 2 xx.flag EQ "Y"
  • Footnote: AL AFTER.D get.meds
    After detail - which is the patients in beds who the xx.flag prompt returns a Y, it pulls meds for those patients.

**PHA.RX.zcus.hab.frag.chk.rx - 1st Fragment    Back to top of ADM.PAT.ZCUS.HAB.RX.TEST      Back to Top of Useful Reports      Main NPR Menu


Important fields
  • Footnote:
    AL START "N"^/R.FRAG.VAL["FLAG"] Sets the value to N. Once the report finds a detail record which meet the select criteria, it changes the flag to "Y" - See Next footnote
    AL D "Y"^/R.FRAG.VAL["FLAG"] Record is found, Flag value is "Y" - returns value to xx.flag in above report.
  • Selects /R.URN - created by macro in above report. (A^urn,@urn^/R.URN).
    Num  Field             Op   Prompt                             Default     (Stored As)
      1  patient           EQ   /R.URN                                         (/R.URN)
      2  med               CO   "WARF"                                         ("WARF")
      3  status            EQ   "AC"                                           ("AC")
      4  start.date        GE   (%Z.date.add(@.today,0-4))                     ((%Z.date.add(@.today,0-4)))
    


**PHA.RX.zcus.hab.frag.shows.rxs - 2nd fragment    Back to top of ADM.PAT.ZCUS.HAB.RX.TEST      Back to Top of Useful Reports      Main NPR Menu

This fragment is called after the detail from admissions is complete. After patient info individual meds that meet criteria are pulled and appended below detail in main ADM report. Main report pulls using footnote - Footnote: AL AFTER.D get.meds - which activates macro: - From MAIN Report
@urn^/R.URN,
%Z.rw.fragment("PHA.RX.zcus.hab.frag.shows.rxs.R","PHA.NCH.N"),
%Z.rw.fragment("LAB.L.SPEC.zcus.hab.frag.inr.R","LAB.NCH")

Detail line sta med_____ dose.an sig___ start.da physic#Disp:tot xx.comment1__________________




**LAB.L.SPEC.zcus.hab.frag.inr - 3rd Fragment    Back to top of ADM.PAT.ZCUS.HAB.RX.TEST      Back to Top of Useful Reports      Main NPR Menu

Similar to above fragment. This fragment is called after the detail from admissions is complete. See footnote details above.
Detail line test'-- resul collection.da



Search For Specific Text in Free Text Field - 3 Examples:     Back to Useful Reports    Main NPR Menu
These reports all use similar logic. Basically the code counts the number of characters in a line of text until if finds the desired text. Once it finds the text, it compares it to the length of the complete line of text. If not equal, text exist. If equal, text is not on line.
Key Fields
  • xx.select (on page 2, xx.select EQ "Y")
    VAL=IF{@tissue.desc.30~$L.TO.U^TXT,    (note: $L.TO.U - Converts any lower case text to upper case)
    VAL=L(TXT,c.xx.search)'=L(TXT) "Y"}
  • xx.search VAL=c.xx.search (on page 2, xx.search IG "Enter Text to Search"
    Key point - User must enter all uppercase letters!
Reports: Click on report name to see full report.
PHA.RX.zcus.hab.string.search Loops through pharamacy comments and searchs for hard coded text
MOX.USER.zcus.hab.search.own.files Searches users MOX files for text - based on user input
LAB.P.SPEC.zcus.hab.tissue.text.search Searches through pathology tissue descriptions - based on user input.



Hard Coding Print On Prompt to Scope    Back to Top of Useful Reports      Main NPR Menu
Below is a report which when run prints a message to the screen, emails two other reports.
When the user runs the report, after filling in select, it automatically prints to screen.
Name of report: PP.PER.zcus.hab.email.pers.chg Macro Code Name of macro in this case is print
IF{'/ONE 1^/ONE,
         1^/Z.SCHED.LOG,
         %Z.printer.open.px("S")},
"PP.PER.zcus.hab.email.pers.chg";
Report Title: Report Title "_%PP.PER.zcus.hab.email.pers.chg.M.print(0)_"



Emailing message   Report: PP.PER.zcus.hab.email.pers.chg.html    Back to Top of Useful Reports      Main NPR Menu
Emailing a report involves using a macro and setting up an array. What appears on page 3 of the report writer is not what is emailed. Rather, it is what is created in the array by the macro.
Steps required
  1. AL START macro.name This macro creates the array. In this example, I have two different messages being emailed:
         "           Employee Demographic Change Form - Human Resouces Copy: "^/TEMP[1],
         1^/CNTR,
         "              Employee Demographic Change Form - Employee Copy:"^/TEMP2[1],
         1^/CNTR2
    
  2. Create Message in array (add lines to existing array) Each line adds info to variable, and then advances count for next line. If did not advance count, only last line would be saved.
         "New Telephone                Previous Telephone"^/TEMP[/CNTR],
         1+/CNTR^/CNTR,
    

  3. Email Message When everything is processed, macro emails message
    In this case - array in #1 gets mailed to 1 person, array in #2 gets mailed back to person running report.
    %MIS.OA.MSG.auto("",Q(^/TEMP,"HAB","HAB")),
    %MIS.OA.MSG.auto("",Q(^/TEMP2,@.user,@.user)),
    END




Security by Device - Patient Info     Back to Top of Useful Reports      Main NPR Menu
This report uses the value @.logical.device and determines if the selected patient's location is associated to the users device. Example: If a person is on a 2nd floor terminal tyring to run the custom report on a patient located in 3rd floor, the results are no records found.
Main Report: PHA.RX.zcus.hab.active.rxs.dis.nh
Main Report has a footnote: AL START lcn
Page 2 patient's.location EQ /R.FRAG.VAL
Page 3 Macro: lcn
%Z.rw.fragment("ADM.PAT.zcus.hab.rx.frag.inp.R","ADM.NCH"),
MOVE(/R.FRAG.VAL,/PATS),
;Note; top two lines of macro do not deal with security. Rather a report 
;is run which pulls the current patients in the room and bed index. Speeds up Report
;Although not mentioned above, on page 2 there is a select: patient  LI /PATS
;1st macro determines current inpatients through room and bed index and returns
;them in a frag footnote: AL D @urn^/R.FRAG.VAL[@urn]  (Hence the need to move)
%Z.rw.fragment("MIS.LOCN.DICT.zcus.hab.access.device.R","MIS")
The above line does the work

Report info: MIS.LOCN.DICT.zcus.hab.access.device
Detail DPM      MIS.LOCN.DICT               Detail Segment  mis.locn.dict.terminals
Index DPM       MIS.LOCN.DICT               Index File      mis.locn.dict.term.index
Page 2 terminal EQ @.logical.device
Footnote AL D locs
Macro: locs
@mnemonic^LOC,
IF{LOC="2EAST"!(LOC="2WEST") 1^/R.FRAG.VAL["2EAST"],
                             1^/R.FRAG.VAL["2WEST"];
   LOC="FC"!(LOC="OB")!(LOC="OBI") 1^/R.FRAG.VAL["FC"],
                                   1^/R.FRAG.VAL["OB"],
                                   1^/R.FRAG.VAL["OBI"];
   LOC="ARU" 1^/R.FRAG.VAL["ARU"];
   LOC="ICU" 1^/R.FRAG.VAL["ICU"];
   LOC="NUR" 1^/R.FRAG.VAL["NUR"],1^/R.FRAG.VAL["SCN"]}
Back to Top of Useful Reports      Main NPR Menu


Suppress Printing or emailing if no records found
The below is if setup to email and to print from a scheduled spool group:

In footnotes have a macro: i.e. AL CLOSE.UP close
Macro close
IF{/R.FOUND %MIS.OA.MSG.auto("",Q(^/TEMP,"HAB","HAB")),END;
IF{'/R.FOUND 1^/R.FOUND^/R.PAGE.NUM}}

If just emailing:
IF{/R.FOUND %MIS.OA.MSG.auto("",Q(^/TEMP,"BMB","BMB")),
END;""}


Supress Printing only
In footnote: AL CLOSE.UP IF{'/R.FOUND 1^/R.FOUND^/R.PAGE.NUM}}
Note: Believe above code is correct - it is referenced in a knowledge based in 2004. Can not seem to find specific #.



HTML Guide   Main NPR Menu

This section is intended as a quick reference for HTML codes used in this report. Click here for an more extensive list created by Kevin Werbach

Essential Components
Formatting - Lines, spaces, bolding, size
Linking


Essential Components     Back To HTML Start    Main NPR Menu
To have any HTML document you must have the following format.
<HTML>
<HEAD>
<TITLE> The text entered here appears on the top title bar in browser </TITLE >
</HEAD>
<BODY> -This is an example of a simple html document - text is placed in the body tags.
</BODY>
</HTML>
Click here to see results of above code

Formatting - Lines, spaces, bolding, size     Back To HTML Start    Main NPR Menu
Because browsers vary in height and width, specific codes need to be used to format text in HTML. Click on the links below to see each type.
Spacing
Font Attributes


Spacing     Back To HTML Formatting     Back To HTML Start    Main NPR Menu
The browser never reads more than one space. Therefore if you copy/paste the below select into your html document:
    @patient's.name                 EQ
           "DOE,JOHN"
It will appear in your browser as: @patient's.name EQ "DOE,JOHN"   -   All one line, no more than 1 space.

Below are the codes which will help in formatting text.

&nbsp = Adds 1 space
<BR> - Break - Text starts on next line
<PRE></PRE> Displays data exactly as typed in editor. Works great for display the select page or displaying the result of a report in landscape format when you don't want text wrapping. Click for example
        @patient's.name           EQ
               "DOE,JOHN"


Font Attributes    Back To HTML Formatting     Back To HTML Start    Main NPR Menu
The below codes can be used to specify how the characters should appear
<B>Bold</B>
<I>Italic </I>
<BIG>BIG <BIG>
<SMALL>SMALL<SMALL>
<FONT SIZE="+2">To Increase Font </FONT>
<FONT SIZE="-2">To Decrease Font </FONT>


Linking     Back To HTML Start    Main NPR Menu
  • To Link to another specific spot in the same document - <A HREF="#SPOTTOLINK">Click here to go to spot</A> For this to work, you must have the desired location named. <A NAME="SPOTTOLINK">This names the desired spot in the html document.</A>
  • To Link to another document - same subdirectory - <A HREF="html file name.html"Text on Screen</A>
  • To link to another document - down subdirectory - <A HREF="directory/html file name.html">Screen text</A>
  • To link to another document - up directory - <A HREF="../NPR-INFO.html">Back to NPR Info Page</A>
    **The "../" means to move up one level.