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

KMPVCBG.m

Go to the documentation of this file.
KMPVCBG ;SP/JML VSM background utility functions ;6/1/2020
 ;;4.0;CAPACITY MANAGEMENT;**1**;3/1/2018;Build 27
 ;
 ; Integration Agreements
 ;  Reference to ^XMD supported by ICR #10070
 ;  Reference to $$SITE^VASITE supported by ICR #10112
 ;
MONLIST(KMPVML) ; Return list of configured Monitors
 K KMPVML
 N KMPVIEN,KMPVMKEY,KMPVNAME
 S KMPVMKEY=""
 F  S KMPVMKEY=$O(^KMPV(8969,"B",KMPVMKEY)) Q:KMPVMKEY=""  D
 .S KMPVIEN=$O(^KMPV(8969,"B",KMPVMKEY,""))
 .I KMPVIEN>0 D
 ..S KMPVNAME=$$GETVAL^KMPVCCFG(KMPVMKEY,"FULL NAME",8969)
 ..S KMPVML(KMPVMKEY)=KMPVNAME
 Q
 ;
STARTALL ; start all monitors - DON'T MOVE FROM THIS ROUTINE, CALLED BY ZSTU
 N KMPMKEY
 S KMPMKEY=""
 F  S KMPMKEY=$O(^KMPV(8969,"B",KMPMKEY)) Q:KMPMKEY=""  D
 .D STARTMON(KMPMKEY,1,1)
 I $$GETVAL^KMPVCCFG("VTCM","VERSION",8969)>2 D CFGMSG^KMPUTLW()
 E  D CFGMSG()
 Q
 ;
STOPALL ; stop all monitors
 N KMPMKEY
 S KMPMKEY=""
 F  S KMPMKEY=$O(^KMPV(8969,"B",KMPMKEY)) Q:KMPMKEY=""  D
 .D STOPMON(KMPMKEY,1,1)
 I $$GETVAL^KMPVCCFG("VTCM","VERSION",8969)>2 D CFGMSG^KMPUTLW()
 E  D CFGMSG()
 Q
 ;
ALLOW(KMPVMKEY) ;
 N KMPCALLOW,KMPNALLOW,DIR,Y
 S KMPCALLOW=$$GETVAL^KMPVCCFG(KMPVMKEY,"ALLOW TEST SYSTEM",8969)
 S KMPNALLOW=$S(KMPCALLOW="NO":"YES",1:"NO")
 K DIR S DIR(0)="Y",DIR("B")="No"
 S DIR("?")="Answer YES to set ALLOW TEST to "_KMPNALLOW_" for "_KMPVMKEY
 S DIR("A")="Do you want to set ALLOW TEST to "_KMPNALLOW_" for "_KMPVMKEY
 D ^DIR
 I $G(Y)=1 D
 .D SETONE^KMPVCCFG(KMPVMKEY,"ALLOW TEST SYSTEM",KMPNALLOW,.KMPVERR)
 Q
 ;
