question

Chandler avatar image
0 Likes"
Chandler asked Chandler commented

Releasing resources only if a label exists - as user command? (healthcare)

I have been working on this and it is nearly working, but I need help to understand why I can't get the right function with a user command.

I am running patients through a release resource, though it is ambiguous which resources they have. I want all patients to release resources, but avoid throwing exceptions if the label does not exist.

This works, when put into the Resource field:

1695236399537.png

/**Custom Code*/
Object current = param(1); 
Object patient = current;
treenode activity = param(2);
Token token = param(3);
treenode processFlow = ownerobject(activity);

Array ret = [];

if (patient.Locations?){
for (int i = 1; i <= patient.Locations.length; i++){
ret.push(i);
}
}
else{
ret.push(0x0);
}

return ret;

But similar code does not work when I run it as a user command (it also doesn't work when I run it as code directly in the Resource field).

1695236448426.png

1695236485118.png

/**Custom Code*/
Object current = param(1); 
Object patient = current;
string lbl = param(2);

Array ret = [];

if (patient.labels[lbl]){
for (int i = 1; i <= patient.labels[lbl].subnodes.length; i++){
ret.push(i);
}
}
else{
ret.push(0x0);
}

return ret;


What am I missing here?

release_ambiguous_3.fsm

FlexSim 23.1.2
labelshealthcarescriptuser command
· 2
5 |100000

Up to 12 attachments (including images) can be used with a maximum of 23.8 MiB each and 47.7 MiB total.

Chandler avatar image Chandler commented ·

Update:


I can't seem to get the length of any label. I tried adding pointers to a staff and doing it on the staff, and directly accessing the patient in the tree as well. It's very odd.

1695237694389.png

1695237707577.png

0 Likes 0 ·
1695237694389.png (40.5 KiB)
1695237707577.png (36.5 KiB)
Jeanette F avatar image Jeanette F ♦♦ commented ·

Hi @Chandler, was one of Matthew Gillespie's or Chandler's answers helpful? If so, please click the "Accept" button at the bottom of the one that best answers your question. Or if you still have questions, add a comment and we'll continue the conversation.

If we haven't heard back from you within 3 business days we'll auto-accept an answer, but you can always comment back to reopen your question.

0 Likes 0 ·
Matthew Gillespie avatar image
1 Like"
Matthew Gillespie answered Chandler commented

Looking at this again, I think you're overcomplicating things. You shouldn't have to write a complicated user command to handle this case. For example, you could set up the Release activity like this:

ReleaseAll.fsm1695419041949.png

Choose the Release All option from the dropdown of the Location Resource field and then set the Label field to

person.labels.assert("Locations")

which will add the label if it doesn't exist. Or if you don't want to add the label in that case

person.labels["Locations"] ? person.labels["Locations"] : 0

1695419041949.png (17.1 KiB)
releaseall.fsm (50.3 KiB)
· 1
5 |100000

Up to 12 attachments (including images) can be used with a maximum of 23.8 MiB each and 47.7 MiB total.

Chandler avatar image Chandler commented ·

This has ended up being more or less what I've done.


I hadn't figured out the use of the ternary operator, though I don't care whether or not I create the label at the time of release - I was writing a multi-line conditional statement because I couldn't get correct results with a simpler

patient.Locations?

I ended up using a user command which indeed overcomplicates things (see a previous comment) - that code is here:

  
                    
  •     /**Custom Code*/    Object current = param(1);    Object patient = current;    string lbl = param(2);        return patient.labels[lbl] ? patient.labels[lbl] : 0x0;

Which is essentially identical to what you've written.

I started by trying to solve the problem in the resource to release field, when the problem really was in the Label field, did backflips to make that solution work, and then applied the same backflip logic to the label field.

Since, I have gone back through and set most components to the user command that slightly over complicates the logic that Matthew shared above.

When that conditional with the ternary operator is applied, the release all works as expected.


Thanks!

0 Likes 0 ·
Chandler avatar image
0 Likes"
Chandler answered Chandler commented

I figured it out, or at least a way to get the right answer:

Where I used:

patient.labels[lbl].subnodes.length

...while I would expect that to work, I substituted:

patient.labels[lbl].evaluate().length

...which gives me the array or value of the label explicitly, so I am getting the length property of the array instead of the treenode.

Seems the same to me, no worse anyway, so that'll do!

· 4
5 |100000

Up to 12 attachments (including images) can be used with a maximum of 23.8 MiB each and 47.7 MiB total.

Matthew Gillespie avatar image Matthew Gillespie ♦♦ commented ·

The locations are stored in an array on the label, not as subnodes under the label node. To access that array (or a number on a number label, etc) you have to get the label's value:

patient.labels[lbl].value

The evaluate() method does the same thing as .value except that if the label is a FlexScript node, it will execute it and return the value instead of returning the text on the node.

Accessing a label with a dot followed by the label name is a shortcut for calling evaluate() on that label. These two statements are equivalent:

patient.Locations
patient.labels["Locations"].evaluate()
1 Like 1 ·
Chandler avatar image Chandler Matthew Gillespie ♦♦ commented ·
Thanks Matthew, that's a concise summary.
0 Likes 0 ·
Chandler avatar image Chandler commented ·
I'm also aware now that this functionality is built-in. I don't know what I had wrong but it wasn't working when I tested it.
0 Likes 0 ·
Chandler avatar image Chandler commented ·

I also experienced something screwy with the use of patient.Locations? (etc) as the label. So, instead I wrote a similar user command that takes current and a string and checks to see if the label exists, returning the label explicitly if it does and returning a null pointer if it does not.

/**Custom Code*/
Object current = param(1);
Object patient = current;
string lbl = param(2);

return patient.labels[lbl] ? patient.labels[lbl] : 0x0;

1695309936216.png

1695309961891.png


I am also trying to set up the release_all user command to release a specific resource if its name is supplied. That code looks like this, and I am not 100% sure that it's correct:

/**Custom Code*/
Object current = param(1); 
Object patient = current;
string lbl = param(2);
string resource = param(3);

// EDIT THIS IF NEEDED
string processFlowLoc = "Tools/ProcessFlow/PtFlow_Dev";
treenode processFlow = Model.find(processFlowLoc);
// EDIT THIS IF NEEDED

Array ret = [];
 
if (patient.labels[lbl]){
if (param(3)){
if(getactivity(processFlow, resource)){
ret.push(getactivity(processFlow, resource));
}
}
else{
for (int i = 1; i <= patient.labels[lbl].evaluate().length; i++){
ret.push(i);
}
}
}

else{
ret.push(0x0);
}
 
return ret;


0 Likes 0 ·
1695309936216.png (41.6 KiB)
1695309961891.png (32.8 KiB)
1695310038328.png (66.7 KiB)