<dataListBox  sql="select id from deepsee_study.doctor" onclick="alert('onclick');onchange="alert('onchange');ondblclick="alert('ondblclick');">

I tested this in the SAMPLES namespace on Cache for Windows (x86-64) 2018.1.2 (Build 309_5U) Wed Jun 12 2019 20:02:36 EDT. When clicking an item, I see the onchange alert. After double clicking the item I previously selected, I see the ondblclick alert.

System Management Portal -> System Administration -> Configuration -> National Language Settings -> Locale Definitions

Please note that your browser will often localize content based on your browser settings, so the Management Portal may not look different after doing this, but if you open terminal you should see your newly selected Locale and if you do things like compile classes in Studio, you should see your output messages in the new Locale also

Hi Scott,

The CSP folders will be located on your system where you have installed HealthShare. This means you can just move your images to this directory and then your apps should be able to reference them.

The documentation for the <image> tag has a few hints:

"If provided, src is the URI of an image to display. If src is the relative pathname of a file, it is understood to be relative to the Caché installation directory. Typically this path identifies the images subdirectory for your Zen application, for example:
<image id="myFrame" src="/csp/myApp/images/myPic.png" />"

Hi Mike,

As you have seen, Class files are stored within Caché and not on the file system. We have Studio hooks available as documented here. These allow you to write code to perform the export and import automatically as you interact with your classes in Studio. After files have been automatically exported, you will be able to run Git commands to commit and push your changes as desired.

Instead of doing all of this yourself, there does seem to be an Open Exchange app available that does something like this. I have not used this before, but @Alexander Koblov may be able to add more details of how complete it is


You can just check $$$ISERR(sc) directly here, you do not need to run it through $system.Status.GetErrorText(sc)  first.

