Well, that's no ordinary rabbit!

The MIS.OA.MSG.auto program can be used to email one, several or even all users. It can be used 2 ways - send a preformatted OA message to the group attached to it in the OA message dictionary or send a custom message to 1 or more users. The users can be hard coded into the program call, loaded from a distribution list, loaded from the group response dictionary, or even determined based on a query response. The program can be called from an attribute on a CDS or from within an NPR report.

Sending a preformatted OA message

This is done using the OA message mnemonic as argument A. The message is sent to the users/devices attached to the OA message in the OA message dictionary. To send the OA message HOT_PIZZA you would use this:

%MIS.OA.MSG.auto("HOT_PIZZA")X

Using a custom message

This is done using argument B. If B exists argument A is ignored. This argument contains at least 2 pieces of information in a packed Q. The first is the structure that holds the text message you want to send. I prefer to store my message in /MSG but any / structure is valid. You load the information you want into /MSG before making the program call.

"This is the first line of info"^/MSG[XX+1^XX],
"This is the second line of info"^/MSG[XX+1^XX],
"This is the third line of info"^/MSG[XX+1^XX]

The other pieces of information are the email recipients. These are simply added to the Q separated by commas. You could send the /MSG message to users "XYZ", "YYZ" and "ZYZ" like this.

%MIS.OA.MSG.auto("",Q(^/MSG,"XYZ","YYZ","ZYZ"))X

In the example "XYZ" is the MIS user id. You can also send messages to printers and even smtp email addresses (as long as you have an external mail server configured). Prefix printers with ! and smtp addresses with !!. You would send to user XYZ and printer PTR75 and smtp address tt@xyz.com like this.

%MIS.OA.MSG.auto("",Q(^/MSG,"XYZ","!PTR75","!!tt@xyz.com"))X

Sending an email from an attribute to a single user

Send an email to user "XXX" from
an OE procedure query if response is "Y"

Note: message is stored in /MSG
Message consists of patient name,
location, and OE procedure name

Note: email is sent when FCL is evaluated, not when order is filed.

FCL1=IF{@.response="Y" @ADM.PAT.name^/MSG[1],
FCL1=@ADM.PAT.location^/MSG[2],
FCL1=@procedure.name^/MSG[3],
FCL1=%MIS.OA.MSG.auto("",Q(^/MSG,"XXX"))X}

Sending an email from an attribute to multiple users

Send an email to users "XXX", "XXY" and "XXZ" from an OE procedure query if response is "Y"

Same other conditions as above.

FCL1=IF{@.response="Y" @ADM.PAT.name^/MSG[1],
FCL1=@ADM.PAT.location^/MSG[2],
FCL1=@procedure.name^/MSG[3],
FCL1=%MIS.OA.MSG.auto("",Q(^/MSG,"XXX","XXY","XXZ"))X}

Sending an email from an attribute to a distribution group

This will send the same info as above but to all users in a distribution group. Again the query response must be "Y"

The first method loops thru the distribution list and emails each one individually. The second method loops thru the distribution group and stores all the recipients in RES and then emails the whole group. Do not use the second method except for short lists.

FCL1=IF{@.response="Y" @ADM.PAT.name^/MSG[1],
FCL1=@ADM.PAT.location^/MSG[2],
FCL1=@procedure.name^/MSG[3],
FCL1=DO{+\GUG["EMAIL","U",XX]^XX
FCL1= %MIS.OA.MSG.auto("",Q(^/MSG,XX))X}}

or

