Title: Top 5 Things You Hate about NPR Report Writing and Learning to Love Them
1Top 5 Things You Hate about NPR Report
Writingand Learning to Love Them!
2AGENDA
- 5. My report is slow4. I created a report only
to find out that MEDITECH had a program that
would have saved me hours.3. I want to create
one report that displays information in different
ways2. I need data from multiple applications
Can/Should I use a Macro?1. Bugs are plaguing
my report and I want them gone!
35
4MY REPORT IS SLOW
- MEDITECH is very fast at reading data from the
database! - The following are examples of items that can
effect the efficiency of a report and result in
slowness - Not selecting the best index for the report
- Sort Fields/Grouping avoid if possible using
too many sort fields as these can effect the
speed of your report - Utilizing fragments can result in slowness
- Defining Select Relationships
5MY REPORT IS SLOW
Indexes Indexes Indexes
Index Files Improve Report Efficiency
- Choose Index files to Reduce Number of Records
Searched - Select Index for Records Searched and not Sort
Order - Use Natural Sort Order
- Use Index Files Subscript as a Select
6MY REPORT IS SLOW
Indexes Choose Wisely!
- Try to find a index where the first field in the
index results in the greatest reduction of
returned records. For example, we want to create
a report that prints all final billed patients
discharged within a specified timeframe. In BAR,
there are two available index - BAR.PAT.bar.status.x this index returns a list
of accounts based on the bar status of the
account. The first field of the index is the
bar.status. - BAR.PAT.discharge.x this index returns a list
of accounts based on the discharge/service date.
The first field of the index is bar.dis.ser.
7MY REPORT IS SLOW
Indexes Choose Wisely!
- Which is the best index to use and why?
- BAR.PAT.bar.status.x
- BAR.PAT.discharge.x
- If the report is running for a relatively small
timeframe, then BAR.PAT.discharge.x is the best
index to use. There will typically be fewer
patients discharged during the specified
timeframe than all final billed patients in the
hospital system. If BAR.PAT.bar.status.x is
utilized where the report selects all accounts
where bar.status FB then the report will loop
through all final billed accounts and then filter
by discharge date.
8MY REPORT IS SLOW
- Fragments
- Fragments are useful for crossing applications
and gathering data. They can return information
from one field to entire lines of report text. - Fragments can be SLOW Reports with a high
number of records (thousands) or fragments called
at the detail level may experience performance
issues, as the application prefixes are
constantly opened and closed. It may be
advisable to redesign your report to avoid this.
9MY REPORT IS SLOW
The Reason Fragments are Slow Each called
Fragment opens its own report process (memory
usage, job , etc.). Each time a fragment is
called, the main report is paused, a new job is
setup, the application database is open, the
fragment is open and run, then the fragment
report is closed, the application is closed, the
job ends, and control returns to the main report.
10MY REPORT IS SLOW
- When it is best to NOT call a Fragment
- When it needs to be called frequently (every
detail section, every HK3, etc.) - When there is extensive sorting in both the
fragment and main report - When you need to print in both the main report
and fragment - Makes formatting more difficult
- Changes in either report can mess up the other
11MY REPORT IS SLOW
- When to use Fragments
- When the Fragment is called only once
- At START to get data
- At TR, with all the printing done in the
fragment - At Detail for simple reports, where the delay is
not an issue - Where the user selects a specific record (one
patient, PO, a couple of mnemonics, etc.) - At major sort regions for long reports (HK1 for
account types, at physician sort when the users
typically only select a few, etc.)
12MY REPORT IS SLOW
If fragments are slow, then how can I cross
applications without using a fragment? Utilize
macros in order to open prefixes to a specified
application and retrieve the desired results
which can then be displayed on the report.
Dont worry an example is coming soon!
13MY REPORT IS SLOW
Defining Select Relationships
- Utilize computed fields as an alternative to
defining select relationships. This will run
faster than applying or statement in the report
criteria via select relationships. - For example, we want a report to return all
patients discharged during a specified timeframe
with either a final billed or unbilled status.
14Option 1 (Slower) Create two selects fields
where one checks if bar.status is equal to FB
and the other checks if bar.status is equal to
UB. Set the Select Relationship to perform an
OR so that if the bar status is either FB or
UB (and discharged within the specified
timeframe) then the account is returned.
15SELECT RELATIONSHIPS
Option 2 (Faster) Create a calculated field that
checks if the bar.status is set to either FB or
UB. If the criteria is true, then Y is
returned otherwise N is returned.
164
- I created a report only to find out that MEDITECH
had a program that would have saved me hours!
MEDITECH provides a number of standard programs
that are very useful and help prevent programmers
from reinventing the wheel.
17Z FIELDS/PROGRAMS
Every MIS system contains Z DPM. This DPM was
created by MEDITECH to store common programs and
data fields which can be accessed by any custom
report.
Z.field.name
18Z FIELDS/PROGRAMS
FUNCTION DESCRIPTION ARGUMENTS
EXAMPLE
19Z FIELDS/PROGRAMS
FUNCTION DESCRIPTION ARGUMENTS
EXAMPLE
20Z FIELDS/PROGRAMS
FUNCTION DESCRIPTION ARGUMENTS EXAMPLE
Defaults B "m d, Y" C "I" (Apr 20, 2003)
21Z FIELDS/PROGRAMS
FUNCTION DESCRIPTION ARGUMENTS
EXAMPLE
22STANDARD PROGRAMS
- Syntax MIS.SCREEN.print(A,B,C,D)
-
- Description Print entire CDS with prompts and
responses -
- Arguments
- Amnemonic of screen
- B_at_Root(segment)
- CStrip blank lines
- DLeft Margin
-
- Example Regular ADM CDS
- MIS.SCREEN.print(_at_cd.screen,_at_Root(customer.defin
ed.queries),1,0)
23STANDARD PROGRAMS
- Syntax LAB.L.SPEC.result.lines(A,B,C,D)
- Description Prints lab results
- Arguments
- Aspecimen urn
- BLIS Report Format
- CConfidential Check
- DQueued Range of tests to print (Default ALL)
- Other Programs
- LAB.B.SPEC.result.lines, LAB.M.SPEC.result.lines,
LAB.P.SPEC.result.lines
24STANDARD PROGRAMS
- Syntax PHA.MAR.allergies(A,B,C,D,E,F)
- Description Builds an array of patient allergies
- Arguments
- APatient
- BMax line length
- CStructure for allergies (Default MVAL)
- DField number in MV for allergies
- EStructure for ADRs (Default /MVAD)
- FField number for ADRs
25STANDARD PROGRAMS
- Syntax BAR.PAT.get.status.date(A)
- Description Returns the status date from BAR
- Arguments
- Apatient urn from BAR (account)
- Syntax BAR.PAT.get.adm.pt.status(A)
- Description Returns the patient status from
Admissions - Arguments
- Apatient urn from BAR (account)
26STANDARD PROGRAMS
- Syntax BAR.PAT.necessity.check(A,B,C,D)
- Description Performs a medical necessity check
for the specified procedure code and diagnosis
code - Arguments
- ARequirement
- BProcedure Mnemonic
- CDiagnosis Code
- DService Date
273
- Tired of creating the
- same report?
- Create a single report that allows the user to
change the sort and specify the desired sections
to print.
28Flexible reports
- Lets start by creating a report that allows the
user to select from a list of available fields to
sort by. In order to accomplish this, we will
utilize computed fields. - The report will print all patients currently
in-house sorted either by - Patient Status
- Location
- Financial Class
29COMPUTED FIELDS
Field
Entered in thefield section
- Must be prefixed with a lowercase xx.
- The only punctuation allowed is a period
(no spaces) - Numerics are allowed
Namingconvention
xx.date.1
!
Must enterthe followingfield attributes
- DAT (data type)
- LEN (length of field)
- VAL (value of field)
30COMPUTED FIELDS
VAL -Value Attribute
Where you define whatvalue the field will hold
MAGIC codesyntax checker
31PROMPT FOR SORT FIELD
Create a report where the index file is set to
the room.bed.index. This index is used to find
all inpatients currently in the hospital.
32PROMPT FOR SORT FIELD
Add a computed field called xx.sort that will
return the value of the selected sort field.
Add a computed field called xx.sort.choice. This
is used to prompt the user for the desired sort
field and store the result.
33PROMPT FOR SORT FIELD
34PROMPT FOR SORT FIELD
Create a calculated field that is used to prompt
the user for the desired field to sort by.
Create a calculated field that checks the sort
field selected by the user and returns the
appropriate value to perform the sort.
35PROMPT FOR SORT FIELD
36PROMPT FOR SORT FIELD
Add the desired choices that should be available
in the lookup for the prompt.
37PROMPT FOR SORT FIELD
Upon execution, the user will be prompted to
enter the desired sort field. Press F9 to access
a lookup of available choices.
38Flexible reports
- Lets take it one step further. Now lets allow
the user to identify whether the patient details
should print, totals by the selected sort field,
or both. - Again, we will utilize computed fields for this
functionality. We will also utilize the LC line
attribute in order to determine whether a line
should print or not.
39(No Transcript)
40(No Transcript)
41PROMPT FOR DISPLAY
Add 2 computed fields one prompting the user
whether the detail section should print and one
prompting the user whether the totals should print
42PROMPT FOR DISPLAY
Modify the report picture to include lines in the
TK2 region for totals as well as a new page
header line for the totals.
43PROMPT FOR DISPLAY
44PROMPT FOR DISPLAY
452
- I need data from multiple applications. How can I
use a macro to capture data from other
applications?
46REPLACING FRAGMENTS
Objective Capture the patients total charges
from BAR and display the results on an In-house
Patient Listing report from Admissions. Why use
a macro instead of a fragment? For querying
information from another application, macros will
run faster than fragments. Also, this could save
the developer time for report creation. Now the
developer can create one report instead of two.
47PROGRAMS
- A macro can also be called from the report title,
line attributes, and field attributes. When
macros are called from any of the above, the code
is not placed directly into the report's object
code only the call to the macro is inserted. - When a macro is called via an attribute or title,
the macro is treated as a program. For this
reason, the last line of the macro must end with
a semi-colon. - When called as a program the macro call takes a
form like DPM.report.name.M.macro("") - Example ADM.PAT.zcus.status.M.get.info("")
48REPLACING FRAGMENTS
- Magic
- Close save our prefix
- Z.link
- Save data from other module
- Close restore everything
- C/S
- Z.link.db
49MAGIC Z.LINK
- Z.link(A,B,C,D,E)
- A Prefix to open
- B Application Name
- C Physical File Name
- D Database Name
- E Argument to logical file name (optional)
- Example Z.link("","BAR",".BAR.data","BAR.XXX")
50CLIENT SERVER Z.link.DB
- Z.link.db(Q(application database),Q(A,B,C))
- A O for Open the database or C for Close the
database - B B for bypass database checks we skip this
logic because we dont care to see msgs - C 1 for suppress messages like argument B
we dont want to see any messages - Example Z.link.db(PHA.XXX, O)
51Magic Example
- Lets Review the Code
- The account number is passed to the macro as
argument A - A Prefix is a pointer to a data structure
- C(S) Stores the prefix in case this prefix
is already in use - _at_Chg.prefix(BAR.PAT,,)Tells the report to
translate all fields with as the prefix to - Z.Link Opens a pointer () to the BAR data
- _at_BAR.PAT.chg.total/TOT.CHG Stores the value
from the charge total field into a global
variable - C(U) Closes the pointer to BAR and restored
the prefix
The macro must end with since this will be
called as a program.
52Call the macro in the VAL statement and pass the
account number from Admissions
53Client Server Example
- Lets Review the Code
- The account number is passed to the macro as
argument A - Z.link.db(BAR.ABC, O) Opens the pointers
for the BAR data - _at_BAR.PAT.chg.total/TOT.CHG Stores the value
from the charge total field into a global
variable - Z.link.db(BAR.ABC, C) Closes the
pointers for BAR
The macro must end with since this will be
called as a program.
541
- Bugs are plaguing my report and I want them gone!
55DEBUGGING YOUR REPORT
Programs are available for placing breakpoints in
code in order to view values stored in local and
global variables.
Magic Platforms DDC(A) or Z.ddc(A,B,C) Client
Server Platforms Z.debug(A,B)
56MAGIC PLATFORMS
DDC(A) A Name to display in the header
section Z.ddc(A,B,C) A Name to display in the
header section B optional argument that when
specified the debugger will only launch when run
on that device C optional argument that when
specified the debugger will only launch for the
specified user
57MAGIC DEBUGGING
Add DDC(A) to the line where you would like to
add a breakpoint. Whatever value is passed in as
the argument A will display in the header.
- Add a breakpoint to check values saved in
variables
58MAGIC DEBUGGING
The value that is passed as argument A will be
displayed here
- From the DDC prompt you can
- Look at the value stored in local variables by
typing the name of the local variable and
pressing the ltEntergt key - Look at values stored in global variables by
utilizing the G utility (G()) - Access the front end by typing FEC(0) and
pressing the ltEntergt key - Execute program calls by typing followed by the
program name (with arguments).
- Add a breakpoint to check values saved in
variables
59MAGIC PLATFORMS
- Z.DDC
- Type gt to return the number of bytes used by
all symbol tables, as well as the number of bytes
available. - Type to copy the contents of the / prefix to
your Windows clipboard. - Type . to bring up the Node(s) prompt for
viewing contents of prefixes. - Type ? to return all symbols in the current
symbol table. - Type ?? to return all symbols in all symbol
tables. - Type the name of any symbol from the current
symbol table to return the value of that symbol. - Execute program calls or other valid Magic
expressions by typing followed by the program
name (with arguments) or a valid Magic statement. - Press ltEntergt to exit the breakpoint.
60CLIENT SERVER PLATFORMS
Z.debug(A,B) A Name to display in the header
section B optional argument that when
specified the debugger will only launch when run
on that device. Specifying a device for the debug
ensures that other users are not adversely
affected if the debug call is left in the code
61CLIENT SERVER DEBUGGING
Add Z.debug(A) to the line where you would like
to add a breakpoint. The value that is passed as
argument A will display in the header.
- Add a breakpoint to check values saved in
variables
62CLIENT SERVER DEBUGGING
The value that is passed as argument A will
display be displayed here
From the breakpoint you can select one of the
following options I Inspect the current
frame P Display open prefixes H Display the
history G Inspect memory based temp F Go to
specific frame S Show symbol table of current
frame ltESCgt Exit
63CLIENT SERVER DEBUGGING
- At the breakpoint
- Enter G to access the G utility
- Enter the prefix that you would like to view
- Once done press ltESCgt to exit the breakpoint and
continue with the report.
64Thanks for joining us today!Questions?
Comments?
Interface People, LP
214.222.1125 (Dallas area)866.539.2188
(toll free)