go to post Jeffrey Drumm · Jan 11, 2020 The OBX segment is probably defined as repeating, so: Should work.
go to post Jeffrey Drumm · Jan 9, 2020 From COS - $SYSTEM.Version.GetVersion() From SQL - SELECT $ZVERSION Not a .NET guy, sorry!
go to post Jeffrey Drumm · Dec 30, 2019 Execution details for routing rules are located in Ens.Rule.Log. The available values are ID, ActivityName, ConfigName, CurrentHeaderId, DebugId, EffectiveBegin, EffectiveEnd, ErrorMsg, IsError, Reason, ReturnValue, RuleName, RuleSet, SessionId, and TimeExecuted. In the SQL facility, you can query Ens_Rule.log: SELECT ID, ConfigName, CurrentHeaderId, RuleName, RuleSet, SessionId, TimeExecuted FROM Ens_Rule.Log
go to post Jeffrey Drumm · Dec 29, 2019 Assuming the stream contains the normal $C(13) segment delimiters: Class User.HL7.Stream Extends %RegisteredObject { ClassMethod GetCounts(pStream As %Stream.FileCharacter, Output pMsgCount As %Numeric, Output pSegCounts As %ArrayOfDataTypes) As %Status { Do pStream.Rewind() Set pStream.LineTerminator = $C(13) Set pSegCounts = 0 While 'pStream.AtEnd { Set tLine = pStream.ReadLine() // Remove leading control characters Set tSeg = $ZSTRIP(tLine,"<C") // Get the segment name Set tSegName = $EXTRACT(tSeg,1,3) If tSegName '= "" { If '$DATA(pSegCounts(tSegName)) { // We have a new subscript Set pSegCounts = pSegCounts + 1 Set pSegCounts(tSegName) = 1 } Else { Set pSegCounts(tSegName) = pSegCounts(tSegName) + 1 } } } Set pMsgCount = pSegCounts("MSH") Return $$$OK } } Call the classmethod with the stream as follows: Do ##class(User.HL7.Stream).GetCounts(stream,.Msgs,.Counts) Counts will be subscripted by the segment names found in the message stream. In the above example, you'll find the occurrence count of FT1 segments in Counts("FT1") and the number of messages will be in Counts("MSH"). The value returned in Msgs is the same as Counts("MSH").
go to post Jeffrey Drumm · Dec 17, 2019 If you have access to Caché terminal, you can run run queries that won't time out: (the sample below assumes your namespace is "PROD"; just substitute whatever your production's namespace is for that). USER> zn "PROD" PROD> d $system.SQL.Shell() SQL Command Line Shell---------------------------------------------------- The command prefix is currently set to: <<nothing>>.Enter q to quit, ? for help.PROD>>SELECT COUNT(*) AS AlertCount FROM Ens.MessageHeader WHERE MessageBodyClassName = 'Ens.AlertRequest' AlertCount2205 PROD>>Q PROD> So ... if you don't have BodiesToo checked, you most likely have lots of orphaned message bodies taking up database space. And KeepIntegrity is probably retaining a lot of message headers (and associated bodies) that you don't care about anymore. There are reasons you would not want to turn KeepIntegrity off in earlier versions of Caché/Ensemble, like pre-2015 releases. If you're on a release more modern than that and you don't need to worry about messages with parent/child relationships (certain batch types, for example), you can probably turn that off. There are a couple of articles regarding the management of orphaned bodies here on DC. Might be worthwhile to peruse them :)
go to post Jeffrey Drumm · Dec 16, 2019 printf formatting tokens (%Y, %m, %d, etc.) are not wildcard characters. You'll be limited to legal file naming characters and OS/Shell specific wildcard characters such as * and ? for fetching files.
go to post Jeffrey Drumm · Dec 12, 2019 Select something for the "In files/file types:" field, then enter a search value. You can also do it in reverse order, but both fields are required
go to post Jeffrey Drumm · Nov 24, 2019 I've done something similar with COS, but in my case it was the ORC group that was repeating: Class HICG.Process.MultiORC Extends Ens.BusinessProcess [ ClassType = persistent ] { Property TargetConfigNames As %String(MAXLEN = 1000); Parameter SETTINGS = "TargetConfigNames:Basic:selector?multiSelect=1&context={Ens.ContextSearch/ProductionItems?targets=1&productionName=@productionId}"; Method OnRequest(pRequest As EnsLib.HL7.Message, Output pResponse As Ens.Response) As %Status { Set tORCcnt = pRequest.GetValueAt("PIDgrpgrp(1).ORCgrp(*)") For i=1:1:tORCcnt { Set tMsg = ##class(EnsLib.HL7.Message).%New() Set tMsg.DocType = pRequest.DocType // Keep MSH:10 unique Set tMsgCtrl = pRequest.GetValueAt("MSH:10")_"."_i Do tMsg.SetValueAt(pRequest.GetValueAt("MSH"),"MSH") Do tMsg.SetValueAt(tMsgCtrl,"MSH:10") Do tMsg.SetValueAt(pRequest.GetValueAt("PIDgrpgrp(1).PIDgrp.PID"),"PIDgrpgrp(1).PIDgrp.PID") Do tMsg.SetValueAt(pRequest.GetValueAt("PIDgrpgrp(1).PIDgrp.PV1grp.PV1"),"PIDgrpgrp(1).PIDgrp.PV1grp.PV1") Do tMsg.SetValueAt(pRequest.GetValueAt("PIDgrpgrp(1).ORCgrp("_i_").ORC"),"PIDgrpgrp(1).ORCgrp(1).ORC") Do tMsg.SetValueAt(pRequest.GetValueAt("PIDgrpgrp(1).ORCgrp("_i_").OBR"),"PIDgrpgrp(1).ORCgrp(1).OBR") Set tOBXcnt = pRequest.GetValueAt("PIDgrpgrp(1).ORCgrp("_i_").OBXgrp(*)") For j=1:1:tOBXcnt { Do tMsg.SetValueAt(pRequest.GetValueAt("PIDgrpgrp(1).ORCgrp("_i_").OBXgrp("_j_").OBX"),"PIDgrpgrp(1).ORCgrp(1).OBXgrp("_j_").OBX") } Set tSC = tMsg.%Save() $$$TRACE(tSC) For iTarget=1:1:$L(..TargetConfigNames, ",") { Set tTarget=$ZStrip($P(..TargetConfigNames,",",iTarget),"<>W") Continue:""=tTarget Set tSC1 = ..SendRequestAsync(tTarget,tMsg) Set:$$$ISERR(tSC1) tSC=$$$ADDSC(tSC,tSC1) } } Return tSC }
go to post Jeffrey Drumm · Oct 16, 2019 The audit log can provide information on who changed a production configuration, such as adding or modifying a business host configuration. It does not contain information on who modified or created a routing rule, DTL, BPL or other class associated with running a production. For the latter you should consider implementing a Source/Version control system that controls how those components progress from development through QA to Prod and tracks who made those changes. Deltanji from George James Software is a strong contender in that area.
go to post Jeffrey Drumm · Oct 13, 2019 Did you select EnsLib.HL7.Service.SOAPService as your service's class? If yes, then I know the following XML format works: <?xml version="1.0" encoding="UTF-8" ?> <SOAP-ENV:Envelope xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:s='http://www.w3.org/2001/XMLSchema'> <SOAP-ENV:Body> <Send xmlns="http://tempuri.org"> <Input> <![CDATA[MSH|^~\&|... rest of hl7 message here, with <CR><LF> at end ]]> </Input> </Send> </SOAP-ENV:Body> </SOAP-ENV:Envelope>
go to post Jeffrey Drumm · Oct 12, 2019 I'm assuming you don't have "Act on Validation Error" enabled in the router's settings ... in which case the message will be set to Completed status even though it failed validation. If you enable "Act on Validation Error" its status will be set to Error; you'll then be able to select for that status in the Message Viewer and resend. Note that with this setting enabled, you may want to set "Reply Code Actions" to do something other than the default, such as sending the messages to the Suspended Messages facility. Another option would be to specify a Bad Message Handler; this forwards failed validations to a business host where other actions can be taken such as alerting or logging to a file. You'll also have the option of resubmitting those messages to their original destination by specifying a new target in the Message Viewer's Resend facility.
go to post Jeffrey Drumm · Sep 17, 2019 Yes, that's the purpose of the EnsLib.HL7.Operation.FileOperation class.
go to post Jeffrey Drumm · Sep 6, 2019 1. Sure, this will work find for just passing a file through to the target system.2. Yes. You can use public/private key authentication as well.3. Do you really want to put the files into the root directory? Normally, a FTP/SFTP server will default to the "home" directory for the account your operation logs in under. If you don't specify a path, that's where the data you're transferring will end up. If the account has its home directory set to the root directory and has permission to write there, your files will end up there.4. You'll need to set the SSL configuration to the special value "!SFTP". There's no profile for it; it's just an indicator for the operation that you'll be using the SFTP protocol.
go to post Jeffrey Drumm · Aug 27, 2019 Hi Scott,The upgrade instructions for HealthShare/HealthConnect 2018.1.2 should be essentially the same as for Caché/Ensemble 2018.1.2. The documentation for the latter is here:https://cedocs.intersystems.com/latest/csp/docbook/DocBook.UI.Page.cls
go to post Jeffrey Drumm · Aug 20, 2019 Hi Leon,You're actually looking to create a batch, with a batch header for your file output.To do this you'll need to define a batch class in your RecordMap, and in that class define your header (I'm assuming it's a fixed header, like field names).You'll then want to use EnsLib.RecordMap.Operation.BatchFileOperation (or BatchFTPOperation) to deliver the batches. There are a few ways to trigger the batch rollover; a schedule, a record limit, or a Batch Rollover Request depending on your needs.
go to post Jeffrey Drumm · Aug 19, 2019 I'm thinking that you may want quotes around the 0000 value ... you are, after all comparing it to a string
go to post Jeffrey Drumm · Aug 12, 2019 Hi Robert,You can actually export the entire production in a single go through the Export button found in the Actions tab of the Production Settings. You would then use the "Manage / Deployment Changes" page on the target system to deploy the entire production to the destination namespace.Other options include: Select "Files of type: DTL Document (*.dtl)" in Studio's Export option under the Tools menu (click "Add"), and select the entire list with shift-click (and similarly import through Studio), or use the ObjectScript class method $System.OBJ.Export("*.dtl","/path/to/exportfile.xml") and corresponding import method $system.OBJ.Load("/path/to/importfile.xml") in the target environment.The class methods work locally on your HealthConnect servers; if they're physically distinct hosts you'll need to copy the export file to the target server. Also you would run the export/load utilities in the namespace in which your production is located, of course ...
go to post Jeffrey Drumm · Aug 1, 2019 You can use the Source property to identify the component that sent the message into the router:
go to post Jeffrey Drumm · Jul 25, 2019 You could do it with an SQL query:DELETE FROM Ens_Util.LookupTable WHERE TableName = '<name of table>'You can create the query either via the Management Console (System Explorer | SQL | Execute Query tab) or from the SQL Shell JEFF>d $system.SQL.Shell() SQL Command Line Shell ---------------------------------------------------- The command prefix is currently set to: <<nothing>>. Enter q to quit, ? for help. JEFF>>delete from Ens_Util.LookupTable where TableName = 'facLookup' 1. delete from Ens_Util.LookupTable where TableName = 'facLookup' 3 Rows Affected statement prepare time(s)/globals/lines/disk: 0.1893s/11322/125529/16ms execute time(s)/globals/lines/disk: 0.0021s/29/408/0ms cached query class: %sqlcq.JEFF.cls27 ---------------------------------------------------------------------------
go to post Jeffrey Drumm · Jul 23, 2019 As @Brian Schoen alluded to, $CHAR -- abbreviated to $C if you want to be one of the cool kids -- is what you need. $C(13,10) is the line-end sequence in Windows. $C(10) is Unix. $C(13), though, is old-school Macintosh* * Also works for HL7 Segment delimiters