STARTMON(KMPVMKEY,KMPVAUTO,KMPNOCFG) ; Schedule transmission task in TaskMan and set ONOFF to ON
 N DA,DIE,DIR,DR,DTOUT,DUOUT,X,Y
 N KMPROUT,KMPRT,KMPRUN,KMPVEARR,KMPVERROR,KMPVRFREQ,KMPVOPT,KMPVSTAT,KMPVSTRT
 ;
 S KMPVAUTO=+$G(KMPVAUTO)
 S KMPNOCFG=+$G(KMPNOCFG)
 ; do not start/stop VETCM if not realtime version - there is no legacy version
 I KMPVMKEY="VETM",$$GETVAL^KMPVCCFG(KMPVMKEY,"VERSION",8969)<3 Q
 ; Do not start monitor in test if ALLOW TEST SYSTEM is set to NO
 I $$PROD^KMPVCCFG()="Test",$$GETVAL^KMPVCCFG(KMPVMKEY,"ALLOW TEST SYSTEM",8969)="NO" D  Q
 .Q:KMPVAUTO=1
 .N DIR S DIR(0)="E"
 .S DIR("A",1)="",DIR("A",2)="Cannot start monitor in test environment"
 .S DIR("A",3)="'ALLOW TEST SYSTEM' is set to 'NO'",DIR("A")="Press any key to continue"
 .D ^DIR
 I 'KMPVAUTO D  D ^DIR Q:$D(DTOUT)!$D(DUOUT)
 .W ! K DIR S DIR(0)="Y",DIR("B")="No"
 .S DIR("?")="Answer YES to start collecting "_KMPVMKEY_" data"
 .S DIR("A")="Do you want to start "_KMPVMKEY_" collection?"
 I ($G(Y)=1)!KMPVAUTO D
 .N KMPVOPT,KMPVSTRT,KMPVRFREQ,KMPVERROR,KMPVSTAT
 .S KMPVOPT=$$GETVAL^KMPVCCFG(KMPVMKEY,"TASKMAN OPTION",8969)
 .S KMPVSTRT=$$GETVAL^KMPVCCFG(KMPVMKEY,"TASKMAN SCHEDULE START",8969)
 .S KMPVRFREQ=$$GETVAL^KMPVCCFG(KMPVMKEY,"TASKMAN SCHEDULE FREQUENCY",8969)
 .I KMPVSTRT=""!(KMPVRFREQ="") D  Q
 ..Q:KMPVAUTO=1
 ..N DIR S DIR(0)="E"
 ..S DIR("A",1)="",DIR("A",2)="This is not configured correctly to be a repeating task."
 ..S DIR("A",3)="Check VSM Configuration related to this task. Task not started."
 ..S DIR("A")="Press any key to continue."
 ..D ^DIR
 .;
 .S KMPVSTAT=$$SETONE^KMPVCCFG(KMPVMKEY,"ONOFF","ON",.KMPVEARR)
 .I KMPVSTAT=0 D
 ..I KMPVMKEY="VBEM" S DIE=8989.3,DA=1,DR="300///YES" D ^DIE
 ..I KMPVMKEY="VCSM" S ^KMPTMP("KMPD-CPRS")=1
 .; schedule background job 
 .D RESCH^XUTMOPT(KMPVOPT,KMPVSTRT,,KMPVRFREQ,"L",.KMPVERROR)
 .I $G(KMPVERROR)=-1 D  Q
 ..S KMPVSTAT=$$SETONE^KMPVCCFG(KMPVMKEY,"ONOFF","OFF",.KMPVEARR)
 ..Q:KMPVAUTO=1
 ..N DIR S DIR(0)="E"
 ..S DIR("A",1)="",DIR("A",2)="ERROR: "_KMPVMKEY_" BACKGROUND TASK NOT STARTED!",DIR("A")="Press any key to continue."
 ..I KMPVSTAT>0 S DIR("A",3)="Failed to set 'ONOFF' field back to 'OFF'"
 ..D ^DIR
 .I KMPNOCFG'=1 D
 ..I $$GETVAL^KMPVCCFG("VTCM","VERSION",8969)>2 D CFGMSG^KMPUTLW()
 ..E  D CFGMSG()
 Q
 ;
STOPMON(KMPVMKEY,KMPVAUTO,KMPNOCFG) ;   Un-schedule transmission task in TaskMan and set ONOFF to OFF
 N DA,DIE,DIR,DR,DTOUT,DUOUT,X,Y
 N KMPVEARR,KMPVERROR,KMPVOPT,KMPVSTAT
 ;
 S KMPVAUTO=+$G(KMPVAUTO)
 S KMPNOCFG=+$G(KMPNOCFG)
 ; do not start/stop VETCM if not realtime version - there is no legacy version
 I KMPVMKEY="VETM",$$GETVAL^KMPVCCFG(KMPVMKEY,"VERSION",8969)<3 Q
 S KMPVOPT=$$GETVAL^KMPVCCFG(KMPVMKEY,"TASKMAN OPTION",8969)
 I 'KMPVAUTO D  D ^DIR Q:$D(DTOUT)!$D(DUOUT)
 .W ! K DIR S DIR(0)="Y",DIR("B")="No"
 .S DIR("?")="Answer YES to stop collecting "_KMPVMKEY_" data"
 .S DIR("A")="Do you want to stop "_KMPVMKEY_" collection?"
 I ($G(Y)=1)!KMPVAUTO D
 .S KMPVSTAT=$$SETONE^KMPVCCFG(KMPVMKEY,"ONOFF","OFF",.KMPVEARR)
 .I KMPVSTAT=0 D
 ..I KMPVMKEY="VBEM" S DIE=8989.3,DA=1,DR="300///NO" D ^DIE
 ..I KMPVMKEY="VTCM" K ^KMPTMP("KMPV","VTCM","TEMP")
 ..I KMPVMKEY="VCSM" D
 ...S ^KMPTMP("KMPD-CPRS")=""
 .; unschedule background job
 .D RESCH^XUTMOPT(KMPVOPT,"@",,,.KMPVERROR)
 .I $G(KMPVERROR) D  Q
 ..Q:KMPVAUTO=1
 ..N DIR S DIR(0)="E"
 ..S DIR("A",1)="",DIR("A",2)="ERROR: "_KMPVMKEY_" BACKGROUND TASK NOT REMOVED!",DIR("A")="Press any key to continue."
 ..S DIR("A",3)=$G(KMPVERROR)
 ..D ^DIR
 .D STOPJOB(KMPVMKEY)
 I KMPNOCFG'=1 D
 .I $$GETVAL^KMPVCCFG("VTCM","VERSION",8969)>2 D CFGMSG^KMPUTLW()
 .E  D CFGMSG()
 Q
 ;
