MEDITECH MAGIC or Client/Server – Force a report to PREVIEW and show bar codes for scanning
A MEDITECH MAGIC customer recently asked us to produce a report that could show bar codes on the screen of all current ER Patients to allow Nurses to scan an account number code and then any supplies issued to the patient.
Charging for the “patient issues” was being done by MM staff who would download the set of account number and item bar codes from the hand-held scanners a few times per day to create patient issue charges in MM.
The plan was to have a PC in the supply room setup to run an NPR report and produce output like this on all current ER patients, so bar codes could be scanned from the screen before item bar codes were scanned as chargeable supplies are picked up:
We want a report that does the following:
- Automatically outputs to PREVIEW (no print on prompt for user)
- Creates a two column list of patients with bar codes
The first step is to build a report in EDM.PAT that gets current ER patients. We can just use the "tracker.patients.index":
We want to sort the patients by name and exclude the entries in the tracker index that represent empty rooms:
Now we want to manipulate the report so that there is no "Print On" prompt for the user and the output automatically goes to PREVIEW.
Step #1 is to "imbed a program in the title." To get the title for the report selection window, and to put the title of the report in the Page Header, the string in the report title is executed as a line of magic code. What this means is that we can imbed a program in the title, and that program will be executed as the selection screen is displayed to the user.
We just need to write a macro "as a program" (below we call the macro "d"), and imbed in the title surrounded by double quotes and underscores:
In Client Server, the "internal" or "object code" name needs to be used, like this:
The way to tell how the macro is named is to use the "List Object Code" option from process reports and check the name in the lookup box:
Let me explain how you create the "d" macro so it is a program that both forces output to "PREVIEW" and gives your report a title to show for the selection screen window and to print in the page banner (if you have one).
The first thing to know is that a macro created to be a program needs to end with a semi-colon, and the last Magic expression before the semi-colon will be the value that the program returns.
So, if we want to have a "title macro" return "THIS IS THE TITLE OF THE REPORT," we write it like this:
With this macro imbedded in the title and no selections for the report, when we run the report we get this:
To suppress the "PRINT on:" prompt and force the report to PREVIEW, we need to do two things in our macro; call the printer selection utility "Z.on.device" with a hardcoded printer selection of "PREVIEW" and then to set the /Z.SCHED.LOG flag, which will cause the report writer’s call to Z.on.device to do nothing.
While we are at it, we will change our report title to something a little less generic:
Finally, we use a /DONE flag to set up the "d" macro so that the diversion to PREVIEW only happens once. Since the report title macro will run multiple times (when the selection screen displays, and then as each new page prints), we would have odd behavior if we tried to open to PREVIEW multiple times in the same report run.
The Client Server "d" macro is slightly different because the arguments to Z.on.device for C/S are different, with the device passed in as C vs E and using the D argument to suppress the dialog box to the user.
For reference when writing macros, it can be very helpful to use the F(4) "get" key in the macro editor to view the source code of a MEDITECH procedure. The arguments are typically in comments at the top of the program. In the example below, I copied these comments into my macro.
The first time the macro runs "not done" or ‘/DONE is TRUE and the code in the IF statement runs and puts a value of 1 into /DONE. The next time the macro runs, ‘/DONE is false so the condition of the IF is not executed.
The apostrophe is the "not" operator. When used on a slash or permanent data structure or a variable, it returns a value (true) if the structure does not exist or if the variable is nil, and nil (false) if the structure exists or the variable has a value.
Now we have a report that goes directly to PREVIEW.
The next step is to set up the report to store the set of patients selected in a list, and print them out in two columns in the trailer.
Our report has no detail region, just a TR. Per each detail record, we store our patients using a bit of code in a footnote:
The "tr" macro is going to run before the TR region gets printed. What we need to do in the tr macro is to split our list of patients into a left column and right column. In this report I decided to keep the columns in alpha order like this:
Rather than like this:
The size of the ER at the hospital for which I was writing was such that the entire set of ER patients would likely fit on one page of output, and I thought snaking rather than zig-zag made a better sort order.
The tr macro takes a structure build by the d footnote:
/LIST = urn of first patient
/LIST = urn of second patient
/LIST = urn of third patient
/LIST = urn of fourth patient
And makes it a list like this:
/DATA|0 = urn of first patient /DATA|1 = urn of third patient
/DATA|0 = urn of second patient /DATA|1 = urn of fourth patient
The steps are:
- Get the last value for the subscript of /LIST (that is total record count)
- Divide by 2
- Loop through the entire /LIST
- If you are in the first half of the list, put the urn into |0 of DATA[n+1^n]
- If you are in the second half of the list, reset n back to nil and put the urn in |1 of DATA[n+1^n]. We use the "r" variable to track whether we have done a "reset" to start loading the right hand values.
- Set n back to 1 as you start loading the second half
The actual macro looks like this:
Why didn’t we just load the data into a couple of /MV arrays and build a trailer region that looks like this?
The problem with this approach is that we are looking for output where each field in the column can have different formatting:
It is quite a nuisance to persuade fields loaded into an MV array to have a variety of characteristics. It is easier (I know – easier for me) to wrap a loop around a set of lines and set up individual fields and use field characteristics to make 1 bold, another a bar code, etc.
The looping code goes through our /DATA[n] structure and puts the left hand column urn into the variable LEFT and the right hand column into the variable RIGHT and then we can set up computed fields like this:
Or for the bar codes:
Here is the ECB-ECE looping code:
Some further explanation for the diehard programmer-wannabes:
The looping is "next get" syntax, which allows you to loop through a data structure and put the value of each node into a variable in a single + operation.
Is the same as:
Takes the zeroth piece of DATA and puts it into the variable LEFT and the 1th piece of data and puts it into the variable RIGHT
It works like this:
All give you this:
XXX|0 = "FIRST"
XXX|1 = "SECOND"
And you can do this:
And then A = "FIRST" and B= "SECOND"
So now we have a report that runs like this (Magic example shown, C/S is similar):
And (here shown with a page banner) has output like this:
Sample reports for C/S and Magic named EDM.PAT.zcus.is.bar.code.page have been loaded to our Report Library.