I need a function that will allow a provider to cycle through all values of a specific OBS term. This is for a program that will have multiple notes per patient every single day, and it's crucial that all providers are able to see all notes for each patient.
I found something in an old form of ours that I was able to isolate and make mostly work. I'll put the code below. Because I had to do some archaeology on the old code, I don't understand very much of it, like how the indexing works, for example. The actual form is just a data display (!DOCUMENT.PREVIOUS_CHART_NOTE) and two buttons (one with the function prevBtn(), one with the function nextBtn()).
The problem I'm having is this code only displays one value per date (using ._TODAYSDATE as a filtering method). Because numerous providers will be seeing a patient every day, I need to be able to cycle through OBS values based on a timestamp, not just by date.
Here is the code I'm working with. There are a LOT of my own notes in there, that I used to help myself remember what I had figured out. I'm sure some of my assumptions aren't correct, so do keep that in mind...
/*
This works in a weird, roundabout way. The data field is filled with a MEL expression of a DOCUMENT variable that is updated by the code below.
getObsFromList(strTermName, strTargetDate, strFlag) only works as long as the INDEX (which is calling LIST_OBS on whatever OBS term is in the function at the bottom of the entire block) is greater than 0 (see: WHILE loop).
If the index is greater than 0, then the loop hits the COND cases, which tie to the "Previous" and "Next" buttons. Those buttons contain the functions prevBtn() and nextBtn(). Those pieces of code connect to the cases by the third parameter fed into getObsFromList(strTermName, strTargetDate, STRFLAG). strFlag either equals "Previous" or "Next", which is how the button affects the direction to go in the returned INDEX.
Each side has a DURATIONDAYS equation that runs through the array in different directions.
All three of these functions affect DOCUMENT.PREVIOUS_CHART_NOTE, which isn't an actual element, but rather the DOCUMENT variable assigned to the data field. This variable in the data field's MEL expression region is altered based on the button clicked, which affects the contents returned by the main function, which displays the previous or next obs value in the data field.
Whew!
There are pieces of this code I still don't understand every part of. I am notating those parts in the actual code so as not to mix up my understanding of the code above with my lack of understanding of individual lines.
I replaced every instance of ._TODAYSDATE with LAST_SIGNED_OBS_DATE
*/
{
!DOCUMENT.PREVIOUS_CHART_NOTE = getObsFromList(DOCUMENT.OBS_SELECT, str(._TODAYSDATE), "Previous")
}
{
!fn getObsFromList(strTermName, strTargetDate, strFlag) {
local i
local nIndex
local strValue = ""
local strFullList = ""
if (strTargetDate == "") then
strTargetDate = str(._TODAYSDATE)
endif
strFullList = LIST_OBS(strTermName, "Signed", "Comma", "valuedate")
if (size(strFullList) < 4) then return ("") endif /* Why does it remove 2 items from the index? Is this to get to the last OBS? According to the documentation, a positive number removes, so does -2 actually ADD two spaces? And what does the ", " do? */ strFullList = remove(strFullList, size(strFullList) - 2) + ", " nIndex = match(strFullList, "), ") /* Why does nIndex subtract 13 from itself? */ while (nIndex > 0) do
/* If you take away "- 13", strValue - "" */
nIndex = nIndex - 13
nIndex = match(strFullList, nIndex, " ")
/* If you take away the "- 10", strValue = "" */
strDate = sub(strFullList, nIndex - 10, 10)
COND
/*if you take away the "- 12" from each nIndex, timestamps show up.*/
CASE (strFlag == "Previous")
if (DURATIONDAYS(strDate, strTargetDate) > 0) then
strValue = strDate + " - " + sub(strFullList, 1, nIndex)
return (strValue)
endif
CASE (strFlag == "Next")
if (DURATIONDAYS(strTargetDate, strDate) > 0) then
strValue = strDate + " - " + sub(strFullList, 1, nIndex)
else
if (strValue == "") then
userok("Last recorded observation reviewed.")
endif
return (strValue)
endif
CASE (strFlag == "Exact")
if (DURATIONDAYS(strDate, strTargetDate) == 0) then
strValue = strDate + " - " + sub(strFullList, 1, nIndex)
return (strValue)
endif
endcond
nIndex = match(strFullList, "), ")
strFullList = remove(strFullList, 1, nIndex + 2)
nIndex = match(strFullList, "), ")
endwhile
userok("Last recorded observation reviewed.")
return ("")
}
}
/*
Why do these match DOCUMENT.PREVIOUS_CHART_NOTEto a blank space?
Does that find the most recent entry, so it can subtract one to access OBSPREV?
*/
{
fn prevBtn() {
local strDate = str(._TODAYSDATE)
local nIndex = match(DOCUMENT.PREVIOUS_CHART_NOTE, " ")
if (nIndex > 1) then
strDate = sub(DOCUMENT.PREVIOUS_CHART_NOTE, 1, nIndex)
endif
DOCUMENT.PREVIOUS_CHART_NOTE = getObsFromList(DOCUMENT.OBS_SELECT, strDate, "Previous")
}
}
{
fn nextBtn() {
local strDate = str(._TODAYSDATE)
local nIndex = match(DOCUMENT.PREVIOUS_CHART_NOTE, " ")
if (nIndex > 1) then
strDate = sub(DOCUMENT.PREVIOUS_CHART_NOTE, 1, nIndex)
endif
DOCUMENT.PREVIOUS_CHART_NOTE = getObsFromList(DOCUMENT.OBS_SELECT, strDate, "Next")
}
}
I will be glad to help you. This is not a difficult issue. Contact me directly.
One possible solution would be to imbed a flowsheet into a custom form and specify the certain OBS Terms for that flowsheet and then your providers could scroll through this imbedded flowsheet.