I feel like I'm missing something really obvious here, but hopefully someone can help explain ! as a concept in a way the three documents about MEL I have can't.
Here's my situation. If the patient has a BMI issue, a message appears on the A&P form that says "Assessment Needed." When the assessment is recorded, the message changes to "Assessment Complete".
Here's my problem: This "Assessment Complete" message needs to persist for a year. Currently, when I make the assessment, sign the document, and start a new Encounter Form, the message reverts to "Assessment Needed".
Here's the code I'm running to check this. I have the ! in front of the fn, but the function doesn't run when I open the form. It does work when I tie it to a button and click it, but that's not helpful to me. What am I missing?
{
!fn oneYearPassed() {
if (DURATIONDAYS(LAST_SIGNED_OBS_DATE("WEIGHT EDUC"),
str(._TODAYSDATE)) >= 365) then
OBSNOW("WEIGHT EDUC", "Needed")
else
OBSNOW("WEIGHT EDUC", "Not Needed")
endif
}
}
Thanks!
I've also just noticed two build errors that so far haven't affected functionality:
ERROR: Unable to open library Utility. Functions will not be included in clinical kit
ERROR: Unable to open library Clinical_Lists. Functions will not be included in clinical kit
Could this be part of the problem? Nothing else I've written for this form has not worked, so I don't think this is the issues, but this is MEL...
Responding from my phone so forgive me if this seems unlikely. Have you tried using >364 as the operator comparison for your DURATIONDAYS statement instead of >=365? I have seen others have issues with the >= operator.
For functions the ! just changes which file the code goes in (moves it to the XLW file), and therefore what order the code is loaded in. Using the ! will load the function before any code is actually run, making it available to be used on open, it doesn't actually run the code on open, to do that follow what you have with this -
{!oneYearPassed()}
Also though, I have found that observation terms are one of the last items to get loaded, so even if you get it to fire, when it does fire you may find that LAST_SIGNED_OBS_DATE(anything) is NULL. It might be more effective to do this (if users don't have the ability to change the selection.)
{!
if (DURATIONDAYS(LAST_SIGNED_OBS_DATE("WEIGHT EDUC"), str(._TODAYSDATE)) >= 365) then
OBSNOW("WEIGHT EDUC", "Needed")
else
OBSNOW("WEIGHT EDUC", "Not Needed")
endif
}
I've learned that nothing is unlikely in MEL! This didn't work, but thanks for the suggestion.
Just to clarify and to make sure I'm testing your ideas right:
{!oneYearPassed()} is a function call that is separate from the actual function, right? So I can call it anywhere in the back end code and it should run first.
The OBS term loads without a problem (I have a data field displaying this and it's always full), but your other thought was to simply have this code run without a function associated with it, right? So I drop the function name and just run the if statement.
Neither of these ideas work. I even put the contents of the function in the button without the function name and it worked. The form just won't open with the right message on top. OBSNOW("WEIGHT EDUC") keeps reverting to "Needed" on form open...
Right, I have never spent the time digging through traces to prove this, but I think the load order goes like this -
1) Load document temp symbols (new ones created as they are called
2) load function definitions from xlw (any function with the ! out front)
3) load and run call from XLW file (non functions with the ! out front
4) load function definitions from XLT (the rest), start loading observations (seems like its loaded on a separate thread)
5) load calls from XLT, execute anything that is called by a change in a variable
If any has more precise knowledge of the inner workings I would love to see it, but for this purpose I think you should be able to figure this out as a guide. So with only the above code in a form, it would fire at step 3, observations would be loaded around step 4 or 4.5ish. I was sort of banking on the fact that another observation term was being set in step 5, causing all observation terms to be re-evaluated and code to fire again correcting itself.
The other thing you can try is create a visibility field and set it to FALSE (so it will not display) and hide it on the form. The put the same code WITHOUT the ! in a data display in the visibility field. The last thing the loads (even after observation terms) is anything on page 1 of the first form in the encounter.
Also, running a MEL Trace would give you some visibility into why it is happening...
The other thing you can try is create a visibility field and set it to FALSE (so it will not display) and hide it on the form. The put the same code WITHOUT the ! in a data display in the visibility field. The last thing the loads (even after observation terms) is anything on page 1 of the first form in the encounter.
This worked! I'm not sure why, but I'm going to try to explain it and hopefully you can tell me if I'm right or not...
By hiding the code in a data field hidden in a visibility field, it is forced to run on page load simply because it's a data field and needs to be filled/active. Is that right?
Regardless, it seems to be working! Thanks for the guidance.
I only just learned about those. I need to get into the habit of doing that.
Yes, I suppose in my outline the items on the first page load as a step 6. If you put code in a data display it will execute when the rest of the items on the page are loaded. My only caution is, it will also run every time the page is refreshed. With your code it looks like that won't really make a difference, but with something that can take longer to run it is important to keep in mind. Glad you got it to work out.
We have found that for some of the more stubborn watcher expressions to fire, you need to place an OBSNow into the variable space to have it fire on start up.
So in addition to your code, for example you would also put {!oneYearPassed(OBSNOW("WEIGHT"))}
This tricks the system into firing the function. We had spent several hours trying to figure out why a watcher expression wouldn't fire, looked at some other forms that did what we wanted, added the OBSNOW and they magically worked.
Thanks for sharing this! I've added this trick to our knowledge base at work, along with the previous solution of hiding the code in a visibility field.
Good thread!
To answer your other question about error msgs
I've also just noticed two build errors that so far haven't affected functionality:
ERROR: Unable to open library Utility. Functions will not be included in clinical kit
ERROR: Unable to open library Clinical_Lists. Functions will not be included in clinical kit
Your form must be referencing these function libraries, it would look like this at the top of the MEL code area:
/**LIBRARY::Utility**/
/**LIBRARY::Clinical_Lists**/
If this is the case, then maybe you got the form from somewhere, which may or may not have included these function library files along with the form kit
utility.nts
clinical_lists.nts
These function libraries should exist in the EMR, if you are using EMR 9.8 or earlier.
GO SETUP SETTINGS/CHART DOCUMENTS/TEXT COMPONENTS
(If you are USING CPS, location of TEXT COMPONENTS may be different)
In the box on the right, choose "Function Libraries"
If the utility and clinical lists are not listed under Function Libraries, this is why you are getting the error message.
These 2 function libraries were created by Logical Innovations (creators of Visual Form Editor).
When I took one of their classes way back in the day, they gave us sample forms and these function libraries. Every now and then these are updated to a new version. Not sure how you get the latest versions of these function libraries.
Also - if you have the function libraries, they should be in your visual form editor LIBRARIES folder (The function library file is not the same as the .nts file)
Clinical_Lists.lib
Clinical_Lists.txt
Utility.lib
Utility.txt
This way any form you edit, if it uses these function libraries, they will be included in the form kit whenever you save the form.
regards,
Beverly
That's good to know. I'm still new to VFE and MEL, so I just figured that these errors were being thrown due to something that happened in the past (and it sounds like maybe that's true). This specific form seems to have been built and rebuilt numerous times over the years, and there is a LOT of vestigial stuff in there I still can't parse. But it's not breaking, so for now, I don't have to worry about it!