STOPJOB(KMPVMKEY) ;
 N KMPJOB,KMPPID,KMPRNS,KMPROUT,KMPRS,KMPTNS
 Q:"%All%Manager"'[$ROLES
 S KMPROUT=$$GETVAL^KMPVCCFG(KMPVMKEY,"CACHE DAILY TASK",8969)
 S KMPRS=##class(%ResultSet).%New("%SYS.ProcessQuery:SS")
 D KMPRS.Execute(1)
 F  Q:'KMPRS.Next()  I KMPRS.Routine=KMPROUT S KMPPID=KMPRS.Process D
 .S KMPRNS=$NAMESPACE,$NAMESPACE="%SYS"
 .S KMPJOB=##class(SYS.Process).%OpenId(KMPPID)
 .Q:KMPJOB=""
 .D KMPJOB.Terminate()
 .D KMPJOB.%Close()
 .H 5
 .K KMPJOB
 .S $NAMESPACE=KMPRNS
 Q
 ;
DUPEJOB(KMPMKEY) ;
 N KMPPIDS,KMPROUT,KMPRS,KMPTEXT
 S KMPROUT=$$GETVAL^KMPVCCFG(KMPMKEY,"CACHE DAILY TASK",8969)
 S KMPPIDS=0
 S KMPRS=##class(%ResultSet).%New("%SYS.ProcessQuery:SS")
 D KMPRS.Execute(1)
 F  Q:'KMPRS.Next()  I KMPRS.Routine=KMPROUT S KMPPIDS(KMPRS.Process)="",KMPPIDS=KMPPIDS+1
 I KMPPIDS>1 D
 .D STOPMON^KMPVCBG(KMPMKEY,1)
 .D STARTMON^KMPVCBG(KMPMKEY,1)
 .S KMPVTEXT("SUBJECT")="VSM ALERT: Duplicate Jobs"
 .S KMPVTEXT(1)="Duplicate jobs running for "_KMPMKEY
 .S KMPVTEXT(2)="Jobs terminated and monitor restarted"
 .D INFOMSG^KMPUTLW(.KMPVTEXT)
 Q
 ;
RESCH(KMPVMKEY,KMPVERR) ; Reschedule transmission task in TaskMan
 K KMPVERR
 N KMPVERROR,KMPVOPT,KMPVRFREQ,KMPVSTRT
 S KMPVOPT=$$GETVAL^KMPVCCFG(KMPVMKEY,"TASKMAN OPTION",8969)
 S KMPVSTRT=$$GETVAL^KMPVCCFG(KMPVMKEY,"TASKMAN SCHEDULE START",8969)
 S KMPVRFREQ=$$GETVAL^KMPVCCFG(KMPVMKEY,"TASKMAN SCHEDULE FREQUENCY",8969)
 D RESCH^XUTMOPT(KMPVOPT,KMPVSTRT,,KMPVRFREQ,"L",.KMPVERROR)
 I $D(KMPVERROR) D
 .S KMPVERR(1)="Failed to add "_KMPVOPT_" to 'OPTION SCHEDULING' file"
 .S KMPVERR(2)=KMPVERROR
 .S KMPVSTAT=$$SETONE^KMPVCCFG(KMPVMKEY,"ONOFF","OFF",.KMPVEARR)
 .I KMPVSTAT'=0 S KMPVERR(3)=$P(KMPVSTAT,"^",2),KMPVERR(4)="Failed to reset 'ONOFF' to 'OFF' after rescheduling failure."
 Q
 ;
