Hi, Below is the code what im using in the watcher expression to automatically create an order only once. But when put the document on hold and open the same document again a new order is created. This time the below condition fails to check. Now I could find that the same order is created twice. Is there any way to prevent multiple entries of orders even after the document is opened from hold? Thanks in advance
if(match(str(ORDERS_ALL("delim")), 1, "(1170F)") > 0) then
""
else
userok("Order Created")
MEL_ADD_ORDER("S", "Quality Codes", "(1170F) Functional status assessed (COA)", "", "", "", "", "", "", "", "")
endif
You might try placing an exclamation point "!" in front of the if statement to ensure the watcher expression runs when the form is opened. Also, you might consider moving your userok statement after the Order is created. While not necessary, you might not want to inform the user the order was created until after the order is actually generated in the event there is an error of some kind. See modified code below:
!if(match(str(ORDERS_ALL(“delim”)), 1, “(1170F)”) > 0) then
//do nothing, order already exists
else
MEL_ADD_ORDER(“S”, “Quality Codes”, “(1170F) Functional status assessed (COA)”, “”, “”, “”, “”, “”, “”, “”, “”)
userok(“Order Created”)
endif
This is the actual code that is being used. It duplicates the order every time the encounter is opened from "On Hold" status.
{
local Var_adlall
Local Var_adlsum
Local Var_iadlall
Local Var_iadlsum
Local Var_funcstatus
Local Var_sel_funcc
Var_adlall= lastobsdate("ADL ALL")
Var_adlsum= lastobsdate("ADL SUM")
Var_iadlall= lastobsdate("IADL ALL")
Var_iadlsum = lastobsdate("IADL SUM")
Var_funcstatus = lastobsdate("FUNCT STATUS")
if (Var_adlall >= Var_adlsum and Var_adlall >= Var_iadlall and Var_adlall >= Var_iadlsum and Var_adlall >= Var_funcstatus) then
Var_sel_funcc = Var_adlall
else if (Var_adlsum >= Var_adlall and Var_adlsum >= Var_iadlall and Var_adlsum >= Var_iadlsum and Var_adlsum >= Var_funcstatus) then
Var_sel_funcc = Var_adlsum
else if (Var_iadlall >= Var_adlall and Var_iadlall >= Var_adlsum and Var_iadlall >= Var_iadlsum and Var_iadlall >= Var_funcstatus) then
Var_sel_funcc = Var_iadlall
else if (Var_iadlsum >= Var_adlall and Var_iadlsum >= Var_adlsum and Var_iadlsum >= Var_iadlall and Var_iadlsum >= Var_funcstatus) then
Var_sel_funcc = Var_iadlsum
else
Var_sel_funcc = Var_funcstatus
endif
endif
endif
endif
if((PATIENT._AGEINMONTHS/12) < 65) then
""
else
if(lastobsvalue("ADL ALL") == "" and lastobsvalue("ADL SUM") == "" and lastobsvalue("IADL ALL") == "" and lastobsvalue("IADL SUM") == "" and lastobsvalue("FUNCT STATUS") == "")then
""
else
if(Var_sel_funcc <> "")then
if(sub(str(Var_sel_funcc), 7,4) == val(sub(str(._todaysdate), 7,4))) then
if(var_iscreated <= 5) then
var_iscreated = var_iscreated + 1
else
if(match(str(ORDERS_ALL("delim")), 1, "(1170F)") > 0) then
""
else
userok("Order Created")
MEL_ADD_ORDER("S", "Quality Codes", "(1170F) Functional status assessed (COA)", "", "", "", "", "", "", "", "")
endif
endif
else
""
endif
else
""
endif
endif
endif
}
I have found that the order in which the document loads and checks data can often lead to unintended results, even if the code is correct. Things like the Problem list not loading until after all my MEL code runs can cause a lot of problems for items on load.
To get around this, I usually put a edit field into a visibility field (set to FALSE) and make it a document variable. in my code, I check the document variable (instead of the orders) and if it is blank, I place the order, and set the document variable to "T" or "Ordered" or whatever you like. Until GE fixes the weird order of loading (I am hopeful for 12.2!) this has been the most consistent fix for me.
I agree with your approach as well. Referencing a hidden document variable is the only tactic I have been able to use that will give consistent results when you are trying to verify the state of the form (initial load vs. opening from hold status).
Daniel/Greg,
I appreciate the response from both of you but I wanted to repost again with a few clarifications. What we are trying to do is automatically add some Orders based on some conditions, without the user having to go to a specific form or orders. The above code was added to the Watcher Expression, which works for the most part but if the encounter is placed on hold and then reopened, the Order is duplicated. Of course, the order is added as many times the encounter is placed on hold. We have several orders that we would like to automate so we have similar code for other orders as well.
I would really appreciate some guidance and thank you in advance. I would be more than happy to share the form as well.
Thank you for the clarification Amar,
The reason it is re-ordering when opened from on hold is most likely due to your very first line:
if(match(str(ORDERS_ALL(“delim”)), 1, “(1170F)”) > 0) then ...
While this is correct code, the problem lies in when CPS loads the problem list. When you load a document (even from on hold) it does the following:
1. load mel
2. check if ORDERS_ALL contains a certain code
3. No orders detected, so order a new Quiality Code (1170F)
4. Load orders.
Notice how it runs the MEL code before the orders? If you run the ORDERS_ALL check when the form loads, then you get duplicates.
A solution to this is to create a hidden document variable, and when an order is successfully placed, populate the DOCUMENT.Q_CODE (or whatever you wish to call it) with a value. then the process when the document is put on hold is:
1.load DOCUMENT variables.
2. load mel
3. check if DOCUMENT variable is set. if not, order the code.
4. DOCUMENT variable == "Done", so no order is placed
5. Load orders.
When the form loads the first, the DOCUMENT variable is set to "", so the order still automatically gets placed, but it will not duplicate for you.
If you are still having issues, please feel free to post the form (or email) and I can look at the code directly. ^_^
Thank you,
Daniel Carpenter
Hi Daniel,
It works when i load one form into the document. What we do is we have a document template and we load couple of form's when we create a new document and this form is loaded at the end so the variable what we place gets executed only when the form is clicked or opened.
Thanks,
For what it's worth, I concur with Daniel's solution below. While creating a document variable that is hidden may seem "clunky", it's generally the only solution that will work consistently when you have multiple forms in a document template. One of the big limitations in forms development and the MEL programming language is the absence of being able to trigger functions on certain events (in your case, when the document loads). Watcher expressions can be used to work around this limitation to a certain degree, but triggering functions to run only one time (e.g. when a form or document template is opened the first time) requires an alternate solution. The scope of local and global variables is not sufficient to "remember" whether or not a particular function was executed once you put the document on hold; this is because local variables die after the function runs AND global variables die when the document is placed on hold. The two workarounds that are often used are one of the following:
- Create a textbox that is bound to a document variable (DOCUMENT.MYTESTVAR) and then place the textbox in a visibility region that is hidden; set the value of the variable to reflect the state of the document so that you can execute some function based on the value of that document variable (this is the approach Daniel has demonstrated below)
- Use a watcher expression to record some value to an unused OBS term and use OBSNOW("SOMEOBSTERM") to evaluate the contents of the OBS term in order to conditionally execute your function. In your case, if OBSNOW("SOMEOBSTERM") evaluated to an empty string, then that would tell you it is the first time the document was opened. You could then store whatever you wanted in that OBSTERM to facilitate the conditional execution of your function. Same strategy as above, only you would be capturing the value to an OBS term.
In my opinion, the first approach would be considered "best practice" for working around the limitations of MEL. While the second approach (i.e. using an OBS term) will work, I would use it only if you needed to track the contents of the variable (e.g. you could use it to track the number of times the document template was opened and by whom); this is a clever trick that can be used if you wanted to create an audit trail that gets stored in an OBS term.
Hello All -
I am having the same issue with multiple orders generating but you're responses above are very high level for a beginner like me.... Can you 'dumb' it down so I can understand what you're talking about? 🙂
Sure thing! Basically, the code that checks if the order has been made today is running as soon as you open the form. if the form and the database could talk, it would sound something like this:
Form: "Hey Database! Has anyone placed an order that has 1170F in this note? "
Database: "Hang on a second, I'm still loading some other data..."
Form: "I'm just going to take that as a 'No' and place another order. Thanks man!"
In order to get around this, we have to create a DOCUMENT Variable (like an edit field) that stores a value when the order is placed the first time. The form now looks at this DOCUMENT variable instead of asking the database if an order was placed last time the form was open.
While this is a bug that GE should fix. (the form should wait for an answer from the database, instead of just moving on), this workaround solves the issue of multiple orders.
If you need help with your specific code, feel free to post it, or ask in a new question. 🙂
Thank you,
Daniel
Good afternoon. Looks like this discussion wound down about 5 years ago, but I sure would appreciate some assistance.
I'm using the MEL string below to generate suicided watch follow-up orders.
{if match(OBSNOW("Watch_FU"), "Standard Follow Up - 1 day. 3 day. and 7 day")>0 then
MEL_ADD_ORDER("T", "Mental Health", "Suicide Watch Follow-Up", "", "", "", "1 day", "", "N", "", ADDDATES(str(._TODAYSDATE), "0", "0", "1")) and
MEL_ADD_ORDER("T", "Mental Health", "Suicide Watch Follow-Up", "", "", "", "3 day", "", "N", "", ADDDATES(str(._TODAYSDATE), "0", "0", "3")) and
MEL_ADD_ORDER("T", "Mental Health", "Suicide Watch Follow-Up", "", "", "", "7 day", "", "N", "", ADDDATES(str(._TODAYSDATE), "0", "0", "7"))
else "" endif}
And like ranpoop, I'm getting duplicate orders when the doc is placed on hold and when a user might toggle then select again the trigger value.
If either the document variable or OBS term resolution will work with this string will you show me how that might look/work?
With regard to the document variable, can the value be pushed using code, or does the user have to manually enter a value?
Hi dfrielodrc. I'd be happy to give you a point in the right direction. It looks like you are just about there with your code as it is. If you would like that OBS term updated, here is what your form should look like:
{if match(OBSNOW("Watch_FU"), "Standard Follow Up - 1 day. 3 day. and 7 day")>0 then
MEL_ADD_ORDER("T", "Mental Health", "Suicide Watch Follow-Up", "", "", "", "1 day", "", "N", "", ADDDATES(str(._TODAYSDATE), "0", "0", "1")) and
MEL_ADD_ORDER("T", "Mental Health", "Suicide Watch Follow-Up", "", "", "", "3 day", "", "N", "", ADDDATES(str(._TODAYSDATE), "0", "0", "3")) and
MEL_ADD_ORDER("T", "Mental Health", "Suicide Watch Follow-Up", "", "", "", "7 day", "", "N", "", ADDDATES(str(._TODAYSDATE), "0", "0", "7"))
OBSNOW("Watch_FU","Standard Follow Up - 1 day. 3 day. and 7 day")
else "" endif}
The last line I added will use code to set the OBS Term to "Standard Follow Up - 1 day. 3 day. and 7 day" This will make it so when the code re-evaluates after being placed on hold, the if statement will return FALSE, and skip the ordering section again.
If you update that OBS term elsewhere, you will want to set up a document variable to check that the orders were added. I can show you how that would look as well if interested.
Thank you, and good luck!
Daniel Carpenter
Good morning dcarpenter,
Appreciate your response to my dilemma. I added the line of code you supplied, thus:
{if match(OBSNOW("Watch_FU"), "Standard Follow Up - 1 day. 3 day. and 7 day")>0 and DOCUMENT.STATUS "H"then
MEL_ADD_ORDER("T", "Mental Health", "Suicide Watch Follow-Up", "", "", "", "1 day", "", "N", "", ADDDATES(str(._TODAYSDATE), "0", "0", "1")) and
MEL_ADD_ORDER("T", "Mental Health", "Suicide Watch Follow-Up", "", "", "", "3 day", "", "N", "", ADDDATES(str(._TODAYSDATE), "0", "0", "3")) and
MEL_ADD_ORDER("T", "Mental Health", "Suicide Watch Follow-Up", "", "", "", "7 day", "", "N", "", ADDDATES(str(._TODAYSDATE), "0", "0", "7"))
OBSNOW("Watch_FU","Standard Follow Up - 1 day. 3 day. and 7 day")
else "" endif}
Uploaded the kit to our build/test environment and the duplicates persist. Not sure if I entered your code improperly, or because I didn't include in my description of the problem that the OBS term gets set by a value selected in a filed in the form.
Here is some detail on the construction of the form component.
The encounter is used by MH clinicians to document the status of patients on suicide watch. Where the clinician determines the patient can be removed from watch they make follow-up recommendations by making a selection in this field. The field is a list box, single select, mapped to the OBS term ("Watch_FU"), selection options/values are: Standard Follow Up - 1 day. 3 day. and 7 day or None. So the Watch_FU OBS term gets set to the value the clinician selects.
I don't know if that bit of information changes your analysis of how to remedy the problem. I am sloe interested in how the document variable fix could work.
I have this same duplication issue with a form that generates directives, based on a selected field value selection. Hoping I can find a solution that I can apply to other form components.
Really appreciate your assistance.
No Problem. I may have steered you wrong a bit, as I misread what your if statement was checking. If they already pick that obs term, and that is what you are checking, then it will keep repeating.
Go ahead and remove my code, and try this one instead:
{if match(OBSNOW("Watch_FU"), "Standard Follow Up - 1 day. 3 day. and 7 day")>0 and match(ORDERS_NEW("list"),"Suicide Watch Follow-up") == 0 then
MEL_ADD_ORDER("T", "Mental Health", "Suicide Watch Follow-Up", "", "", "", "1 day", "", "N", "", ADDDATES(str(._TODAYSDATE), "0", "0", "1")) and
MEL_ADD_ORDER("T", "Mental Health", "Suicide Watch Follow-Up", "", "", "", "3 day", "", "N", "", ADDDATES(str(._TODAYSDATE), "0", "0", "3")) and
MEL_ADD_ORDER("T", "Mental Health", "Suicide Watch Follow-Up", "", "", "", "7 day", "", "N", "", ADDDATES(str(._TODAYSDATE), "0", "0", "7"))
else "" endif}
The statement I added is {match(ORDERS_NEW("list"),"Suicide Watch Follow-up") == 0} This will check the orders placed today, and if they select the Obsterm for standard follow up as you have described, and no orders have been placed, it will run your code. Once the orders are in the system, the code will not run again in this note. Notice that I se ORDERS_NEW, so it only checks for orders placed in the current note, not all orders in the patient chart record.
To use a document variable, you would create a new edit field and name it SUI_ORDER. Make sure to delete the text translation so it doesn't randomly show up in the provider's note. You would then place the edit in a visibility field, and in the logic section, enter FALSE.
finally, change your code with this function:
{if match(OBSNOW("Watch_FU"), "Standard Follow Up - 1 day. 3 day. and 7 day")>0 and DOCUMENT.SUI_ORDER == "" then
MEL_ADD_ORDER("T", "Mental Health", "Suicide Watch Follow-Up", "", "", "", "1 day", "", "N", "", ADDDATES(str(._TODAYSDATE), "0", "0", "1")) and
MEL_ADD_ORDER("T", "Mental Health", "Suicide Watch Follow-Up", "", "", "", "3 day", "", "N", "", ADDDATES(str(._TODAYSDATE), "0", "0", "3")) and
MEL_ADD_ORDER("T", "Mental Health", "Suicide Watch Follow-Up", "", "", "", "7 day", "", "N", "", ADDDATES(str(._TODAYSDATE), "0", "0", "7"))
DOCUMENT.SUI_ORDER = "Suicide Watch Orders Placed"
else "" endif}
You can do either one of these options in your other forms. I sometimes use the Doc Variable if I want specific text to show in the note, or if I have multiple visibility fields controlled by the same option. You can even make a new Visibility field that has the following logic {DOCUMENT.SUI_ORDER <> ""} and then put a text item to say "Suicide Watch orders placed."
There is a lot you can do, but let me know if you need further info on the code above, or s not work. Sorry for the goof-up before. 🙂
Thank you,
Daniel C.