ORCgrp is a member of PIDgrpgrp and PIDgrpgrp is missing from your "if" statement. The condition should read:

..Contains(..ToUpper(source.{PIDgrpgrp(k1).ORCgrp(k2).OBXgrp(k3).OBX:ObservationValue()}),"DETECTED")

I don't know whether you're using the same doctype for the target, but if you are, the target path will need to be updated as well.

Here's an example of the generated query, updated with calls to HICG.GetMsg():
 

SELECT TOP 100 head.ID As ID, 
    {fn RIGHT(%EXTERNAL(head.TimeCreated),999 )} As TimeCreated,
    head.SessionId As Session, 
    head.Status As Status,
    CASE head.IsError WHEN 1 THEN 'Error' ELSE 'OK' END As Error,
    head.SourceConfigName As Source,
    head.TargetConfigName As Target,
    head.SourceConfigName, 
    head.TargetConfigName, 
    head.MessageBodyClassName As BodyClassname, 
    head.MessageBodyId As BodyId, 
    EnsLib_HL7.Message.%ID As Body_ID, 
    HICG.GetMsg(head.MessageBodyId,'PID:3') As Body_PID_PatientID,
    HICG.GetMsg(head.MessageBodyId,'PID:18') As Body_PID_PatientAccountNumber 
    FROM %IGNOREINDEX Ens.MessageHeader.SessionId Ens.MessageHeader head, 
        EnsLib_HL7.Message 
    WHERE (((head.SourceConfigName = 'From_Some_Router'
        AND head.TargetConfigName = 'To_Some_Operation')) 
        AND head.MessageBodyClassName='EnsLib.HL7.Message'
        AND head.MessageBodyId=EnsLib_HL7.Message.%ID) 
    ORDER BY head.ID Desc

I just replaced the null values with calls to HICG.GetMsg(). The 2nd argument is the schema-specific path to the values you're extracting, using the same syntax as found in EnsLib.HL7.Message's GetValueAt() method. You can download the class from the HL7 Spy website: https://hl7spy.ca/downloads/HICG_HL7.xml.

While @David.M's response will provide a query, it will likely not include the HL7 message-derived values. For example, a search that includes the HL7 field values you've listed will return null for their values when executed via the SQL menu or SQL shell.

That said, I created a tool (originally for use with HL7 Spy to extract HL7 messages from Ensemble/Health Connect) that has some features that may help get you what you want. See this thread for an example of its use.

On Ubuntu, check your /etc/apache2/apache2.conf file and verify that the csp Directory stanza contains a CSPFileTypes line with all of the required file extensions needed:

<Directory "/opt/webgateway/csp">
        CSPFileTypes csp cls zen cxw png jpg css gif svg js
        AllowOverride None
        Options MultiViews FollowSymLinks ExecCGI
        Require all granted
        <FilesMatch "\.(log|ini|pid|exe)$">
                Require all denied
        </FilesMatch>
</Directory>

Getting this error with SQL tools when connecting to IRIS 2025.1.1 via https. The customer I'm working with has an internal CA and its root/chain is in my trusted root certificate store. The ObjectScript extension doesn't appear to complain about it when using https for my server configurations, with or without NODE_TLS_REJECT_UNAUTHORIZED = 0 set in the environment.

From the SQL Tools error log:

