Hi Dmitry,

I just typed a lengthy answer but I think Marc's answer is better... looks like Ensemble has a Business Operation that solves your issue

Yes or course... in this case, you would return patients that have an instance of one Facility but not the other.

There might be an easier way:

Select * from HS_Registry.Patient where Facility='ABC' and MPIID in

(select MPIID from HS_Registry.Patient where Facility='XYZ')

MPIID is an indexed field so this should be relatively fast. Since the Patent table is the same you really need to get your "*" data only once; you just need to constrain it to only return a subset of patients that have instances of both Facilities (if I understand you correctly)

Hi George,

I would start by reading the following:


This explains how the FTP Inbound Adapter works and how to create a Business Service with the ADAPTER parameter. As an example, take a look at EnsLib.FTP.PassthroughService  class.

An Ensemble FTP Service is essentially a poller - it would connect to the remote FTP server and pull files from a remote folder that is specified in the File Path property on the Business Service.

We had to deal with this issue once. The class is EnsLib.HL7.SearchTable which extends Ens.VDoc.SearchTable. You can extend EnsLib.HL7.SearchTable and add a new PropName "MSHSendingFacility" to the SearchSpec XData block:

<Item DocType=""  PropName="MSHSendingFacility>[MSH:3]</Item>

Or you can create a parallel class that extends %Persistent and Ens.VDoc.SearchTable directly and copy the XData block from EnsLib.HL7.SearchTable, adding the line above to the block.

Hi Ahmad,

I would start with the following:

Generating Alerts:


Monitoring Alerts:


There is more documentation about Alerts and and ISC Training (it is part of Study Materials for Certified Health Connect Expert Certification). 

Implementing alerts might let you sort the errors you are getting in the Event Log and decide which errors would need an alert that can then be sent to your Participant.


I may try this later if I have time by I think I know why this would not work.

SourceTable.Field2 is a static Property so I don't think you can change its name on the fly. 

I have to run now but I would suspect that we may be able to get to the Property name with a Dynamic SQL Query and maybe set it while iterating through the ResultSet

Globals are not my strongest suite... I am not sure how the data elements are stored in Globals. That said, I think I can answer your 2nd question. HealthShare will not store Allergies without AllergyCode. The SDA is actually only an intermediate format for the HealthShare Data Model; the data is stored in the Streamlet database on each Edge Gateway. You will get an Alert in your Ensemble Production; something like "An Allergy Code needed to store Allergy".

To answer your more general question, such as "How many patients are there with a specific Allergy Code?", I have to admit that HealthShare is quite poor for running report-style aggregated queries of type "select count(Patient), AllergyCode from ... group by AllergyCode". The Streamlets are stored as XML Objects with no discrete data fields and have to be loaded into memory using, for example, an API method LoadSDAObject(pStreamletId, ByRef pSDA) in the HS.SDA3.Streamlet.ContainerMethods class. pSDA would be your HS.SDA3.Allergy object. But these objects are of type %SerialObject, not %Persistent. Data for all patients on an Edge Gateway are typically stored in a single global ^HS.SDA3.Streamlet.AbstractD (you can use the System Explorer -> Globals browser to see how it looks). 

The only time I remember we needed to aggregate Patient/Encounter data we had to write custom code to pull it out of the global. And even after that, we had to transfer the data to a SQL server to run aggregated queries.

I think HealthInsight is a product where these aggregated queries are handled better.

I hope this helps.

Hi Ahmad,

Your added code seems correct. Except for the where you add the remainder to the newline... $PIECE(line"|", 8) gets the content of the 8th column. remainder begins with the content of the 9th column, without any separator between them. So maybe $PIECE(line"|", 8)_"^"_remainder or $PIECE(line"|", 8)_"|"_remainder if you want to keep the original separator between 8th and 9th columns.

Also I assume you have Set tLineNumber = 0 before the while loop. Then, set tLineNumber tLineNumber + 1 makes sense at the beginning of the loop (I usually initialize at 1 and would have the increment at the very end of the loop).

Also, SetPatientContact takes "line" by reference... I assume there is a reason for that... usually strings in COS can be passed by value... unless you are going to change it inside SetPatientContact; then it makes sense.