I've used ChatGPT for some IRIS related things.. Sometimes it's been useful and some times its simply made up stuff, it made up the names of classes in IRIS that have never existed and do not exist in the most recent version.  Other times it's provided me some information that wasnt boiler plate to copy and paste but led me down a path that allowed me to find the solution.

There is in fact a global on the Registry that has a record of the Patient data each time it is changed, the global is ^HS.Registry.Patient.OldHistory

the way to understand this is to determine what resource is required to access the database associated with /database/db4/syb/.  You can find this out by going to System Administration->Configuration->System Configuration->Local Databases and view the table that is associated with /database/db4/syb/.  You should see something like

find your and find the Resource then add the Resource to the Role you are connecting with.  While adding %All as a role will prevent the error it will also grant a whole lot more permissions than just the <protect> error.  

If you are describing your globals in a class and they do not use default storage, but rather SQL Storage(%Storage.SQL) you can define your storage to include extended references.  This is a technique that I have used in the past.  How you loop thru the extended references is up to you.  In my case we took advantage of the ability to SetServerInitCode which is called once when the connection is made to the server, there is an equivalent capability in DeepSee/Analytics.  In our ServerInitCode we populated an array of the different extended references we needed to access and our storage map firstly looped thru this structure and then the actual global.

If those fields are not used in the ReportDisplay, ie the HTML or PDF output, you could consider removing them from the ReportDefinition.  If on the other hand, you do need these fields then leave them in.  However, something else seems to be going on.  I commonly have this style of ReportDefinition

The usage of <macrodef > just allows me to have a single set of code that injects the same attributes into the <Master> node.

When running the report in XML mode it produces

<Master runDt="10/13/2022" footerDate="October 13, 2022" runTm="08:47AM" runBy="_SYSTEM" Draft="" ISCPrime="0" Instance="HEALTHSHARE" Namespace="HSEDGE1" Server="LAPTOP-ET8APOSR" InternalURLLinkPrefix="http://localhost:52773" CustomerName="Ready Computing, Inc" CoverPageDate="October 13, 2022" CustomerLink="" PageNumbering="1" SystemMode="" FilterSpecDisplay="" ReportName="Ensemble Message Management" HeaderLine2="" Top="9999999999999" ReportClass="RC.Ens.Report.MessageManagement" ZVERSION="IRIS for Windows (x86-64) 2021.1.2 (Build 336_0_21564U) Tue Apr 12 2022 12:13:45 EDT" ReportTitle="">

I don't think attributes found in the root node, in my case Master, are emitted to the Excel file.

If I run the report in MODE=XLSX mode it produces.. note it does not show the attributes 

so this is answering your question regarding your attributes at the top level.  Your question regarding the elements at the ProssData node is something different.  In my example, if I change 


and then run the report in XLSX mode the attributes Namespace and TaskId do not appear in the Excel file.  However, I would have to change the ReportDisplay so that I now reference

@Namespace and @TaskId

if I want the PDF and HTML output to work properly.

Can you elaborate on what you mean by "hide" any component under ReportDefinition.  The ReportDefinition is where you define the XML document that will be created that is later used by ReportDisplay to output the data for a PDF report, Excel utilizes the ReportDefinition.   Just because you have an entity(element/attribute/group) in a ReportDefinition doesn't mean it will be utilized in the ReportDisplay.

I dont think your solution is a solution that works long term, someone can regenerate the record map and if your script isn't run then the property would be removed.  To answer your last question I think you would have better success if you define the property like

Property InsertDate As %UTC [ ReadOnly, SqlComputeCode = {set {*}=##class(%UTC).NowUTC()}, SqlComputed, SqlComputeOnChange = %%INSERT ];

I'm not 100% certain but the initial expression may only be executed as part of an object implementation but not part of an SQL statement.  If the RecordMap code is actually doing SQL inserts this may produce better results.

Late in replying but the differences between sourcing data from Cache vs a warehouse/data mart is that Cache will be able to provide you real-time information vs a warehouse/data mart which can have some degree of staleness, but that's likely obvious.  The advantage with a warehouse/datamart is that you could bring in other data and join with that data.  At the same time, there would be nothing to exclude you from bringing in external data in the HSPI namespace.   We at Ready Computing have extensive experience with reporting of the HSPI data.  This includes several ZEN reports, although note that the ZEN reports are just calling SQL Stored Procedures we wrote.  We also have DeepSee cubes defined that provide analysis on both the Patient table as well as the Classified pairs data.  It should be noted that the Classified pairs table has a number of indices defined to support most use cases for SQL queries.  Lastly, we've not found issues with the definition of the Patient table as far as performance goes.

Ok so this is definetely Centricity Business aka Flowcast and not GroupCast.

Generally speaking your query looks correct but some considerations

The join is incorrect.  Following your exact FROM clause, you would consider

FROM   Registration.Patient reg

       JOIN BAR.Invoice BAR on BAR.GID = Reg.ID

       JOIN Dict.Provider prov on prov.Id=BAR.prov

There is an index on bar.invnum so there is no issue with indices defined.

Note that properties/columns are properly typed in these classes so you could make the statement more concise by doing


                GID->PatNm As Guarantor,

                 GID->MRN As MRN

                  Prov->Name As Provider,


FROM     BAR.Invoice

WHERE  InvNum BETWEEN 63882965 and 64306671

Not to my knowledge.  While there is a global node in the storage map that is used to get the next available Id this would only work on tables/objects based on a single integer id.  At the same time, this is the next available Id and does not account for physical deletes that may have occurred, ie the next Id might be = 101 but you may have fewer than 100 rows/objects as some may have been deleted.  The simplest way to accomplish this would then to perform a SELECT COUNT(*) FROM TableName.  If the table implements this bitmap indices this should be ms.  If you don't get the performance you want you might consider adding %PARALLEL to the FROM clause and let the optimizer decide if it makes sense to split the job.