| 1 | TMGFMUT2 ;TMG/kst/Fileman utility functions ;02/19/10
 | 
|---|
| 2 |          ;;1.0;TMG-LIB;**1**;02/19/10
 | 
|---|
| 3 |  ;
 | 
|---|
| 4 |  ;"TMG FILEMAN-UTILITY FUNCTIONS
 | 
|---|
| 5 |  ;"(c) Kevin Toppenberg MD
 | 
|---|
| 6 |  ;"Released under: GNU General Public License (GPL)
 | 
|---|
| 7 |  ;"2/19/10
 | 
|---|
| 8 |  ;
 | 
|---|
| 9 |  ;"=======================================================================
 | 
|---|
| 10 |  ;"NOTE: This module will provide pointer tools that are different than found
 | 
|---|
| 11 |  ;"     if ^TMGFMUT.  The approach here will be to create tables of pointer
 | 
|---|
| 12 |  ;"    relationships, and then allow faster analysis from the tables.  This
 | 
|---|
| 13 |  ;"   recognizes that such tables can rapidly become out of sync with the
 | 
|---|
| 14 |  ;"  actual data.  Thus the tools will only be valid on a system at rest (i.e.
 | 
|---|
| 15 |  ;" no users on the system).  They could be used for system maint. overnight
 | 
|---|
| 16 |  ;" etc.
 | 
|---|
| 17 |  ;" Several of the routines here are called from ^TMGSIPH*
 | 
|---|
| 18 |  ;"Data is stored here:
 | 
|---|
| 19 |  ;"^TMG("PTXREF","OUT",FROMFILE,IENS,FROMFLD,P2FILE,PT)=""
 | 
|---|
| 20 |  ;"^TMG("PTXREF","IN",P2FILE,PT,FROMFILE,IENS,FROMFLD)=""
 | 
|---|
| 21 |  ;"=======================================================================
 | 
|---|
| 22 |  ;" API -- Public Functions.
 | 
|---|
| 23 |  ;"=======================================================================
 | 
|---|
| 24 |  ;"PREPPTO(FILENUM,FLD,ARRAY) -- set up an easy to use array of potential pointers out from a file.
 | 
|---|
| 25 |  ;"SETPTOUT(FILENUM,DESTREF,PGFN,PGFREQ,LIMITS) -- scan a given file and create an array with all pointers INTO that file.
 | 
|---|
| 26 |  ;"KILLPTIX -- delete the last run of PT XREF, so it can be refreshened.
 | 
|---|
| 27 |  ;"GETPTIN(PARAMS,OUT,PGFN) --get a listing of all pointers INTO requested record
 | 
|---|
| 28 |  ;"BAKXREF(PARAMS,PGFN) --Make a xref of cross-references (a backward xref)
 | 
|---|
| 29 |  ;"BAKSXREF(PARAMS,PGFN)-- Make a xref of cross-references (a backward xref) **OF SUBFILES**
 | 
|---|
| 30 |  ;"GETXRAGE --Return, in HOURS, the time since the ^TMG("PTXREF") array has had any modification
 | 
|---|
| 31 |  ;"GETGL(SUBFILENUM,IENDEPTH) --return a reference 'GL' string for subfiles.
 | 
|---|
| 32 |  ;"GETGREF(FILENUM,IENS) -- To return a reference to a ** SUBFILE **
 | 
|---|
| 33 |  ;"IENCOMBO(REF,IENDEPTH,IEN) --set up global vars IEN(2),IEN(3),... etc, as needed for next combo when cycling through subfile arrays.
 | 
|---|
| 34 |  ;"TOPFILEN(FILENUM) -- Return the highest level of filenumber.
 | 
|---|
| 35 |  ;"ISSUBFIL(FILENUM) -- Return if a file is a subfile.
 | 
|---|
| 36 |  ;"GETIENS(IEN) --Turn IEN Array into IENS
 | 
|---|
| 37 |  ;"IENS2IEN(IENS,IEN) -- Turn IENS into IEN Array, opposite of GETIENS function
 | 
|---|
| 38 |  ;"GETSPFN(FILENUM) -- Turn a subfile number into 'SubFileNum{ParentFileNum{GrandParentFileNum....'
 | 
|---|
| 39 |  ;"HASPTR(FILENUM) --Return if file contains fields that are pointers to other files
 | 
|---|
| 40 |  ;"HASPTRSF(FILENUM) -- Return if file contains subfiles (or sub-subfiles) that contain pointers to other files)
 | 
|---|
| 41 |  ;"FILENAME(FILENUM) -- turn a (SUB)File number into a file name.
 | 
|---|
| 42 |  ;"=======================================================================
 | 
|---|
| 43 |  ;" API - Private Functions
 | 
|---|
| 44 |  ;"=======================================================================
 | 
|---|
| 45 |  ;"TESTSPTO -- test out PT XREF setup.
 | 
|---|
| 46 |  ;"HNDLPTIX(FILENUM,PGFN) -- prepair PT XREF for all records pointing INTO specified file.
 | 
|---|
| 47 |  ;"=======================================================================
 | 
|---|
| 48 |  ;"Dependancies
 | 
|---|
| 49 |  ;"=======================================================================
 | 
|---|
| 50 |  ;"TMGKERN2, TMGUSRIF
 | 
|---|
| 51 |  ;"=======================================================================
 | 
|---|
| 52 |  ;
 | 
|---|
| 53 | PREPPTO(FILENUM,FLD,ARRAY) ;
 | 
|---|
| 54 |         ;"Purpose: To set up an easy to use array of potential pointers out from a file.
 | 
|---|
| 55 |         ;"Input: FILENUM-- the filenumber to evaluate
 | 
|---|
| 56 |         ;"       FLD -- the field to check for.
 | 
|---|
| 57 |         ;"       ARRAY -- PASS BY REFERENCE.  An OUT PARAMETER.  Format
 | 
|---|
| 58 |         ;"          ARRAY(GREF,ENTRY)
 | 
|---|
| 59 |         ;"          Note: ENTRY=DataPiece^PointedToFile^PointedToReference^IENDepth^[V]^FromFile^Fromfield^ONEREF
 | 
|---|
| 60 |         ;"          ONEREF will have multipe IEN entries if IENDepth>1, e.g. '^SC(IEN,"S",IEN(2),1,IEN(3),"C")'
 | 
|---|
| 61 |         ;"          with order of IEN, IEN(2), IEN(3), ... etc.
 | 
|---|
| 62 |         ;"NOTE: This function was originally coppied from SETPTOUT^TMGSIPH1
 | 
|---|
| 63 |         ;
 | 
|---|
| 64 |         IF +$GET(FILENUM)'=FILENUM GOTO SPODN
 | 
|---|
| 65 |         NEW IENDEPTH SET IENDEPTH=1
 | 
|---|
| 66 |         NEW REF SET REF=$GET(^DIC(FILENUM,0,"GL"))
 | 
|---|
| 67 |         IF (REF=""),$DATA(^DD(FILENUM,0,"UP")) DO
 | 
|---|
| 68 |         . SET REF=$$GETGL(FILENUM,.IENDEPTH)
 | 
|---|
| 69 |         IF REF="" GOTO SPODN
 | 
|---|
| 70 |         NEW GREF SET GREF=REF
 | 
