go to post Julian Matthews · Jan 14, 2022 Hey Connor. You will likely want to look at this which describes reporting asyncs for mirroring.
go to post Julian Matthews · Dec 29, 2021 Hey Yuri. Depending on the context, this answer I gave for a similar question may be relevant: ...you can pass ..Adapter.ExecuteQuery() a snapshot object (EnsLib.SQL.Snapshot) which will then get populated rather than a getting a result set returned. With this populated snapshot object, you can then iterate through it using its Next() method just like the result set, but then you can use its Rewind() method. For example: Set Snapshot = ##Class(EnsLib.SQL.Snapshot).%New() Set sql = "SELECT * FROM MY_TABLE WHERE X= '"_Y_"'" Set status = ..Adapter.ExecuteQuery(Snapshot, sql) While Snapshot.Next(){ //First run through of snapshot } Do Snapshot.Rewind() While Snapshot.Next(){ //Second run through of snapshot }
go to post Julian Matthews · Nov 11, 2021 Hey Nicola. Changing the theme can certainly make Studio a little easier on the eyes (although it does feel like a bit of a hack): https://github.com/doublefint/CacheColorTheme
go to post Julian Matthews · Nov 5, 2021 Hey Nicola. As an alternative to Davids response, you can pass ..Adapter.ExecuteQuery() a snapshot object (EnsLib.SQL.Snapshot) which will then get populated rather than a getting a result set returned. With this populated snapshot object, you can then iterate through it using its Next() method just like the result set, but then you can use its Rewind() method. For example: Set Snapshot = ##Class(EnsLib.SQL.Snapshot).%New() Set sql = "SELECT * FROM MY_TABLE WHERE X= '"_Y_"'" Set status = ..Adapter.ExecuteQuery(Snapshot, sql) While Snapshot.Next(){ //First run through of snapshot } Do Snapshot.Rewind() While Snapshot.Next(){ //Second run through of snapshot } Something to be mindful of - as I'm passing ..Adapter.ExecuteQuery() an object rather than trying to get it to output something, the period before the variable is intentionally missing in my example.
go to post Julian Matthews · Nov 4, 2021 Thanks John, that's very good to know about. It's missing 1 or 2 features I like in ScreenToGif, but it's certainly going in my bookmark bar.
go to post Julian Matthews · Nov 3, 2021 Hey Ben. I use a program called ScreenToGif. Since moving to remote working it has become invaluable for demonstrating functionality for apps via email or IM. However it gets the most use when I'm reporting bugs to a supplier, or in this case how I'm incorrectly using VSCode extensions I'm pretty sure it's a Windows-only app, so you may need to find an alt if you're on another OS and wish to try it out. *edit* As a tip, try to keep any gifs you do make for bug reporting fairly short. No one wants to be waiting 2 minutes for a gif to loop because they missed the important part!
go to post Julian Matthews · Nov 3, 2021 Hey Brett, thank you for your help. I have found the issue. It looks like a file needs to be saved as a .cls first before the formatter is available for use. This differs from other languages within VSCode which just needs the language to be set for the new document.
go to post Julian Matthews · Nov 3, 2021 Hey @Brett Saviano I have the Language Server extension installed, however invoking the formatter using the keyboard shortcut Shift+Alt+F ( as per the VSCode documentation you linked) gives this popup:
go to post Julian Matthews · Nov 3, 2021 Hey Ben. Specifically looking to be able reformat the code layout. For example, if I was working with javascript or json, I can use the keyboard command Shift+Alt+F and it will reformat the code: However, when I attempt this with the language set to ObjectScript or ObjectScript-Class, pressing that same keyboard shortcut gives a popup stating no formatter is installed and it directs me to the Extension Marketplace
go to post Julian Matthews · Oct 29, 2021 Hey Kurro. To access values from your message class, you will need to alter your references to your class in your if statements. For example, rather than just calling "CodigoProveedor", you will need to state "Document.CodigoProveedor" so that the router is looking for "CodigoProveedor" within the document received by the router. You can test this by adding a new "When" within your Rule and use the expression editor to start type "Document.Cod" and this should then start giving you autocomplete options. For example: As an aside (and because it's caught me out a few times) if your router is working with just custom classes and not HL7, do make sure your router is a General message router and not a HL7 message router as this can sometimes lead to odd errors.
go to post Julian Matthews · Oct 28, 2021 Hey Yone. Assuming you're only using ObjectScript for this, then way to achieve this would be to take your HL7 as Enslib.HL7.Message, and then loop through the segments to pull out the PID segment, and then loop through PID:3 for a match. For example: //loop through HL7 and find PID Segment set SegCount = request.SegCount for i=1:1:SegCount{ set segment = request.GetSegmentAt(i) if (segment.Name="PID"){ //Loop through PID:3 set numCnt = segment.GetValueAt("3(*)") for j=1:1:numCnt{ set P341=segment.GetValueAt("3("_j_").4.1") set P5=segment.GetValueAt("3("_j_").5") if (P341="CAC")&&(P5="JHN") { $$$TRACE("Match found!") } } } } Alternatively, you could create a DTL with the logic which you can from the ObjectScript, and then have the target in your DTL be something like a string container that you can then grab a result from. However that might be a bit clunky depending on your use case.
go to post Julian Matthews · Oct 18, 2021 Hey Muhammad, I hope you are well. I hope you don't mind if I provide some feedback. First, the serious feedback - It is important that reference ranges are linked to the unit of measure provided in the result. This is because a change to the units used in the source could then mean that you provide the incorrect reference range/flag. This could then in turn lead to someone misinterpreting the results in the destination system and impact the treatment of a patient. Now to the less serious feedback - Some systems have extended the high/low flag so as to differentiate between something being slightly high, and something being extremely high. In the versions I have seen, this has been done as: LLL - Extremely LowLL - Severely LowL - Moderately LowN - NormalH - Moderately HighHH - Severely HighHHH - Extremely High It could make for an interesting expansion on what you have done so far.
go to post Julian Matthews · Sep 24, 2021 Hey Rochdi. The issue here is that you can't use the Arrow within the ON Clause and the alternative here would be to use ANSI Join syntax. If it helps, the documentation (under Join Definitions) states that -> performs a left outer join? There's also a section further down for ON Clause if that is useful in any way.
go to post Julian Matthews · Sep 17, 2021 Hey Sean. I had considered using the values from Memory and Startup, but was unsure of the exact class to call it, so thank you. I think my approach will be to use a util function which then returns a value based on SystemMode (I say based on, as I would want the same behavior even when failed over in a mirrored setting)
go to post Julian Matthews · Sep 16, 2021 Hey Thomas. EnableConfigItem from Ens.Director should be what you're looking for. You will need to call it twice (once to stop, and a second time to start it again). From Terminal: Do ##class(Ens.Director).EnableConfigItem("ConfigNameHere", 0, 1) Do ##class(Ens.Director).EnableConfigItem("ConfigNameHere", 1, 1) It returns a status, so you may want to evaluate the status when stopping it to ensure it stopped before trying to start it again, or report an error if it fails to stop or start.
go to post Julian Matthews · Aug 17, 2021 Hey Eduard. For question 3 - you could technically group them using managed alerts, as there is a function you can include in the router that is supposed to not raise an alert but instead update an existing managed alert (IsRecentManagedAlert) but this would mean getting alerted on the first message. However, I have found this to be a bit inconsistent as it relies on a match on the AlertText and SourceConfigName within a user defined timeframe. Where this catches me out is when the alert text contains something like a timestamp, as this makes it unique so a new alert is raised anyway. Alternatively, you could create a function that writes the alerts to an internal table, and then poll that table every x minutes to generate a single detailed alert message?
go to post Julian Matthews · Aug 11, 2021 Hey Muhammad. When you say validation, what exactly do you mean? If you are interested in making sure it matches the format of ICD-10-AM codes, then you could use pattern matching to ensure it fits the expected format. At first glance, it looks to be 1 Letter + 2 Numbers + 1 period + 1 or 2 numbers. The pattern match for this would be "1A2N1"."1.2N" For example: USER> Set ICD10 = "K76.3" USER> If ICD10?1A2N1"."1.2N {Write "This is ICD10"} else {write "This is not ICD10"} This is ICD10 If you are looking to actually make sure the code is a real ICD10 code, then you would need to be able to query a data source that contains a full list of valid codes. If this is the direction you're looking to go in, then you may want to look into FHIR based terminology services to be able to query your codes against to see if they're valid? But I'm not familiar with the practicality or cost of something like that. (ps - I have linked to the temporary documentation, however I'm not sure how long that will exist)
go to post Julian Matthews · Aug 9, 2021 Hey Muhammad. This should happen automatically when the message schema is applied. So, if this is based on an inbound HL7 service, then the Schema must be set in service using the setting "MessageSchemaCategory": Alternatively, if you are generating the message using the test option for a process/operation, then you can set the HL7 Document Property from the test options:
go to post Julian Matthews · Aug 6, 2021 It's been a short while since I threw this together, and I ended up adding in two important changes. OS Authentication Use of ##Class(Backup.General).ExternalSetHistory() As Global Masters reminded me of this post, I thought I should at least update it with the latest version: @echo off rem VMTools should pass in either freeze or thaw. if "%1" == "freeze" goto doFreeze if "%1" == "thaw" goto doThaw echo. echo Nothing Matched. Exiting... EXIT /b :doFreeze rem Call external freeze. OS Authentication negates need for login credentials. c:\InterSystems\HealthShare\bin\irisdb -s"C:\InterSystems\HealthShare\Mgr" -U%%SYS ##Class(Backup.General).ExternalFreeze() echo. echo. rem Check errorlevel from highest to lowest here. if errorlevel 5 goto FreezeOK if errorlevel 3 goto FreezeFAIL rem If here, errorlevel did not match an expected output. rem Assume Failure. echo errorlevel returned unexpected value goto FreezeFAIL :FreezeOK echo SYSTEM IS FROZEN rem Error levels from freeze do not match standard convention, so we return 0 when successful. EXIT /b 0 :FreezeFAIL echo SYSTEM FREEZE FAILED EXIT /b 1 :doThaw c:\InterSystems\HealthShare\bin\irisdb -s"C:\InterSystems\HealthShare\Mgr" -U%%SYS ##Class(Backup.General).ExternalThaw() echo. echo SYSTEM IS THAWED echo. c:\InterSystems\HealthShare\bin\irisdb -s"C:\InterSystems\HealthShare\Mgr" -U%%SYS ##Class(Backup.General).ExternalSetHistory() echo. echo BACKUP RECORDED EXIT /b 0