Home   Package List   Routine Alphabetical List   Global Alphabetical List   FileMan Files List   FileMan Sub-Files List   Package Component Lists   Package-Namespace Mapping  
Routine: XINDX13

XINDX13.m

Go to the documentation of this file.
XINDX13 ; OSE/SMH - Input, Print, and Sort Template Analysis;03/01/2018  8:37 AM
 ;;7.3;TOOLKIT;**140**;Apr 25, 1995;Build 40
 ; Per VHA Directive 2004-038, this routine should not be modified.
 ;
 ; This routine finds non-self files that are pointed to by a template
 ; EPs DIPTM and DIETM support XINDX12 in finding M code in Input and
 ; Print templates.
 ;
ALL(path) ; [Public] Export all template CSV files at once to a specific dir
 I $G(path)="" S path=$$DEFDIR^%ZISH()
 D DIBT(path),DIET(path),DIPT(path)
 Q
 ;
DIBT(path,filename) ; [Public] Sort template analysis
 N outputData
 I $G(path)="" S path=$$DEFDIR^%ZISH()
 I $G(filename)="" S filename="DIBTOUT.csv"
 D DIBTCOL(.outputData)
 D DIBTOUT(.outputData,path,filename)
 Q
 ;
DIET(path,filename) ; [Public] Input template analysis
 N outputData
 I $G(path)="" S path=$$DEFDIR^%ZISH()
 I $G(filename)="" S filename="DIETOUT.csv"
 D DIETCOL(.outputData)
 D DIETOUT(.outputData,path,filename)
 Q
 ;
DIPT(path,filename) ; [Public] Print template analysis
 N outputData
 I $G(path)="" S path=$$DEFDIR^%ZISH()
 I $G(filename)="" S filename="DIPTOUT.csv"
 D DIPTCOL(.outputData)
 D DIPTOUT(.outputData,path,filename)
 Q
 ;
DIBTCOL(outputData) ; [Private] Sort Template Data Collection
 ; for each template
 N dibt F dibt=0:0 S dibt=$O(^DIBT(dibt)) Q:'dibt  D
 . Q:'$D(^DIBT(dibt,0))  ; get valid ones only
 . N name,file,isSort,line
 . S name=$P(^DIBT(dibt,0),U),file=$P(^DIBT(dibt,0),U,4)
 . S isSort=$O(^DIBT(dibt,2,0)) ; make sure they are sort templates
 . I 'isSort Q
 . ;
 . ; walk through each field
 . F line=0:0 S line=$O(^DIBT(dibt,2,line)) Q:'line  D
 .. N lineData,lineFile,lineField,lineFieldSpec
 .. ; We have some variances on how the data is stored (lines below)
 .. S:$D(^DIBT(dibt,2,line))#2 lineData=^(line)
 .. S:$D(^DIBT(dibt,2,line,0))#2 lineData=^(0)
 .. ;
 .. ; some vital data
 .. S lineFile=$P(lineData,U)
 .. I '$D(^DD(lineFile)) Q  ; bad DD
 .. S lineField=$P(lineData,U,2),lineFieldSpec=$P(lineData,U,3)
 .. ;
 .. ; if it's the same file, and not a relational field, we are not interested
 .. I lineFile=file,(lineFieldSpec'[":"&(lineFieldSpec'[" IN ")) Q
 .. ;
 .. ; if the parent is the same file, and ditto, we are still not interested
 .. I $$PARENT(lineFile)=file,(lineFieldSpec'[":"&(lineFieldSpec'[" IN ")) Q
 .. ;
 .. ; We are interested
 .. ; Do we have the field?
 .. I lineField="" D
 ... ; no we don't so get the fields using DICOMP
 ... N X,pairs,pair
 ... D EXPR^DICOMP(lineFile,"dmFITSL",lineFieldSpec)
 ... I '$D(X) Q
 ... ; X("USED")="404.51^.07;404.57^.02"
 ... I X("USED")="" Q  ; not an expression that uses fields
 ... F pairs=1:1:$L(X("USED"),";") D
 .... S pair=$P(X("USED"),";",pairs)
 .... N thisFile,thisField
 .... S thisFile=$P(pair,U,1),thisField=$P(pair,U,2)
 .... I thisFile=file Q
 .... S outputData(file,thisFile,thisField)=dibt_U_name
 .. ; we have a field. Take it at face value
 .. E  S outputData(file,lineFile,lineField)=dibt_U_name
 Q
 ;