Error t [RequestError]: Error: unable to verify the first certificate
at new t (c:\Users\Jeff.vscode\extensions\intersystems-community.sqltools-intersystems-driver-0.1.7\dist\ls\plugin.js:2:405571)
at U.callback (c:\Users\Jeff.vscode\extensions\intersystems-community.sqltools-intersystems-driver-0.1.7\dist\ls\plugin.js:2:407384)
at e.callback.t.callback [as _callback] (c:\Users\Jeff.vscode\extensions\intersystems-community.sqltools-intersystems-driver-0.1.7\dist\ls\plugin.js:2:406830)
at t._callback.t.callback.t.callback (c:\Users\Jeff.vscode\extensions\intersystems-community.sqltools-intersystems-driver-0.1.7\dist\ls\plugin.js:2:430662)
at U.emit (node:events:518:28)
at U.onRequestError (c:\Users\Jeff.vscode\extensions\intersystems-community.sqltools-intersystems-driver-0.1.7\dist\ls\plugin.js:2:439522)
at ClientRequest.emit (node:events:518:28)
at emitErrorEvent (node:_http_client:104:11)
at TLSSocket.socketErrorListener (node:_http_client:518:5)
at TLSSocket.emit (node:events:518:28)
at emitErrorNT (node:internal/streams/destroy:170:8)
at emitErrorCloseNT (node:internal/streams/destroy:129:3)
at process.processTicksAndRejections (node:internal/process/task_queues:90:21) {
cause: Error: unable to verify the first certificate
at TLSSocket.onConnectSecure (node:_tls_wrap:1679:34)
at TLSSocket.emit (node:events:518:28)
at TLSSocket._finishInit (node:_tls_wrap:1078:8)
at ssl.onhandshakedone (node:_tls_wrap:864:12) {
code: 'UNABLE_TO_VERIFY_LEAF_SIGNATURE'

A similar issue has been reported on GitHub, and I added the relevant stuff from above as a comment; the issue has been open since May and he developer hasn't responded. Just wondering if anyone else has experienced this and found a solution.

The Matches() method in the DTL and Routing Rule function list does not use regex syntax; it uses COS "?" pattern matching. The pattern you'd need for your specific example is "1A2N" for 1 alpha character followed by 2 digits.

There's also a ..RegexMatch() method for the DTL and Routing Rule editors in most modern versions of IRIS. That accepts most pcre regex patterns.

It's been my experience that the contents of the ACK message are not evaluated by any of the ReplyCodeActions. If you need to specifically suspend messages that are NAK'ed with this value in MSA:3, you'll need to create a custom operation and associated adapter (likely extending EnsLib.HL7.Operation.TCPOperation and EnsLib.HL7.Adapter.TCPOutboundAdapter respectively) that implements the NAK/Suspend logic.

There were a couple of solutions mentioned in my reply.

If you need to work with field values in the message, either for routing or transformation, you will need to create a custom schema that includes the Z segment (which you'll also need to create) and assign that Message Schema Category in the inbound interface.

And if you want to transform the message using the DTL Editor, you'll need to specify the custom Message Schema Category for the Source (and possibly Target, if the downstream application needs it) message.

Include the setting in the SETTINGS string, but prefix it with a dash (-) character:

Parameter SETTINGS = "-Whatever,DSN:Basic:selector?context={Ens.ContextSearch/DSNs},..."

EDIT: Was apparently typing that while you were reading the documentation 😁

And for competeness' sake, the actual documentation:

Adding and Removing Settings

While I love this idea (and have voted for it!) I think it would be ideal to generalize it into the concept of themes. I've elaborated on my reasoning in a comment on the idea @Yone Moreno Jiménez  posted in the Ideas Portal.

I'm wondering if it should be its own Idea, though ... but I don't want to "split the vote" if it interferes with Yone getting his accessibility issue addressed.

Also, one might be tempted to simply kill the ^Ens.Queue global.

Don't.

^Ens.Queue is used for other housekeeping tasks, and while killing it will absolutely remove all messages from visibility in the queue viewer, it won't change the message headers for those items from queued status to something else (like aborted or discarded). And it will very likely break other things that you really don't want to break.

Here's a short method you can place in a utility class that does what you want:

ClassMethod AbortAll() As %Status
{
    Set tSC = $$$OK
    Set tQry = ##class(%SQL.Statement).%New()
    Set tSC = tQry.%PrepareClassQuery("Ens.Queue","Enumerate")
    If $$$ISOK(tSC)
    {
        Set tRS = tQry.%Execute()
        While tRS.%Next()
        {
            Set tQueue = tRS.%Get("Name")
            Write !, "Aborting Queue "_tQueue
            Do ##class(Ens.Queue).AbortQueue(tQueue)
        }
    }
    Return tSC
}