David Hockenbroch · Feb 22, 2021 go to post

Neither of the previous replies did exactly what I wanted to do, but action set to "New Window", filled the URL box with the URL but putting $$$VALUELIST where I needed that value to be, and set the "Active When" drop down to "1 Listing Item Selected". I set the Type to "Button" and gave it a label.

Now when you view listings in this dashboard and select one, you can click that button at the top to navigate where you need to go. That works for my purposes!

David Hockenbroch · Mar 11, 2021 go to post

I'd do an if before you create the result set.

if doUnion{
    set myquery = "query 2"
}
else{
    set myquery = "query 1"
}

set rs = ##class(%ResultSet).%New(myquery)
David Hockenbroch · Mar 26, 2021 go to post

I think you can accomplish this is $LISTFIND. It searches a list for a value, and returns its position in the list. If the item isn't found in the list, it will return a 0. For example, if you've got a list of colors called colorlist you'd use "where $LISTFIND(colorlist,'blue') > 0" in your SQL predicate to only include rows that have "blue" in their list. If the list contained "red", "blue", and "green" in that order, the $LISTFIND would return a 2. If the list contained "orange", "yellow", "taupe", the $LISTFIND would return a 0 because "blue" wasn't found and that row would be excluded.

David Hockenbroch · Apr 16, 2021 go to post

If you want to be able to call that method without first creating an instance of your class, you need to define the method as a Class Method, not just a Method. Add "Class" before Method on that function definition and recompile your class, and it will probably work.

Otherwise, like Marc said, you'll have to instantiate the class then call the method on that instance.

David Hockenbroch · Apr 21, 2021 go to post

It's hard to answer your question without more details about your class definition, but in general, you'd create an instance of your class, then just use the typical dot-separated syntax. So if your instance was called "MyTask" you should be able to use MyTask.Patient.FirstName to refer to the FirstName property of your patient.

David Hockenbroch · Apr 28, 2021 go to post

If it's a problem communicating with the broker applet, this could be a problem with your configuration or with your programming. To help figure out which it is, go to http://(your server):(your port)/samples/zipcode.csp and try to use that page. Just put 90210 in the zip code box and press tab. It should say that's the city Beverly Hills in the state of CA. If you get an error doing that, it's a configuration problem.

If it's a programming problem. Are using any #server calls when the page is loading, like in an OnLoad event or using embedded javascript in a runat="server" block? If so, you'll need to change those to use ObjectScript in a runat="server" code block.

David Hockenbroch · Apr 30, 2021 go to post

Try replacing your while loop with this:

//set RET to a blank string to start to avoid issues with the first concatenation inside the loop
s RET = ""
while res.Next()
    {
     //Append a ~ and the value to RET
     s RET = RET_"~"_ res.GetData(2)
}
//The way we did this, RET will now start with a ~, which we'll want to remove
//This will look at RET, replace tildes with nothing, starting at the beginning, and only making one replacement
$REPLACE(RET,"~","",1,1)

//having done that, RET should now be, "description 1~description 2"
David Hockenbroch · Apr 30, 2021 go to post

I think you're looking for the %ArrayOfObjects class for this one. You'd create your objects with all of their value, ID, and type properties, then you'd create the array:

set array = ##class(%ArrayOfObjects).%New()

Then you set values of the array using the SetAt method:

do array.SetAt(downobject,"down")

Then to access a particular value, you use the GetAt method, then dot syntax to access the object's properties:

set myid = array.GetAt("down").id

Here's the %ArrayOfObjects class documentation.

David Hockenbroch · May 7, 2021 go to post

If that's what you want to do, you may want to consider using an array, not a list. By default, arrays are projected as a child table for SQL. You can find more details on the differences in the Working with Collections article, and the part I'm referring to specifically is the Default Projection of Array Properties section.

You could also change the storage default parameter of your list to  "array", which is also described in the above article.

David Hockenbroch · May 17, 2021 go to post

I'm throwing in another vote for streams for all the reasons in the above reply chain, plus two more:

1. More efficient hard drive usage. If you have a ton of tiny files and your hard drive is formatted with a larger allocation unit, you're going to use a lot of space very inefficiently and very quickly.

2. At my previous job, we got hit by ransomware years ago that encrypted every document on our network. (Fortunately, we had a small amount of data and good offline backup process, so we were able to recover fairly quickly!) We were also using a document management solution that ran on Cache and stored the files as Stream objects, and they were left untouched. I'm obviously not going to say streams and ransomewareproof, but that extra layer of security can't hurt!

David Hockenbroch · May 18, 2021 go to post

Dmitry, I've added one now. It comes up every time I click on anything on the left side or just when I click on a different tab at the top.

David Hockenbroch · May 19, 2021 go to post

Steven, I'm getting this even after doing a docker logout too. Same error, BAD_CREDENTIAL. I see there's a comment above about linking an account to an organization. Do I need to do that?

David Hockenbroch · May 20, 2021 go to post

I tried it without those commas, and it made no difference. Thanks for the suggestion, though.

David Hockenbroch · May 20, 2021 go to post

You were right. The requested URL /api/atelier/ was not found on this server. What do I do about that, though?

David Hockenbroch · May 20, 2021 go to post

FYI, I enabled the /api/atelier web app, and that fixed the issue. Once I did that, I tried it both with and without the extra commas, and it was fine letting me connect either way. They were incorrect JSON, but they weren't the source of this particular problem.

David Hockenbroch · May 20, 2021 go to post

EnsLib.File.PassthroughOperation that lets you use timestamp variables, not EnsLib.File.PassthroughService. PassthroughOperation sends files, PassthroughService receives them.

David Hockenbroch · May 27, 2021 go to post

Just to clarify, in those bottom two queries, is that the entire query? No grouping, no sorting, no COUNT() functions?

If these are counts, it sounds like you've got some nulls in those columns. Try SELECT COUNT(*) FROM ACCT.Services WHERE TransID IS NULL and see what it says.

David Hockenbroch · Jun 25, 2021 go to post

A while back, I downloaded Crystal Reports for Eclipse and projected a couple of classes into Java and used them to set up an interface for us to automate emailing, printing, or archiving reports through Cache/IRIS's internal task manager.

David Hockenbroch · Jun 28, 2021 go to post

The %OnAfterCreatePage() method takes place after an instance of your page has been created on the server, but before it gets sent to the client, so it's really intended for server-side stuff.

Maybe instead you should be using the onloadHandler() method. That one runs on the client just before the page is displayed.

David Hockenbroch · Jul 13, 2021 go to post

ObjectScript variables are untyped, so preserving the type isn't necessary.

You'll build the list by adding your MyPackage.MyClass objects to it, then you'll return the %ListOfObjects, then you'll use that list's methods to manipulate those objects. For instance, set mything = mylist.GetAt(1) will give you an object that is identical to the MyPackage.MyClass object you put in the list with all of its properties an methods.

David Hockenbroch · Jul 15, 2021 go to post

It looks to me like the data returned in the HTTP response might not be proper JSON. Do you have that data for us to see?

David Hockenbroch · Jul 19, 2021 go to post

Somewhere in your button tag, you have onselect= something. Buttons don't have an onselect, but even if they did, I'm guessing that's not the event you actually want. onselect happens when a user highlights text within a control, like in a text input.

If you're trying to set what happens when the user clicks the button, that's onclick.

If you're trying to set what happens when the user selects the button but doesn't click it (say by pressing tab until the button is highlighted) that's onfocus.

David Hockenbroch · Jul 20, 2021 go to post

Sam, thanks, that solves the first part! Any idea how to make it show the item number somewhere no matter what drill down level I'm at?