DIBTOUT(outputData,outputPath,outputFile) ; [Private] Sort Template Data Output
 N POP
 D OPEN^%ZISH("file1",outputPath,outputFile,"W")
 I POP Q
 U IO
 N c,file,dstFile,dstField,dibtIEN,dibtName
 S c=","
 W "SORT TEMPLATE IEN,SORT TEMPLATE NAME,SOURCE FILE,DESTINATION FILE,DESTINATION FIELD",!
 F file=0:0 S file=$Q(outputData(file)) Q:'file  D
 . F dstFile=0:0 S dstFile=$O(outputData(file,dstFile)) Q:'dstFile  D
 .. F dstField=0:0 S dstField=$O(outputData(file,dstFile,dstField)) Q:'dstField  D
 ... N data S data=outputData(file,dstFile,dstField)
 ... S dibtIEN=$P(data,U,1),dibtName=$P(data,U,2)
 ... W dibtIEN_c_dibtName_c_file_c_dstFile_c_dstField,!
 D CLOSE^%ZISH("file1")
 Q
 ;
DIETCOL(outputData,mCodeData) ; [Private] Input Template Data Collection
 ; for each template
 ; s outputData(file,thisFile,thisField)=dibt_U_name
 N diet F diet=0:0 S diet=$O(^DIE(diet)) Q:'diet  D
 . Q:'$D(^DIE(diet,0))  ; get valid ones only
 . N name,file,line,lineFile
 . S name=$P(^DIE(diet,0),U),file=$P(^DIE(diet,0),U,4)
 . ; for each file in the input template
 . F line=0:0 S line=$O(^DIE(diet,"DR",line)) Q:line>98!(line="")  D  ; 99 is reserved for some compiled code
 .. F lineFile=0:0 S lineFile=$O(^DIE(diet,"DR",line,lineFile)) Q:'lineFile!(lineFile'=+lineFile)  D
 ... N fields,fieldIndex,field
 ... S fields=^DIE(diet,"DR",line,lineFile)
 ... F fieldIndex=1:1:$L(fields,";") D
 .... S field=$P(fields,";",fieldIndex)
 .... ; various tests for the field
 .... Q:field=""  ; empty field. Can happen!
 .... ;
 .... ; FROM X+2^DIA3: Get M field and check it
 .... N X S X=field
 .... I X'?.E1":" S X=$S(X["//^":$P(X,"//^",2),1:X),X=$S(X[";":$P(X,";"),1:X) D ^DIM
 .... I $D(X) S mCodeData(lineFile,line)=X Q
 .... ;
 .... ; We analyzed the M code; now we just want the dependencies
 .... Q:lineFile=file  ; DR file same as our file; not interested
 .... Q:$$PARENT(lineFile)=file  ; ditto, for parent
 .... ;
 .... ; range like .01:5
 .... I $L(field,":")=2,(+$P(field,":"))=$P(field,":") D  Q
 ..... N start,end,eachField
 ..... S start=$P(field,":",1),end=$P(field,":",2)
 ..... I $D(^DD(lineFile,start)) S outputData(file,lineFile,start)=diet_U_name
 ..... S eachField=start
 ..... F  S eachField=$O(^DD(lineFile,eachField)) Q:eachField>end!(eachField="")  D
 ...... S outputData(file,lineFile,eachField)=diet_U_name
 .... ;
 .... Q:$E(field)="@"  ; jump to another place in the template. Not a field
 .... S field=+field
 .... Q:'$D(^DD(lineFile,field))  ; field doesn't exist
 .... S outputData(file,lineFile,field)=diet_U_name
 Q
 ;
