Our Blogs

Home / Blogs

  • 2025-03-06

Saving a client over $60,000 through automation

Boosting Efficiency with AutoHotkey: Automating Patient Record Generation

In many clinical or administrative workflows, manually navigating software screens, typing in patient data, and saving PDFs can be incredibly time-consuming and boring. With AutoHotkey (AHK), you can automate repetitive mouse clicks and keystrokes to save hours of work every day. Below is a script I created to generate patient PDF reports in NextGen EDR by reading a list of patients from a CSV file. The people I built this for offered over $60,000 for a solution like this. Doing this task manually would take over 44+ weeks with 5 people doing this 2 hours a day, 5 days a week. If you factor in the longer someone does this manual process, the slower they will get. This process would have lowered employee morale and motivation to do meaningful things. With the solution I explain below, it saved 5 people from doing this and thousands of dollars while only taking less than 3 weeks to complete. Aren’t computers wonderful? They sit there processing away and will never get tired. I’ll walk through how it works and the benefits it provides.


Why Automate with AutoHotkey?

  • Reduce Manual Errors: Eliminates typos and missed clicks caused by human fatigue.
  • Save Time: An AHK script can process dozens—or even thousands—of records in a fraction of the time it takes a person.
  • Enhance Consistency: Automation ensures the same workflow is followed every single time.
  • Free Up Staff: Staff members can focus on higher-value tasks instead of repetitive data entry.

AutoHotkey Script Snippet

Below is the full script. It demonstrates how we read patient MRNs and last names from a CSV (or text file), open the NextGen EDR application, and export a PDF report for each patient:



 1: #SingleInstance, Force
 2: CoordMode, Mouse, Screen
 3:
 4: ; Read MRNs and Last Names from CSV file
 5: FileRead, PatientList, C:\Users\jboris\Desktop\EDR-Patient-Project\patients.txt
 6: StringSplit, PatientArray, PatientList, n  ; Split by newline
 7:
 8: ; Loop through each patient in the CSV
 9: Loop, %PatientArray0%
10: {
11:     ; Split MRN and Last Name by comma
12:     StringSplit, Data, PatientArray%A_Index%, ,
13:
14:     ; Clean MRN (keep only numbers)
15:     MRN := RegExReplace(Trim(Data1), "[^0-9]")
16:
17:     ; Clean Last Name (preserve letters, spaces, dashes)
18:     LastName := RegExReplace(Trim(Data2), "[^a-zA-Z -]")
19:     LastName := StrReplace(LastName, " ", "_")
20:
21:     ; Step 1: Activate NextGen EDR window
22:     WinActivate, NextGen EDR - \\Remote
23:     WinWaitActive, NextGen EDR - \\Remote
24:
25:     ; Step 2: Move mouse & click patients button
26:     MouseMove, 383, 39
27:     Sleep, 2000
28:     Click
29:     Sleep, 1000
30:
31:     ; Step 3: Click last name field
32:     MouseMove, 594, 349
33:     Sleep, 1000
34:     Click 2
35:     Sleep, 5000
36:
37:     ; Step 4: Click MRN field & type MRN
38:     MouseMove, 1000, 390
39:     Sleep, 1000
40:     Click 2
41:     Sleep, 4000
42:     Send, %MRN%
43:     Sleep, 2000
44:
45:     ; Step 5: Find the patient record
46:     MouseMove, 687, 500
47:     Sleep, 2000
48:     Click
49:     Sleep, 5000
50:
51:     ; Confirm if rendering provider is not a dental provider
52:     MouseMove, 1030, 601
53:     Sleep, 500
54:     Send, {Enter}
55:     Sleep, 500
56:
57:     ; Step 6: Cancel button to close any pop-up
58:     MouseMove, 1415, 867
59:     Sleep, 5000
60:     Click
61:     Sleep, 2000
62:
63:     ; Step 7: Print the char button
64:     MouseMove, 1861, 107
65:     Sleep, 500
66:     Click
67:     Sleep, 500
68:
69:     ; Step 8: Patient summary report
70:     MouseMove, 1800, 132
71:     Sleep, 500
72:     Click
73:     Sleep, 500
74:
75:     ; Step 9: Enter date range
76:     MouseMove, 817, 375  ; Start date field
77:     Sleep, 3000
78:     Click
79:     Send, 01/01/2024
80:     Sleep, 500
81:
82:     ; End date field
83:     MouseMove, 816, 398
84:     Sleep, 500
85:     Click
86:     Sleep, 500
87:     Send, 12/31/2024
88:     Sleep, 500
89:
90:     ; Step 10: Check tooth chart & confirm
91:     MouseMove, 671, 548
92:     Sleep, 500
93:     Click
94:     Sleep, 500
95:
96:     MouseMove, 1201, 696  ; OK button
97:     Sleep, 500
98:     Click
99:     Sleep, 5000
100:
101:    ; Step 11: Export to PDF
102:    MouseMove, 576, 263
103:    Sleep, 2000
104:    Click
105:    Sleep, 500
106:
107:    ; PDF option
108:    MouseMove, 612, 306
109:    Sleep, 2000
110:    Click
111:    Sleep, 3000
112:
113:    ; Save file: MRN_LastName_PatientSummaryReport.pdf
114:    FolderPath := "\\servname\Dental_Charts\Charts\"
115:    FileName := MRN . "_" . LastName . "_PatientSummaryReport.pdf"
116:    Send, %FolderPath%%FileName%
117:    Sleep, 2000
118:    Send, {Enter}
119:    Sleep, 2000
120:    Send, {Enter}
121:
122:    ; Step 12: Close the report
123:    MouseMove, 1644, 236
124:    Sleep, 1000
125:    Click
126:    Sleep, 5000
127:
128:    ; Exit the summary
129:    MouseMove, 1897, 103
130:    Sleep, 1000
131:    Click
132:    Sleep, 10000
133: }
134:
135: ; Emergency Stop Hotkeys
136: ^Esc::ExitApp
137: ^q::ExitApp