$$$ISERR(status) will compile into ('status). In the case where sc=1, status will become = "". This means that 'status will evaluate to true when sc=1, which means it will think there is an error when there is not.

USER>set sc=1
USER>set status=$system.Status.GetErrorText(sc)
USER>zw sc
USER>zw status
USER>w ('status)
USER>w ('sc)

Hi Lawrence,

I suggest opening a new WRC with Support. Here are a couple first step diagnosis options that can be helpful, but without a deeper understanding of the DeepSee Engine, it may be difficult to debug or correct the issues.

1) Run MDXUtils and produce a performance report.

This tool will kill your DeepSee Cache and then execute the query. It will log statistics about the query and the cube. It then runs the query a second time which will use the Cache that was just generated. Depending on the query, this can often be much faster.

2) Run DeepSeeButtons.

This will give a snapshot of your entire DeepSee environment. It will also look for recommended configurations and alert if the recommendations are not followed. For example, if the Database your Cache globals are stored in is journaled, this can negatively impact query performance. Lots of globals are modified during query execution, so it is recommended to not have this journaled. If DeepSeeButtons detects that the Database your DeepSee Cache is in is journaled, it will create an alert.

As I mentioned earlier, it is probably a good idea to contact Support, but these are two good steps to start with (and the WRC will probably ask for these as well)

Would this be for a Development System or a Production System?

If it is a Development System you could consider using source control hooks to basically prevent people from modifying the class unless they first check out the file. If they attempt to modify it without first checking it out, they will get a message saying they need to first check out the file. If they do not have permission to do so, they will not be able to. If they do have permission to, using source control will allow you to revert any changes that end up causing issues.

If it is a Production System, you can consider using deployed mode. See documentation here. The documentation says: "You can open the class definition in Atelier, but it is read-only." (This is true for Studio also).

As you mention, making the Database Read Only is also an option.

Hi Nael,

I was able to make this work using an XData Map (Documentation here). I have uploaded my Sample to GitHub so you can see how I implemented it. I will also summarize what I did here:

This Sample uses 3 classes: Teacher, Student, and TeacherStudent. As you describe and as your JSON output suggests, Teacher and Student have a reference to TeacherStudent, which simply has an ID. To allow this to output the link to the next object (depending on the direction) I had to use Calculated properties. This means I can access data from TeacherStudent, but I am not storing the references again. The calculations to get the Teacher/Student are pretty simple, just an SQL statement to get the related record. At this point, if you try and use %JSONExport() on a student, it will print out the teachers as expected, but then the teachers print out all the students, and the students print the teachers again. This continues until reaching an error.

To avoid this, I used the XData Map. One map for "Student" and one map for "Teacher". Each is named based on the starting point. When using the Teacher map, the Teacher class will output the name and the link to TeacherStudent. TeacherStudent will then output the name and the link to Student. Student will then output only the name and will not link back to TeacherStudent. The same is true for using the Student map for Student (but going the other way).

I hope this accomplishes what you are looking for!


Here are a couple of ways for getting information about a file:

Get file size:

set file=##class(%Stream.FileBinary).%New()
write file.LinkToPath("C:\temp\test.csv")
write file.Size

Get number of lines:

set file=##class(%Stream.FileBinary).%New()
write file.LinkToPath("C:\temp\test.csv")
while 'file.AtEnd {
    do file.ReadLine()
    set linecount=$i(linecount)
write linecount

Hi Kevin,

This can be achieved by applying a dynamic filter spec to your cube/subject area. This can be done within the %OnGetFilterSpec method. Below you will find a sample that can be used against the HOLEFOODS Sample:

ClassMethod %OnGetFilterSpec(pFilterSpec As %String) As %String
Set pFilterSpec=""
If $USERNAME="Peter" {
Set pFilterSpec="[PRODUCT].[P1].[PRODUCT CATEGORY].&[Candy]"
ElseIf $USERNAME="Kevin" {
Set pFilterSpec="[PRODUCT].[P1].[PRODUCT CATEGORY].&[Pasta]"
Quit pFilterSpec

In this sample, when I log in, I will only see data related to Candy sales. When you log in, you will only see data related to Pasta sales. If anyone else logs in, they will see all categories.

Subject Areas are typically used on top of cubes when you want to filter the data like this. You can also do this directly on the cube, but it is easier to create multiple subject areas with different criteria if you stick to only using Subject Areas for this.

The logic and specs can be more complex if needed. I usually go to Analyzer and put together the necessary criteria and use the generated MDX directly or as a guide for my filter spec.


Hi Semen,

You can accomplish this using Pivot Variables + Calculated Members.

You will need to define a pivot variable named "CommonDate" (or whatever, we will use "CommonDate" for this example). This Pivot Variable will contain values like "65211". The Patients Cube in SAMPLES contains an example YEAR Pivot Variable.

You will then define two calculated members:

1) Start Date = "[StartDate].[H1].[StartDay].&[$variable.CommonDate]"

2) End Date = "[EndDate].[H1].[EndDay].&[$variable.CommonDate]"

You can then create an "Apply Pivot Variable" control in your dashboard pointing to the "CommonDate" pivot variable. This date will then be applied to both dimensions even though they have different names.

Modifying your level definition in Architect to have a "Sort Order" or "desc numeric" will provide the sort that you desire. This will change the sort wherever this level is used though, not just for this one pivot.

You MIGHT also be able to create a new measure that can be used just for sorting this dimension, the measure could be based off of the $h value for the date. I have not tested this, but in theory it should work. You would also need to use the AVG value, since the SUM would not work for this

After selecting the Terminal tab (like you have done in the picture), you can click on the "Open a Terminal" button on the right side of the bar that contains the tabs. This will open a "Launch Terminal" popup. Mine defaults to "Telnet Terminal" for "Choose terminal". In here, I normally just type "localhost" into the "Host" field and leave the rest of the default values. After clicking OK, I am connected to my instance.

Note: Make sure %Service_Telnet is enabled

Hi Jaqueline,

You may also want to consider implementing %OnProcessFact (documentation link). This will allow you to run some code to determine if the record should be included or not. This can potentially be easier to implement some advanced logic rather than adding a build restriction. For many people, using the Build Restriction is enough though. As Evgeny says, this will add a WHERE clause to the SQL that is used to get the source records during a cube build.