DIETOUT(outputData,outputPath,outputFile) ; [Private] Input Template Data Output
 N POP
 D OPEN^%ZISH("file1",outputPath,outputFile,"W")
 I POP Q
 U IO
 N c,file,dstFile,dstField,dietIEN,dietName
 S c=","
 W "INPUT TEMPLATE IEN,INPUT TEMPLATE NAME,SOURCE FILE,DESTINATION FILE,DESTINATION FIELD",!
 F file=0:0 S file=$O(outputData(file)) Q:'file  D
 . F dstFile=0:0 S dstFile=$O(outputData(file,dstFile)) Q:'dstFile  D
 .. F dstField=0:0 S dstField=$O(outputData(file,dstFile,dstField)) Q:'dstField  D
 ... N data S data=outputData(file,dstFile,dstField)
 ... S dietIEN=$P(data,U,1),dietName=$P(data,U,2)
 ... W dietIEN_c_dietName_c_file_c_dstFile_c_dstField,!
 D CLOSE^%ZISH("file1")
 Q
 ;
DIPTCOL(outputData,mCodeData) ; [Private] Print Template Data Collection
 ; for each template
 N dipt F dipt=0:0 S dipt=$O(^DIPT(dipt)) Q:'dipt  D
 . Q:'$D(^DIPT(dipt,0))  ; get valid ones only
 . N name,file
 . S name=$P(^DIPT(dipt,0),U),file=$P(^DIPT(dipt,0),U,4)
 . ;
 . ;D:$T(^XTMLOG)]"" INITEASY^XTMLOG("C","WARN")
 . ; debug
 . ; b:name="ZBJM FEE BASIS LIST"
 . ; debug
 . ;
 . ; for each field
 . N fileNamePrint,line
 . S fileNamePrint=1
 . F line=0:0 S line=$O(^DIPT(dipt,"F",line)) Q:'line  D
 .. N lineContents,fieldDataIndex
 .. S lineContents=^DIPT(dipt,"F",line)
 .. F fieldDataIndex=1:1:$L(lineContents,"~") D
 ... N fieldData,fields
 ... S fieldData=$P(lineContents,"~",fieldDataIndex) Q:fieldData=""
 ... S fields=$P(fieldData,";")
 ... Q:fields=""!(fields=" ")
 ... ;
 ... ; analyze the fields
 ... ;
 ... ; See if we have a multiple navigation. These are noted in the first piece
 ... ; as a series of numbers like 50,1,2,5...
 ... ; don't process these any further if we find them
 ... ; We don't process them as they mean we don't branch out to other files
 ... ; --we just trace our own file down.
 ... N fieldsUpright,fieldIndex,field
 ... S fieldsUpright=1 F fieldIndex=1:1:$L(fields,",") D  Q:'fieldsUpright
 .... S field=$P(fields,",",fieldIndex)
 .... S:field'=+field!(field<0) fieldsUpright=0
 ... I fieldsUpright Q  ;D:$T(^XTMLOG)]"" DEBUG^XTMLOG("Qutting since upright","name,file,fieldData") Q
 ... ;
 ... ; Exclude transition lines
 ... ; We are not interested in the lines that switch files (e.g. in 52: 'PROVIDER:')
 ... N ignoreTransition,fieldIndex,field,nextField
 ... S ignoreTransition=0 F fieldIndex=1:1:$L(fields,",") D  Q:ignoreTransition
 .... S field=$P(fields,",",fieldIndex),nextField=$P(fields,",",fieldIndex+1)
 .... I $E(nextField)=U S ignoreTransition=1 Q
 ... I ignoreTransition Q  ;D:$T(^XTMLOG)]"" DEBUG^XTMLOG("Quitting due to context transistion with no fields","name,file,fieldData") Q
 ... ;
 ... ; If zpiece is defined, then we have a COMPUTED EXPRESSION or M code
 ... N Zpiece,i
 ... S Zpiece=0 F i=1:1:$L(fieldData,";") I $P(fieldData,";",i)="Z" S Zpiece=i Q
 ... ;
 ... ; exclude print only fields (quoted values, or literal $C)
 ... N printOnlyField
 ... S printOnlyField=0
 ... I 'Zpiece F fieldIndex=1:1:$L(fields,",") D  Q:printOnlyField
 .... S field=$P(fields,",",fieldIndex)
 .... Q:+field=field  ; numeric -- quit -- not a literal
 .... I $E(field)="""" S printOnlyField=1
 .... I $E(field,1,5)="W $C(" S printOnlyField=1
 ... I printOnlyField Q  ;D:$T(^XTMLOG)]"" DEBUG^XTMLOG("Quitting for printOnlyField","name,file,fieldData,printOnlyField") Q
 ... ;
 ...  ; This can be a "hidden" M field masqurading
 ... N isNonTradMCode S isNonTradMCode=0
 ... I 'Zpiece D
 .... N p1 S p1=$P(fields,",")
 .... Q:+p1=p1  ; Just a normal field
 .... N X S X=$P(fields,";") D ^DIM
 .... I $D(X) S isNonTradMCode=1
 .... ;D:$t(^XTMLOG)]"" WARN^XTMLOG("Treating Print Field as M code","file,fieldData")
 .... S mCodeData(+file,line)=X
 ... ;
 ... ; Don't process any further if non-Traditional M code
 ... Q:isNonTradMCode
 ... ;
 ... ; Now, process non-M code fields
 ... ; Best template to test this with: MAGV-PAT-QUERY
 ... ; NB: This is a recursive search; each search updates the pointerFile variable
 ... ; We only want the last entry in the pointerFile chain to file the data if there
 ... ; is a field we want to grab
 ... N pointerFile S pointerFile=0
 ... I 'Zpiece F fieldIndex=1:1:$L(fields,",") D
 .... N field,nextField
 .... S field=$P(fields,",",fieldIndex),nextField=$P(fields,",",fieldIndex+1)
 .... I field<0 S pointerFile=-field Q
 .... I field>0,'pointerFile Q  ; field in original file. We are not interested
 .... D ASSERT(+pointerFile=pointerFile)
 .... D ASSERT(+field=field)
 .... ;D:$T(^XTMLOG)]"" INFO^XTMLOG("Num Parsed as:","fieldData,pointerFile,field")
 .... I field>0,pointerFile S outputData(file,pointerFile,field)=dipt_U_name
 ... I 'Zpiece Q  ; can't quit on the for line above
 ... ;
 ... ; Now, process M code/Copmputed code fields.
 ... N exitEarly S exitEarly=0
 ... ;
 ... ; We are really interested in capturing the computed field information
 ... ; (Z piece stuff only)
 ... ; Calculate the correct context for the Computed Expression
 ... N mCodeContext,mCode
 ... S mCode="",mCodeContext=file ; The default
 ... N fileField,fileFieldIndex
 ... F fileFieldIndex=1:1:$L(fields,",") D  Q:mCode]""
 .... S fileField=$P(fields,",",fileFieldIndex)
 .... I fileField'=+fileField S mCode=$P(fields,",",fileFieldIndex,99) Q
 .... ;
 .... ; Relational navigation
 .... I fileField<0 S mCodeContext=-fileField Q
 .... ;
 .... ; Subfile processing. Move context to subfile
 .... I '$D(^DD(mCodeContext,fileField,0)) S exitEarly=1 D  Q  ; doesn't exist!
 ..... ;D:$T(^XTMLOG)]"" WARN^XTMLOG("^DD("_mCodeContext_","_fileField_",0) does not exist")
 .... I fileField>0,$P(^DD(mCodeContext,fileField,0),U,2) S mCodeContext=+$P(^DD(mCodeContext,fileField,0),U,2) Q
 ... Q:exitEarly
 ... ;D:$t(^XTMLOG)]"" DEBUG^XTMLOG("Context for "_fieldData_" is "_mCodeContext_" and M code is "_mCode)
 ... ;
 ... ; debug
 ... ; w mCodeContext,!
 ... ; debug
 ... ;
 ... ;
 ... ; Get the potentially COMPUTED EXPRESSION code for this field
 ... N potComputedCode S potComputedCode=$P(fieldData,";",Zpiece+1)
 ... S potComputedCode=$E(potComputedCode,2,$L(potComputedCode)-1)
 ... ;
 ... ; If M Code is broken up, put it back together
 ... I $F(mCode,"X DXS") D
 .... N startdxs,enddxs,dxsString,s1,s2,dxsCode,%
 .... S startdxs=$f(mCode,"DXS")-3,enddxs=$f(mCode,")",startdxs)-1,dxsString=$E(mCode,startdxs,enddxs)
 .... S s1=$QS(dxsString,1),s2=$QS(dxsString,2),dxsCode=^DIPT(dipt,"DXS",s1,s2)
 .... S %("X "_dxsString)=dxsCode,mCode=$$REPLACE^XLFSTR(mCode,.%)
 ... ;
 ... ; Is it the same (after removing the quotes) as the MCode?
 ... ; If so, then this is not a computed expression
 ... ; We can abandon hope of finding what field it refers to.
 ... I potComputedCode=mCode D  Q
 .... S mCodeData(+file,line)=mCode
 .... ;D:$T(^XTMLOG)]"" INFO^XTMLOG(fieldData_" in "_file_" considered to be M code")
 ...
 ... ; debug
 ...
 ... ; At this point, we think it's a computed expression.
 ... ; Lets try to to see
 ... N X
 ... D EXPR^DICOMP(mCodeContext,"dmFITSL",potComputedCode)
 ... I '$D(X) Q  ;D:$T(^XTMLOG)]"" ERROR^XTMLOG("Can't resolve "_fieldData_" into fields (context "_mCodeContext_", name "_name_")") Q
 ... Q:X("USED")=""  ; not an expression that uses fields (NOW, PAGE)
 ... ;
 ... N pairs,pair F pairs=1:1:$L(X("USED"),";") D
 .... S pair=$P(X("USED"),";",pairs)
 .... N thisFile,thisField
 .... S thisFile=$P(pair,U,1),thisField=$P(pair,U,2)
 .... Q:thisFile=file
 .... S outputData(file,thisFile,thisField)=dipt_U_name
 ;D:$T(^XTMLOG)]"" ENDLOG^XTMLOG()
 Q
 ;
DIPTOUT(outputData,outputPath,outputFile) ; [Private] Print Template Data Output
 N POP
 D OPEN^%ZISH("file1",outputPath,outputFile,"W")
 I POP Q
 U IO
 N c,file,dstFile,dstField,dietIEN,dietName
 S c=","
 W "PRINT TEMPLATE IEN,PRINT TEMPLATE NAME,SOURCE FILE,DESTINATION FILE,DESTINATION FIELD",!
 F file=0:0 S file=$O(outputData(file)) Q:'file  D
 . F dstFile=0:0 S dstFile=$O(outputData(file,dstFile)) Q:'dstFile  D
 .. F dstField=0:0 S dstField=$O(outputData(file,dstFile,dstField)) Q:'dstField  D
 ... N data S data=outputData(file,dstFile,dstField)
 ... S dietIEN=$P(data,U,1),dietName=$P(data,U,2)
 ... W dietIEN_c_dietName_c_file_c_dstFile_c_dstField,!
 D CLOSE^%ZISH("file1")
 Q
 ;
 ; DIETM and DIPTM are used by XINDEX to process input and sort templates
 ; respectively. XINDEX passes required parameters through the stack instead
 ; passed variables.
 ;
 ; B = {IEN}
 ; INDLC = {counter}
 ; INDRN = {faux routine prefix}
 ; INDC = {IEN} ; {NAME} - {DISPLAY NAME}
 ; INDX = {code to be XINDEXED}
 ; INDL = {NAME field (.01) of IEN}
DIETM ; [Public] Collect M code fileds from all input templates
 ; ZEXCEPT: B,INDX
 Q:'$D(^DIE(B,0))  ; get valid ones only
 N name,file
 S name=$P(^DIE(B,0),U),file=$P(^DIE(B,0),U,4)
 ;
 ; for each file in the input template
 N line,lineFile
 F line=0:0 S line=$O(^DIE(B,"DR",line)) Q:line>98!(line="")  D  ; 99 is reserved for some compiled code
 . F lineFile=0:0 S lineFile=$O(^DIE(B,"DR",line,lineFile)) Q:'lineFile!(lineFile'=+lineFile)  D
 .. N fields,fieldIndex,field
 .. S fields=^DIE(B,"DR",line,lineFile) F fieldIndex=1:1:$L(fields,";") D
 ... S field=$P(fields,";",fieldIndex)
 ... ; various tests for the field
 ... Q:field=""  ; empty field. Can happen!
 ... ;
 ... ; FROM X+2^DIA3: Get M field and check it
 ... N X S X=field
 ... I X'?.E1":" S X=$S(X["//^":$P(X,"//^",2),1:X),X=$S(X[";":$P(X,";"),1:X) D ^DIM
 ... ; Add code to be INDEXed
 ... I $D(X) S INDX=X D ADDLN^XINDX11
 Q
 ;
DIPTM ; [Public] Collect M code fields from all print templates
 ; ZEXCEPT: B,INDX
 Q:'$D(^DIPT(B,0))                 ; get valid ones only
 N name,file,fileNamePrint,line
 S name=$P(^DIPT(B,0),U),file=$P(^DIPT(B,0),U,4)
 ;
 ; for each field
 S fileNamePrint=1
 F line=0:0 S line=$O(^DIPT(B,"F",line)) Q:'line  D
 . N lineContents,fieldDataIndex,fieldData,fields
 . S lineContents=^DIPT(B,"F",line)
 . F fieldDataIndex=1:1:$L(lineContents,"~") D
 .. S fieldData=$P(lineContents,"~",fieldDataIndex)
 .. Q:fieldData=""
 .. S fields=$P(fieldData,";")
 .. Q:fields=""!(fields=" ")
 .. ;
 .. ; If zpiece is defined, then we have a COMPUTED EXPRESSION or M code
 .. N i,Zpiece
 .. S Zpiece=0 F i=1:1:$L(fieldData,";") I $P(fieldData,";",i)="Z" S Zpiece=i Q
 .. ;
 .. ; This can be a "hidden" M field masqurading -- the entire line is M code
 .. ; NB: This is rare, but print templates support that.
 .. N isNonTradMCode S isNonTradMCode=0
 .. I 'Zpiece D
 ... N p1,X
 ... S p1=$P(fields,",") I +p1=p1 Q  ; Just a normal field
 ... S X=$P(fields,";") D ^DIM
 ... ; Add code to be INDEXed
 ... I $D(X) S isNonTradMCode=1 S INDX=X D ADDLN^XINDX11 Q
 .. ;
 .. Q:isNonTradMCode  ; We already have M code. Quit.
 .. ;
 .. Q:'Zpiece  ; Straight field
 .. ;
 .. ; extract compiled code from file/subfile references
 .. N mCode,fileField,fileFieldIndex
 .. S mCode=""
 .. F fileFieldIndex=1:1:$L(fields,",") D  Q:mCode]""
 ... S fileField=$P(fields,",",fileFieldIndex)
 ... I fileField'=+fileField S mCode=$P(fields,",",fileFieldIndex,99)
 .. ;
 .. I mCode="" Q  ; no compiled code in this field
 .. ;
 .. ; If zpiece is defined, see if computed expression or M code
 .. ; Get the potentially COMPUTED EXPRESSION code for this field
 .. N potComputedCode S potComputedCode=$P(fieldData,";",Zpiece+1)
 .. S potComputedCode=$E(potComputedCode,2,$L(potComputedCode)-1)
 .. ;
 .. ; If M Code is broken up, put it back together
 .. I $F(mCode,"X DXS") D
 ... N startdxs,enddxs,dxsString,s1,s2,dxsCode,%
 ... S startdxs=$F(mCode,"DXS")-3,enddxs=$F(mCode,")",startdxs)-1
 ... S dxsString=$E(mCode,startdxs,enddxs),s1=$QS(dxsString,1),s2=$QS(dxsString,2)
 ... S dxsCode=^DIPT(B,"DXS",s1,s2)
 ... S %("X "_dxsString)=dxsCode,mCode=$$REPLACE^XLFSTR(mCode,.%)
 .. ;
 .. ; Is it the same (after removing the quotes) as the MCode?
 .. ; If so, then this is not a computed expression
 .. I potComputedCode=mCode D  Q
 ... N X S X=mCode D ^DIM
 ... ; Add code to be INDEXed
 ... I $D(X) S INDX=X D ADDLN^XINDX11
 Q
 ;
PARENT(subfile) ; [Private] Find out who my parent is
 ; WARNING: Recursive algorithm
 I $D(^DD(subfile,0,"UP")) Q $$PARENT(^("UP"))
 Q subfile
 ;
ASSERT(x) I 'x S $EC=",u-assert,"
 Q
 ;