Explanation by Line

  • Line 1: #SingleInstance, Force ensures only one instance of the script runs at a time, preventing duplicates.
  • Line 2: CoordMode, Mouse, Screen sets the mouse coordinate system to the entire screen (rather than a window).
  • Line 5: FileRead, PatientList... reads the entire list of patients from a text file containing MRN/LastName data.
  • Line 6: StringSplit... splits the file contents on newline (n), storing each line in an array.
  • Line 9: Loop, %PatientArray0% iterates over the array, once per patient record.
  • Line 12: StringSplit... splits each line by comma, extracting MRN and LastName.
  • Line 15: Cleans the MRN, removing non-numeric characters using a regular expression.
  • Line 18-19: Cleans the LastName, preserving only letters/spaces/dashes, and replaces spaces with underscores.
  • Lines 21-23: Activate the NextGen EDR window and wait until it’s fully active.
  • Lines 25-29: Move the mouse to coordinates (383,39) and click—this presumably opens or selects the “Patients” function.
  • Lines 31-35: Click on the last name field to focus it, then wait for the system to respond.
  • Lines 37-43: Click on the MRN field, type the MRN value, and pause.
  • Lines 45-49: Click “Find” or a similar button to perform the patient search, then wait for results.
  • Lines 51-55: Handle a prompt if the rendering provider is not dental (press Enter to confirm).
  • Lines 57-61: Click “Cancel” to close any open prompts or pop-ups.
  • Lines 63-73: Access the “Print the char” button, then select the “Patient Summary Report.”
  • Lines 75-80 & 82-88: Specify the start/end dates by clicking on date fields and typing them in.
  • Lines 90-95 & 96-99: Check the tooth chart, click OK, and wait for the system to generate the report.
  • Lines 101-111: Move the mouse to the export icon, click it, then select the PDF option.
  • Lines 113-120: Construct the final filename (MRN_LastName_PatientSummaryReport.pdf) and save the file.
  • Lines 122-132: Close out the report and return to the main screen, allowing for the next loop iteration.
  • Lines 135-137: Defines emergency hotkeys (^Esc or ^q) to terminate the script instantly.

What This Script Accomplishes

  • Bulk Processing: Automates reading and processing for an entire patient list.
  • Accurate Data Entry: Reduces human typos and missed clicks.
  • Consistent File Organization: Each PDF follows the MRN_LastName naming convention, simplifying record management.
  • Time & Cost Savings: Completes tasks in minutes instead of hours, freeing staff for more important responsibilities.

Benefits and Outcomes

  • Time Saved: Manual data entry can take several minutes per patient. Automation reduces that to a few seconds per record.
  • Scalability: As the patient list grows, just update the CSV—no extra staff needed.
  • Reliability: Built-in waits (Sleep commands) give the system time to respond, minimizing script failures.
  • Emergency Stop Hotkeys: ^Esc or ^q instantly kill the script if necessary.

AutoHotkey is a powerful tool for anyone looking to automate desktop tasks—especially those that involve repetitive clicking and typing. Even a short script can significantly streamline your organization’s patient record generation workflows. For larger data manipulation or reporting needs, you can integrate other languages (like Python) or add advanced logging and error handling. But for purely desktop-based automation, AHK alone can handle the bulk of the work.

Got questions or suggestions? Share them with us via email!

How AWS Amazon Connect Improves Phone Communicatio...

2025-03-26


Saving a client over $60,000 through automation...

2025-03-06


What's up with AWS endpoints?...

2024-08-12


Fault Tolerance vs High Availability...

2024-08-08


Do you know your ABC's?...

2024-08-07