DESCH(KMPVMKEY,KMPVERR) ; De-schedule transmission task in TaskMan
 N KMPVERROR,KMPVOPT
 S KMPVOPT=$$GETVAL^KMPVCCFG(KMPVMKEY,"TASKMAN OPTION",8969)
 D RESCH^XUTMOPT(KMPVOPT,"@",,,.KMPVERROR)
 I $D(KMPVERROR) D
 .S KMPVERR(1)="Failed to remove "_KMPVOPT_" from 'OPTION SCHEDULING' file"
 .S KMPVERR(2)=KMPVERROR
 Q
 ;
PURGEDLY(KMPVMKEY) ; Purge any data older than VSM CONFIURATION file specifies
 N KMPDDAT1,KMPDID,KMPDSUB,KMPI,KMPID,KMPSINF,KMPTEXT,KMPVCURH,KMPVDAY,KMPVH,KMPVKEEP,KMPVNODE
 S KMPVH="",KMPVCURH=+$H,KMPVKEEP=$$GETVAL^KMPVCCFG(KMPVMKEY,"DAYS TO KEEP DATA",8969)
 D GETENV^%ZOSV S KMPVNODE=$P(Y,U,3)_":"_$P($P(Y,U,4),":",2)
 Q:$$ISBENODE^KMPVCCFG(KMPVNODE)=0
 S KMPSINF=$$SITEINFO^KMPVCCFG(),KMPI=2
 ; always kill the TRANSMIT node
 K ^KMPTMP("KMPV",KMPVMKEY,"TRANSMIT")
 ; kill daily
 F  S KMPVH=$O(^KMPTMP("KMPV",KMPVMKEY,"DLY",KMPVH)) Q:KMPVH=""  D
 .I (KMPVCURH-KMPVH)>KMPVKEEP D
 ..K ^KMPTMP("KMPV",KMPVMKEY,"DLY",KMPVH)
 ..S KMPTEXT(KMPI)=KMPVMKEY_" DLY node for "_$ZD(KMPVH),KMPI=KMPI+1
 ; kill retry
 F  S KMPVH=$O(^KMPTMP("KMPV",KMPVMKEY,"RETRY",KMPVH)) Q:KMPVH=""  D
 .I (KMPVCURH-KMPVH)>KMPVKEEP D
 ..K ^KMPTMP("KMPV",KMPVMKEY,"RETRY",KMPVH)
 ..S KMPTEXT(KMPI)=KMPVMKEY_" RETRY node for "_$ZD(KMPVH),KMPI=KMPI+1
 ; kill COMPRESS node for VBEM 
 I KMPVMKEY="VBEM" D
 .S KMPVH=""
 .F  S KMPVH=$O(^KMPTMP("KMPV",KMPVMKEY,"COMPRESS",KMPVH)) Q:KMPVH=""  D
 ..I (KMPVCURH-KMPVH)>KMPVKEEP D
 ...K ^KMPTMP("KMPV",KMPVMKEY,"COMPRESS",KMPVH)
 ...S KMPTEXT(KMPI)=KMPVMKEY_" COMPRESS node for "_$ZD(KMPVH),KMPI=KMPI+1
 ; check for old VCSM data
 I KMPVMKEY="VCSM" D
 .S KMPDSUB=""
 .F  S KMPDSUB=$O(^KMPTMP("KMPDT",KMPDSUB)) Q:KMPDSUB=""  D
 ..S KMPDID=""
 ..F  S KMPDID=$O(^KMPTMP("KMPDT",KMPDSUB,KMPDID)) Q:KMPDID=""  D
 ...S KMPDDAT1=$G(^KMPTMP("KMPDT",KMPDSUB,KMPDID))
 ...S KMPVDAY=$P($P(KMPDDAT1,U),",",1)
 ...I (KMPVCURH-KMPVDAY)>KMPVKEEP D
 ....K ^KMPTMP("KMPDT",KMPDSUB,KMPDID)
 ....S KMPTEXT(KMPI)=KMPVMKEY_" Coversheet data"
 I $D(KMPTEXT) D
 .S KMPTEXT("SUBJECT")="VSM ALERT: Data deletion at "_$P(KMPSINF,"^")
 .S KMPTEXT(1)="Purging data older than DAYS TO KEEP DATA"
 .D INFOMSG^KMPUTLW(.KMPTEXT)
 Q
 ;
