系统间缓存:类 中的 <Framestack> 和 <Command> 错误:如何解决和避免?
Intersystems cache: <Framestack> and <Command> error in Classes : How to solve AND avoid?
我在 Intersystems Cache 中有一个 class
- 根据用户的调用在
globals
上写入记录
- 迭代
globals
并将结果放在 string
- 通过
FILE
将所述结果写入记事本文件
但是,部分代码总是returns<FRAMESTACK>
错误。
在他们的文档中搜索显示:
该例程对 Do、For、Xecute、New 或用户编写的函数的嵌套调用过多。
如果你想知道为什么我使用一个违反 SOLID 的 class,那是因为当我尝试在一个方法中通过 ##class()
调用其他方法时,我遇到了错误 <COMMAND>
。因此,我将代码放入我需要的方法中,并将它们混合在一个方法中。
有没有办法在 CLASS 中正确调用 class 方法?
关于FrameStack错误,到底多少算太多?我该如何避免这种情况?
编辑:请求的代码
ClassMethod GetRRCDelToNP(DateFrom As %String, TimeFrom As %String, DateTo As %String, TimeTo As %String, Startparam As %String, Type As %String, Operator As %String, User As %String) As %String [ SqlProc ]
{
k ^IDXCMAWEB("ROADRECEIVAL",User)
S RRCTR=0
n conwt
Q:$G(DateFrom)="" "E:Please enter date time entry."
Q:$G(TimeFrom)="" "E:Please enter date time entry."
Q:$G(DateTo)="" "E:Please enter date time entry."
Q:$G(TimeTo)="" "E:Please enter date entry."
Q:$G(Type)="" "E:Please enter type entry."
Q:$G(Operator)="" "E:Please enter operator entry."
Q:$G(User)="" "E:Cannot process query. I dont know who you are."
s (I,J,K,CN,CN1)=""
s I=$ZDH(DateFrom,9)
s J=$ZTH(TimeFrom)
s TDT3=$ZDH(DateTo,9)
s TTM3=$ZTH(TimeTo)
Q:(TDT3<I) "E:Date time to cannot be greater than date time from."
Q:(TDT3=I)&(TTM3<J) "E:Date time to cannot be greater than date time from."
s MTY=$s(Type="optall":"",Type="optrec":"R",Type="optdel":"D")
s OPR=$s(Operator="A":"",Operator="a":"",1:Operator)
i OPR'=""
S
OPR=$tr(OPR,"abcdefghijklmnopqrstuvwxyz,","ABCDEFGHIJKLMNOPQRSTUVWXYZ|")_"|"
s %id=User
i K="" S CN=""
loopi2 ;loopi
if J="" s I=$O(^IDXLGE(I)) Q:(I="")!(+I>TDT3)
loopj2 ;loopj
if K="" s J=$O(^IDXLGE(I,J)) g loopi2:J=""
if (I'="")&((I=TDT3)&(J>TTM3)) s J="",K="",CN="" g loopi2
loopk2 ;loopk
if CN="" S K=$O(^IDXLGE(I,J,K)) g loopj2:K=""
if "RD"'[K g loopk2
I $G(MTY)'="",MTY'[K g loopk2
if (I="")!(+I>TDT3) quit ;$G(I)_"/"_$G(J)_"/"_$G(K)_"/"_"0"_"/"_$G(^WK($J))
loopcn2 ;loopcn
S CN=$O(^IDXLGE(I,J,K,CN)) g loopk2:CN=""
S D=$G(^IDXLGE(I,J,K,CN))
S HIS=$P(D,"|"),MOV=$P(D,"|",2),GEN=$P(D,"|",3)
g loopcn2:HIS=""!(MOV="")!(GEN="")
S N=$G(^CNREC(CN,HIS,"MOVE",MOV))
S NB=$G(^CNREC(CN,HIS,"MOVEB",MOV))
I $P(N,"|",3)="CANCL" g loopcn2
S Z=$G(^CNREC(CN,HIS,"GEN",GEN))
I $P($G(^CNREC(CN,HIS,"GENB",GEN)),"|",3)["CSW" g loopcn2
g loopcn2:$P(Z,"|",9)=""
I OPR'="",OPR'[($P(Z,"|",9)_"|") g loopcn2
I "56"[$E($P(Z,"|",2)) g loopcn2
S Q=$P(Z,"|"),VSC=$P(Z,"|",3)
s VOY=$P(Z,"|",4)
I $L($$^CMAUTH(%id,CN,VSC,VOY,$P(Z,"|",9))) s Error="" g loopcn2
S YEAR=""
I VSC'="" D
.S VCN=$P($G(^CDTAB("SEQN",VSC,VOY)),"|")
.g loopcn2:VCN=""
.S VN1=$G(^CDTAB("VOY",VSC,VCN,"1"))
.S VN2=$G(^CDTAB("VOY",VSC,VCN,"2"))
.S V=$S(Q="E":$P(VN1,"|"),Q="I":$P(VN1,"|",2),1:"UNK")
.S YEAR=$p($zd($P($P(^CDTAB("VOY",VSC,VCN,1),"|",5),",",1)),"/",3)
.S R=$P(VN2,"|",9)
E S (VSC,V,R)=""
g loopcn2:$E(R,1,3)="ATI"!($E(R,1,3)="BOC")
S DATE=$zd(I,9)
S ARR=$G(DATE)_" "_$zt(J,4)
S Q=$S(Q="E":"Export",Q="I":"Import",Q="S":"Recirculation",1:"Unknown")
S M=$P(Z,"|",17)
s conwt=$p(Z,"|",18)
i conwt'="" s conwt=conwt_" Tons"
s othersealno=$P(Z,"|",15)
s bookingseal=$P(Z,"|",5)
s seal=$P(Z,"|",16)
s plate=$P(N,"|",11)
s trucker=""
i plate'="" D
.S truckercode=$P($G(^CDTAB("PLATE",plate)),"|",1)
.i truckercode'="" S
trucker=$TR($P($G(^CDTAB("CART",truckercode)),"|",1),"/","")
S shipper=""
I YEAR'="" D
.S ivn=$G(^IXVH("R",YEAR,R))
.I ivn="" S ivn=$G(^IXVH("R",YEAR-1,R))
.I ivn'="" D
..S BLN=$O(^IXIFM(ivn,CN,""))
..I BLN'="" S shipper=$TR($P(^BSIFM(ivn,BLN),"|",3),"/","")
s dmg=$P(NB,"|",3)
S CN1=CN1+1
S M=$S(M="F":"Full Container Load",M="L":"Less Container Load",M="E":"Empty",M="T":"Transhipment",1:"unknown")
S K1=CN_"|"_$E($P(N,"|",22),2)_"|"_Q_"|"_M_"|"_$P(Z,"|",2)
S K1=K1_"|"_$P(Z,"|",10)_"|"_$P(Z,"|",9)_"|"_VSC_"|"_V_"|"_R_"|"_ARR
S K1=K1_"|"_conwt_"|"_$P(Z,"|",2)_"|"_HIS_"|"_GEN_"|"_CN1_"|"_othersealno_"|"_bookingseal_"|"_dmg_"|"_seal_"|"_plate_"|"_trucker_"|"_shipper
i $P(K1,"|",2)'="" s $P(K1,"|",2)=$s($P(K1,"|",2)="R":"Received",$P(K1,"|",2)="D":"Delivered",1:$P(K1,"|",2))
S sz=$P(K1,"|",5)
i sz'="" s sz=$e(sz,1,1)
s $P(K1,"|",5)=$s(sz="0":"20'",sz="2":"20'",sz="4":"40'",sz="9":"45'",sz="L":"45'",sz="1":"10'")
i $P(K1,"|",6)'="" s $P(K1,"|",6)=$p(^CDTAB("COMM",$P(K1,"|",6)),"|")
i $P(K1,"|",7)'="" s $P(K1,"|",7)=$tr($p(^CDTAB("OPER",$P(K1,"|",7)),"|"),"/","")
i $P(K1,"|",8)'="" s $P(K1,"|",8)=$tr($p(^CDTAB("VESS",$P(K1,"|",8)),"|"),"/","")
S ^IDXCMAWEB("ROADRECEIVAL",User,RRCTR)=K1
S RRCTR=RRCTR+1 ;now holds the total number of GLOBALS
s recctr=CN1
set getrows=""
s NewI=I
g loopcn2 ;THIS POINT WORKS AND CREATES THE GLOBALS
;####201694:2017-05-18 = GET THE DATA FROM THE GLOBALS JUST MADE ABOVE WITH THE loopcn2
S totrec=""
S totrec=RRCTR-1 ;-1 so that the loop clearly shows all records
;totrec will now contain the total number of records. iterate on totrec
S ctr=0 ;will contain the current record count
S rsult="" ;will contain the total string result, to be written on the notepad
Do
{
S data=""
I $D(^IDXCMAWEB("ROADRECEIVAL",User,ctr)) D
.S data=$G(^IDXCMAWEB("ROADRECEIVAL",User,ctr))
E D
.S data=""
S rsult=rsult_"|"_ctr_$P(data,"|",1) ;modify further. this will be the returned string
S ctr=ctr+1
} WHILE ctr<=totrec
;Q rsult ;return the results...
;now, we write the results in a notepad file.
;writes the text file. OLD: S FILE="\SOMELOC\PubShare\theFileToJSON.TXT"
S FILE="\SOMELOC\PubShare\theFileToJSON.TXT"
O FILE:"WNS" U FILE
S WriteToFile=rsult
W rsult ;...we actually write the file?
C FILE
Q FILE ;display the file?
}
在这里,在生成全局变量的部分之后,我迭代了总记录数 RRCTR
以将所述全局变量的一部分放入单个字符串中。
全局创建成功,但是没有创建文件。为什么是这样?当 运行 时,它说 <COMMAND>
作为错误
<FRAMESTACK>
通常在递归调用代码时发生。这不是一个好的编程习惯,尤其是当您遇到堆栈溢出错误时,您可以配置更大的堆栈,但我建议您尝试重写您的代码,不要使用递归。
看起来你的 <COMMAND>
错误发生了,因为你在你的 do..while 循环中混合了 "curly brackets" 最后使用 "do with a dot" 语法。这是不支持的,请重写您的那部分代码以在所有地方使用大括号:
Do
{
S data=""
I $D(^IDXCMAWEB("ROADRECEIVAL",User,ctr)) {
S data=$G(^IDXCMAWEB("ROADRECEIVAL",User,ctr))
} else {
S data=""
}
S rsult=rsult_"|"_ctr_$P(data,"|",1) ;modify further. this will be the returned string
S ctr=ctr+1
} WHILE ctr<=totrec
尝试用 "do ##class(class).method" 而不是 "Write ##class(class).method)" 调用 class 这也不是真正的缓存代码,它的 Mumps 代码和(恕我直言)旧的遗留问题写得很糟糕。你个人应该重写它(或付钱请顾问)
我同意保罗的观点。使用 Go 命令 'g' 代替 'argumentless For' 进行迭代是非常糟糕的编程习惯。整个事情需要在没有任何 Go ("g") 命令的情况下重写。
我在 Intersystems Cache 中有一个 class
- 根据用户的调用在
globals
上写入记录 - 迭代
globals
并将结果放在string
- 通过
FILE
将所述结果写入记事本文件
但是,部分代码总是returns<FRAMESTACK>
错误。
在他们的文档中搜索显示:
该例程对 Do、For、Xecute、New 或用户编写的函数的嵌套调用过多。
如果你想知道为什么我使用一个违反 SOLID 的 class,那是因为当我尝试在一个方法中通过 ##class()
调用其他方法时,我遇到了错误 <COMMAND>
。因此,我将代码放入我需要的方法中,并将它们混合在一个方法中。
有没有办法在 CLASS 中正确调用 class 方法?
关于FrameStack错误,到底多少算太多?我该如何避免这种情况?
编辑:请求的代码
ClassMethod GetRRCDelToNP(DateFrom As %String, TimeFrom As %String, DateTo As %String, TimeTo As %String, Startparam As %String, Type As %String, Operator As %String, User As %String) As %String [ SqlProc ]
{
k ^IDXCMAWEB("ROADRECEIVAL",User)
S RRCTR=0
n conwt
Q:$G(DateFrom)="" "E:Please enter date time entry."
Q:$G(TimeFrom)="" "E:Please enter date time entry."
Q:$G(DateTo)="" "E:Please enter date time entry."
Q:$G(TimeTo)="" "E:Please enter date entry."
Q:$G(Type)="" "E:Please enter type entry."
Q:$G(Operator)="" "E:Please enter operator entry."
Q:$G(User)="" "E:Cannot process query. I dont know who you are."
s (I,J,K,CN,CN1)=""
s I=$ZDH(DateFrom,9)
s J=$ZTH(TimeFrom)
s TDT3=$ZDH(DateTo,9)
s TTM3=$ZTH(TimeTo)
Q:(TDT3<I) "E:Date time to cannot be greater than date time from."
Q:(TDT3=I)&(TTM3<J) "E:Date time to cannot be greater than date time from."
s MTY=$s(Type="optall":"",Type="optrec":"R",Type="optdel":"D")
s OPR=$s(Operator="A":"",Operator="a":"",1:Operator)
i OPR'=""
S
OPR=$tr(OPR,"abcdefghijklmnopqrstuvwxyz,","ABCDEFGHIJKLMNOPQRSTUVWXYZ|")_"|"
s %id=User
i K="" S CN=""
loopi2 ;loopi
if J="" s I=$O(^IDXLGE(I)) Q:(I="")!(+I>TDT3)
loopj2 ;loopj
if K="" s J=$O(^IDXLGE(I,J)) g loopi2:J=""
if (I'="")&((I=TDT3)&(J>TTM3)) s J="",K="",CN="" g loopi2
loopk2 ;loopk
if CN="" S K=$O(^IDXLGE(I,J,K)) g loopj2:K=""
if "RD"'[K g loopk2
I $G(MTY)'="",MTY'[K g loopk2
if (I="")!(+I>TDT3) quit ;$G(I)_"/"_$G(J)_"/"_$G(K)_"/"_"0"_"/"_$G(^WK($J))
loopcn2 ;loopcn
S CN=$O(^IDXLGE(I,J,K,CN)) g loopk2:CN=""
S D=$G(^IDXLGE(I,J,K,CN))
S HIS=$P(D,"|"),MOV=$P(D,"|",2),GEN=$P(D,"|",3)
g loopcn2:HIS=""!(MOV="")!(GEN="")
S N=$G(^CNREC(CN,HIS,"MOVE",MOV))
S NB=$G(^CNREC(CN,HIS,"MOVEB",MOV))
I $P(N,"|",3)="CANCL" g loopcn2
S Z=$G(^CNREC(CN,HIS,"GEN",GEN))
I $P($G(^CNREC(CN,HIS,"GENB",GEN)),"|",3)["CSW" g loopcn2
g loopcn2:$P(Z,"|",9)=""
I OPR'="",OPR'[($P(Z,"|",9)_"|") g loopcn2
I "56"[$E($P(Z,"|",2)) g loopcn2
S Q=$P(Z,"|"),VSC=$P(Z,"|",3)
s VOY=$P(Z,"|",4)
I $L($$^CMAUTH(%id,CN,VSC,VOY,$P(Z,"|",9))) s Error="" g loopcn2
S YEAR=""
I VSC'="" D
.S VCN=$P($G(^CDTAB("SEQN",VSC,VOY)),"|")
.g loopcn2:VCN=""
.S VN1=$G(^CDTAB("VOY",VSC,VCN,"1"))
.S VN2=$G(^CDTAB("VOY",VSC,VCN,"2"))
.S V=$S(Q="E":$P(VN1,"|"),Q="I":$P(VN1,"|",2),1:"UNK")
.S YEAR=$p($zd($P($P(^CDTAB("VOY",VSC,VCN,1),"|",5),",",1)),"/",3)
.S R=$P(VN2,"|",9)
E S (VSC,V,R)=""
g loopcn2:$E(R,1,3)="ATI"!($E(R,1,3)="BOC")
S DATE=$zd(I,9)
S ARR=$G(DATE)_" "_$zt(J,4)
S Q=$S(Q="E":"Export",Q="I":"Import",Q="S":"Recirculation",1:"Unknown")
S M=$P(Z,"|",17)
s conwt=$p(Z,"|",18)
i conwt'="" s conwt=conwt_" Tons"
s othersealno=$P(Z,"|",15)
s bookingseal=$P(Z,"|",5)
s seal=$P(Z,"|",16)
s plate=$P(N,"|",11)
s trucker=""
i plate'="" D
.S truckercode=$P($G(^CDTAB("PLATE",plate)),"|",1)
.i truckercode'="" S
trucker=$TR($P($G(^CDTAB("CART",truckercode)),"|",1),"/","")
S shipper=""
I YEAR'="" D
.S ivn=$G(^IXVH("R",YEAR,R))
.I ivn="" S ivn=$G(^IXVH("R",YEAR-1,R))
.I ivn'="" D
..S BLN=$O(^IXIFM(ivn,CN,""))
..I BLN'="" S shipper=$TR($P(^BSIFM(ivn,BLN),"|",3),"/","")
s dmg=$P(NB,"|",3)
S CN1=CN1+1
S M=$S(M="F":"Full Container Load",M="L":"Less Container Load",M="E":"Empty",M="T":"Transhipment",1:"unknown")
S K1=CN_"|"_$E($P(N,"|",22),2)_"|"_Q_"|"_M_"|"_$P(Z,"|",2)
S K1=K1_"|"_$P(Z,"|",10)_"|"_$P(Z,"|",9)_"|"_VSC_"|"_V_"|"_R_"|"_ARR
S K1=K1_"|"_conwt_"|"_$P(Z,"|",2)_"|"_HIS_"|"_GEN_"|"_CN1_"|"_othersealno_"|"_bookingseal_"|"_dmg_"|"_seal_"|"_plate_"|"_trucker_"|"_shipper
i $P(K1,"|",2)'="" s $P(K1,"|",2)=$s($P(K1,"|",2)="R":"Received",$P(K1,"|",2)="D":"Delivered",1:$P(K1,"|",2))
S sz=$P(K1,"|",5)
i sz'="" s sz=$e(sz,1,1)
s $P(K1,"|",5)=$s(sz="0":"20'",sz="2":"20'",sz="4":"40'",sz="9":"45'",sz="L":"45'",sz="1":"10'")
i $P(K1,"|",6)'="" s $P(K1,"|",6)=$p(^CDTAB("COMM",$P(K1,"|",6)),"|")
i $P(K1,"|",7)'="" s $P(K1,"|",7)=$tr($p(^CDTAB("OPER",$P(K1,"|",7)),"|"),"/","")
i $P(K1,"|",8)'="" s $P(K1,"|",8)=$tr($p(^CDTAB("VESS",$P(K1,"|",8)),"|"),"/","")
S ^IDXCMAWEB("ROADRECEIVAL",User,RRCTR)=K1
S RRCTR=RRCTR+1 ;now holds the total number of GLOBALS
s recctr=CN1
set getrows=""
s NewI=I
g loopcn2 ;THIS POINT WORKS AND CREATES THE GLOBALS
;####201694:2017-05-18 = GET THE DATA FROM THE GLOBALS JUST MADE ABOVE WITH THE loopcn2
S totrec=""
S totrec=RRCTR-1 ;-1 so that the loop clearly shows all records
;totrec will now contain the total number of records. iterate on totrec
S ctr=0 ;will contain the current record count
S rsult="" ;will contain the total string result, to be written on the notepad
Do
{
S data=""
I $D(^IDXCMAWEB("ROADRECEIVAL",User,ctr)) D
.S data=$G(^IDXCMAWEB("ROADRECEIVAL",User,ctr))
E D
.S data=""
S rsult=rsult_"|"_ctr_$P(data,"|",1) ;modify further. this will be the returned string
S ctr=ctr+1
} WHILE ctr<=totrec
;Q rsult ;return the results...
;now, we write the results in a notepad file.
;writes the text file. OLD: S FILE="\SOMELOC\PubShare\theFileToJSON.TXT"
S FILE="\SOMELOC\PubShare\theFileToJSON.TXT"
O FILE:"WNS" U FILE
S WriteToFile=rsult
W rsult ;...we actually write the file?
C FILE
Q FILE ;display the file?
}
在这里,在生成全局变量的部分之后,我迭代了总记录数 RRCTR
以将所述全局变量的一部分放入单个字符串中。
全局创建成功,但是没有创建文件。为什么是这样?当 运行 时,它说 <COMMAND>
作为错误
<FRAMESTACK>
通常在递归调用代码时发生。这不是一个好的编程习惯,尤其是当您遇到堆栈溢出错误时,您可以配置更大的堆栈,但我建议您尝试重写您的代码,不要使用递归。
看起来你的 <COMMAND>
错误发生了,因为你在你的 do..while 循环中混合了 "curly brackets" 最后使用 "do with a dot" 语法。这是不支持的,请重写您的那部分代码以在所有地方使用大括号:
Do
{
S data=""
I $D(^IDXCMAWEB("ROADRECEIVAL",User,ctr)) {
S data=$G(^IDXCMAWEB("ROADRECEIVAL",User,ctr))
} else {
S data=""
}
S rsult=rsult_"|"_ctr_$P(data,"|",1) ;modify further. this will be the returned string
S ctr=ctr+1
} WHILE ctr<=totrec
尝试用 "do ##class(class).method" 而不是 "Write ##class(class).method)" 调用 class 这也不是真正的缓存代码,它的 Mumps 代码和(恕我直言)旧的遗留问题写得很糟糕。你个人应该重写它(或付钱请顾问)
我同意保罗的观点。使用 Go 命令 'g' 代替 'argumentless For' 进行迭代是非常糟糕的编程习惯。整个事情需要在没有任何 Go ("g") 命令的情况下重写。