Question Chris Bransden · Jul 25, 2017

How to automatically populate a transient array property?

Hi! I am trying to automatically populate an array property of cash amounts keyed by currency ("GBP", "USD", etc). This property needs to be NOT stored on the database and visible via SQL and the cache object. 

Here's my attempt. Ultimately the array will be populated based on the the some child classes, but for now I'm just hardcoding it:

Property Amounts As array Of %Numeric [ SqlComputeCode = { set {*} = ##class(ContainerSize).GetTotalAmounts()}, SqlComputed, Transient ];
ClassMethod GetTotalAmounts(thisID) As %Collection.ArrayOfDT{set arrAmounts=##class(%Collection.ArrayOfDT).%New()do arrAmounts.SetAt(1.23,"GBP")do arrAmounts.SetAt(2.45,"EUR")quit arrAmounts}

This compiles but accessing via SQL gives:

[SQLCODE: <-350>:<An unexpected error occurred executing SqlComputeCode>]

Via object:

macdocs:MACDEV1>w obj.Amounts
 
<INVALID OREF>zSetAt+4^%Collection.ArrayOfDT.1

If what I'm trying isn't possible, is there another datatype that I could populate with this kind of information, via compute code ?

Thanks!

Comments

Sean Connelly · Jul 25, 2017

From the documentation...

The %Collection.ArrayOfDataTypes class represents an array of literal (i.e., data type) elements, each of which is associated with a unique key value. Keys can have any value, string or numeric. These %Collection classes can only be used when you have a collection property of another object as they rely on storing the data inside the parent object, they can not be used as 'stand alone' collections, for this use the %ArrayOfDataTypes.

0
Sean Connelly  Jul 25, 2017 to Sean Connelly
Set arr=##class(%ArrayOfDataTypes).%New()
; place items into the array
Do arr.SetAt("red","color")
Do arr.SetAt("large","size")
Do arr.SetAt("expensive","price")
; iterate over contents of array
Set key=""
For  Set value=arr.GetNext(.key) Quit:key=""  Write key,":",value,!
0
Chris Bransden  Jul 25, 2017 to Vitaliy Serdtsev

perfect, works! Thanks!!

0
Vitaliy Serdtsev · Jul 25, 2017

Try this:

<FONT COLOR="#000080">Property </FONT><FONT COLOR="#000000">Amounts </FONT><FONT COLOR="#000080">As %ArrayOfDataTypes </FONT><FONT COLOR="#000000">[ </FONT><FONT COLOR="#000080">SqlComputeCode </FONT><FONT COLOR="#000000">= { </FONT><FONT COLOR="#0000ff">set </FONT><FONT COLOR="#800080">{*} </FONT><FONT COLOR="#000000">= </FONT><FONT COLOR="#000080">##class</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008080">ContainerSize</FONT><FONT COLOR="#000000">).</FONT><FONT COLOR="#0000ff">GetTotalAmounts</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#800080">{ID}</FONT><FONT COLOR="#000000">)}, </FONT><FONT COLOR="#000080">SqlComputed</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#000080">Transient </FONT><FONT COLOR="#000000">];</FONT>

<FONT COLOR="#000080">ClassMethod </FONT><FONT COLOR="#000000">GetTotalAmounts(</FONT><FONT COLOR="#ff00ff">thisID</FONT><FONT COLOR="#000000">) </FONT><FONT COLOR="#000080">As %List </FONT><FONT COLOR="#000000">{   </FONT><FONT COLOR="#0000ff">quit $lb</FONT><FONT COLOR="#000000">(            </FONT><FONT COLOR="#0000ff">$lb</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008000">"GBP"</FONT><FONT COLOR="#000000">,1.23),            </FONT><FONT COLOR="#0000ff">$lb</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008000">"EUR"</FONT><FONT COLOR="#000000">,2.45)           ) }</FONT>

0