FCL1=IF{@.response="Y" @ADM.PAT.name^/MSG[1],
FCL1=@ADM.PAT.location^/MSG[2],
FCL1=@procedure.name^/MSG[3],
FCL1=^/MSG^RES|0,DO{+\GUG["EMAIL","U,XX]^XX
FCL1= QQ+1^QQ,XX^RES|QQ},%MIS.OA.MSG.auto("",RES)X}

Sending an email from an attribute to a group response list

Same conditions as above but this time using a list of users stored in the group response dictionary in a group called "EMAIL".

The first sends each individual a message. The second emails the group. Again, do not use the second method except for short lists.

FCL1=IF{@.response="Y" @ADM.PAT.name^/MSG[1],
FCL1=@ADM.PAT.location^/MSG[2],
FCL1=@procedure.name^/MSG[3],
FCL1=DO{+\GGL["EMAIL","E",XX]^XX
FCL1= %MIS.OA.MSG.auto("",Q(^/MSG,XX))X}}

or

FCL1=IF{@.response="Y" @ADM.PAT.name^/MSG[1],
FCL1=@ADM.PAT.location^/MSG[2],
FCL1=@procedure.name^/MSG[3],
FCL1=^/MSG^RES|0,DO{+\GGL["EMAIL","E,XX]^XX
FCL1= QQ+1^QQ,XX^RES|QQ},%MIS.OA.MSG.auto("",RES)X}

Sending an email from an attribute to all active users

Sending email to all users from an attribute is not something I would recommend since it could take quite a while to loop thru all the users and email them. Meanwhile someone is waiting for the cursor to go on the next query and is probably getting frustrated.

FCL1=IF{@.response="Y" @ADM.PAT.name^/MSG[1],
FCL1=@ADM.PAT.location^/MSG[2],
FCL1=@procedure.name^/MSG[3],
FCL1=DO{+\GU[XX]^XX IF{"Y"=\GU[XX]|0
FCL1= %MIS.OA.MSG.auto("",Q(^/MSG,XX))X}}}

Sending an email from an NPR report

I use this quite often so users do not have to look for spool files or to immediately notify someone of a problem. I have reports that check printer status, scheduled reports status, fax port status, etc. The reports email me any problems found. This example checks the MIS report scheduler and notifies me of any that have been running for an excessive amount of time or that are missing from the schedule. The report itself doesn't print anything - the detail macro loads data into /MSG and the email macro emails it when the report is finished.

Detail DPM: MIS.JOB
Detail Segment: mis.print.jobs

Selection 1: mnemonic NE "SCHEDULES"
Note: SCHEDULES is the mnemonic of the schedule that runs the report. We skip it because it would always be running.
Selection 2: end.date EQ ""
Selection 3: end.date GE (@.today)
Selection 4: active EQ "Y"

Select Relationship: C2!C3

Footnotes: AL START start
           AL D detail
           AL CLOSE.UP email

;--- start macro
;--- this loops thru the scheduled jobs and stores
;--- the next run information in /INFO
""^DT,
DO{+:GZJI[DT]^DT ""^TM,
                 DO{+:GZJI[DT,TM]^TM ""^MNE,
                                     DO{+:GZJI[DT,TM,MNE]^MNE @JOB.INFO}}}

JOB.INFO
;--- store next run date, time, current status in /INFO
IF{/INFO[MNE];
   DT^/INFO[MNE]|0,
   TM^/INFO[MNE]|1,
   :GZJI[DT,TM,MNE,DT,TM]|0^/INFO[MNE]|2}

;--- detail macro
mnemonic^MN,
IF{/INFO[MN]|2="R" @RUNNING;
   /INFO[MN]|0_.=. @MISSING}

RUNNING
;--- sometimes a report will crash but its status is improperly reported as running
;--- if report is currently running give time and date it started to run
;--- if the start run time is over 1 hr from current time send messge
%Z.elapsed.time(/.DAT,@.now,/INFO[MN]|0,/INFO[MN]|1,"hh.hh")^LAPSE,
IF{LAPSE+0<1;
   MN_" has been running since "_%Z.date.out(/INFO[MN]|0)_" "_/INFO[MN]|1^/MSG[XX+1^XX],
   "Please investigate."^/MSG[XX+1^XX]}

MISSING
mnemonic_" is missing from schedule."^/MSG[XX+1^XX],
"Please investigate and reschedule if necessary."^/MSG[XX+1^XX]

;--- email macro
;--- if message queue is empty send OK message
IF{/MSG[1]_.=. "All scheduled RPTs OK "_%Z.date.out(@.today)_" "_@.now^/MSG[1]},
;--- replace "ISTJT" with user initials who should receive the email
Q(^/MSG,"ISTJT")^ARG,
%MIS.OA.MSG.auto("",ARG)X

More emailing from an NPR report

This is basically the same as the previous example, but this time we'll make it a little more complicated. We'll use one report to email each department head a list of the dept's employees with birthdays in a selected month/day range. To make it easy let's assume the department head ids are stored in a group response dictionary called DEPTHEADS with the department as the element and the department head as the element name.We need to put all the intended output including headers and/or footers into /MSG. We need to do these things:

   1. store a header in the first line of the message

   2. load the employee info for each detail record in suceeding message lines

   3. email the message to the dept head in the dept trailer region and store errors

   4. delete the previous message lines to prepare for the next dept

   5. repeat from step 2 until all depts are processed and emailed

   6. email an error report for missing dept head information

Detail DPM: PP.PER
Detail Segment: pp.employee.file
Index DPM: PP.PER
Index File: pp.employee.dept.name.index

Sorts - leave as they appear - dept/sort.name/employee

Select 1: month.and.day.of.birth  GE  From Birthday (MM/DD)
Select 2: month.and.day.of.birth  LE  Thru Birthday (MM/DD)
Select 3: being.paid  EG  "Y"

Footnotes:
AL START "Missing Dept Heads Error Message"^/ERR[YY+1^YY]
AL HK1 load.header
AL D @name:30TL_(@number:10TL)_(%Z.date.out(@date.of.birth))^/MSG[XX+1^XX]
AL TK1 email.and.cleanup
AL CLOSE.UP email.errors

;--- load.header macro
;--- Load header line into /MSG
"Employee Name":30TL_("Number":10TL)_"Birthdate"^/MSG[1^XX],
;--- Load a line of dashes to separate the header from the data
"-":49^/MSG[XX+1^XX],
;--- store the dept for use in the email macro
@dept^DPT

;--- email.and.cleanup macro
;--- get the recipient from the group response dictionary
\GGL["DEPTHEADS","E",DPT]|0^RCP,
;--- if no value exists store the dept in /ERR for error email
;--- otherwise send the email
IF{'RCP DPT^/ERR[YY+1^YY];
   %MIS.OA.MSG.auto("",Q(^/MSG,RCP))X},
;--- clear out /MSG so the same structure can be used for the next dept
""^XX,
DO{+/MSG[XX]^XX ""^/MSG[XX]}

;--- email.errors macro
;--- the departments that did not have dept heads defined in the group response
;--- dictionary have been stored in /ERR.
;--- We will email these to user ABCDEF who is responsible for the dictionary upkeep
;--- First check to see if there were any errors and if so email them
;--- We put header information into the first line
;--- so the first error will be in line 2 so see if it exists
;--- this should fit as a footnote but where would I have put the comments?
IF{/ERR[2]_.'=. %MIS.OA.MSG.auto("",Q(^/ERR,"ABCDEF"))X}


Other Magic Pages

CDS Attributes Emailing Messages Emailing Scheduled Reports
@W. prompts String Manipulation NPR Viewer
Text Edit/View Attribute Meds in an NUR CDS NUI Desktop Icons
Field Attributes Lab results in a CDS Ultimate Message Box
Display Message Attributes Run NPR Report Attribute Multiple Query Checklist
NUR Canned Text in Query Mousetributes LAB TEST VIEW GROUP
OA Msg from PHA Rule FTP Standard Report HTML Pt Master Logs
PCI NPR Report


Don't see what you need?  Visit one of these other sites

Iatric Systems web site
Attributes
NPR tips
NPR reports
Magic and C/S Products
ITNurse.net
Hosted by Daniel Davis
Resources for the IT Nurse
Articles and Discussion Forum
Debbie Kelly web site
Attributes
Meditech tips
Nursing Informatics
Debbie Bate-Travis web site
Attributes
Links to other attribute sites
Links to Nursing Informatics sites
Magic NPR Report Writing
Blogged by John Sharpe
NPR Report Writing Tips

or email me your request (tomt at thomast357.com).