I ran a Mel Trace on your function after placing it in my userlib and calling from a form. I see the following error in the trace log:
03/23/2013 12:26:07.645 INFO Process Id #5112 Thread Id #1 [MelTrace] >{!SMRMC_APPT_ALL_FUTURE()} 03/23/2013 12:26:07.645 INFO Process Id #5112 Thread Id #1 [MelTrace] execute>call SMRMC_APPT_ALL_FUTURE() 03/23/2013 12:26:07.645 INFO Process Id #5112 Thread Id #1 [MelTrace] execute>I = 0 03/23/2013 12:26:07.645 INFO Process Id #5112 Thread Id #1 [MelTrace] results>0 03/23/2013 12:26:07.645 INFO Process Id #5112 Thread Id #1 [MelTrace] execute>RESULT = "" 03/23/2013 12:26:07.645 INFO Process Id #5112 Thread Id #1 [MelTrace] results>"" 03/23/2013 12:26:07.645 INFO Process Id #5112 Thread Id #1 [MelTrace] execute>call GETROWCOUNT("_MELCurPatientAppt")03/23/2013 12:26:07.645 INFO Process Id #5112 Thread Id #1 [MelTrace] results>7 03/23/2013 12:26:07.645 INFO Process Id #5112 Thread Id #1 [MelTrace] execute>J = 7 03/23/2013 12:26:07.645 INFO Process Id #5112 Thread Id #1 [MelTrace] results>7 03/23/2013 12:26:07.645 INFO Process Id #5112 Thread Id #1 [MelTrace] execute>7 == 1 03/23/2013 12:26:07.645 INFO Process Id #5112 Thread Id #1 [MelTrace] results>FALSE 03/23/2013 12:26:07.645 INFO Process Id #5112 Thread Id #1 [MelTrace] execute>if FALSE 03/23/2013 12:26:07.645 INFO Process Id #5112 Thread Id #1 [MelTrace] results>FALSE 03/23/2013 12:26:07.645 INFO Process Id #5112 Thread Id #1 [MelTrace] execute>7 > 1 03/23/2013 12:26:07.645 INFO Process Id #5112 Thread Id #1 [MelTrace] results>TRUE 03/23/2013 12:26:07.645 INFO Process Id #5112 Thread Id #1 [MelTrace] execute>if TRUE 03/23/2013 12:26:07.645 INFO Process Id #5112 Thread Id #1 [MelTrace] results>TRUE 03/23/2013 12:26:07.645 INFO Process Id #5112 Thread Id #1 [MelTrace] execute>0 < 7 03/23/2013 12:26:07.645 INFO Process Id #5112 Thread Id #1 [MelTrace] results>TRUE 03/23/2013 12:26:07.645 INFO Process Id #5112 Thread Id #1 [MelTrace] execute>while TRUE 03/23/2013 12:26:07.645 INFO Process Id #5112 Thread Id #1 [MelTrace] results>TRUE 03/23/2013 12:26:07.645 INFO Process Id #5112 Thread Id #1 [MelTrace] execute>0 + 1 03/23/2013 12:26:07.645 INFO Process Id #5112 Thread Id #1 [MelTrace] results>1 03/23/2013 12:26:07.645 INFO Process Id #5112 Thread Id #1 [MelTrace] execute>I = 1 03/23/2013 12:26:07.645 INFO Process Id #5112 Thread Id #1 [MelTrace] results>1 03/23/2013 12:26:07.645 INFO Process Id #5112 Thread Id #1 [MelTrace] execute>call GETROW("_MELCurPatientAppt", 1, "ApptDate", "ApptTime", "Appttype", "Booklist", "ApptStatus")03/23/2013 12:26:07.645 INFO Process Id #5112 Thread Id #1 [MelTrace] results>NULL 03/23/2013 12:26:07.645 INFO Process Id #5112 Thread Id #1 [MelTrace] execute>A = NULL 03/23/2013 12:26:07.645 INFO Process Id #5112 Thread Id #1 [MelTrace] results>NULL 03/23/2013 12:26:07.645 INFO Process Id #5112 Thread Id #1 [MelTrace] execute>NULL[1] 03/23/2013 12:26:07.645 INFO Process Id #5112 Thread Id #1 [MelTrace] results>NULL 03/23/2013 12:26:07.645 INFO Process Id #5112 Thread Id #1 [MelTrace] execute>call VAL(NULL) 03/23/2013 12:26:07.645 INFO Process Id #5112 Thread Id #1 [MelTrace] results>NULL 03/23/2013 12:26:07.645 INFO Process Id #5112 Thread Id #1 [MelTrace] execute>NULL >= 03/23/2013 03/23/2013 12:26:07.645 INFO Process Id #5112 Thread Id #1 [MelTrace] results>FALSE 03/23/2013 12:26:07.645 INFO Process Id #5112 Thread Id #1 [MelTrace] execute>NULL[5] 03/23/2013 12:26:07.645 INFO Process Id #5112 Thread Id #1 [MelTrace] results>NULL 03/23/2013 12:26:07.645 INFO Process Id #5112 Thread Id #1 [MelTrace] execute>call VAL(NULL) 03/23/2013 12:26:07.646 INFO Process Id #5112 Thread Id #1 [MelTrace] results>NULL 03/23/2013 12:26:07.646 INFO Process Id #5112 Thread Id #1 [MelTrace] execute>NULL == 0 03/23/2013 12:26:07.646 INFO Process Id #5112 Thread Id #1 [MelTrace] results>TRUE 03/23/2013 12:26:07.646 INFO Process Id #5112 Thread Id #1 [MelTrace] execute>FALSE AND TRUE 03/23/2013 12:26:07.646 INFO Process Id #5112 Thread Id #1 [MelTrace] results>FALSE 03/23/2013 12:26:07.646 INFO Process Id #5112 Thread Id #1 [MelTrace] execute>if FALSE 03/23/2013 12:26:07.646 INFO Process Id #5112 Thread Id #1 [MelTrace] results>FALSE 03/23/2013 12:26:07.646 INFO Process Id #5112 Thread Id #1 [MelTrace] execute>1 < 7 03/23/2013 12:26:07.646 INFO Process Id #5112 Thread Id #1 [MelTrace] results>TRUE 03/23/2013 12:26:07.646 INFO Process Id #5112 Thread Id #1 [MelTrace] execute>while TRUE 03/23/2013 12:26:07.646 INFO Process Id #5112 Thread Id #1 [MelTrace] results>TRUE 03/23/2013 12:26:07.646 INFO Process Id #5112 Thread Id #1 [MelTrace] execute>1 + 1 03/23/2013 12:26:07.646 INFO Process Id #5112 Thread Id #1 [MelTrace] results>2 03/23/2013 12:26:07.646 INFO Process Id #5112 Thread Id #1 [MelTrace] execute>I = 2 03/23/2013 12:26:07.646 INFO Process Id #5112 Thread Id #1 [MelTrace] results>2
The same NULL error repeats out for each of the loops (this patient has 7 appointments in their history). Do you notice that the GETROWCOUNT works, however the GETROW returns NULL?
Again, I am working with CPS 10 so that may be the issue, but I'm not sure. I can't find any documentation on GETROW to fiddle with it. I'd really like to see what is contained in_MELCurPatientAppt. Do you know any hooks that might work?
Any ideas why GETROW is returning NULL? (thanks so much!!!)
We are using EMR 9.5 do you have this line in your mellib.txt file like we do?:
global _MELCurPatientAppt = _PatientAppointment
Maybe you could also try manually typing the sections that reference getrow.
We don't have any documention in help about getrow either, just getfield.
Stacey LaGrange said:
We are using EMR 9.5 do you have this line in your mellib.txt file like we do?:
global _MELCurPatientAppt = _PatientAppointment
Maybe you could also try manually typing the sections that reference getrow.
We don't have any documention in help about getrow either, just getfield.
Yes, my mellib.txt has "global _MELCurPatientAppt = _PatientAppointment" in it. What do you mean by manually typing those sections? BTW thanks for all the help so far!
Has anyone had any success with any function/forms using _MELCurPatientAppt running CPS 10? jjordet, what version are you running on?
sorry...EMR 9.5
I meant that sometimes when you copy and paste code it doesn't work, even if you paste it in notepad first. I have had issues that didn't make sense and then after I did this it magically worked.
Stacey LaGrange said:
I meant that sometimes when you copy and paste code it doesn't work, even if you paste it in notepad first. I have had issues that didn't make sense and then after I did this it magically worked.
I see. Okay so I painstakingly retyped your function, Stacey, and ran a trace as I loaded the form. Again, same result. GetRowCount returns the correct number of rows (appointments) that this patient has, however GetRow always returns NULL.
I wonder what happened to GetRow between CPS 9.5 and 10?
Game over?
Oh no, that is too bad. Just one more thing, you have the function below in your usrlib.txt file (and there is only one copy of this file on your PC) and then you tried using {SMRMC_APPT_ALL_FUTURE()} in a letter or patient banner right? If so, I would say it probably is your version and I can let you know what happens when we upgrade someday.
//APPT (ALL FUTURE) FUNCTION
fn SMRMC_APPT_ALL_FUTURE() {
//lists all future appts with a comma between fields a hret between records
//use nested getfields to turn in to a 2D array if you want to pick elements
//DN--3-31-04 modified from mellib stock function
local a, b,c, loc, atype, book, i = 0
local result=''
local j = getRowCount('_MELCurPatientAppt')
// Loop thru patients appointments
if j == 1 then a = getRow('_MELCurPatientAppt',0, 'ApptDate',
'ApptTime','Appttype','Booklist','ApptStatus')
// Find the next appointmnet
if val(a[1]) >= ._TODAYSDATE and val(a[5]) = 0 then
// Get the type of appointment
atype = find('_MELApptDef', 'ApptType', 'ID', a[3])
// Get the location of care from the first book
b = getfield(a[4],',',' :')
loc = find('_MELBook', 'LocationAbbrevName', 'ID',b[1])
//Get the Book Name
c = getfield(a[4],',',' :')
book = find('_MELBook', 'Name', 'ID',c[1])
// Build the result
result = a[1] + ',' + appttime(a[2]) + ',' + atype + ',' + book
//edit previous line if you want to return only part or use different
delimiters etc
//note this first part is if theres only 1 appointment
endif
else if j > 1 then
while i < j do
i = i+1
a = getRow('_MELCurPatientAppt',i,
'ApptDate','ApptTime','Appttype','Booklist','ApptStatus')
// Find the next appointmnet
if val(a[1]) >= ._TODAYSDATE and val(a[5]) = 0 then
// Get the type of appointment
atype = find('_MELApptDef', 'ApptType', 'ID', a[3])
// Get the location of care from the first book
b = getfield(a[4],',',' :')
loc = find('_MELBook', 'LocationAbbrevName', 'ID',b[1])
//Get the Book Name
c = getfield(a[4],',',' :')
book = find('_MELBook', 'Name', 'ID',c[1])
// Build the result
if result=="" then
result = result + a[1] + ',' + appttime(a[2]) + ',' +
atype + ',' + book else result = result + hret + a[1] + ',' + appttime(a[2])
+ ',' + atype + ',' + book endif
//edit previous line if you want to return only part or use different
delimiters etc
//this part there are 2 or more appointments or rows
endif
endwhile
endif
endif
result
}
I have a different version of this same function (that I borrowed from the CHUG community, I dont remember who but thanks!) on CPS 10 and it works fine. I have had trouble writing these in the past if you use a field that the function doesn't recognize it returned nothing for me, it is possible that one of those fields is in 9.5 and not 10, this is the getrow I am using -
local a = (getRow("_MELCurPatientAppt",iq,"AppointmentsId","ApptStart","ApptTypeId","FacilityId","DoctorID","ResourceId","Status","Canceled"))
I don't have the booklist field, if you want to try my tweaked version go ahead, it has filters for all previous, all future, all cancelled, and different return methods. Here it is -
{fn SEARCH_APPTS(returnMethod,type){
//Valid types are NEXT, PREV, and CANC
if (toUpper(returnMethod) <> "DELIMITED" AND toUpper(returnMethod) <> "LIST" AND toUpper(returnMethod) <> "COMMA" AND toUpper(returnMethod) <> "FORMATTEDLONG") then
// Default Return Method if no value passed edit this if you want to change the default
returnMethod = "LIST"
endif
// initialize local variables
local retVal = ""
local z = getRowCount("_MELCurPatientAppt")
// loop through rows in _MELCurPatientAppt data object
for iq=1, iq<=z, iq=iq+1 do
local a = (getRow("_MELCurPatientAppt",iq,"AppointmentsId","ApptStart","ApptTypeId","FacilityId","DoctorID","ResourceId","Status","Canceled"))
if (val(durationdays(datestamp(),a[2]))>0 and a[8]=="" and toupper(type) == "NEXT") or (val(durationdays(datestamp(),a[2]))<0 and a[8]=="" and toupper(type) = "PREV") or (a[8]<>"" and toupper(type) == "CANC") then
// Appointment type lookup in _MELApptType data object
if (find("_MELApptType","Name","ApptTypeID",a[3]) <> "") then
a[3] = find("_MELApptType","Name","ApptTypeID",a[3])
endif
// Facility lookup in _MELLocation data object
if (find("_MELLocation","ListName","DoctorFacilityID",a[4]) <> "") then
a[4] = find("_MELLocation","ListName","DoctorFacilityID",a[4])
endif
// Doctor lookup in _DoctorFacilityForPatAppt data object
if (find("_DoctorFacilityForPatAppt","ListName","DoctorFacilityID",a[5]) <> "") then
a[5] = find("_DoctorFacilityForPatAppt","ListName","DoctorFacilityID",a[5])
endif
// Resource lookup in _DoctorFacilityForPatAppt data object
if (find("_DoctorFacilityForPatAppt","ListName","DoctorFacilityID",a[6]) <> "") then
a[6] = find("_DoctorFacilityForPatAppt","ListName","DoctorFacilityID",a[6])
endif
// ApptStatus is actually a combination of two fields, Canceled or ApptStatus. If Canceled <> "" then write Canceled, else write contents of ApptStatus
if (a[8] <> "") then
a[7] = "Canceled"
endif
cond
case toUpper(returnMethod) == "DELIMITED"
// Don't add pipe before first element
if (retVal <> "") then
retVal = "|" + retVal
endif
retVal = str(a[2],"^",a[3],"^",a[4],"^",a[6]) + retVal
case toUpper(returnMethod) == "LIST"
// Don't add HRET before first element
if (retVal <> "") then
retVal = HRET + retVal
endif
retVal = str(a[2],", ",a[3],", ",a[4],", ",a[6]) + retVal
case toUpper(returnMethod) == "COMMA"
// Don't add comma before first element
if (retVal <> "") then
retVal = "," + retVal
endif
// Need to replace commas in elements with semicolon to prevent errors in comma separated list
retVal = str(ReplaceStr(a[2], ",",";")," ",ReplaceStr(a[3], ",",";")," ",ReplaceStr(a[4], ",",";")," ",ReplaceStr(a[6], ",",";")) + retVal
case toUpper(returnMethod) == "FORMATTEDLONG"
// Don't add new lines before first element
if (retVal <> "") then
retVal = HRET + HRET + retVal
endif
// Need to replace commas in elements with semicolon to prevent errors in comma separated list
retVal = str("ApptTime: ",ReplaceStr(a[2], ",",";"),HRET,"ApptType: ",ReplaceStr(a[3], ",",";"),HRET,"FacilityID: ",ReplaceStr(a[4], ",",";"),HRET,"ResourceID: ",ReplaceStr(a[6], ",",";")) + retVal
endcond
endif
endfor
return retVal
}}
FYI (in case it helps)
When upgrading from 10.1.2 to 10.1.3 we found a problem with our appointment code when running in 10.1.3.
In testing 10.1.3, I found that I needed to change the parameter in our getRowCount() from '_MELCurPatientAppt' to '_PatientAppointments'. Also needed to make the same parameter change to any getRow code that used that object too.
In 10.1.2, the call, getRowCount('_MELCurPatientAppt'), returned the correct # of appts, but in 10.1.3 it returned -1.
@gibsonmi that worked! You rock!
Thanks to everyone who's pitched in on this thread so far. You guys make this community awesome.
SO, apparently the _MELCurPatientAppt data object changed with CPS version 10. Does anyone know how/where to go to learn about these data objects and what arguments/calls can be passed to them? I'm wondering whoever wrote gibsonmi's function originally HOW they knew to pass in different GETROW arguments? I would really like to learn how to figure this stuff out...
For that you could take a look at the mel files in the CPS client folder. The mellib.txt contains some global definitions like
// The following Objects are ok for MEL to access
global _MELCurPatientAppt = _PatientAppointments
Then searching through the mldef files, I found _PatientAppointments in mldefs3.txt:
Object: _PatientAppointments Table: Appointments Refresh: RBook
Property: Snapshot
Property: Prepare
Field: AppointmentsId Type: ID Hidden Key
Field: FacilityId Type: Long
Field: ApptKind Type: Long
Field: OwnerId Type: Long
Field: EmrApptStart Type: DateTime
Field: ApptStart Type: DateTime
Field: ApptStop Type: DateTime
Field: Status Type: String Length: 50
Field: Canceled Type: Long
Field: PatientCheckIn Type: Long
Field: PriorAuthorizationNumber Type: String Length: 50
Field: WCCId Type: Long
Field: Notes Type: CLOB
Field: ApptStatusMId Type: Long
Field: DoctorId Type: Long
Field: ResourceId Type: Long
Field: Type Type: String Length: 50
Field: PatientVisitId Type: Long
Field: TicketNumber Type: String Length: 20
Field: HideNewVisit Type: Short
Field: ApptTypeId Type: Long
Field: ApptSetId Type: Long
Field: ApptChainId Type: Long
Field: RoomNo Type: String Length: 30
Field: CasesId Type: Long
Field: CompanyId Type: Long
Field: ExternalApptId Type: String Length: 75
Field: DocCreate Type: Short
Field: DocId Type: Double
Field: CreatedBy Type: String
Filter: filter1, OwnerId = Patient.PatientProfileId Hidden
Variable: dateVar Type: Date Hidden
Filter: dateFilter, EmrApptStart >= dateVar Disable Hidden
Filter: apptKindFilter, ApptKind = 1
Order: 'ApptStart'
I would like to use this code in a button that will add the next appointment date to the patient instructions. I have this as a RUNPROCESS.
{IF APPT_NEXT() = "" then "No appointments" else global apptinfo = getfield (APPT_NEXT(),",","") apptinfo[1] + " for " + apptinfo[3] endif}
How do I make this fill in to the instructions multi-line edit field labeled DOCUMENT.AP_INST when the button is pressed?
Thank You
{IF APPT_NEXT() = "" then "No appointments" else global apptinfo = getfield (APPT_NEXT(),",","") apptinfo[1] + " for " + apptinfo[3]
return result
document.ap_inst = result
endif}
would that work?
Does anyone have a version of this that works with CPS12? I have tried pasting some of the above into a History View but can't get it to work. Would like a function to display any future appointments.