KMPVTSK(KMPVNSP) ; CHECK CREATE OR RESUME KMPVRUN TASK IN CACHE TASKMGR
 D TASK^KMPTASK($G(KMPVNSP))
 Q
 ;
ROUTCHK(KMPROUT) ; Check to see if routine is running
 N KMPRS,KMPRUN
 S KMPRUN=0
 S KMPRS=##class(%ResultSet).%New("%SYS.ProcessQuery:SS")
 D KMPRS.Execute(1)
 F  Q:'KMPRS.Next()!(KMPRUN=1)  I KMPRS.Routine=KMPROUT S KMPRUN=1
 Q KMPRUN
 ;
CANMESS(MTYPE,KMPVMKEY,KMPVSITE,KMPVD) ; Repeatable, configured informational mail messages --- legacy
 N KMPVEMAIL,KMPVTEXT,XMSUB,XMY
 I MTYPE="JOBLATE" D
 .S KMPVTEXT($J,1)="Daily "_KMPVMKEY_" job behind for "_$P(KMPVSITE,"^",2)
 .S KMPVTEXT($J,2)="Number of days behind: "_KMPVD
 .S KMPVTEXT($J,3)="Message date: "_$ZD(+$H)
 .S XMSUB=KMPVMKEY_" DAILY JOB NOT RUN: "_$P(KMPVSITE,"^",2)_" Production="_$$PROD^KMPVCCFG
 I MTYPE="DELETE" D
 .S KMPVTEXT($J,1)="Purging "_KMPVMKEY_" data for "_$P(KMPVSITE,"^",2)
 .S KMPVTEXT($J,2)="Data purged for: "_KMPVD
 .S KMPVTEXT($J,3)="Message date: "_$ZD(+$H)
 .S XMSUB=KMPVMKEY_" PURGING DATA -- NOT TRANSMITTED: "_$P(KMPVSITE,"^",2)_" Production="_$$PROD^KMPVCCFG
 I MTYPE="TRANWARN" D
 .S KMPVTEXT($J,1)="Data transmissions of "_KMPVMKEY_" data late for "_$P(KMPVSITE,"^",2)
 .S KMPVTEXT($J,2)="Message date: "_$ZD(+$H)
 .S XMSUB=KMPVMKEY_" Late Transmission Warning: "_$P(KMPVSITE,"^",2)_" Production="_$$PROD^KMPVCCFG
 I MTYPE="FAILTRAN" D
 .S KMPVTEXT($J,1)="Failed transmission for "_$P(KMPVSITE,"^",2)
 .S KMPVTEXT($J,2)="Collection date: "_KMPVD
 .S KMPVTEXT($J,3)="Message date: "_$ZD(+$H)
 .S XMSUB=KMPVMKEY_" FAILED "_KMPVMKEY_" TRANSMISSION: "_$P(KMPVSITE,"^",2)_" "_KMPVD_" Production="_$$PROD^KMPVCCFG
 I MTYPE="KILL" D
 .S KMPVTEXT($J,1)="All data deleted at "_$P(KMPVSITE,"^",2)_" for "_KMPVMKEY
 .S KMPVTEXT($J,2)="Username: "_$$USERNAME^KMPVCCFG(DUZ)
 .S KMPVTEXT($J,3)="Message date: "_$ZD(+$H)
 .S XMSUB="EMERGENCY DATA DELETION AT "_$P(KMPVSITE,"^",2)_" "_KMPVMKEY_" Production="_$$PROD^KMPVCCFG
 Q:$D(XMSUB)=""
 S XMTEXT="KMPVTEXT("_$J_","
 S KMPVEMAIL=$$GETVAL^KMPVCCFG(KMPVMKEY,"NATIONAL SUPPORT EMAIL ADDRESS",8969) I KMPVEMAIL'="" S XMY(KMPVEMAIL)=""
 S KMPVEMAIL=$$GETVAL^KMPVCCFG(KMPVMKEY,"LOCAL SUPPORT EMAIL ADDRESS",8969) I KMPVEMAIL'="" S XMY(KMPVEMAIL)=""
 D ^XMD
 Q
 ;
