Property cAge As %String(TRUNCATE = 1) [ Calculated, SqlComputeCode = {set {cAge}=0 if {dDateOfBirth}>0 set {cAge}=$ZD($H,8)-$zd({dDateOfBirth},8)\10000 }, SqlComputed ];

This code turns my date of birth (+$h style ) into age

I use to find the age of animals in my competitions. as they return year on year. but the Date of birth is constant.

There appears to a confusion and understanding between a ClassMethod and a Method

your code ret=zenPag.getSessionValue()

looks like a Method as it is dependant on the object zenPage existing.

A ClassMethods can be called from anywhere thus must be identified in full

##class(ClassName).ClassMethod(Params if any)

getSessionValue must be a method with the zenPage Class structure.

You do not disclose the Class object that hosts the method1 of the onloadHandler so these may be ClassMethods

But Not the zenPage.getSessionValue() this defines a Method.

I have a financial module that communicated with a 'Futers' company in London

this downloades the daily changes of the stocks to my Client's processor


John Peck

var xhttp new XMLHttpRequest();
        xhttp.onreadystatechange function (obj) {
           if (this.readyState == && this.status == 200) {
             window.obj JSON.parse(this.responseText);
// http:/ / ip csp
var xhttpUrl=UrlRoute+"/smartrest/RsvpSpecial?Invite="+Invite
var xhttpRpl=UrlRoute+"/smartrest/RsvpActivity""GET",xhttpUrl, true);

There are two issues here

The xhttp is triggered to wait for the traffic to be completed,

xhttp.onreadystatechange function (obj) {
           if (this.readyState == && this.status == 200

There are four changes of state. the 4 means competed. then the Next Fuction can be called to populate the data that has just been uploaded.

The next problem for me. was that the data is out of scope. thus the 'window.obj'

The reply Post:

var ReplyString=JSON.stringify(objReply)
var xhttpRpl=obj.Landing.ReplyRoute
var xhttp new XMLHttpRequest();"POST",xhttpRpl, true);
xhttp.setRequestHeader('Content-type','application/json; charset=utf-8');
xhttp.onreadystatechangefunction() {
if (this.readyState==='4' && this.status==='200') { return true;}

Roll back is an issue that is often hard to track. When I have encountered it it is caused by the same object being opened twice where a further save of data will compromise the other instance (within the same session). hence the rollback. You can generally prove this by watching the ID of the class. as the data is rolled back it takes on a new ID. Once you can identify this you can refocus your attention to track down the the logic flaw.


As usual it depends what you are trying to do.

Cache passwords may take care of themselves but I have a Web Portal that does not use the cache logon process.

I save the HashEncryption in the string property. As Far as I know this cannot be decrypted

set obj=##class(abc.portal.objPortalAccount).%OpenId(PortalAccountId)
set obj.sPassword=##class(abc.util.Encryption).HashEncryption(Password)
set sc=obj.%Save()

On the next login I encrypt the entry field and compare to the original established version.

When the Web user estabilshes his account, he enters the Email address that I need to prove.

I return an email to that address with a url and a coded string to continue with the challenge.

set Return=##class(abc.util.Encryption).Base32Encode(Return)

This can be decrypted within  the web page when it is retuned attached to the URL and this allows me to validate the retuning process.

set Return=##class(abc.util.Encryption).Base32Decode(Return)

Once all this has been extablished I invite the users prefered Password and save it with the HashEncryption it then becomes non readable.

Hope this helps.


I have a dll that creates an Excel document

I would be delighted to help you debug your word dll.

I have been using activate for years. but when the 64 bit Cache was lauanced the 64 bit link did not work with the activate wizard. ( this is now fixed in the 2016.2 version)

So I was forced to created the .net dll

My original problem was that there were too  many parameters. so I added a top level dll to simplyfy the call

The Cache Studio allows you to chain these dll(s) go gether.

I also used the viual studio to create this module. and it is in constans use.

Since your version is not working yet may I offfer some advice for your consideration.

Embed all the commands with a single common library. in this way all your 'File Generation' code call will be a single source. in this way you will have only one place to expand or correct any problems.

All my reports are in excel spread sheets. Thus all these report generating routines build a common template

at the very end of the code each calls a common code with evokes all the file creation processes.

The younger developers know how to populate the template for with the reporting cache software, but they have no need of the knowledge on how to transfer this template into an actual file.  The system does this for them. Thus the maintenance of the library is entirely independent of all these reports. Thus if in the future Mircosoft or Intersystems change the rules there is only one place to go and fix the change

I have extended this further. When I call the template I first check the Cache version. if it is a 32 bit code I pass the template through the Activate channel for both Word and Excel. If I am running a 64 bit Cache version I pass the templaye to the Dll version.

If you think we have common email me

set Header=$$Line("Sequence\HeatNo\Calalogue\First\Surname\Bisca No\LeftHand\Flexible\Country\Exhibitor No")

set NewFileName=$p(Target_"\"_$$$NewDocument(PageTitle),".",1)_".csv"
        set File=##class(abc.file.FlatFile).%New(),xcount=0
        do File.WriteLine(Header)

set Seq=Seq+1,Line=Seq_"\"_$lg(ExportData,12)_"\"_CatNo_"\"_$lg(ExportData,3)_"\"_$lg(ExportData,4)_"\"_$lg(ExportData,16)_"\"_$lg(ExportData,18)_"\"_$lg(ExportData,17)_"\"_$lg(ExportData,15)_"\"_$lg(ExportData,10)
        set Data=$$Line(Line) do File.WriteLine(Data)

do File.SaveFile(NewFileName)
    kill File            

    set ln=$l(str,"\"),New=""
    for lp=1:1:ln set New=New_$c(34)_$p(str,"\",lp)_$c(34,44)
    quit $e(New,1,$l(New)-1)
    q str


build the Taget folder and make sure that the file Name is legal and ends in.csv

I built my row (line) data with a delimitor "\"

then I pass this through the $$Line(Line)

1) open the file and add a header to identify the columns

2) loop down the data build the Line of data and file the 'do file.WriteLine(Line)' for each row

3) Close the file and kill the file object