LoadHL7Files
Overview
LoadHL7FilesTask processes HL7 message files from a directory, parsing and importing patient demographics, visits, orders, and charges into database tables. The task reads all HL7 files from a specified folder, validates message types against an allowed list, extracts structured data, and archives processed files to a separate directory.
Use this task when: You need to import HL7 messages (ADT, SIU, ORM, DFT) from external systems like EMRs, practice management systems, or lab interfaces to populate patient, visit, order, and charge data.
Don't use this task when:
- Processing real-time HL7 messages via TCP/IP interfaces (use HL7 listener service instead)
- Working with non-HL7 data formats like CSV or delimited files (use
LoadDataFileTaskinstead) - Need to export HL7 messages (this task is import-only)
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
MessageFolderPath |
string |
Yes | - | Directory path containing HL7 message files to process. All files except those ending in .part are processed. |
MessageProcessedFolderPath |
string |
Yes | - | Directory path where processed files will be moved after successful or failed processing. Files are organized into subdirectories based on processing status. |
AllowedMessageTypes |
List<string> |
No | All supported types | List of HL7 message types to process (e.g., ADT^A01, SIU^S12). Messages not in this list are skipped and archived. Default includes all 16 supported message types. |
AddTimestampToFileName |
bool |
No | true |
When true, appends timestamp to filename when archiving (e.g., message.hl7 becomes message_2025-01-15T14-30-00.hl7). Prevents filename collisions. |
Execution Flow
Processing Algorithm
The task processes HL7 files using a three-phase approach:
Phase 1: File Discovery and Reading
- File Enumeration: Scans
MessageFolderPathfor all files, excluding.partextension (incomplete transfers) - Progress Logging: Logs progress every 10 files to track batch processing
Phase 2: Message Parsing and Validation
- Read File: Extracts raw HL7 message text from file
- Parse Message: Uses
HL7Processorto parse message structure:- Validates MSH segment (message header) is present
- Extracts message type from MSH-9 field (e.g.,
ADT^A01) - Checks if message type is in
AllowedMessageTypeslist - Parses all segments into structured data dictionary
- Error Handling:
- Missing MSH segment → Mark as Error, log "No MSH segment found"
- Unknown message type → Mark as Error, log "Unknown message type"
- Disallowed message type → Mark as Skip, log "Message type not allowed"
- Incomplete required segments → Mark as Error with specific segment error
Phase 3: Database Import and Archiving
HL7Archive Table: Every message (including errors and skips) is saved with:
- Unique archive key
- Original message text
- Error flag and error message (if applicable)
- Skip flag (if message type not allowed)
HL7Message Table: Every message is saved with:
- Parsed segment list (MSH, PID, PV1, etc.)
- Message metadata
Type-Specific Table: For successfully parsed, allowed messages only:
- ADT Messages (A01, A03, A04, A09, A10) →
HL7ADTtable - Patient Messages (A08, A28, A31) →
HL7Patienttable - Visit Messages (S12, S13, S14, S15, S17, S26) →
HL7Visittable - Order Messages (O01) →
HL7Ordertable - Charge Messages (P03) →
HL7Chargetable
- ADT Messages (A01, A03, A04, A09, A10) →
File Archiving: Move processed file to
MessageProcessedFolderPath:- Optionally append timestamp if
AddTimestampToFileName = true - Organize into subdirectories by status (successful vs. error/skip)
- Optionally append timestamp if
Supported Message Types
| Category | Message Types | Table | Description |
|---|---|---|---|
| ADT (Admission/Discharge/Transfer) | ADT^A01, ADT^A03, ADT^A04, ADT^A09, ADT^A10 | HL7ADT | Patient admission, discharge, registration |
| Patient | ADT^A08, ADT^A28, ADT^A31 | HL7Patient | Patient demographics updates |
| Visit | SIU^S12, SIU^S13, SIU^S14, SIU^S15, SIU^S17, SIU^S26 | HL7Visit | Appointment scheduling |
| Order | ORM^O01 | HL7Order | Clinical orders |
| Charge | DFT^P03 | HL7Charge | Detailed financial transactions |
Usage Examples
Example 1: Process all supported message types with archiving
var task = new LoadHL7FilesTask
{
MessageFolderPath = @"C:\HL7\Incoming",
MessageProcessedFolderPath = @"C:\HL7\Archive",
// AllowedMessageTypes omitted - defaults to all 16 supported types
// AddTimestampToFileName omitted - defaults to true
};
Example 2: Process only patient and visit messages
var task = new LoadHL7FilesTask
{
MessageFolderPath = @"C:\HL7\Incoming",
MessageProcessedFolderPath = @"C:\HL7\Archive",
AllowedMessageTypes = new List<string>
{
"ADT^A08", // Patient update
"ADT^A28", // Add patient
"ADT^A31", // Update patient
"SIU^S12", // Appointment notification
"SIU^S13", // Appointment rescheduling
"SIU^S15" // Appointment cancellation
},
AddTimestampToFileName = true
};
Example 3: Process only charge messages without timestamp
var task = new LoadHL7FilesTask
{
MessageFolderPath = @"\\server\share\HL7\DFT",
MessageProcessedFolderPath = @"\\server\share\HL7\Processed",
AllowedMessageTypes = new List<string> { "DFT^P03" },
AddTimestampToFileName = false // Use original filenames in archive
};
Example 4: Import from network share with full message type filtering
var task = new LoadHL7FilesTask
{
MessageFolderPath = @"\\EMR-Server\HL7Export\Outbound",
MessageProcessedFolderPath = @"\\EMR-Server\HL7Export\Archived",
AllowedMessageTypes = new List<string>
{
// ADT messages
"ADT^A01", "ADT^A03", "ADT^A04",
// Patient updates
"ADT^A08", "ADT^A28",
// Orders
"ORM^O01",
// Charges
"DFT^P03"
},
AddTimestampToFileName = true
};
Related Tasks Comparison
| Task | Use Case | Message Format | File Handling | Tables Updated |
|---|---|---|---|---|
| LoadHL7FilesTask | Import HL7 messages from files | HL7 v2.x standard | Batch processing from folder, moves files after processing | Multiple HL7 tables (Archive, Message, ADT, Patient, Visit, Order, Charge) |
LoadDataFileTask |
Import delimited data files | CSV, pipe-delimited, etc. | Single file import with optional archiving | Single target table defined in DataFileSpec |
ProcessDataFileTask |
Import and merge data files | CSV, delimited | Scans file structure and performs merge | Import table + source table |
When to use LoadHL7FilesTask:
- Source data is HL7 v2.x format
- Need to import patient demographics, visits, orders, or charges from EMR/PM systems
- Processing batch HL7 feeds from interfaces
- Want automatic file archiving by processing status
When to use alternatives:
- Non-HL7 format data → Use
LoadDataFileTaskorProcessDataFileTask - Real-time HL7 messages → Use HL7 listener service
- Custom data transformations → Use
ProcessDataFileTaskwith custom mappings
Performance Considerations
Database Impact
- Connection Usage: Single connection maintained throughout task execution
- Tables Affected: Up to 7 tables per message:
HL7Archive(always)HL7Message(always)- One of:
HL7ADT,HL7Patient,HL7Visit,HL7Order, orHL7Charge(if valid message)
- Transaction Scope: Each file is saved independently (failure of one file doesn't affect others)
- Bulk Operations: Individual row inserts per message (not bulk copy)
- Locking: Row-level locks during insert; minimal blocking
File System Impact
- I/O Pattern: Sequential read of each file, then move operation
- File Locking: Files must not be locked by other processes
- Network Shares: Task supports UNC paths but performance depends on network latency
- Partial Files: Files ending in
.partare automatically excluded to avoid processing incomplete transfers
Optimization Tips
| Scenario | Recommendation | Rationale |
|---|---|---|
| Large file batches (1000+ files) | Split into multiple smaller batches or run during off-hours | Task processes files sequentially; progress logged every 10 files |
| Network share processing | Copy files to local folder first, then process | Reduces network I/O overhead during parsing |
| High error rate | Filter AllowedMessageTypes to expected types only | Skips unwanted message types early in processing |
| Archive storage concerns | Disable timestamp (AddTimestampToFileName = false) or implement archive cleanup job |
Prevents archive folder growth from duplicate filenames |