SUPMSG(KMPVTEXT) ; Send email to local/national support mail groups ---- legacy
 N KMPVEMAIL,KMPVPROD,XMSUB,XMTEXT,XMY,XMZ
 S KMPVPROD=$$PROD^KMPVCCFG()
 ;
 S XMSUB=KMPVTEXT_" Prod="_KMPVPROD
 S XMTEXT="KMPVTEXT("
 S KMPVMKEY=""
 F  S KMPVMKEY=$O(^KMPV(8969,"B",KMPVMKEY)) Q:KMPVMKEY=""  D
 .S KMPVEMAIL=$$GETVAL^KMPVCCFG(KMPVMKEY,"LOCAL SUPPORT EMAIL ADDRESS",8969) I KMPVEMAIL'="" S XMY(KMPVEMAIL)=""
 .S KMPVEMAIL=$$GETVAL^KMPVCCFG(KMPVMKEY,"NATIONAL SUPPORT EMAIL ADDRESS",8969) I KMPVEMAIL'="" S XMY(KMPVEMAIL)=""
 D ^XMD
 Q
 ;
DBAMSG(KMPVTEXT) ; Send email to national support mail groups --- legacy
 N KMPVEMAIL,KMPVPROD,XMSUB,XMTEXT,XMY,XMZ
 S KMPVPROD=$$PROD^KMPVCCFG()
 ;
 S XMSUB=KMPVTEXT_" Prod="_KMPVPROD
 S XMTEXT="KMPVTEXT("
 S KMPVMKEY=""
 F  S KMPVMKEY=$O(^KMPV(8969,"B",KMPVMKEY)) Q:KMPVMKEY=""  D
 .S KMPVEMAIL=$$GETVAL^KMPVCCFG(KMPVMKEY,"NATIONAL SUPPORT EMAIL ADDRESS",8969) I KMPVEMAIL'="" S XMY(KMPVEMAIL)=""
 D ^XMD
 Q
 ;
CFGMSG(KMPVRQNAM) ; Send configuration data to update Location Table at National VSM Database --- legacy
 N KMPVDOM,KMPVEMAIL,KMPVLN,KMPVMKEY,KMPVPROD,KMPVSINF,KMPVSITE,KMPVUP,KMPVUPCFG,XMSUB,XMTEXT,XMY,XMZ
 S KMPVPROD=$$PROD^KMPVCCFG()
 ;
 I $G(KMPVRQNAM)="" S KMPVRQNAM=$$USERNAME^KMPVCCFG($G(DUZ))
 S KMPVSITE=$$SITE^VASITE ;IA 10112
 S KMPVLN=1
 S KMPVUP="KMP CFG"
 S KMPVDOM=$P($$NETNAME^XMXUTIL(.5),"@",2) ;IA 2734
 S KMPVSINF=$$SITEINFO^KMPVCCFG()
 S KMPVUP(KMPVLN)="SYSTEM ID="_KMPVSINF,KMPVLN=KMPVLN+1
 S KMPVUP(KMPVLN)="UPDATE CONFIG="_+$H_"^"_KMPVRQNAM,KMPVLN=KMPVLN+1
 S KMPVUP(KMPVLN)="SYSTEM CONFIG="_$$SYSCFG^KMPVCCFG(),KMPVLN=KMPVLN+1
 S KMPVMKEY=""
 F  S KMPVMKEY=$O(^KMPV(8969,"B",KMPVMKEY)) Q:KMPVMKEY=""  D
 .S KMPVUP(KMPVLN)="MONITOR CONFIG="_$$CFGSTR^KMPVCCFG(KMPVMKEY),KMPVLN=KMPVLN+1
 S XMSUB=KMPVUP,XMTEXT="KMPVUP("
 S KMPVMKEY=""
 F  S KMPVMKEY=$O(^KMPV(8969,"B",KMPVMKEY)) Q:KMPVMKEY=""  D
 .S KMPVEMAIL=$$GETVAL^KMPVCCFG(KMPVMKEY,"VSM CFG EMAIL ADDRESS",8969) I KMPVEMAIL'="" S XMY(KMPVEMAIL)=""
 D ^XMD
 Q