NOTE: This is an advanced topic, the author assumes the reader has an intermediate level of skill on the NPR Report Writer.
If you're looking to mimic the functionality in a standard MEDITECH lookup, the MEDITECH Z.id program will get the job done. The information in your lookup can be a simple list or generated from MEDITECH data. Using Z.id, you can create a lookup for a standard field or a custom field, the process is the same.

To get started, read the rest of this article in the February MEDITECH Bulletin.
How do you add a comma in the thousands place?eg. 1000.00 = 1,000.00 or 1000000.00 = 1,000,000.00
Read the MEDITECH Answer here.
How do you use a predefined list in an NPR LI Select?
I have tried both LI and CL with my criteria ("ED", "PNP") and I am crashing my report.
Read the MEDITECH Answer here.
Where can I find the MEDITECH Programmer's User Manual?
Read the MEDITECH Answer here.
Come to the MEDITECH KE and ask a question of your own.
BUF NONE, it's not just for pretty translation screens & readable object code.

This overlooked NPR FOOTNOTE can improve the performance of your MEDITECH reports. Joe's tip in the Iatric Systems, December 2009 Newsletter explains why you might want to use this FOOTNOTE in most of your Client Server NPR reports.

Quoting the MEDITECH NPR Manual: "To turn off buffering, enter BUF NONE in the report's footnote section. If a report has a VAL statement that attempts to replace elements with buffered results increasing a line's length longer than 255 characters, a translation error message appears."
NPR Report Writer, Ben Dorsey, at Iatric Systems, cleverly used @Macro in a recent MEDITECH CS Report. Not being familiar with @Macro, I've compiled it in a report to share it with you.

@Macro works by dynamically compiling the local macro named init, into NPR object code.
NPR macros become unweildy, when their length extends beyond a couple hundred lines; at which time, NPR Macro Editor Screen corruption is possible, risking macro integrity.

Upside:
- You don't have to call each macro by its fully qualified name. This saves you trouble later, when the report is copied or renamed.
- Macros are easier to read & edit, because they are shorter.

Downside: Translate your report after any changes - and I'm not sure there is one.
If you've been writing reports for awhile, you've found that MEDITECH Data Definitions are essential to your success in writing reports. Report writers, everywhere, use them on a daily basis.
If you'd like to learn how to search them all at once, read the rest here in the MEDITECH Community Bulletin.
Most programming languages have a lot of different functions for manipulating text, example: converting text to lower OR upper case.

Come kick off a new section in The MEDITECH KE, a MEDITECH Community Wiki, titled String Manipulation. The first entry is titled 1 way to Convert MEDITECH Text to Lower or Upper Case.
For months - this bug ran undetected. One day the right conditions allowed it to crash the report.
In this case, /PROC[SU,6] was printed in a custom field:
xx.proc.6
DAT=FREE
LEN=40
VAL=/PROC[SU,6]
The vendor, who'd requested the extract, didn't need data beyond procedure 5 and requested that any remaining data reported in field xx.proc.6. The values in xx.proc.6 would likely be used for manual review if needed. The field only reported the value to a length of 40 characters.
As you know, MEDITECH variables on the Client Server & Magic platforms are limited to 255 characters. However, this code allowed more than 255 characters to be assigned to a variable (/PROC[SU,6]): /PROC[SU,6]_", "_@actual.op^/PROC[SU,6].
To resolve this overflow, the IF statement can be modified to stop processing when the length of the existing variable (/PROC[SU,6]) and field (@actual.op) will be greater than 255 characters when strung together:
IF{L(/PROC[SU,6]_", "_@actual.op)>255 0^/CONTINUE; ...
By implementing a condition based on the value /CONTINUE; the variable /PROC[SU,6] will never contain more than 255 characters. Now our DO{@PROC.NXT stops; this prevents inaccurate reporting if the next value for @actual.op is short enough to print in a field of 40 characters.
PROC.NXT
(/CONTINUE=1)&(@Next(actual.op.urn))
PROCEDURES
""^actual.op.urn,1^/CONTINUE,
DO{@PROC.NXT IF{actual.op.urn<6 @actual.op^/PROC[SU,actual.op.urn];
IF{L(/PROC[SU,6]_", "_@actual.op)>255 0^/CONTINUE;
/PROC[SU,6] /PROC[SU,6]_", "_@actual.op^/PROC[SU,6];
@actual.op^/PROC[SU,6]}}},
IF{/CONTINUE=0 (/PROC[SU,6]_", "_@actual.op):40TL^/PROC[SU,6]}
When you've inherited a report from another report writer, it is tempting to re-design and re-write the report from scratch. There's a saying in the programmer / developer world that goes something like this: if you can come back a year from now and review code you wrote today ... and not want to change anything, you're an expert.
Question: What could be more important than writing expert code in every report you work on?
Answer: Keeping your time focused on those reports that most 1) improve patient outcomes OR 2) contribute to the bottom line.
Have questions? Need answers? Join some of the smartest MEDITECH people in the industry at the Meditech Knowledge Exchange