VPRSDA ;SLC/MKB -- SDA utilities ;10/25/18 15:29
;;1.0;VIRTUAL PATIENT RECORD;**8,10,16,20,26,28,29,30,31,33**;Sep 01, 2011;Build 8
;;Per VHA Directive 6402, this routine should not be modified.
;
; External References DBIA#
; ------------------- -----
; ^DIC(4 10090
; ^SC 10040
; %DT 10003
; DILFD 2055
; DIQ 2056
; ETSLNC 6731
; ETSRXN 6758
; ICPTCOD 1995
; LEXTRAN 4912
; VASITE 10112
; XLFNAME 3065
; XUAF4 2171
; XUPARAM 2541
;
INTDATE(X) ; -- Return internal form of date X
N %DT,Y
S %DT="TSX" D ^%DT
Q Y
;
DATE(X,DTO) ; -- return FM date X as SDA Timestamp
N D,T,Y
S X=$G(X) I X'?7N.1".".7N Q ""
S D=$P(X,"."),T=$P(X,".",2)
; validate date
I '$$VALID(D) Q ""
S Y=(1700+$E(D,1,3))_"-"_$E(D,4,5)_"-"_$E(D,6,7)
; if imprecise, add month or day of 01
F I=2,3 I $P(Y,"-",I)="00" S $P(Y,"-",I)="01"
I $G(DTO) Q Y ;date only
;
; validate T = time
I T=24 S T=235959 ;for SDA
S:$L(T)<6 T=$E((T_"000000"),1,6) ;pad the time to 6 digits
I $E(T,1,2)>23 S T="000000" ;invalid hours >> remove time
I $E(T,3,4)>59 S $E(T,3,6)="0000" ;strip invalid minutes/seconds
I $E(T,5,6)>59 S $E(T,5,6)="00" ;strip invalid seconds
S Y=Y_"T"_$E(T,1,2)_":"_$E(T,3,4)_":"_$E(T,5,6)
Q Y
;
VALID(X) ; -- returns 1 or 0, if valid FM date
N %DT,Y S %DT="",X=$G(X)
I X["." S X=$P(X,".") ;ck date only
D ^%DT I Y<1 Q 0
; check if out of HL7 range
I (Y<1410102)!(Y>4141015) Q 0
Q 1
;
NAMECOMP(NAME) ; -- return name as string of component pieces
; NAME -> FAMILY^GIVEN^MIDDLE^SUFFIX
D NAMECOMP^XLFNAME(.NAME)
N I,Y S Y=$G(NAME("FAMILY"))
F I="GIVEN","MIDDLE","SUFFIX" S Y=Y_U_$G(NAME(I))
Q Y
;
CODED ; -- ck Code Table ID for internal^external format
; called from DDEG for entity VPR CODE TABLE using variables:
; FILE, FIELD, ID (read only, do NOT kill)
Q:$G(ID)="" Q:$L(ID,"^")>1 ;ok
N X,NM S NM=ID
I $G(FILE),$G(FIELD) D
. S X=$$EXTERNAL^DILFD(FILE,FIELD,,ID)
. S:X'="" NM=X
S ID=ID_U_NM
Q
;
CODE(IEN,FILE,CSYS,CDT) ; -- find CSYS code for IEN in FILE
; CSYS can be string of abbreviations to look for, in order
N FLD,VPRC,SFN,S,SYS,NAMES,IENS,SFN1,I,X,Y
S Y="",CDT=$G(CDT) S:CDT<1 CDT=DT
S FLD=$$FLDNUM^DILFD(FILE,"CODING SYSTEM") Q:'FLD ""
D GETS^DIQ(FILE,IEN_",",FLD_"*","NR","VPRC")
S SFN=+$O(VPRC(0)) Q:'SFN "" ;Sub-file# = Coding System multiple
F S=1:1 S SYS=$P(CSYS,U,S) Q:SYS="" D Q:$L(Y)
. S NAMES=$S(SYS="RXN":"RxNorm^RXNORM",SYS="NDF":"NDF-RT^NDFRT^NDF",SYS="SCT":"SNOMED CT^SNOMED-CT^SCT",SYS="LNC":"LOINC^LNC",SYS="UNI":"UNII^UNI",1:SYS)
. S IENS="" F S IENS=$O(VPRC(SFN,IENS)) Q:IENS="" D Q:$L(Y)
.. S X=$G(VPRC(SFN,IENS,"CODING SYSTEM")) Q:X="" Q:NAMES'[X
.. S SFN1=$O(VPRC(SFN)),I=$O(VPRC(SFN1,""))
.. S:I Y=$G(VPRC(SFN1,I,"CODE")) ;first code for system
. I $L(Y) S Y=Y_U_$$DESC(Y)_U_$P(NAMES,U)
Q Y
;
DESC(CODE) ; -- called from CODE, to return coding system text
; Expects all the variables used in CODE()
N X,Y,LEX S Y=""
I SYS="SCT" D
. S X=$$CODE^LEXTRAN(CODE,"SCT",CDT)
. S:X>0 Y=$G(LEX("P")) ;preferred term
I SYS="RXN",$L($T(CSDATA^ETSRXN)) D
. S X=$$CSDATA^ETSRXN(CODE,"RXN",CDT,.LEX)
. S:X>0 Y=$P($G(LEX("LEX",1)),U,2)
I SYS="LNC",$L($T(GETNAME^ETSLNC)) D
. S X=$$GETNAME^ETSLNC(CODE,"C",.LEX)
. S:X>0 Y=$G(LEX("LONGNAME"))
I '$L($G(Y)) S Y=$$GET1^DIQ(FILE,IEN_",",.01)
Q Y
;
NULL(N) ; -- return null string(s) to delete property
N I,Y,QOT S N=+$G(N,1),QOT=""""""
S Y=QOT I N>1 F I=1:1:(N-1) S Y=Y_U_QOT
Q Y
;
CPT(IEN,DATE,LONG) ; -- return code^description^CPT-4 for #81 IEN
N X0,VPRX,N,I,X,Y
S IEN=+$G(IEN),DATE=$G(DATE) S:DATE<1 DATE=DT
S X0=$$CPT^ICPTCOD(IEN,DATE) I X0<0 Q ""
S Y=$P(X0,U,2,3)_"^CPT-4" ;CPT Code^Short Name
I $G(LONG) D ;CPT Description instead
. S N=$$CPTD^ICPTCOD($P(Y,U),"VPRX",,DATE)
. I N'>0!'$L($G(VPRX(1))) Q
. S X=$G(VPRX(1)),I=1
. F S I=$O(VPRX(I)) Q:I<1 Q:VPRX(I)=" " S X=X_" "_VPRX(I)
. S $P(Y,U,2)=X
Q Y
;
HLOC(X) ; -- return Hosp Loc #44 ien from location name X
N Y S Y=0
I $L($G(X)) S Y=+$O(^SC("B",X,0))
Q Y
;
COUNTY(ST,CTY) ; -- return ien^name for a STate and CounTY
N Y S Y=""
I +$G(ST),+$G(CTY) S Y=$$GET1^DIQ(5.01,(+CTY_","_+ST_","),.01)
S:$L(Y) Y=+CTY_U_Y
Q Y
;
FAC(HLOC) ; -- return facility #4 ien for HospLOC #44 ien
N X,Y S Y=""
S HLOC=+$G(HLOC) I HLOC<1 S Y=$$SITE G FACQ
S X=$$GET1^DIQ(44,HLOC,3,"I")
S:X<1 X=$$GET1^DIQ(44,HLOC,"3.5:.07","I")
S Y=$$CKFAC(X)
FACQ Q Y
;
CKFAC(IEN) ; -- validate #4 ien, return Parent if no stn#
N VPRZ S IEN=+$G(IEN)
I IEN<1 S Y=$$SITE Q Y
I $L($P($G(^DIC(4,IEN,99)),U)) Q IEN ;ok
D PARENT^XUAF4("VPRZ","`"_IEN,2) S Y=$O(VPRZ("P",0))
S:Y<1 Y=$$SITE
Q Y
;
SITE() ; -- return current site#
N Y S Y=+$$SITE^VASITE
S:Y'>0 Y=$$KSP^XUPARAM("INST")
Q Y
;
DEL1 ; -- ID Action for Delete entities, returns VPR0=data
N SEQ,VST S VPR0=""
S SEQ=+$G(FILTER("sequence")) I SEQ,$L($G(DIEN)) D
. S VPR0=$G(^XTMP("VPR-"_SEQ,DIEN,0)) Q:$L(VPR0) ;ok
. ; else get visit# from header node
. S VST=$P($G(^XTMP("VPR-"_SEQ,DIEN)),U,5) S:VST VPR0="^^"_VST
Q
;
NOQ ; -- no query
Q
--- Routine Detail --- with STRUCTURED ROUTINE LISTING ---[H[J[2J[HVPRSDA 5505 printed Oct 16, 2024@18:46:20 Page 2
VPRSDA ;SLC/MKB -- SDA utilities ;10/25/18 15:29
+1 ;;1.0;VIRTUAL PATIENT RECORD;**8,10,16,20,26,28,29,30,31,33**;Sep 01, 2011;Build 8
+2 ;;Per VHA Directive 6402, this routine should not be modified.
+3 ;
+4 ; External References DBIA#
+5 ; ------------------- -----
+6 ; ^DIC(4 10090
+7 ; ^SC 10040
+8 ; %DT 10003
+9 ; DILFD 2055
+10 ; DIQ 2056
+11 ; ETSLNC 6731
+12 ; ETSRXN 6758
+13 ; ICPTCOD 1995
+14 ; LEXTRAN 4912
+15 ; VASITE 10112
+16 ; XLFNAME 3065
+17 ; XUAF4 2171
+18 ; XUPARAM 2541
+19 ;
INTDATE(X) ; -- Return internal form of date X
+1 NEW %DT,Y
+2 SET %DT="TSX"
DO ^%DT
+3 QUIT Y
+4 ;
DATE(X,DTO) ; -- return FM date X as SDA Timestamp
+1 NEW D,T,Y
+2 SET X=$GET(X)
IF X'?7N.1".".7N
QUIT ""
+3 SET D=$PIECE(X,".")
SET T=$PIECE(X,".",2)
+4 ; validate date
+5 IF '$$VALID(D)
QUIT ""
+6 SET Y=(1700+$EXTRACT(D,1,3))_"-"_$EXTRACT(D,4,5)_"-"_$EXTRACT(D,6,7)
+7 ; if imprecise, add month or day of 01
+8 FOR I=2,3
IF $PIECE(Y,"-",I)="00"
SET $PIECE(Y,"-",I)="01"
+9 ;date only
IF $GET(DTO)
QUIT Y
+10 ;
+11 ; validate T = time
+12 ;for SDA
IF T=24
SET T=235959
+13 ;pad the time to 6 digits
if $LENGTH(T)<6
SET T=$EXTRACT((T_"000000"),1,6)
+14 ;invalid hours >> remove time
IF $EXTRACT(T,1,2)>23
SET T="000000"
+15 ;strip invalid minutes/seconds
IF $EXTRACT(T,3,4)>59
SET $EXTRACT(T,3,6)="0000"
+16 ;strip invalid seconds
IF $EXTRACT(T,5,6)>59
SET $EXTRACT(T,5,6)="00"
+17 SET Y=Y_"T"_$EXTRACT(T,1,2)_":"_$EXTRACT(T,3,4)_":"_$EXTRACT(T,5,6)
+18 QUIT Y
+19 ;
VALID(X) ; -- returns 1 or 0, if valid FM date
+1 NEW %DT,Y
SET %DT=""
SET X=$GET(X)
+2 ;ck date only
IF X["."
SET X=$PIECE(X,".")
+3 DO ^%DT
IF Y<1
QUIT 0
+4 ; check if out of HL7 range
+5 IF (Y<1410102)!(Y>4141015)
QUIT 0
+6 QUIT 1
+7 ;
NAMECOMP(NAME) ; -- return name as string of component pieces
+1 ; NAME -> FAMILY^GIVEN^MIDDLE^SUFFIX
+2 DO NAMECOMP^XLFNAME(.NAME)
+3 NEW I,Y
SET Y=$GET(NAME("FAMILY"))
+4 FOR I="GIVEN","MIDDLE","SUFFIX"
SET Y=Y_U_$GET(NAME(I))
+5 QUIT Y
+6 ;
CODED ; -- ck Code Table ID for internal^external format
+1 ; called from DDEG for entity VPR CODE TABLE using variables:
+2 ; FILE, FIELD, ID (read only, do NOT kill)
+3 ;ok
if $GET(ID)=""
QUIT
if $LENGTH(ID,"^")>1
QUIT
+4 NEW X,NM
SET NM=ID
+5 IF $GET(FILE)
IF $GET(FIELD)
Begin DoDot:1
+6 SET X=$$EXTERNAL^DILFD(FILE,FIELD,,ID)
+7 if X'=""
SET NM=X
End DoDot:1
+8 SET ID=ID_U_NM
+9 QUIT
+10 ;
CODE(IEN,FILE,CSYS,CDT) ; -- find CSYS code for IEN in FILE
+1 ; CSYS can be string of abbreviations to look for, in order
+2 NEW FLD,VPRC,SFN,S,SYS,NAMES,IENS,SFN1,I,X,Y
+3 SET Y=""
SET CDT=$GET(CDT)
if CDT<1
SET CDT=DT
+4 SET FLD=$$FLDNUM^DILFD(FILE,"CODING SYSTEM")
if 'FLD
QUIT ""
+5 DO GETS^DIQ(FILE,IEN_",",FLD_"*","NR","VPRC")
+6 ;Sub-file# = Coding System multiple
SET SFN=+$ORDER(VPRC(0))
if 'SFN
QUIT ""
+7 FOR S=1:1
SET SYS=$PIECE(CSYS,U,S)
if SYS=""
QUIT
Begin DoDot:1
+8 SET NAMES=$SELECT(SYS="RXN":"RxNorm^RXNORM",SYS="NDF":"NDF-RT^NDFRT^NDF",SYS="SCT":"SNOMED CT^SNOMED-CT^SCT",SYS="LNC":"LOINC^LNC",SYS="UNI":"UNII^UNI",1:SYS)
+9 SET IENS=""
FOR
SET IENS=$ORDER(VPRC(SFN,IENS))
if IENS=""
QUIT
Begin DoDot:2
+10 SET X=$GET(VPRC(SFN,IENS,"CODING SYSTEM"))
if X=""
QUIT
if NAMES'[X
QUIT
+11 SET SFN1=$ORDER(VPRC(SFN))
SET I=$ORDER(VPRC(SFN1,""))
+12 ;first code for system
if I
SET Y=$GET(VPRC(SFN1,I,"CODE"))
End DoDot:2
if $LENGTH(Y)
QUIT
+13 IF $LENGTH(Y)
SET Y=Y_U_$$DESC(Y)_U_$PIECE(NAMES,U)
End DoDot:1
if $LENGTH(Y)
QUIT
+14 QUIT Y
+15 ;
DESC(CODE) ; -- called from CODE, to return coding system text
+1 ; Expects all the variables used in CODE()
+2 NEW X,Y,LEX
SET Y=""
+3 IF SYS="SCT"
Begin DoDot:1
+4 SET X=$$CODE^LEXTRAN(CODE,"SCT",CDT)
+5 ;preferred term
if X>0
SET Y=$GET(LEX("P"))
End DoDot:1
+6 IF SYS="RXN"
IF $LENGTH($TEXT(CSDATA^ETSRXN))
Begin DoDot:1
+7 SET X=$$CSDATA^ETSRXN(CODE,"RXN",CDT,.LEX)
+8 if X>0
SET Y=$PIECE($GET(LEX("LEX",1)),U,2)
End DoDot:1
+9 IF SYS="LNC"
IF $LENGTH($TEXT(GETNAME^ETSLNC))
Begin DoDot:1
+10 SET X=$$GETNAME^ETSLNC(CODE,"C",.LEX)
+11 if X>0
SET Y=$GET(LEX("LONGNAME"))
End DoDot:1
+12 IF '$LENGTH($GET(Y))
SET Y=$$GET1^DIQ(FILE,IEN_",",.01)
+13 QUIT Y
+14 ;
NULL(N) ; -- return null string(s) to delete property
+1 NEW I,Y,QOT
SET N=+$GET(N,1)
SET QOT=""""""
+2 SET Y=QOT
IF N>1
FOR I=1:1:(N-1)
SET Y=Y_U_QOT
+3 QUIT Y
+4 ;
CPT(IEN,DATE,LONG) ; -- return code^description^CPT-4 for #81 IEN
+1 NEW X0,VPRX,N,I,X,Y
+2 SET IEN=+$GET(IEN)
SET DATE=$GET(DATE)
if DATE<1
SET DATE=DT
+3 SET X0=$$CPT^ICPTCOD(IEN,DATE)
IF X0<0
QUIT ""
+4 ;CPT Code^Short Name
SET Y=$PIECE(X0,U,2,3)_"^CPT-4"
+5 ;CPT Description instead
IF $GET(LONG)
Begin DoDot:1
+6 SET N=$$CPTD^ICPTCOD($PIECE(Y,U),"VPRX",,DATE)
+7 IF N'>0!'$LENGTH($GET(VPRX(1)))
QUIT
+8 SET X=$GET(VPRX(1))
SET I=1
+9 FOR
SET I=$ORDER(VPRX(I))
if I<1
QUIT
if VPRX(I)=" "
QUIT
SET X=X_" "_VPRX(I)
+10 SET $PIECE(Y,U,2)=X
End DoDot:1
+11 QUIT Y
+12 ;
HLOC(X) ; -- return Hosp Loc #44 ien from location name X
+1 NEW Y
SET Y=0
+2 IF $LENGTH($GET(X))
SET Y=+$ORDER(^SC("B",X,0))
+3 QUIT Y
+4 ;
COUNTY(ST,CTY) ; -- return ien^name for a STate and CounTY
+1 NEW Y
SET Y=""
+2 IF +$GET(ST)
IF +$GET(CTY)
SET Y=$$GET1^DIQ(5.01,(+CTY_","_+ST_","),.01)
+3 if $LENGTH(Y)
SET Y=+CTY_U_Y
+4 QUIT Y
+5 ;
FAC(HLOC) ; -- return facility #4 ien for HospLOC #44 ien
+1 NEW X,Y
SET Y=""
+2 SET HLOC=+$GET(HLOC)
IF HLOC<1
SET Y=$$SITE
GOTO FACQ
+3 SET X=$$GET1^DIQ(44,HLOC,3,"I")
+4 if X<1
SET X=$$GET1^DIQ(44,HLOC,"3.5:.07","I")
+5 SET Y=$$CKFAC(X)
FACQ QUIT Y
+1 ;
CKFAC(IEN) ; -- validate #4 ien, return Parent if no stn#
+1 NEW VPRZ
SET IEN=+$GET(IEN)
+2 IF IEN<1
SET Y=$$SITE
QUIT Y
+3 ;ok
IF $LENGTH($PIECE($GET(^DIC(4,IEN,99)),U))
QUIT IEN
+4 DO PARENT^XUAF4("VPRZ","`"_IEN,2)
SET Y=$ORDER(VPRZ("P",0))
+5 if Y<1
SET Y=$$SITE
+6 QUIT Y
+7 ;
SITE() ; -- return current site#
+1 NEW Y
SET Y=+$$SITE^VASITE
+2 if Y'>0
SET Y=$$KSP^XUPARAM("INST")
+3 QUIT Y
+4 ;
DEL1 ; -- ID Action for Delete entities, returns VPR0=data
+1 NEW SEQ,VST
SET VPR0=""
+2 SET SEQ=+$GET(FILTER("sequence"))
IF SEQ
IF $LENGTH($GET(DIEN))
Begin DoDot:1
+3 ;ok
SET VPR0=$GET(^XTMP("VPR-"_SEQ,DIEN,0))
if $LENGTH(VPR0)
QUIT
+4 ; else get visit# from header node
+5 SET VST=$PIECE($GET(^XTMP("VPR-"_SEQ,DIEN)),U,5)
if VST
SET VPR0="^^"_VST
End DoDot:1
+6 QUIT
+7 ;
NOQ ; -- no query
+1 QUIT