|---|
| 71 |         IF GREF["IEN," SET GREF=$PIECE(GREF,"IEN,",1)
 | 
|---|
| 72 |         NEW ZNODE SET ZNODE=$GET(^DD(FILENUM,FLD,0))
 | 
|---|
| 73 |         NEW FLDTYPE SET FLDTYPE=$PIECE(ZNODE,"^",2)
 | 
|---|
| 74 |         IF (FLDTYPE'["P")&(FLDTYPE'["V") GOTO SPODN
 | 
|---|
| 75 |         NEW LOC SET LOC=$PIECE(ZNODE,"^",4)
 | 
|---|
| 76 |         NEW NODE SET NODE=$PIECE(LOC,";",1)
 | 
|---|
| 77 |         NEW PCE SET PCE=+$PIECE(LOC,";",2)
 | 
|---|
| 78 |         IF +NODE'=NODE SET NODE=""""_NODE_""""
 | 
|---|
| 79 |         NEW ONEREF,SUBSCR
 | 
|---|
| 80 |         SET SUBSCR=$SELECT((IENDEPTH>1):"("_IENDEPTH_")",1:"")
 | 
|---|
| 81 |         SET ONEREF=REF_"IEN"_SUBSCR_","_NODE_")"
 | 
|---|
| 82 |         NEW P2FILE SET P2FILE=0
 | 
|---|
| 83 |         NEW VREC SET VREC=0
 | 
|---|
| 84 |         NEW DONE SET DONE=0
 | 
|---|
| 85 |         FOR  DO  QUIT:(DONE=1)
 | 
|---|
| 86 |         . NEW ISVIRT SET ISVIRT=""
 | 
|---|
| 87 |         . NEW P2REF
 | 
|---|
| 88 |         . IF FLDTYPE["V" DO  QUIT:(DONE=1)
 | 
|---|
| 89 |         . . SET VREC=+$ORDER(^DD(FILENUM,FLD,"V",VREC))
 | 
|---|
| 90 |         . . IF VREC=0 SET DONE=1 QUIT
 | 
|---|
| 91 |         . . SET P2FILE=+$GET(^DD(FILENUM,FLD,"V",VREC,0))
 | 
|---|
| 92 |         . . SET ISVIRT="V"
 | 
|---|
| 93 |         . . SET P2REF=$PIECE($GET(^DIC(P2FILE,0,"GL")),"^",2)
 | 
|---|
| 94 |         . ELSE  DO
 | 
|---|
| 95 |         . . SET P2FILE=+$PIECE(FLDTYPE,"P",2)
 | 
|---|
| 96 |         . . SET P2REF=$PIECE(ZNODE,"^",3)
 | 
|---|
| 97 |         . . SET DONE=1
 | 
|---|
| 98 |         . NEW ENTRY
 | 
|---|
| 99 |         . SET ENTRY=PCE_"^"_P2FILE_"^"_P2REF_"^"_IENDEPTH_"^"_ISVIRT_"^"_FILENUM_"^"_FLD_"^"_ONEREF
 | 
|---|
| 100 |         . SET ARRAY(GREF,ENTRY)=""
 | 
|---|
| 101 | SPODN   QUIT
 | 
|---|
| 102 |  ;
 | 
|---|
| 103 |  ;
 | 
|---|
| 104 | GETIENS(IEN) ;"Turn IEN Array into IENS
 | 
|---|
| 105 |         NEW RESULT SET RESULT=IEN
 | 
|---|
| 106 |         NEW I SET I=1
 | 
|---|
| 107 |         FOR  SET I=$ORDER(IEN(I)) QUIT:(+I'>0)  DO
 | 
|---|
| 108 |         . SET RESULT=$GET(IEN(I))_","_RESULT
 | 
|---|
| 109 |         IF RESULT["," SET RESULT=RESULT_","
 | 
|---|
| 110 |         QUIT RESULT
 | 
|---|
| 111 |  ;
 | 
|---|
| 112 |  ;
 | 
|---|
| 113 | IENS2IEN(IENS,IEN) ;
 | 
|---|
| 114 |         ;"Purpose: Turn IENS into IEN Array, opposite of GETIENS function
 | 
|---|
| 115 |         ;"Input: IENS - an IENS string to convert.  E.g. '7,2342,"
 | 
|---|
| 116 |         ;"       IEN -- PASS BY REFERENCE.  An OUT PARAMETER.
 | 
|---|
| 117 |         ;"Results: None.
 | 
|---|
| 118 |         KILL IEN
 | 
|---|
| 119 |         SET IENS=$GET(IENS)
 | 
|---|
| 120 |         NEW LEN SET LEN=$LENGTH(IENS,",")-1
 | 
|---|
| 121 |         NEW I FOR I=1:1:LEN DO
 | 
|---|
| 122 |         . NEW IDX SET IDX=(LEN-I+1)
 | 
|---|
| 123 |         . NEW VALUE SET VALUE=$PIECE(IENS,",",I)
 | 
|---|
| 124 |         . IF IDX>1 SET IEN(IDX)=VALUE
 | 
|---|
| 125 |         . ELSE  SET IEN=VALUE
 | 
|---|
| 126 |         QUIT
 | 
|---|
| 127 |  ;
 | 
|---|
| 128 |  ;
 | 
|---|
| 129 | SETPTOUT(FILENUM,DESTREF,PGFN,PGFREQ,LIMITS)
 | 
|---|
| 130 |         ;"Purpose: To scan a given file and create an array with all pointers INTO that file.
 | 
|---|
| 131 |         ;"         NOTE: The output will be a snapshot of the database that will quickly be out
 | 
|---|
| 132 |         ;"               of date if/when the database changes.
 | 
|---|
| 133 |         ;"Input:  FILENUM -- the Fileman file number to test. This is that file that other records will point TO
 | 
|---|
| 134 |         ;"        DESTREF -- OPTIONAL.  PASS BY NAME.  The name of an array to store output into.
 | 
|---|
| 135 |         ;"                   MUST BE IN CLOSED FORMAT.  If not specified, then ^TMG("PTXREF" will be used.
 | 
|---|
| 136 |         ;"        PGFN -- OPTIONAL.  <Progress Function Code>
 | 
|---|
| 137 |         ;"                A string of mumps code that will be executed once for every 100 records that are scanned.
 | 
|---|
| 138 |         ;"                The following variables will be defined for use.
 | 
|---|
| 139 |         ;"                 TMGCT -- The total number of that have been scanned so far.
 | 
|---|
| 140 |         ;"                 TMGFNAME -- The file that is currently begin scanned.
 | 
|---|
| 141 |         ;"                 TMGIEN -- Record number in the current file being scanned.
 | 
|---|
| 142 |         ;"                 TMGMAX -- Max record number in the current file being scanned.
 | 
|---|
| 143 |         ;"                 TMGMIN -- Min record number in the current file being scanned.
 | 
|---|
| 144 |         ;"        PGFREQ --OPTIONAL.  The number of records that must be scanned before the Progress Fn
 | 
|---|
| 145 |         ;"                      code is called.  Default = 100.
 | 
|---|
| 146 |         ;"        LIMITS -- OPTIONAL.  If $DATA(LIMITS("REF"))'=0 then REF should be an array with format:
 | 
|---|
| 147 |         ;"                           LIMITS("REF")=<aREF>
 | 
|---|
| 148 |         ;"                           @aREF@(FILENUM,IEN)=""  <-- Forms a set that will limit search.  Only these entries are considered.
 | 
|---|
| 149 |         ;"                           @aREF@(FILENUM,IEN)=""  <--
 | 
|---|
| 150 |         ;"Result: none.
 | 
|---|
| 151 |         NEW RESULT SET RESULT=0
 | 
|---|
| 152 |         SET FILENUM=+$GET(FILENUM) GOTO:(FILENUM=0) SPODN
 | 
|---|
| 153 |         SET DESTREF=$GET(DESTREF,$NAME(^TMG("PTXREF")))
 | 
|---|
| 154 |         SET PGFN=$GET(PGFN,"QUIT")
 | 
|---|
| 155 |         SET PGFREQ=+$GET(PGFREQ) IF PGFREQ'>0 SET PGFREQ=100
 | 
|---|
| 156 |         NEW LIMITREF SET LIMITREF=$GET(LIMITS("REF"))
 | 
|---|
| 157 |         SET LIMITS=(LIMITREF'="")
 | 
|---|
| 158 |         ;
 | 
|---|
| 159 |         ;"Build up ARRAY, an easy to use array of potential pointers OUT from a file.
 | 
|---|
| 160 |         ;"NOTE: Only files that point INTO FILENUM will be put into this array.
 | 
|---|
| 161 |         NEW ARRAY
 | 
|---|
| 162 |         NEW FROMFILE SET FROMFILE=0  ;"OtherFile
 | 
|---|
| 163 |         FOR  SET FROMFILE=$ORDER(^DD(FILENUM,0,"PT",FROMFILE)) QUIT:(+FROMFILE'>0)  DO
 | 
|---|
| 164 |         . NEW FLD SET FLD=0
 | 
|---|
| 165 |         . FOR  SET FLD=$ORDER(^DD(FILENUM,0,"PT",FROMFILE,FLD)) QUIT:(+FLD'>0)  DO
 | 
|---|
| 166 |         . . DO PREPPTO(FROMFILE,FLD,.ARRAY) ;
 | 
|---|
| 167 |         ;
 | 
|---|
| 168 |         ;"Now, cycle through possible pointers to look for real pointers.
 | 
|---|
| 169 |         SET @DESTREF@("TIMESTAMP")=$H
 | 
|---|
| 170 |         NEW ABORT SET ABORT=0
 | 
|---|
| 171 |         NEW TMGCT SET TMGCT=0
 | 
|---|
| 172 |         NEW GREF SET GREF=""
 | 
|---|
| 173 |         FOR  SET GREF=$ORDER(ARRAY(GREF)) QUIT:(GREF="")!ABORT  DO
 | 
|---|
| 174 |         . NEW TEMPN SET TEMPN=0
 | 
|---|
| 175 |         . NEW SKIP SET SKIP=0
 | 
|---|
| 176 |         . NEW FOUND SET FOUND=0
 | 
|---|
| 177 |         . FOR  SET TEMPN=$ORDER(^DIC(TEMPN)) QUIT:(+TEMPN'>0)!FOUND  DO  ;"Get filenumber of GREF
 | 
|---|
| 178 |         . . IF $GET(^DIC(TEMPN,0,"GL"))'=GREF QUIT
 | 
|---|
| 179 |         . . SET FOUND=1
 | 
|---|
| 180 |         . . SET @DESTREF@("OUT",TEMPN)=$H
 | 
|---|
| 181 |         . IF SKIP QUIT
 | 
|---|
| 182 |         . NEW REF SET REF=$$CREF^DILF(GREF)
 | 
|---|
| 183 |         . NEW TMGMAX SET TMGMAX=$ORDER(@REF@("+"),-1)
 | 
|---|
| 184 |         . NEW TMGMIN SET TMGMIN=$ORDER(@REF@(0))
 | 
|---|
| 185 |         . NEW SKIP SET SKIP=0
 | 
|---|
| 186 |         . NEW IEN SET IEN=0
 | 
|---|
| 187 |         . FOR  SET IEN=$ORDER(@REF@(IEN)) QUIT:(+IEN'>0)!ABORT!SKIP  DO
 | 
|---|
| 188 |         . . IF LIMITS DO  QUIT:SKIP  ;"If running on client side, only look at downloaded records.
 | 
|---|
| 189 |         . . . IF $DATA(@LIMITREF@(TEMPN,IEN))'=0 QUIT
 | 
|---|
| 190 |         . . . SET SKIP=1
 | 
|---|
| 191 |         . . NEW INFO SET INFO=""
 | 
|---|
| 192 |         . . FOR  SET INFO=$ORDER(ARRAY(GREF,INFO)) QUIT:(INFO="")!ABORT  DO
 | 
|---|
| 193 |         . . . NEW PCE SET PCE=$PIECE(INFO,"^",1)
 | 
|---|
| 194 |         . . . NEW IENDEPTH SET IENDEPTH=$PIECE(INFO,"^",4)
 | 
|---|
| 195 |         . . . NEW ONREF SET ONEREF=$PIECE(INFO,"^",8,99)
 | 
|---|
| 196 |         . . . NEW TEMP SET TEMP=IEN KILL IEN SET IEN=TEMP ;"clear subscripts
 | 
|---|
| 197 |         . . . FOR  QUIT:($$IENCOMBO(ONEREF,IENDEPTH,.IEN)'=1)!ABORT  DO
 | 
|---|
| 198 |         . . . . NEW FROMFILE SET FROMFILE=$PIECE(INFO,"^",6)
 | 
|---|
| 199 |         . . . . SET TMGCT=TMGCT+1
 | 
|---|
| 200 |         . . . . IF TMGCT#PGFREQ=0 DO
 | 
|---|
| 201 |         . . . . . SET ABORT=$$UserAborted^TMGUSRIF() QUIT:ABORT
 | 
|---|
| 202 |         . . . . . NEW TMGFNAME SET TMGFNAME=$PIECE($GET(^DIC(FROMFILE,0)),"^",1)
 | 
|---|
| 203 |         . . . . . NEW TMGIEN SET TMGIEN=IEN
 | 
|---|
| 204 |         . . . . . NEW $ETRAP SET $ETRAP="W ""(Invalid M Code!.  Error Trapped.)"" S $ETRAP="""",$ECODE="""""
 | 
|---|
| 205 |         . . . . . XECUTE PGFN
 | 
|---|
| 206 |         . . . . NEW PT SET PT=$PIECE($GET(@ONEREF),"^",PCE) ;"$$IENCOMBO sets up IEN(n).. needed for @REF
 | 
|---|
| 207 |         . . . . NEW ISVIRT SET ISVIRT=($PIECE(INFO,"^",5)="V")
 | 
|---|
| 208 |         . . . . NEW P2REF SET P2REF=$PIECE(INFO,"^",3)
 | 
|---|
| 209 |         . . . . IF ISVIRT,$PIECE(PT,";",2)'=P2REF QUIT ;"Loop to handle PTR with different INFO entry (V-Ptrs stored as IEN;OREF)
 | 
|---|
| 210 |         . . . . SET PT=+PT QUIT:(PT'>0)
 | 
|---|
| 211 |         . . . . NEW IENS SET IENS=$$GETIENS(.IEN)
 | 
|---|
| 212 |         . . . . NEW P2FILE SET P2FILE=$PIECE(INFO,"^",2)
 | 
|---|
| 213 |         . . . . NEW FROMFLD SET FROMFLD=$PIECE(INFO,"^",7)
 | 
|---|
| 214 |         . . . . SET @DESTREF@("OUT",FROMFILE,IENS,FROMFLD,P2FILE,PT)=""
 | 
|---|
| 215 |         . . . . SET @DESTREF@("IN",P2FILE,PT,FROMFILE,IENS,FROMFLD)=""
 | 
|---|
| 216 |         QUIT
 | 
|---|
| 217 |  ;
 | 
|---|
| 218 |  ;
 | 
|---|
| 219 | TESTSPTO
 | 
|---|
| 220 |         ;"Purpose: test out PT XREF setup.
 | 
|---|
| 221 |         NEW X,Y,DIC
 | 
|---|
| 222 |         SET DIC=1,DIC(0)="MAEQ"
 | 
|---|
| 223 |         DO ^DIC WRITE !
 | 
|---|
| 224 |         IF +Y'>0 QUIT
 | 
|---|
| 225 |         NEW TMGSTIME SET TMGSTIME=$H
 | 
|---|
| 226 |         NEW PGFN SET PGFN="DO ProgressBar^TMGUSRIF(TMGIEN,TMGFNAME,TMGMIN,TMGMAX,60,TMGSTIME)"
 | 
|---|
| 227 |         DO SETPTOUT(+Y,$NAME(^TMG("PTXREF")),PGFN,500)
 | 
|---|
| 228 |         WRITE !,"Quitting normally.",!
 | 
|---|
| 229 |         QUIT
 | 
|---|
| 230 |  ;
 | 
|---|
| 231 |  ;
 | 
|---|
| 232 | KILLPTIX ;
 | 
|---|
| 233 |         ;"Purpose: To delete the last run of PT XREF, so it can be refreshened.
 | 
|---|
| 234 |         KILL ^TMG("PTXREF")
 | 
|---|
| 235 |         QUIT
 | 
|---|
| 236 |  ;
 | 
|---|
| 237 |  ;
 | 
|---|
| 238 | HNDLPTIX(FILENUM,PGFN) ;
 | 
|---|
| 239 |         ;"Purpose: To prepair PT XREF for all records pointing INTO specified file.
 | 
|---|
| 240 |         ;"Input: FILENUM -- The fileman file number to get pointers INTO.
 | 
|---|
| 241 |         ;"       PGFN -- OPTIONAL -- M Code that wil be periodically executed to show progress.
 | 
|---|
| 242 |         ;"Result: None
 | 
|---|
| 243 |         SET FILENUM=+$GET(FILENUM) IF FILENUM'>0 QUIT
 | 
|---|
| 244 |         NEW TMGSTIME SET TMGSTIME=$H
 | 
|---|
| 245 |         DO SETPTOUT(FILENUM,$NAME(^TMG("PTXREF")),.PGFN,3000,CLSIDE)
 | 
|---|
| 246 |         SET ^TMG("PTXREF","IN",FILENUM)=$H
 | 
|---|
| 247 |         SET ^TMG("PTXREF")=$H
 | 
|---|
| 248 |         QUIT
 | 
|---|
| 249 |  ;
 | 
|---|
| 250 |  ;
 | 
|---|
| 251 | GETPTIN(PARAMS,OUT,PGFN) ;
 | 
|---|
| 252 |         ;"Purpose: To get a listing of all pointers INTO requested record
 | 
|---|
| 253 |         ;"Input: PARAMS -- this is FILENUM^IEN
 | 
|---|
| 254 |         ;"       OUT  -- PASS BY REFERNCE.  Will be filled as with format:
 | 
|---|
| 255 |         ;"                   OUT(1)=FROMFILE^FROMIENS^FROMFLD
 | 
|---|
| 256 |         ;"                   OUT(2)=FROMFILE^FROMIENS^FROMFLD
 | 
|---|
| 257 |         ;"       PGFN -- OPTIONAL -- M Code that wil be periodically executed to show progress.
 | 
|---|
| 258 |         ;"                   ...
 | 
|---|
| 259 |         NEW FILENUM SET FILENUM=+$PIECE(PARAMS,"^",1)
 | 
|---|
| 260 |         NEW TMGCT SET TMGCT=1
 | 
|---|
| 261 |         NEW IEN SET IEN=+$PIECE(PARAMS,"^",2)
 | 
|---|
| 262 |         IF $DATA(^TMG("PTXREF","IN",FILENUM))'>0 DO HNDLPTIX(FILENUM,.PGFN)
 | 
|---|
| 263 |         NEW FROMFILE,FROMIENS,FROMFLD
 | 
|---|
| 264 |         SET (FROMFILE,FROMIENS,FROMFLD)=0
 | 
|---|
| 265 |         FOR  SET FROMFILE=$ORDER(^TMG("PTXREF","IN",FILENUM,IEN,FROMFILE)) QUIT:(+FROMFILE'>0)  DO
 | 
|---|
| 266 |         . FOR  SET FROMIENS=$ORDER(^TMG("PTXREF","IN",FILENUM,IEN,FROMFILE,FROMIENS)) QUIT:(+FROMIENS'>0)  DO
 | 
|---|
| 267 |         . . FOR  SET FROMFLD=$ORDER(^TMG("PTXREF","IN",FILENUM,IEN,FROMFILE,FROMIENS,FROMFLD)) QUIT:(+FROMFLD'>0)  DO
 | 
|---|
| 268 |         . . . SET OUT(TMGCT)=FROMFILE_"^"_FROMIENS_"^"_FROMFLD
 | 
|---|
| 269 |         . . . SET TMGCT=TMGCT+1
 | 
|---|
| 270 |         QUIT
 | 
|---|
| 271 |  ;
 | 
|---|
| 272 |  ;
 | 
|---|
| 273 | BAKXREF(PARAMS,PGFN) ;
 | 
|---|
| 274 |         ;"Purpose: Make a xref of cross-references (a backward xref)
 | 
|---|
| 275 |         ;"Input: PARAMS -- This is FILENUM^[KEEP]
 | 
|---|
| 276 |         ;"                 FILENUM -- The fileman file to work with
 | 
|---|
| 277 |         ;"                 KEEP -- optional.  DEFAULT=0;  If '1', then nothing done if xref already exists.
 | 
|---|
| 278 |         ;"       PGFN -- OPTIONAL -- M Code that wil be periodically executed to show progress.
 | 
|---|
| 279 |         ;"              The following globally-scoped variables will be available for use:
 | 
|---|
| 280 |         ;"              FILENUM,INDEX
 | 
|---|
| 281 |         ;"Output: ^TMG("PTXREF","XREFS",FILENUM,IEN,REF)=<xref value>
 | 
|---|
| 282 |         ;"        e.g. ^TMG("PTXREF","XREFS",FILENUM,113,"^VA(200,""A"",8870804679,113)")=6188
 | 
|---|
| 283 |         ;"Result: none.
 | 
|---|
| 284 |         SET PARAMS=$GET(PARAMS)
 | 
|---|
| 285 |         SET FILENUM=$PIECE(PARAMS,"^",1) IF +FILENUM'>0 GOTO BXDN
 | 
|---|
| 286 |         IF FILENUM["{" DO BAKSXREF(.PARAMS,.PGFN) GOTO BXDN
 | 
|---|
| 287 |         IF $DATA(^TMG("PTXREF","XREFS",FILENUM))>0 GOTO BXDN
 | 
|---|
| 288 |         SET PGFN=$GET(PGFN)
 | 
|---|
| 289 |         NEW STIME SET STIME=$H
 | 
|---|
| 290 |         NEW GREF SET GREF=$GET(^DIC(FILENUM,0,"GL"))
 | 
|---|
| 291 |         IF GREF="" QUIT  ;"Happened for file 799.6
 | 
|---|
| 292 |         NEW GRLEN SET GRLEN=$LENGTH(GREF)
 | 
|---|
| 293 |         NEW CGREF SET CGREF=$$CREF^DILF(GREF)
 | 
|---|
| 294 |         NEW GREFQLEN SET GREFQLEN=$QLENGTH(CGREF)
 | 
|---|
| 295 |         NEW REF SET REF=$QUERY(@CGREF@("@"))
 | 
|---|
| 296 |         NEW INDEX,LASTINDEX SET LASTINDEX=""
 | 
|---|
| 297 |         NEW DELAYCT SET DELAYCT=500 ;"ensure fires at least once to avoid timeout with many quick XREFS
 | 
|---|
| 298 |         NEW DONE SET DONE=0
 | 
|---|
| 299 |         KILL ^TMG("PTXREF","XREFS",FILENUM)
 | 
|---|
| 300 |         IF $GET(^TMG("PTXREF"))="" SET ^TMG("PTXREF")=$H
 | 
|---|
| 301 |         SET ^TMG("PTXREF","XREFS",FILENUM)=$H
 | 
|---|
| 302 |         FOR  QUIT:(REF="")  DO
 | 
|---|
| 303 |         . SET DELAYCT=DELAYCT+1
 | 
|---|
| 304 |         . IF (DELAYCT>500),(PGFN'="") DO
 | 
|---|
| 305 |         . . SET DELAYCT=0
 | 
|---|
| 306 |         . . IF ($PIECE($H,",",2)-STIME)<5 QUIT
 | 
|---|
| 307 |         . . SET STIME=$PIECE($H,",",2)
 | 
|---|
| 308 |         . . NEW $ETRAP SET $ETRAP="SET $ETRAP="""",$ECODE="""""
 | 
|---|
| 309 |         . . XECUTE PGFN
 | 
|---|
| 310 |         . IF $EXTRACT(REF,1,GRLEN)'=GREF SET REF="" QUIT
 | 
|---|
| 311 |         . NEW IEN SET IEN=$QSUBSCRIPT(REF,$QLENGTH(REF))
 | 
|---|
| 312 |         . SET ^TMG("PTXREF","XREFS",FILENUM,IEN,REF)=$GET(@REF)
 | 
|---|
| 313 |         . SET INDEX=$QSUBSCRIPT(REF,GREFQLEN+1)
 | 
|---|
| 314 |         . IF INDEX'=LASTINDEX DO
 | 
|---|
| 315 |         . . SET LASTINDEX=INDEX
 | 
|---|
| 316 |         . . SET STIME=$PIECE($H,",",2)
 | 
|---|
| 317 |         . . SET DELAYCT=0
 | 
|---|
| 318 |         . . NEW $ETRAP SET $ETRAP="SET $ETRAP="""",$ECODE="""""
 | 
|---|
| 319 |         . . XECUTE PGFN
 | 
|---|
| 320 |         . SET REF=$QUERY(@REF)
 | 
|---|
| 321 | BXDN    QUIT
 | 
|---|
| 322 |  ;
 | 
|---|
| 323 |  ;
 | 
|---|
| 324 | BAKSXREF(PARAMS,PGFN) ;
 | 
|---|
| 325 |         ;"Purpose: Make a xref of cross-references (a backward xref) **OF SUBFILES**
 | 
|---|
| 326 |         ;"Input: PARAMS -- This is FILENUM^[KEEP]
 | 
|---|
| 327 |         ;"                 FILENUM -- subfilenum{parentfilenum{grandparent....
 | 
|---|
| 328 |         ;"                 KEEP -- optional.  DEFAULT=0;  If '1', then nothing done if xref already exists.
 | 
|---|
| 329 |         ;"       PGFN -- OPTIONAL -- M Code that wil be periodically executed to show progress.
 | 
|---|
| 330 |         ;"              The following globally-scoped variables will be available for use:
 | 
|---|
| 331 |         ;"              FILENUM,INDEX
 | 
|---|
| 332 |         ;"Output: ^TMG("PTXREF","XREFS",SUBFILENUM,IENS,REF)=<xref value>
 | 
|---|
| 333 |         ;"Result: none.
 | 
|---|
| 334 |         SET PARAMS=$GET(PARAMS)
 | 
|---|
| 335 |         SET FILENUM=+$PIECE(PARAMS,"^",1) ;"Just get the subfile number.
 | 
|---|
| 336 |         IF FILENUM'>0 GOTO BXSDN
 | 
|---|
| 337 |         IF $DATA(^TMG("PTXREF","XREFS",FILENUM))>0 GOTO BXSDN
 | 
|---|
| 338 |         SET PGFN=$GET(PGFN)
 | 
|---|
| 339 |         NEW IEN SET IEN=0
 | 
|---|
| 340 |         NEW INDEX SET INDEX=""
 | 
|---|
| 341 |         NEW IENDEPTH SET IENDEPTH=""
 | 
|---|
| 342 |         NEW GREF SET GREF=$$GETGL(FILENUM,.IENDEPTH)  ;" e.g. file 44.003 --> ^SC(IEN,"S",IEN(2),1,   (open format)
 | 
|---|
| 343 |         IF GREF="" QUIT  ;"Happened for file 799.6
 | 
|---|
| 344 |         NEW CGREF SET CGREF=$$CREF^DILF(GREF)
 | 
|---|
| 345 |         NEW J FOR J=1:1:IENDEPTH SET IEN(J)=1  ;"dummy values to satisfy $QLENGTH on line below
 | 
|---|
| 346 |         NEW GREFQLEN SET GREFQLEN=$QLENGTH($NAME(@CGREF))
 | 
|---|
| 347 |         NEW DELAYCT SET DELAYCT=999
 | 
|---|
| 348 |         ;"NOTE: IENCOMBO is only for getting subfile combos.  It doesn't modify IEN.  So I need
 | 
|---|
| 349 |         ;"to manually cycle between all the records of the top-most file. Use GETTOPFILEN^TMGFMUT2 to get this.
 | 
|---|
| 350 |         NEW TOPFILE SET TOPFILE=+$$TOPFILEN(FILENUM)
 | 
|---|
| 351 |         NEW TOPREF SET TOPREF=$GET(^DIC(TOPFILE,0,"GL"))
 | 
|---|
| 352 |         IF TOPREF="" GOTO BXSDN
 | 
|---|
| 353 |         KILL IEN SET IEN=0
 | 
|---|
| 354 |         SET TOPREF=$$CREF^DILF(TOPREF)
 | 
|---|
| 355 |         FOR  SET IEN=$ORDER(@TOPREF@(IEN)) QUIT:(+IEN'>0)  DO
 | 
|---|
| 356 |         . FOR  DO  QUIT:(OKCOMBO=0)
 | 
|---|
| 357 |         . . SET DELAYCT=DELAYCT+1
 | 
|---|
| 358 |         . . IF (DELAYCT>500),(PGFN'="") DO
 | 
|---|
| 359 |         . . . SET DELAYCT=0
 | 
|---|
| 360 |         . . . NEW $ETRAP SET $ETRAP="SET $ETRAP="""",$ECODE="""""
 | 
|---|
| 361 |         . . . XECUTE PGFN
 | 
|---|
| 362 |         . . SET OKCOMBO=$$IENCOMBO^TMGFMUT2(CGREF,IENDEPTH,.IEN) ;"Sets up IEN(n).. needed for @CGREF
 | 
|---|
| 363 |         . . QUIT:(OKCOMBO=0)
 | 
|---|
| 364 |         . . NEW GREF SET GREF=$$OREF^DILF($NAME(@CGREF))  ;"resolve IEN vars into actual numbers
 | 
|---|
| 365 |         . . NEW GRLEN SET GRLEN=$LENGTH(GREF)
 | 
|---|
| 366 |         . . NEW REF SET REF=$NAME(@CGREF@("@"))
 | 
|---|
| 367 |         . . FOR  DO  QUIT:(REF="")
 | 
|---|
| 368 |         . . . SET REF=$QUERY(@REF)
 | 
|---|
| 369 |         . . . IF $EXTRACT(REF,1,GRLEN)'=GREF SET REF="" QUIT
 | 
|---|
| 370 |         . . . SET INDEX=$QSUBSCRIPT(REF,GREFQLEN+1)  ;"set up for use by PGFN
 | 
|---|
| 371 |         . . . NEW PTR SET PTR=$QSUBSCRIPT(REF,$QLENGTH(REF))
 | 
|---|
| 372 |         . . . NEW TMPIEN MERGE TMPIEN=IEN
 | 
|---|
| 373 |         . . . SET TMPIEN(IENDEPTH+1)=PTR
 | 
|---|
| 374 |         . . . NEW IENS SET IENS=$$GETIENS(.TMPIEN)
 | 
|---|
| 375 |         . . . SET ^TMG("PTXREF","XREFS",FILENUM,IENS,REF)=$GET(@REF)
 | 
|---|
| 376 |         . KILL IEN("DONE"),IEN("INIT")
 | 
|---|
| 377 | BXSDN    QUIT
 | 
|---|
| 378 |  ;
 | 
|---|
| 379 |  ;
 | 
|---|
| 380 | GETXRAGE() ;
 | 
|---|
| 381 |         ;"Purpose: Return, in HOURS, the time since the ^TMG("PTXREF") array has had any modification
 | 
|---|
| 382 |         ;"Results: 0 if not currently defined, otherwise number of HOURS since setup.
 | 
|---|
| 383 |         NEW LASTT SET LASTT=$GET(^TMG("PTXREF","TIMESTAMP"))
 | 
|---|
| 384 |         NEW DELTAT SET DELTAT=0
 | 
|---|
| 385 |         IF LASTT'="" SET DELTAT=$$HDIFF^XLFDT($H,LASTT,2)\(60*60)
 | 
|---|
| 386 |         QUIT DELTAT
 | 
|---|
| 387 |  ;
 | 
|---|
| 388 |  ;
 | 
|---|
| 389 | GETGL(SUBFILENUM,IENDEPTH) ;
 | 
|---|
| 390 |         ;"Purpose: To return a reference 'GL' string for subfiles.
 | 
|---|
| 391 |         ;"         E.g. file 44.003 --> ^SC(IEN,"S",IEN(2),1,
 | 
|---|
| 392 |         ;"INPUT: SUBFILENUM -- The sub file number
 | 
|---|
| 393 |         ;"       IENDEPTH -- PASS BY REFERENCE. Should be 1 on first call
 | 
|---|
| 394 |         ;"Results: Returns an OPEN reference.
 | 
|---|
| 395 |         NEW RESULT SET RESULT=""
 | 
|---|
| 396 |         SET IENDEPTH=+$GET(IENDEPTH)+1
 | 
|---|
| 397 |         NEW UPFILE SET UPFILE=+$GET(^DD(SUBFILENUM,0,"UP"))
 | 
|---|
| 398 |         IF UPFILE'>0 DO  GOTO IDN
 | 
|---|
| 399 |         . SET RESULT=$GET(^DIC(SUBFILENUM,0,"GL"))
 | 
|---|
| 400 |         NEW UPFLD SET UPFLD=+$ORDER(^DD(UPFILE,"SB",SUBFILENUM,""))
 | 
|---|
| 401 |         IF UPFLD'>0 GOTO IDN
 | 
|---|
| 402 |         NEW NODE SET NODE=$PIECE(^DD(UPFILE,UPFLD,0),"^",4)
 | 
|---|
| 403 |         SET NODE=$PIECE(NODE,";",1)
 | 
|---|
| 404 |         IF +NODE'=NODE SET NODE=""""_NODE_""""
 | 
|---|
| 405 |         SET RESULT=NODE_","
 | 
|---|
| 406 |         NEW GREF SET GREF=$GET(^DIC(UPFILE,0,"GL"))
 | 
|---|
| 407 |         NEW NUM2 SET NUM2=IENDEPTH
 | 
|---|
| 408 |         IF GREF="" SET GREF=$$GETGL(UPFILE,.IENDEPTH)
 | 
|---|
| 409 |         SET RESULT=GREF_"#"_$CHAR(64+NUM2)_"#,"_RESULT
 | 
|---|
| 410 | IDN     NEW I,TMGSPEC
 | 
|---|
| 411 |         FOR I=1:1:IENDEPTH DO
 | 
|---|
| 412 |         . IF I=IENDEPTH SET TMGSPEC("#"_$CHAR(64+I)_"#")="IEN"
 | 
|---|
| 413 |         . ELSE  SET TMGSPEC("#"_$CHAR(64+I)_"#")="IEN("_(IENDEPTH-I+1)_")"
 | 
|---|
| 414 |         SET RESULT=$$REPLACE^XLFSTR(RESULT,.TMGSPEC)
 | 
|---|
| 415 | IDN2    QUIT RESULT
 | 
|---|
| 416 |  ;
 | 
|---|
| 417 |  ;
 | 
|---|
| 418 | GETGREF(FILENUM,IENS) ;
 | 
|---|
| 419 |         ;"Purpose: To return a reference to a file or a subfile
 | 
|---|
| 420 |         ;"         This function differs from GETGL in that REF from GETGREFhere has actual record numbers
 | 
|---|
| 421 |         ;"         put in, while REF from GETGL has variable names (e.g. IEN(2)) in it.
 | 
|---|
| 422 |         ;"Input: IENS -- A standard IENS string to locate subfile.    Not used unless FILENUM is a subfile.
 | 
|---|
| 423 |         ;"              NOTE: the lowest level IEN is not used.  e.g. '7,22345,' --> 7 is not used
 | 
|---|
| 424 |         ;"Returns : an OPEN format reference.
 | 
|---|
| 425 |         NEW GREF
 | 
|---|
| 426 |         NEW IENDEPTH SET IENDEPTH=1
 | 
|---|
| 427 |         SET GREF=$$GETGL(FILENUM,.IENDEPTH)
 | 
|---|
| 428 |         IF $$ISSUBFIL(FILENUM)=0 GOTO GGRDN
 | 
|---|
| 429 |         SET GREF=$$CREF^DILF(GREF)
 | 
|---|
| 430 |         NEW IEN DO IENS2IEN(.IENS,.IEN)
 | 
|---|
| 431 |         SET GREF=$NAME(@GREF) ;"Lock IEN value(s) from IENS into GREF
 | 
|---|
| 432 |         SET GREF=$$OREF^DILF(GREF)
 | 
|---|
| 433 | GGRDN   QUIT GREF
 | 
|---|
| 434 |  ;
 | 
|---|
| 435 |  ;
 | 
|---|
| 436 | IENCOMBO(REF,IENDEPTH,IEN) ;
 | 
|---|
| 437 |         ;"Purpose: To set up global vars IEN(2),IEN(3),... etc, as needed for next combo when
 | 
|---|
| 438 |         ;"         cycling through subfile arrays.
 | 
|---|
| 439 |         ;"Input: REF -- the is the potential pointer reference, as stored in ^TMG("TMGSIPH","DD",FILENUM,"PTR OUT",REF,INFO)
 | 
|---|
| 440 |         ;"              e.g. '^SC(IEN,"S",IEN(2),1,IEN(3),"C")    (and IENDEPTH would be 3 for this example)
 | 
|---|
| 441 |         ;"       IENDEPTH -- The number of variables to consider.  I.e if value=3, then REF will
 | 
|---|
| 442 |         ;"                   contain IEN,IEN(2),IEN(3)
 | 
|---|
| 443 |         ;"       IEN -- PASS BY REFERENCE.  This variable will serve as an array to store the
 | 
|---|
| 444 |         ;"              information needed to create the next valid set of variables needed
 | 
|---|
| 445 |         ;"              to make use of the reference.  NOTE: The value of IEN itself (e.g. IEN=4),
 | 
|---|
| 446 |         ;"              is not modified.
 | 
|---|
| 447 |         ;"Results: 1 if a new valid IEN combo has been set up.
 | 
|---|
| 448 |         ;"         0 if there are no more subfile entries.
 | 
|---|
| 449 |         ;"
 | 
|---|
| 450 |         ;"NOTE!!!: If IENDEPTH=3, then this function will fail if there are records for depth 1,2, but not 3
 | 
|---|
| 451 |         ;"  Needs debugging...
 | 
|---|
| 452 |         ;"
 | 
|---|
| 453 |         ;
 | 
|---|
| 454 |         NEW RESULT SET RESULT=0 ;"Default to invalid
 | 
|---|
| 455 |         IF $DATA(IEN("DONE")) GOTO ICODN
 | 
|---|
| 456 |         IF IENDEPTH=1 DO  GOTO ICODN
 | 
|---|
| 457 |         . SET IEN("DONE")=1
 | 
|---|
| 458 |         . SET RESULT=1
 | 
|---|
| 459 |         NEW I
 | 
|---|
| 460 |         SET RESULT=1 ;"Default to valid
 | 
|---|
| 461 |         IF $DATA(IEN("ORDS"))=0 DO
 | 
|---|
| 462 |         . FOR I=2:1:IENDEPTH SET IEN("ORDS",I)=$$CREF^DILF($PIECE(REF,"IEN("_I_")",1))
 | 
|---|
| 463 |         IF +$GET(IEN("INIT"))=0 DO
 | 
|---|
| 464 |         . SET IEN("INIT")=1
 | 
|---|
| 465 |         . NEW INVALID SET INVALID=0
 | 
|---|
| 466 |         . NEW POS FOR POS=2:1:IENDEPTH  DO  QUIT:(INVALID=1)
 | 
|---|
| 467 |         . . IF $GET(IEN(POS))'="" QUIT
 | 
|---|
| 468 |         . . NEW TEMPREF SET TEMPREF=IEN("ORDS",POS)
 | 
|---|
| 469 |         . . SET IEN(POS)=+$ORDER(@TEMPREF@(0))
 | 
|---|
| 470 |         . . IF IEN(POS)'>0 SET INVALID=1
 | 
|---|
| 471 |         . IF (POS=IENDEPTH),(INVALID=0) SET RESULT=1
 | 
|---|
| 472 |         ELSE  DO  ;"At this point, IEN(n),IEN(n+1),... vars should be set to last valid combo.
 | 
|---|
| 473 |         . SET I=IENDEPTH
 | 
|---|
| 474 |         . NEW REF,NODE
 | 
|---|
| 475 |         . FOR  DO  QUIT:(I<2)!(I=IENDEPTH)
 | 
|---|
| 476 |         . . SET REF=IEN("ORDS",I)
 | 
|---|
| 477 |         . . SET IEN(I)=$ORDER(@REF@(IEN(I)))
 | 
|---|
| 478 |         . . IF (IEN(I)="") SET I=I-1 QUIT ;"reached last record at this level, so backup up level
 | 
|---|
| 479 |         . . IF (I<IENDEPTH) DO ;"We have a valid record, now get next subrecord
 | 
|---|
| 480 |         . . . NEW J FOR J=(I+1):1:IENDEPTH DO  QUIT:(IEN(J)="")
 | 
|---|
| 481 |         . . . . SET REF=IEN("ORDS",J)
 | 
|---|
| 482 |         . . . . SET IEN(J)=$ORDER(@REF@(""))
 | 
|---|
| 483 |         FOR I=2:1:IENDEPTH IF +$GET(IEN(I))'>0 SET RESULT=0
 | 
|---|
| 484 | ICODN   QUIT RESULT
 | 
|---|
| 485 |         ;
 | 
|---|
| 486 |         ;
 | 
|---|
| 487 | TOPFILEN(FILENUM) ;
 | 
|---|
| 488 |         ;"Purpose: Return the highest level of filenumber.  I.e. if subfile, then return parent
 | 
|---|
| 489 |         ;"         parent filenumber.  If sub-sub-file, then return higest file number that is
 | 
|---|
| 490 |         ;"         not a sub file.
 | 
|---|
| 491 |         ;"         If FILENUM is not a subfile, then just return same FILENUM
 | 
|---|
| 492 |         ;"Results: 0 if problem, or Top-most filenumber.
 | 
|---|
| 493 |         NEW RESULT SET RESULT=0
 | 
|---|
| 494 |         IF +$GET(FILENUM)'=FILENUM GOTO TFNDN
 | 
|---|
| 495 |         FOR  QUIT:$DATA(^DD(FILENUM,0,"UP"))=0  DO
 | 
|---|
| 496 |         . SET FILENUM=+$GET(^DD(FILENUM,0,"UP"))
 | 
|---|
| 497 |         SET RESULT=FILENUM
 | 
|---|
| 498 | TFNDN   QUIT RESULT
 | 
|---|
| 499 |  ;
 | 
|---|
| 500 |  ;
 | 
|---|
| 501 | ISSUBFIL(FILENUM) ;
 | 
|---|
| 502 |         ;"Purpose: Return if a file is a subfile.
 | 
|---|
| 503 |         ;"Input: FILENUM -- a File, or Subfile, number
 | 
|---|
| 504 |         ;"Result: 1 if file is a subfile
 | 
|---|
| 505 |         QUIT ($DATA(^DD(FILENUM,0,"UP"))>0)
 | 
|---|
| 506 |  ;
 | 
|---|
| 507 |  ;
 | 
|---|
| 508 | HASPTRSF(FILENUM) ;" HAS POINTER-CONTAINING SUBFILES
 | 
|---|
| 509 |         ;"Purpose: Return if file contains subfiles (or sub-subfiles) that contain pointers to other files)
 | 
|---|
| 510 |         ;"Input: FILENUM -- The file number to investigatge
 | 
|---|
| 511 |         ;"Results: 1 if has pointer subfiles.
 | 
|---|
| 512 |         ;";
 | 
|---|
| 513 |         NEW RESULT SET RESULT=0
 | 
|---|
| 514 |         NEW FLD SET FLD=0
 | 
|---|
| 515 |         FOR  SET FLD=$ORDER(^DD(FILENUM,FLD)) QUIT:(+FLD'>0)!(RESULT=1)  DO
 | 
|---|
| 516 |         . NEW ZNODE SET ZNODE=$GET(^DD(FILENUM,FLD,0))
 | 
|---|
| 517 |         . NEW FLDTYPE SET FLDTYPE=$PIECE(ZNODE,"^",2)
 | 
|---|
| 518 |         . IF (+FLDTYPE'>0) QUIT
 | 
|---|
| 519 |         . NEW SUBFILEN SET SUBFILEN=+FLDTYPE
 | 
|---|
| 520 |         . IF $GET(^DD(SUBFILEN,0,"UP"))'=FILENUM QUIT
 | 
|---|
| 521 |         . SET RESULT=$$HASPTR(SUBFILEN)
 | 
|---|
| 522 |         QUIT RESULT
 | 
|---|
| 523 |  ;
 | 
|---|
| 524 |  ;
 | 
|---|
| 525 | HASPTR(FILENUM) ;" HAS POINTER fields
 | 
|---|
| 526 |         ;"Purpose: Return if file contains fields that are pointers to other files
 | 
|---|
| 527 |         ;"Input: FILENUM -- The file number to investigatge
 | 
|---|
| 528 |         ;"Results: 1 if has pointer subfiles.
 | 
|---|
| 529 |         ;"
 | 
|---|
| 530 |         NEW RESULT SET RESULT=($DATA(^DD(FILENUM,0,"PT"))'=0)
 | 
|---|
| 531 |         IF RESULT GOTO HPDN
 | 
|---|
| 532 |         NEW FLD SET FLD=0
 | 
|---|
| 533 |         FOR  SET FLD=$ORDER(^DD(FILENUM,FLD)) QUIT:(+FLD'>0)!(RESULT=1)  DO
 | 
|---|
| 534 |         . NEW ZNODE SET ZNODE=$GET(^DD(FILENUM,FLD,0))
 | 
|---|
| 535 |         . NEW FLDTYPE SET FLDTYPE=$PIECE(ZNODE,"^",2)
 | 
|---|
| 536 |         . IF +$PIECE(FLDTYPE,"P",2)>0 SET RESULT=1 QUIT
 | 
|---|
| 537 |         . IF (+FLDTYPE'>0) QUIT
 | 
|---|
| 538 |         . NEW SUBFILEN SET SUBFILEN=+FLDTYPE
 | 
|---|
| 539 |         . IF $GET(^DD(SUBFILEN,0,"UP"))'=FILENUM QUIT
 | 
|---|
| 540 |         . SET RESULT=$$HASPTRSF(SUBFILEN)
 | 
|---|
| 541 | HPDN    QUIT RESULT
 | 
|---|
| 542 |  ;
 | 
|---|
| 543 |  ;
 | 
|---|
| 544 | FILENAME(FILENUM) ;
 | 
|---|
| 545 |         ;"Purpose: to turn a File number into a file name.  ALSO, turn input with format of
 | 
|---|
| 546 |         ;"         SubfileNumber{ParentFileNumber into a meaningful name too.
 | 
|---|
| 547 |         ;"Input: FILENUM:  A file number, or a SubfileNumber{ParentFileNumber
 | 
|---|
| 548 |         ;"Result: returns name or name{name{name
 | 
|---|
| 549 |         ;"
 | 
|---|
| 550 |         IF (FILENUM'["{"),$$ISSUBFIL(+FILENUM) DO
 | 
|---|
| 551 |         . SET FILENUM=$$GETSPFN(FILENUM)
 | 
|---|
| 552 |         NEW RESULT SET RESULT=""
 | 
|---|
| 553 |         NEW I
 | 
|---|
| 554 |         FOR I=1:1:$LENGTH(FILENUM,"{") DO
 | 
|---|
| 555 |         . NEW ANUM SET ANUM=$PIECE(FILENUM,"{",I)
 | 
|---|
| 556 |         . NEW PFILE SET PFILE=+$GET(^DD(ANUM,0,"UP"))
 | 
|---|
| 557 |         . NEW ANAME
 | 
|---|
| 558 |         . IF PFILE=0 DO
 | 
|---|
| 559 |         . . SET ANAME=$PIECE($GET(^DIC(ANUM,0)),"^",1)
 | 
|---|
| 560 |         . ELSE  DO
 | 
|---|
| 561 |         . . SET ANAME=$PIECE($GET(^DD(ANUM,0)),"^",1)
 | 
|---|
| 562 |         . . SET ANAME=$PIECE(ANAME,"SUB-FIELD",1)
 | 
|---|
| 563 |         . . SET ANAME=$$TRIM^XLFSTR(ANAME)
 | 
|---|
| 564 |         . IF RESULT'="" SET RESULT=RESULT_"{"
 | 
|---|
| 565 |         . SET RESULT=RESULT_ANAME
 | 
|---|
| 566 |         QUIT RESULT
 | 
|---|
| 567 |  ;
 | 
|---|
| 568 |  ;
 | 
|---|
| 569 | GETSPFN(FILENUM) ;" Get Special Filenum
 | 
|---|
| 570 |         ;"Purpose: Turn a subfile number into a 'special' subfilenumber, in format of:
 | 
|---|
| 571 |         ;"         SubFileNum{ParentFileNum{GrandParentFileNum....
 | 
|---|
| 572 |         ;"Results: 0 if problem, or Top-most filenumber.
 | 
|---|
| 573 |         NEW RESULT SET RESULT=""
 | 
|---|
| 574 |         NEW FN SET FN=FILENUM
 | 
|---|
| 575 |         FOR  DO  QUIT:FN=0
 | 
|---|
| 576 |         . IF RESULT'="" SET RESULT=RESULT_"{"
 | 
|---|
| 577 |         . SET RESULT=RESULT_FN
 | 
|---|
| 578 |         . SET FN=+$GET(^DD(FN,0,"UP"))
 | 
|---|
| 579 |         QUIT RESULT
 | 
|---|
| 580 |  ;
 | 
|---|
| 581 |  ;
 | 
|---|