I ran into this problem as well, and I vaguely recalled that the passthrough file service has issues with multiple targets. So I went to the documentation and tried to find any reference to the need to ensure the operations were called synchronously and (initially) couldn't. So I went ahead and configured the services with Work and Archive directories and waited for something bad to happen.

And of course, something bad did happen.

I later found the file adapter documentation that provides a clear description of how the Work and Archive directories impact synchronous delivery. It seems to indicate that the Work directory is more likely to break sync than the Archive directory, and that you can have an Archive directory configured while still supporting sync as long as the Work directory is not configured.

Oh yes, it finally settled down and worked normally, but it seemed to be spending a lot of time talking to the servers before displaying the package listing. The servers are on AWS and I'm connected via a VPN, but my connection is quite fast for a home office and I've never noticed that before.

I've also exited and relaunched VS Code since without any significant delay, so it must've been a one-off.

I upgraded to the new beta that uses the proposed apis (v2.12.9-beta.1), and when I reconnected to the server, it took quite some time (5-10 minutes) before I could get to work. Since then, performance has been normal. Is there some new feature that indexes classes/routines locally or something? I couldn't find anything in the usual logs that indicated what was going on.

While the EnsLib.FTP.OutboundAdapter class has no Filename property, the FTP Operation classes do. The problem is you can't obtain the Session Id in the ISC-supplied operation classes, but you can insert it in the message Source property (or OriginalFilename property of Ens.StreamContainer) via a DTL or other Business Process. That value is what the %f token uses to provide the filename in those Operations.

The mechanism to obtain the Session Id differs by the process used; In a DTL, the macro $$$JobSessionId should work. In a BPL, ..%PrimaryRequestHeader.SessionId should provide the same.

If you're building your own Operation class and are, for example, subclassing EnsLib.FTP.PassthroughOperation, you can override OnMessage() and prepend $$$JobSessionId to the filename variable passed to ..Adapter.PutStream().

Yes, there's a "raw" syntax, but I think it's counterproductive in the long run. Segments and fields can be addressed numerically, i.e. target.{1:4} would reference MSH:4. Not very descriptive; one of the beauties of using the DTL editor and message DocTypes is that your transformations become somewhat self-documenting.

You could attempt to build an HL7 "SuperSchema" DocType/Category, I suppose, if your intent is to address message elements using the "symbolic" Virtual Document syntax. For that, you need a DocType.

$E is the shorthand version of $EXTRACT ...

ConvertDateTime(source.{PID:DateTimeOfBirth},"%Y%m%d%H%M%S","%Y%m%d") should work just fine.$E(source.{PID:DateTimeOfBirth},1,8) by itself should provide the same result.

But ConvertDateTime($e(source.{PID:DateTimeofBirth},1,8)) is basically taking the 8-digit date returned from $E() and converting it without any input and output patterns ... which gets you the exact same 8-digit date.

The field definitions are properties of the *.Record class, so you could perform a property query against %Dictionary.Properties using the *.Record class as the parent.

SELECT Name
FROM %Dictionary.PropertyDefinition
WHERE parent = 'OSUMC.RecordMap.Patient.Record' AND Name >='A' AND Name <= 'z'
ORDER BY SequenceNumber ASC

That would get you the field names in the same order as the data and exclude any percent properties.