It is common to have a report that should be run for a GL period (here we assume this is a calendar month) and the easiest way to program this is to prompt for a date range and let the user figure out how many days in the month. You can add some error checking to reject an ending date that is not the last day of the month with an "FCL" attribute, but another approach would be to prompt them for the GL period and write some code to get the start and end dates based on the period selected.
This month we will show you how to add this programming to your report in a "start" macro and, for extra credit, show how to have the report run automatically for the prior month for the case where it is scheduled to run after month end.
First we set up a report with a date based index, in this example we want to go through BAR transactions in BAR.BCH:
Next we set up selections to prompt for a period, to restrict to "RCP" transactions, and to limit the report to a date range we will create from the GL period selected.
We need to write a small "start" macro to use the period that the user has selected to put the start date of the period in /FROM and the end date in /THRU.
When you prompt for field, the value supplied by the user at run time is stored in the temp file and the value is stored in a variable which has a name based on a "b", "c" or "e" based on the selection operator. "b" for GT and GE. "e" for "LT and LE" and "c" for EQ or IG. When you are prompting for a field that is in some other DPM (not the DPM of the report), the screen translator puts the "b", "c", or "e" after the DPM.
So we will have the user selected period in MIS.GL.PERIOD.c.period.
All we need to do is to put that value into MIS.GL.PERIOD.period (the subscript of the GL period dictionary) and then we have the ending date in @MIS.GL.PERIOD.ending.date to put into /FROM.
Then cut the YYYYMMDD off that value (using $6) and add a "01" and you have the start date to put in /THRU.
Then add a footnote to call the macro at "START"
The AL = ALGORITHM, the START is where the code gets called and "start" is the name of the macro on this report that is going to be incorporated into the report program by the translator at the "start" point (after printer and some report setup, but before any looping on indexes and record selection).
You might think this footnote is from the Department of Redundancy Department, but it actually is far better (in my opinion) to name your macros based on where they are called (or included in report translation) than with some invented name about what they do.
- If you look at a report written by someone else, you know that a macro called "detail" is called per record. If you see a macro called "guts" and another called "process" what does that tell you about where the code is executed?
- After you write the macro and are about to write the footnote reference, with my method you do not have to remember what you just called the macro, you just have to remember what you always would call it.
What if you schedule the report for the 5th day of the next month, allowing five days for any Month End snafus. How can we have the report run from the scheduler and automatically run for the prior month?
There is a scheduler convention to run for a calendar month, including a way to run for the prior calendar month, but I do not think there is a "prior period" convention, so we’d need to created a date range prompt version of the report to get that functionality. Instead, we can schedule the report with no period selected and modify our macro code to automatically run for the prior month.
In keeping with the MEDITECH practice of creating small annoying differences in the report writer between platforms, if you use the IG operator in MAGIC, the fields remains required, but if you use IG in C/S the field is optional. So, in MAGIC we need to go into the "Edit Elements" routine and change REQ=1 to REQ=N or REQ="" to avoid:
If we look at the C/S version of the report we see that the screen translator has already done things this way for us:
Now we need to modify our "start" macro so we use the MIS.GL.PERIOD.c.period selected if the report was run by the user (and a period was selected) or we use the current date and figure out the prior month if no period is selected. This adds a bit of convenience for the user because if they typically run for the prior month, then they can just leave the period blank and run the report and it will automatically do this.
First we write an IF statement and call two "sub-macros" based on whether we detect a period in the temp field or not. The way to break your macro into sub-macros is to call the submacro using an @ sign followed by some label, which should be all upper case with no spaces. Then these submacros are in the macro code separated by a single blank line and the same label with no leading @. This makes your code more readable and easier to maintain. Also you can use the same sub-macro in multiple places. You can nest these calls and have a macro call a sub-macro which then calls another sub-macro.
Warning – do not create infinite recursion like this:
If you do this, your translation will crash. If you submerge the translation, you can run your (MAGIC at least) system out of space.
Here is our new macro (C/S version, but MAGIC is identical) with the code to run for either the selected period or the prior month when no period is selected:
So if we run the report for no period:
Or if we run the report for a user-selected period:
This example report BAR.BCH.zcus.is.eupdate.run.for.period has been uploaded to both our MAGIC and C/S report libraries.