/*-------------------------------------------------------------------------------------*\ | PROGRAM NAME: scdm_standard_macros.sas | | | |---------------------------------------------------------------------------------------| | PURPOSE: | | The purpose of the program is to store macros used repeatedly in QA programs | |---------------------------------------------------------------------------------------| | PROGRAM INPUT: | | see 00.0_scdm_data_qa_review_master_file.sas | | | | PROGRAM OUTPUT: | | see Workplan PDF | |---------------------------------------------------------------------------------------| | CONTACT: | | Sentinel Coordinating Center | | info@sentinelsystem.org | \*-------------------------------------------------------------------------------------*/ *-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-; * PLEASE DO NOT EDIT BELOW WITHOUT CONTACTING THE SENTINEL OPERATIONS CENTER ; *-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-; /*********************************************************************************/ /* START ==> %isBlank */ /*********************************************************************************/ /* Checks if a macro variable is blank: outputs 1 if blank and 0 if not blank */ /*-------------------------------------------------------------------------------*/ %macro isBlank(param); %sysevalf(%superq(param)=,boolean) %mend isBlank; /*-------------------------------------------------------------------------------*/ /* END ==> %isBlank */ /*-------------------------------------------------------------------------------*/ /*********************************************************************************/ /* START ==> %kill_directory */ /*********************************************************************************/ /* Deletes all existing SAS datasets if {dir}=y in Master program */ /*-------------------------------------------------------------------------------*/ %macro kill_directory (kill_list=); %local k; %do k=1 %to %sysfunc(countw(&kill_list.)); %let dir=%scan(&kill_list.,&k.); %let kill=&&kill_dir_&dir.; %put &kill; %if %lowcase(&kill.)=%str(y) %then %do; proc datasets kill lib=&dir. memtype=data nowarn nolist nodetails; quit; %end; %end; %mend kill_directory; /*-------------------------------------------------------------------------------*/ /* END ==> %kill_directory */ /*-------------------------------------------------------------------------------*/ /*********************************************************************************/ /* START ==> %table_size */ /*********************************************************************************/ /* Used in the L1 module retrieve the File Size of each SCDM table */ /*-------------------------------------------------------------------------------*/ %macro table_size (libin=, dsin=, libout=, dsout=); %local lib ds; %let lib=%upcase(&libin.); %let ds=%upcase(&dsin.); proc sql noprint; create table %bquote(&libout..&dsout.) as select distinct( upcase("&tabid.") )as tabid length=3 , PRXCHANGE('s/\d+$//', 1, trim(upcase(memname))) as memname length 32 , sum(filesize) as filesize , obslen , nvar , sum(npage) as npage , compress , pcompress from dictionary.tables where libname="&lib." and calculated memname = "&ds." group by calculated memname ; quit; %mend table_size; /*********************************************************************************/ /* START ==> %remove_labels */ /*********************************************************************************/ /* Used to delete all variable labels from any dataset */ /*-------------------------------------------------------------------------------*/ %macro remove_labels(lib, ds); proc datasets nolist lib=&lib. memtype=data; modify &ds.; attrib _all_ label=' '; quit; %mend remove_labels; /*-------------------------------------------------------------------------------*/ /* END ==> %remove_labels */ /*-------------------------------------------------------------------------------*/ /*********************************************************************************/ /* START ==> %redirect_libs */ /*********************************************************************************/ /* Redirect subdirectory macro variables and libraries back to specified root */ /* folder */ /*-------------------------------------------------------------------------------*/ %macro redirect_libs(root); /* Define request specific subdirectories */ %let DPLOCAL=&root./dplocal/ ; %let MSOC= &root./msoc/ ; %let INFOLDER= &root./inputfiles/; %let SASPROGRAMS= &root./sasprograms/ ; /* Assign libnames */ %soc_lib(DPLOCAL,&DPLOCAL) %soc_lib(MSOC,&MSOC) %soc_lib(INFOLDER,&INFOLDER, options=%str(access=readonly)) %mend redirect_libs; /*-------------------------------------------------------------------------------*/ /* END ==> %redirect_libs */ /*-------------------------------------------------------------------------------*/ /*********************************************************************************/ /* START ==> %dircopy */ /*********************************************************************************/ /* Copy all files from one directory to another */ /* */ /* Code to read directories recursively (outputting dirs_found and files_found */ /* datasets) pulled from https://www.lexjansen.com/wuss/2012/55.pdf */ /*-------------------------------------------------------------------------------*/ %macro dircopy (indir=,outdir=); /* Obtain list of all directories within &indir, and list of files within each directory */ data dirs_found (compress=no); length Root $256.; root="&indir."; output; run; data dirs_found files_found (compress=no); keep Path FileName; length fref $8 Filename $256; /* Read the name of a directory to search. */ modify dirs_found; /* Make a copy of the name, because we might reset root. */ Path = root; rc = filename(fref, path); if rc = 0 then do; did = dopen(fref); rc = filename(fref); end; else do; length msg $200.; msg = sysmsg(); putlog msg=; did = .; end; if did <= 0 then do; putlog 'ERR' 'OR: Unable to open ' Path=; return; end; dnum = dnum(did); do i = 1 to dnum; filename = dread(did, i); fid = mopen(did, filename); if fid > 0 then do; output files_found; end; else do; /* A directory name was found; calculate the complete */ /* path, and add it to the dirs_found data set, */ /* where it will be read in the next iteration of this */ /* data step. */ root = catt(path, "/", filename); output dirs_found; end; end; rc = dclose(did); run; /* Obtain list of output directories to copy files to */ data dirs_all; set dirs_found; outpath=tranwrd(root,"&indir","&outdir"); run; /* Create output directory folders if they don't exist */ options dlcreatedir; data _null_; set dirs_all; call execute("libname folder " ||'"'||trim(outpath)||'";'); run; options nodlcreatedir; /* Create macro variable list for each directory and output directory */ proc sql noprint; select root, count(root), outpath into :dirlist separated by '*', :dircnt, :outlist separated by '*' from dirs_all ; quit; %do i=1 %to &dircnt; %let dir=%scan(&dirlist.,&i.,'*'); %let copydir=%scan(&outlist.,&i.,'*'); /* Obtain list of files in directory to copy */ proc sql noprint; select filename, count(filename) into :flist separated by '*', :fcnt from files_found where path="&dir." ; quit; %do j=1 %to &fcnt; %let file=%scan(&flist.,&j.,'*'); filename source "&dir./&file" recfm=n; filename dest "©dir./&file" recfm=n; data _null_; length msg $500.; rc=fcopy('source', 'dest'); if rc=0 then put "Copied source file &dir./&file to destination ©dir."; else do; msg=sysmsg(); put rc= msg=; end; run; %end; %end; %mend dircopy; /*-------------------------------------------------------------------------------*/ /* END ==> %dircopy */ /*-------------------------------------------------------------------------------*/ /*********************************************************************************/ /* START ==> %set_ds */ /*********************************************************************************/ /* Used in all table modules to combine datasets based on the specified prefix */ /*-------------------------------------------------------------------------------*/ %macro set_ds (libin=, dsin_prefix=, libout=, dsout=); %let libin=%upcase(&libin.); %let dsin_pre=%upcase(&dsin_prefix.); proc sql noprint; select count(memname) into :exist trimmed from dictionary.members where libname="&libin." and memtype='DATA' and memname contains "&dsin_pre."; quit; %if &exist. > 0 %then %do; data &libout..&dsout.; set &libin..&dsin_prefix.:; format coun: comma15.; run; proc datasets lib=&libin. nowarn nolist nodetails; delete &dsin_prefix.:; quit; %end; %mend; /*-------------------------------------------------------------------------------*/ /* END ==> %set_ds */ /*-------------------------------------------------------------------------------*/ /*********************************************************************************/ /* START ==> %set_ds_varlength */ /*********************************************************************************/ /* Used in all table modules to combine datasets based on the specified prefix */ /* but change column length of variable to the max length of all tables */ /*-------------------------------------------------------------------------------*/ %macro set_ds_varlength (dsin_prefix=, dsout=); %local vlen; %let vlen = 0; proc sql noprint; select max(length) into :vlen from dictionary.columns where libname="DPLOCAL" and memtype='DATA' and memname contains "%upcase(&dsin_prefix.)" and upper(name)='VALUE' group by name; quit; %if &vlen ^= 0 %then %do; data dplocal.&dsout. (drop=temp); length Value $&vlen. temp $&vlen.; set dplocal.&dsin_prefix.: (rename=(value=temp)); value=temp; format coun: comma15.; run; proc datasets lib=dplocal nowarn nolist nodetails; delete &dsin_prefix.:; quit; %end; /* End if datasets exists */ %mend; /*-------------------------------------------------------------------------------*/ /* END ==> %set_ds_varlength; */ /*-------------------------------------------------------------------------------*/ /*********************************************************************************/ /* START ==> %get_flagid */ /*********************************************************************************/ /* Used in L2 and table modules to add flagid, etc. to the flags dataset. */ /* ntabs=number of SCDM tables referenced in FlagID (1 or 2) */ /* nvars=number of variables referenced in FlagID (1 or 2) */ /* checkid=CheckID value for flagid */ /* tabid1=tabid or table1 value */ /* tabid2=table2 value */ /* var1=variable1 value */ /* var2=variable2 value */ /* i=row number used to append to dataset name */ /* Note: Currently, this will only work for up to 2 variable checks. */ /*-------------------------------------------------------------------------------*/ %macro get_flagid (ntabs=, nvars=, checkid=, tabid1=, tabid2=, var1=, var2=, i=); %let countvar=; %let temp_nobs=0; data _null_; length dummy 3; if 0 then set flag nobs=flagid_n; /* If there is no count variable, create dummy to prevent array warning */ dummy=1; array numerics {*} _numeric_; do i = 1 to dim(numerics); if index(lowcase(vname(numerics{i})),'count') then call symputx('countvar',vname(numerics{i})); end; call symputx('temp_nobs',flagid_n); stop ; run; /*continue only if there is at least one row in the flags dataset */ %if %eval(&temp_nobs. gt 0) %then %do; /* Join existing temp flags dataset with the flags lkp table to get the following variables: flagid, flag_descr, flagtype, abortyn */ proc sql noprint; create table /* name of new flags dataset will depend on macro variable ntabs */ %if %eval(&ntabs.=1) %then %do; %str(flag_l2_&checkid._&tabid1._&i) %end; %else %if %eval(&ntabs.=2) %then %do; %str(flag_l2_&checkid._&tabid1._&tabid2._&i) %end; as select b.flagid , b.flag_descr , b.flagtype , b.abortyn /* if a 'count' variable already exists in temp dataset, sum the values and rename as 'count' */ %if %length(&countvar.) > 0 %then %do; , sum(a.&countvar.) as count %end; /* else count the rows and create variable 'count' */ %else %do; , count(*) as count %end; from (select *, "&checkid." as checkid from flag) as a /* perform the join based on the number of SCDM tables and variables specified in ntabs and nvars */ /* if the flagid only references one SCDM table (e.g. Tabid=ENR) */ %if %eval(&ntabs.=1) %then %do; , temp_l2_flags(where=(checkid="&checkid." and lowcase(tableid)=lowcase("&tabid1.") %if %eval(&nvars. gt 0) %then %do; and lowcase(variable1)=lowcase("&var1.") %end; %if %eval(&nvars.=2) %then %do; and lowcase(variable2)=lowcase("&var2.") %end; )) as b where a.checkid=b.checkid %end; /* if the flagid references 2 SCDM table (e.g. Tabid=DEM-ENR) */ %else %if %eval(&ntabs.=2) %then %do; left join temp_l2_flags(where=(checkid="&checkid." %if %eval(&nvars. gt 0) %then %do; and lowcase(variable1)=lowcase("&var1.") %end; %if %eval(&nvars.=2) %then %do; and lowcase(variable2)=lowcase("&var2.") %end; )) as b on a.table1=b.table1 and a.table2=b.table2 %end; group by b.flagid,b.flag_descr,b.flagtype,b.abortyn; drop table flag; quit; %end; %else %do; proc datasets lib=work nolist nodetails nowarn; delete flag; quit; %end; %mend get_flagid; /*-------------------------------------------------------------------------------*/ /* END ==> %get_flagid */ /*-------------------------------------------------------------------------------*/ /*********************************************************************************/ /* START ==> %ds_nodupkey - subset of l2_ds_nodupkey */ /*********************************************************************************/ %macro ds_nodupkey; %let keyvarlist=; %let dupct=0 ; %local tabid_exc_lc; %let tabid_exc_lc=%lowcase(%bquote(&tabid_exc)) ; proc sql noprint; select lowcase(variable) into :keyvarlist separated by ' ' from infolder.lkp_all_l1(where=(lowcase(tabid)="&tabid.")) where upcase(keyvar)='K'; quit; %if %length(&keyvarlist) > 0 %then %do; %if %lowcase(&tabid.)=enr %then %do; data _null_; count_obs = &&&tabid._nobs ; call symputx('nobs',put(count_obs,best12.)); run; data _null_; if 0 then set dplocal.l2_distinctkey_enr nobs=flag_nobs; call symputx('distinctnobs',flag_nobs); stop ; run; %let dupct=%eval(&nobs-&distinctnobs); %end; %else %do; %if &do_partitions and not %eval(%lowcase(&tabid.) in &tabid_exc_lc) %then %do ; data t_view / view=t_view ; set qadata.&&&tabid.table.: (keep=&keyvarlist); ;run; proc sort data = t_view nodupkey out=_null_ dupout=_dup_data; by &keyvarlist; run; proc sql noprint; drop view t_view ; ;quit; %end; %else %do ; proc sort data = qadata.&&&tabid.table (keep=&keyvarlist) nodupkey out=_null_ dupout=_dup_data; by &keyvarlist; run; %end ; data _null_; if 0 then set _dup_data nobs=dupnobs; call symputx('dupct', dupnobs); stop ; run; %end; %put **** Number of duplicate rows in the &tabid. table: &dupct.; %end; data dplocal.nobs_dup_&tabid.; length TabID $3 count_Dup 8; tabid=upcase("&tabid."); count_dup=&dupct; format count_dup comma15.; run; %mend ds_nodupkey; /*-------------------------------------------------------------------------------*/ /* END ==> %ds_nodupkey */ /*-------------------------------------------------------------------------------*/ /*********************************************************************************/ /* START ==> %l2_ds_enr_overlap */ /*********************************************************************************/ /* Identify and capture invalid enrollment spans */ /* Create intermediate dataset with valid enrollment spans */ /* /*-------------------------------------------------------------------------------*/ %macro l2_ds_enr_overlap; %if %sysfunc(exist(dplocal.l2_distinctkey_enr)) %then %do; data dplocal.l2_nodup_enr (drop = lag_: dateconflict ) dplocal.enr_overlap_patid_dates ; length dateconflict $ 12; format lag_: mmddyy10.; set dplocal.l2_distinctkey_enr ; by patid; dateconflict=' '; lag_start=lag(enr_start); lag_end=lag(enr_end); %*exclude records with invalid dates from output - identified via check 226 that sources directly from MSCDM table; if enr_end lt enr_start then delete; %* output first record per patid; else if first.patid then do; lag_start=.; lag_end=.; output dplocal.l2_nodup_enr ; end; %* evaluate remaining records to identify invalid spans and separately output from valid records; else do; %* categorize invalid types and output to overlap dataset;; if enr_start le lag_end and enr_end le lag_end then dateconflict="Subset"; /* subset span */ else if (enr_start le lag_end) or (enr_end le lag_end) then dateconflict="Overlap"; /*overlapping span*/ if not missing(dateconflict) then output dplocal.enr_overlap_patid_dates; /* output records with populated date conflict to select dataset */ %* output valid spans separately; else output dplocal.l2_nodup_enr; end; run; %end; %mend l2_ds_enr_overlap; /*-------------------------------------------------------------------------------*/ /* END ==> %l2_ds_enr_overlap */ /*-------------------------------------------------------------------------------*/ /*********************************************************************************/ /* START ==> %flag_201 */ /*********************************************************************************/ %macro flag_201; data _null_; set temp_l2_flags(where=(checkid='201')); if _n_ > 0 then do; i=put(_N_,3. -L); call execute(cat('proc sql noprint; create table flag as select ', quote(strip(table1)), ' as table1, ', quote(strip(table2)),' as table2, sum(count) as count', ' from dplocal.all_l2_',strip(variable1),'_match', ' where ',strip(table1),'="1" and ',strip(table2),'="0" and count>0', ' group by table1, table2; quit;')); call execute(cats('%nrstr(%get_flagid(ntabs=2,nvars=1,checkid=201,tabid1=',strip(table1),',tabid2=',strip(table2),',var1=',strip(variable1),',i=',i,'));')); end; run; %mend flag_201; /*-------------------------------------------------------------------------------*/ /* END ==> %flag_201 */ /*-------------------------------------------------------------------------------*/ /*********************************************************************************/ /* START ==> %flag_203 */ /*********************************************************************************/ %macro flag_203; proc sql noprint; create table tmp as select a.*, b.VarLength2 from (select c.*, d.dp_length as VarLength1 label= ' ' from temp_l2_flags(drop=variable2--variable4 test: data: look: ms: result_type) as c left join dplocal.all_l1_scdm_comp(keep=TabID var dp_length) as d on lower(c.table1)=lower(d.TabID) and lower(c.variable1)=lower(d.var) where c.checkid = '203') as a full join (select c.*, d.dp_length as VarLength2 label= ' ' from temp_l2_flags(drop=variable2--variable4 test: data: look: ms: result_type) as c left join dplocal.all_l1_scdm_comp(keep=TabID var dp_length) as d on lower(c.table2)=lower(d.TabID) and lower(c.variable1)=lower(d.var) where c.checkid = '203') as b on a.flagid=b.flagid; quit; data dplocal.all_l2_crosstab_length_var(keep=table1 table2 variable1 Varlength1 Varlength2 rename=(table1=TabID1 table2=TabID2 variable1=Variable)) flag_l2_203(where=(VarLength1^=Varlength2)); set tmp; count=99999; run; proc sort data = dplocal.all_l2_crosstab_length_var; by Variable TabID1 TabID2; run; proc datasets lib=work nolist nowarn nodetails memtype=data; delete tmp; quit; %mend flag_203; /*-------------------------------------------------------------------------------*/ /* END ==> %flag_203 */ /*-------------------------------------------------------------------------------*/ /********************************************************************************* * START ==> %flag_209 * Description: if varlength for ID variables is consistent across tables, checks * that length of var is not larger than needed capacity * FlagType: Warn / No Abort **********************************************************************************/ %macro flag_209; proc sql noprint; create table flag_l2_209 as select *, 99999 as count from (select a.* , max(b.req_length) as maxReqLength label=' ' , b.dp_length as dpLength label=' ' from temp_l2_flags (keep = Flag: AbortYN Level VarID CheckID Variable1 Table1 where=(checkid="209")) as a left join dplocal.all_l1_scdm_comp (keep=TabID var dp_length req_length) as b on lowcase(a.table1)=lowcase(b.TabID) and lowcase(a.variable1)=lowcase(b.var) group by variable1 ) where dplength > maxReqLength order by variable1, table1; quit; %mend flag_209; /*-------------------------------------------------------------------------------*/ /* END ==> %flag_209 */ /*-------------------------------------------------------------------------------*/ /*********************************************************************************/ /* START ==> %flag_205 */ /*********************************************************************************/ %macro flag_205; %local sql_tabid_exc_lc; %let sql_tabid_exc_lc=%lowcase(%bquote(&sql_tabid_exc)) ; data _null_; set temp_l2_flags(where=(checkid='205')); length firsttable $45 secondtable $45; if _n_ > 0 then do; i=put(_N_,3. -L); if lowcase(table1) = 'dem' and exist("dplocal.patid2bdate") then firsttable='dplocal.patid2bdate'; else do; if &do_partitions and lowcase(table1) not in (&sql_tabid_exc_lc) then do ; call execute(cat('data t_view1 /view=t_view1; set ', strip(cats('qadata.','&',table1,'table.:')) , '(keep=patid ' , strip(variable1),' where=(',strip(variable1),' ne .)) ;' )) ; firsttable='t_view1' ; end ; else do ; firsttable = cats('qadata.','&',table1,'table (keep=patid ' , strip(variable1) ,' where=(',strip(variable1),' ne .)) '); end; end ; if lowcase(table2) = 'enr' and exist("dplocal.l2_nodup_enr") then secondtable='dplocal.l2_nodup_enr'; else do; if &do_partitions and lowcase(table2) not in (&sql_tabid_exc_lc) then do ; call execute(cat('data t_view2 /view=t_view2; set ', strip(cats('qadata.','&',table2,'table.:')) , '(keep=patid ' , strip(variable2),' where=(',strip(variable2),' ne .)) ;' )) ; secondtable='t_view2' ; end ; else do ; secondtable = cats('qadata.','&',table2,'table (keep=patid ' , strip(variable2) ,' where=(',strip(variable2),' ne .)) '); end; end ; call execute(cat('proc sql noprint magic=102; create table flag as select ', quote(strip(variable1)), ' as variable1, ', quote(strip(variable2)),' as variable2, ', quote(strip(table1)),' as table1, ', quote(strip(table2)),' as table2 from ', strip(firsttable), ' as a, ', strip(secondtable), ' as b ', ' where a.patid=b.patid and a.',strip(variable1),' >', ' b.',strip(variable2), ';')); call execute(cats('%nrstr(%get_flagid(ntabs=2,nvars=2,checkid=205,tabid1=',strip(table1),',tabid2=',strip(table2), ',var1=',strip(variable1),',var2=',strip(variable2),',i=',i,'));')); end; run; %mend; /*-------------------------------------------------------------------------------*/ /* END ==> %flag_205 */ /*-------------------------------------------------------------------------------*/ /*********************************************************************************/ /* START ==> %flag_206 */ /*********************************************************************************/ %macro flag_206; %local sql_tabid_exc_lc; %let sql_tabid_exc_lc=%lowcase(%bquote(&sql_tabid_exc)) ; data _null_; set temp_l2_flags(where=(checkid = '206')); length firsttable secondtable jointable $750; if _n_ > 0 then do; i=put(_N_,3. -L); if lowcase(table1) = 'prs' or lowcase(table2) = 'prs' then do; if &do_partitions and lowcase(table1) not in (&sql_tabid_exc_lc) then do ; call execute(cat('data t_view1 /view=t_view1; set qadata.&',table1,'table.:' , '(keep=prm_code surveyID questionID questionVerID ',strip(variable1) , ' where=(',strip(variable1),' ne .) );' )) ; firsttable = 't_view1' ; end; else do; firsttable = cat( strip(cats('qadata.&',table1,'table.A')) , '(keep=prm_code surveyID questionID questionVerID ',strip(variable1) , ' where=(',strip(variable1),' ne .) )' ); end; if &do_partitions and lowcase(table2) not in (&sql_tabid_exc_lc) then do ; call execute(cat('data t_view2 /view=t_view2; set ', strip(cats('qadata.','&',table2,'table.:')) , '(keep=prm_code surveyID questionID questionVerID ',strip(variable2) , ' where=(',strip(variable2),' ne .) );' )) ; secondtable='t_view2'; end; else do; secondtable = cat( strip(cats('qadata.','&',table2,'table.')) , '(keep=prm_code surveyID questionID questionVerID ',strip(variable2) , ' where=(',strip(variable2),' ne .) )' ); end; jointable=cat(strip(firsttable), ' a,', strip(secondtable), ' b ' , " where a.prm_code=b.prm_code and a.surveyID=b.surveyID and a.questionID=b.questionID and a.questionVerID=b.questionVerID and a.",strip(variable1), ' < ', "b.",strip(variable2),';'); end; else do; if &do_partitions and lowcase(table1) not in (&sql_tabid_exc_lc) then do ; call execute(cat('data t_view1 /view=t_view1; set ', strip(cats('qadata.','&',table1,'table.:')) , '(keep=patid ',strip(variable1) , ' where=(',strip(variable1),' ne .) );' )) ; firsttable = 't_view1' ; end; else do; firsttable = cat(strip(cats('qadata.','&',table1,'table.')) , '(keep=patid ',strip(variable1) , ' where=(',strip(variable1),' ne .) )' ); end; if lowcase(table2) = 'enr' and exist("dplocal.l2_nodup_enr") then secondtable='dplocal.l2_nodup_enr'; else do; if &do_partitions and lowcase(table2) not in (&sql_tabid_exc_lc) then do ; call execute(cat('data t_view2 /view=t_view2; set ', strip(cats('qadata.','&',table2,'table.:')) , '(keep=patid ',strip(variable2) , ' where=(',strip(variable2),' ne .) );' )) ; secondtable='t_view2'; end; else do; secondtable = cat( strip(cats('qadata.','&',table2,'table.')) , '(keep=patid ',strip(variable2) , ' where=(',strip(variable2),' ne .) )' ); end; end; jointable=cat(strip(firsttable), ' a, ', strip(secondtable),' b ' , " where a.patid=b.patid and a.",strip(variable1), ' < ',"b.",strip(variable2),";"); end; call execute(cat('proc sql noprint magic=102; create table flag as select ', quote(strip(variable1)), ' as variable1, ', quote(strip(variable2)),' as variable2, ', quote(strip(table1)),' as table1, ', quote(strip(table2)),' as table2 from ', jointable,';')); call execute(cats('%nrstr(%get_flagid(ntabs=2,nvars=2,checkid=206,tabid1=',strip(table1),',tabid2=',strip(table2), ',var1=',strip(variable1),',var2=',strip(variable2),',i=',i,'));')); end; run; %mend; /*-------------------------------------------------------------------------------*/ /* END ==> %flag_206 */ /*-------------------------------------------------------------------------------*/ /*********************************************************************************/ /* START ==> %flag_211 */ /*********************************************************************************/ /* Check 211 - Perform duplicate record by key variables check */ /*-------------------------------------------------------------------------------*/ %macro flag_211; data _null_; set temp_l2_flags(where=(checkid='211')); if _n_ > 0 then do; i=put(_N_,3. -L); call execute(cat('proc sql noprint; create table flag as select b.flagid, b.flag_descr, b.flagtype, b.abortyn, a.count_dup as count from dplocal.all_l2_nobs_dup a inner join temp_l2_flags b on a.TabID=b.tableid where b.checkid="211" and a.TabID=',quote(strip(tableid)),';quit;')); call execute(cat('%nrstr(%get_flagid(ntabs=1,nvars=0,checkid=211,tabid1=',strip(tableid),',i=',i,'));')); end; run; %mend flag_211; /*-------------------------------------------------------------------------------*/ /* END ==> %flag_211 */ /*-------------------------------------------------------------------------------*/ /*********************************************************************************/ /* START ==> %flag_215 */ /*********************************************************************************/ /* Overlapping enrollment spans by PatID, enr_start, enr_end; */ /* includes enrollment spans that are subset of another */ /* Regardless of coverage type (must be 2nd L2 flag macro run) */ /*-------------------------------------------------------------------------------*/ %macro flag_215; proc sql noprint; select dataset into :ds trimmed from temp_l2_flags (where=(checkid="215")) ; quit; /* defensive coding: ensure specified ds from lkp exists prior to running check */ %if %sysfunc(exist(&ds.)) %then %do; proc sql noprint; select count(*) into :recct trimmed from &ds. ; quit; proc sql noprint; create table flag_l2_215 as select flagid , flag_descr , flagtype , abortyn , checkid , &recct as count format=comma15. informat=comma15. from temp_l2_flags (where=(checkid="215")) ; quit; %end; %mend flag_215; /*-------------------------------------------------------------------------------*/ /* END ==> %flag_215 */ /*-------------------------------------------------------------------------------*/ /*********************************************************************************/ /* START ==> %flag_216 */ /*********************************************************************************/ /* Identify non-bridged enrollment spans by non-date key variables */ /*-------------------------------------------------------------------------------*/ %macro flag_216; %if %sysfunc(exist(dplocal.L2_NODUP_ENR)) %then %do; /* Extract variables dynamically for check */ proc sql noprint; select name, cats('lag_',name) into :flag_216_varlist separated by ' ', :flag_216_laglist separated by ' ' from dictionary.columns where LIBNAME = 'DPLOCAL' and MEMNAME = 'L2_NODUP_ENR' and upper(NAME) not in ('DP', 'PATID'); select cats(name,'=prev_',name) into :flag_216_cond separated by ' and ' from dictionary.columns where LIBNAME = 'DPLOCAL' and MEMNAME = 'L2_NODUP_ENR' and upper(NAME) not in ('DP', 'PATID', 'ENR_START', 'ENR_END'); quit; data flag; set dplocal.l2_nodup_enr(where=(not missing(enr_start) and not missing(enr_end))); by patid; retain &flag_216_laglist.; if first.patid then do; %do i = 1 %to %sysfunc(countw(&FLAG_216_VARLIST)); %let enrvar = %scan(&FLAG_216_VARLIST,&i); lag_&enrvar = &enrvar; %end; diff=0; end; else do; %do i = 1 %to %sysfunc(countw(&FLAG_216_VARLIST)); %let enrvar = %scan(&FLAG_216_VARLIST,&i); prev_&enrvar = lag_&enrvar; lag_&enrvar = &enrvar; %end; diff = enr_start - prev_enr_end; end; if diff=1 and &flag_216_cond. then output flag; drop lag_: prev_: diff; run; proc sql noprint; create table flag_l2_216 as select b.flagid , b.flag_descr , b.flagtype , b.abortyn , a.count from (select count(*) as count, "216" as checkid from flag) a, temp_l2_flags (where=(checkid="216")) b where a.checkid=b.checkid ; quit; %end; %mend flag_216; /*-------------------------------------------------------------------------------*/ /* END ==> %flag_216 */ /*-------------------------------------------------------------------------------*/ /*********************************************************************************/ /* START ==> %flag_220 */ /*********************************************************************************/ /* Intra-table LAB check for missing data relationship across 2 variables */ /* LAB Specific: LOINC should not be missing when ms_test_name = UNMAPPED */ /*-------------------------------------------------------------------------------*/ %macro flag_220; data _null_; set temp_l2_flags(where=(checkid='220')); if _n_ > 0 then do; i=put(_N_,3. -L); call execute(cat('data flag; set ',strip(dataset),'(where=(missing(',strip(variable1),') and upcase(',strip(variable2),')="UNMAPPED")); run;')); call execute(cat('%nrstr(%get_flagid(ntabs=1,nvars=2,checkid=220,tabid1=',strip(tableid),',var1=',strip(variable1),',var2=',strip(variable2),',i=',i,'));')); end; run; %mend; /*-------------------------------------------------------------------------------*/ /* END ==> %flag_220 */ /*-------------------------------------------------------------------------------*/ /*********************************************************************************/ /* START ==> %flag_222 */ /*********************************************************************************/ /* Intra-table LAB check for invalid data relationship across 2 variables */ /*-------------------------------------------------------------------------------*/ %macro flag_222; data _null_; set temp_l2_flags(where=(checkid='222')); if _n_ > 0 and exist("infolder.lkp_all_l2") and lookup_table = "lkp_all_l2" then do; i=put(_N_,3. -L); call execute(cat('proc sql noprint; select flagcondition into :where separated by " or " from ', cats('infolder.',strip(lookup_table)), '(where=(lowcase(tabid)=',quote(strip(lowcase(tableid))), ' and lowcase(variable1)=',quote(strip(lowcase(variable1))), ' and lowcase(variable2)=',quote(strip(lowcase(variable2))), ' and lowcase(abortyn)=',quote(strip(lowcase(abortyn))), ' and checkid="222"));')); call execute(cat('%nrstr(data flag; set ', strip(dataset), '(where=(&where) keep= ',variable1, ' ', variable2,');',' run;)')); call execute(cat('%nrstr(%get_flagid(ntabs=1,nvars=2,checkid=222,tabid1=',strip(tableid),',var1=',strip(variable1),',var2=',strip(variable2),',i=',i,'));')); end; run; %mend flag_222; /*********************************************************************************/ /* END ==> %flag_222 */ /*********************************************************************************/ /*********************************************************************************/ /* START ==> %flag_223 */ /*********************************************************************************/ /* Intra-table check for invalid data relationship across 2 variables */ /*-------------------------------------------------------------------------------*/ %macro flag_223; data _null_; set temp_l2_flags(where=(checkid="223")); if _n_ > 0 then do; i=put(_N_,3. -L); if exist(dataset) then do; call execute(cat('proc sql noprint; select flagcondition into :where separated by " or " from ', cats("infolder.",lookup_table), ' where lowcase(tabid)=lowcase(',quote(strip(table1)),')',' and lowcase(variable1)=lowcase(',quote(strip(variable1)),')', ' and lowcase(variable2)=lowcase(',quote(strip(variable2)),')',' and checkID = "223";')); call execute(cat('%nrstr(data flag; set ',strip(dataset),'(where=(&where));',' run;)')); call execute(cat('%nrstr(%get_flagid(ntabs=1,nvars=2,checkid=223,tabid1=',strip(table1),',var1=',strip(variable1),',var2=',strip(variable2),',i=',i,'));')); end; end; run; %mend flag_223; /*-------------------------------------------------------------------------------*/ /* END ==> %flag_223 */ /*-------------------------------------------------------------------------------*/ /*********************************************************************************/ /* START ==> %flag_224 */ /*********************************************************************************/ %macro flag_224(tab=&module.); %put ====> MACRO CALLED: flag_224; %local tabid_exc_lc; %let tabid_exc_lc=%lowcase(%bquote(&tabid_exc)) ; %local qa_table ; %if &do_partitions and not %eval(%lowcase(&tab.) in &tabid_exc_lc) %then %do ; data t_view_224 /view=t_view_224 ; set qadata.&&&&&tab.table.: ; run; %let qa_table = t_view_224 ; %end; %else %do; %let qa_table = qadata.&&&&&tab.table. ; %end; data dplocal.l2_flags_&tab._224; length count 8.; keep Flag: TableID AbortYN Level VarID CheckID Variable1 Variable2 count; set infolder.lkp_all_flags; where TableID = upcase("&tab.") and checkid = "224"; if _N_ > 0 then do; rc = dosubl(cat('proc sql noprint; create table dplocal.flag224_nomatch_', _N_, ' as select patid, ', variable1, ', ', variable2, ' from ', "&qa_table.", ' (keep=Patid ', variable1, ' ', variable2, ') where not missing(', variable2, ') and compare(', variable1, ', ', variable2, ') ne 0; quit;')); length dsin $ 32. dsout $ 32.; dsin = catx("_", "flag224_nomatch", _N_); dsout = catx("_", "&tab.", Variable1, "vars_match"); rc = dosubl('data _null_; if 0 then set dplocal.'||dsin|| ' nobs=n; call symputx("nrows", n); stop; run;'); count = input(symget("nrows"), COMMA15.); if count = 0 then do; rc = dosubl('proc datasets library=dplocal; delete '||dsin||'; run;'); end; else do; rc= dosubl('proc datasets library=dplocal; change '||dsin||'='||dsout||'; run;'); end; end; run; %put ******** NOTE: END OF MACRO flag_224; %mend flag_224; /*********************************************************************************/ /* START ==> %flag_226 */ /*********************************************************************************/ /* Intra-table check for invalid date relationship (var1 gt var2) */ /*-------------------------------------------------------------------------------*/ %macro flag_226; data _null_; set temp_l2_flags(where=(checkid ='226')); if _n_ > 0 then do; i=put(_N_,3. -L); call execute(cat('data flag; set ', cats("qadata.","&",strip(tableid),"table:"), '(keep=',variable1, variable2,' where=(not missing(',strip(variable1),') and not missing(',strip(variable2),') and ',strip(variable1),' gt ',strip(variable2),')); run;')); call execute(cat('%nrstr(%get_flagid(ntabs=1,nvars=2,checkid=226,tabid1=',strip(tableid),',var1=',strip(variable1),',var2=',strip(variable2),',i=',i,'));')); end; run; %mend flag_226; /*-------------------------------------------------------------------------------*/ /* END ==> %flag_226 */ /*-------------------------------------------------------------------------------*/ /*********************************************************************************/ /* START ==> %flag_227 */ /*********************************************************************************/ /* Intra-table check for invalid date relationship (var1 lt var2) */ /*-------------------------------------------------------------------------------*/ %macro flag_227; data _null_; set temp_l2_flags(where=(checkid ='227')); if _n_ > 0 then do; i=put(_N_,3. -L); call execute(cat('data flag; set ', cats("qadata.","&",strip(tableid),"table:"), '(keep=',variable1, variable2,' where=(not missing(',strip(variable1),') and not missing(',strip(variable2),') and ',strip(variable1),' lt ',strip(variable2),')); run;')); call execute(cat('%nrstr(%get_flagid(ntabs=1,nvars=2,checkid=227,tabid1=',strip(tableid),',var1=',strip(variable1),',var2=',strip(variable2),',i=',i,'));')); end; run; %mend flag_227; /*-------------------------------------------------------------------------------*/ /* END ==> %flag_227 */ /*-------------------------------------------------------------------------------*/ /*********************************************************************************/ /* START ==> %flag_228 */ /*********************************************************************************/ /* Intra-table check for invalid data value relationship across 2 variables */ /*-------------------------------------------------------------------------------*/ %macro flag_228; data _null_; set temp_l2_flags(where=(checkid="228")); if _n_ > 0 then do; i=put(_N_,3. -L); if exist(dataset) then do; call execute(cat('proc sql noprint; select flagcondition into :where separated by " or " from ', cats("infolder.",lookup_table), ' where lowcase(tabid)=lowcase(',quote(strip(table1)),')',' and lowcase(variable1)=lowcase(',quote(strip(variable1)),')', ' and lowcase(variable2)=lowcase(',quote(strip(variable2)),')',' and checkID = "228";')); call execute(cat('%nrstr(data flag; set ',strip(dataset),'(where=(&where));',' run;)')); call execute(cat('%nrstr(%get_flagid(ntabs=1,nvars=2,checkid=228,tabid1=',strip(table1),',var1=',strip(variable1),',var2=',strip(variable2),',i=',i,'));')); end; end; run; %mend flag_228; /*-------------------------------------------------------------------------------*/ /* END ==> %flag_228 */ /*-------------------------------------------------------------------------------*/ /*********************************************************************************/ /* START ==> %flag_229 */ /*********************************************************************************/ /* Intra-table check for invalid variable value based on specified date */ /*-------------------------------------------------------------------------------*/ %macro flag_229; data _null_; set temp_l2_flags(where=(checkid="229")); if _n_ > 0 then do; i=put(_N_,3. -L); if exist(dataset) then do; call execute(cat('proc sql noprint; select flagcondition into :where separated by " or " from ', cats("infolder.",lookup_table), ' where lowcase(tabid)=lowcase(',quote(strip(table1)),')',' and lowcase(variable1)=lowcase(',quote(strip(variable1)),')', ' and lowcase(variable2)=lowcase(',quote(strip(variable2)),')',' and checkID = "229";')); call execute(cat('%nrstr(data flag; set ',strip(dataset),'(where=(&where));',' run;)')); call execute(cat('%nrstr(%get_flagid(ntabs=1,nvars=2,checkid=229,tabid1=',strip(table1),',var1=',strip(variable1),',var2=',strip(variable2),',i=',i,'));')); end; end; run; %mend flag_229; /*-------------------------------------------------------------------------------*/ /* END ==> %flag_229 */ /*-------------------------------------------------------------------------------*/ /*********************************************************************************/ /* START ==> %flag_236 */ /*********************************************************************************/ /* Check for 0 CauseType=U records per PatID in COD table */ /*-------------------------------------------------------------------------------*/ %macro flag_236; /*check to see if COD table exists*/ %local qa_table ; %let qa_table = ; %if &do_partitions and %sysfunc(exist(qadata.&CODTABLE.1)) %then %do; data t_view /view=t_view ; set qadata.&CODTABLE: ; run; %let qa_table = t_view ; %end ; %else %if %sysfunc(exist(qadata.&CODTABLE)) %then %do; %let qa_table = qadata.&CODTABLE ; %end ; %if %length(&qa_table) %then %do ; proc sql noprint; select count(distinct patid) into :count_236 trimmed from &qa_table where PatID not in ( select patid from &qa_table where upper(causetype) = "U" ) ; create table flag_l2_236 as select flagid , flag_descr , flagtype , abortyn , &count_236 as count from temp_l2_flags where checkid="236" ; quit; %end; %mend flag_236; /*-------------------------------------------------------------------------------*/ /* END ==> %flag_236 */ /*-------------------------------------------------------------------------------*/ /*********************************************************************************/ /* START ==> %flag_237 */ /*********************************************************************************/ /* Check for >1 CauseType=U record per PatID in COD table */ /*-------------------------------------------------------------------------------*/ %macro flag_237; %local pn qa_table ; %if &do_partitions %then %let pn=1 ; /* use 1st partition as proxy for all partition */ %else %let pn= ; /*check to see COD table exists*/ %if %sysfunc(exist(qadata.&CODTABLE.&pn)) %then %do; %if &do_partitions %then %do ; data t_view /view=t_view ; set qadata.&CODTABLE.: ; ;run; %let qa_table = t_view ; %end ; %else %do ; %let qa_table = qadata.&CODTABLE ; %end ; proc sql noprint; select count(distinct patid) into :count_237 trimmed from &qa_table. where PatID in ( select patid from &qa_table. where upper(causetype) = "U" group by patid having count(*) gt 1 ); create table flag_l2_237 as select flagid , flag_descr , flagtype , abortyn , &count_237 as count from temp_l2_flags where checkid="237" ; quit; %end; %mend flag_237; /*-------------------------------------------------------------------------------*/ /* END ==> %flag_237 */ /*-------------------------------------------------------------------------------*/ /*********************************************************************************/ /* START ==> %flag_244 */ /*********************************************************************************/ /* Used to create dataset to check invalid combinations of variables */ /*-------------------------------------------------------------------------------*/ %macro flag_244; data _null_; set temp_l2_flags(where=(checkid ='244')); if _n_ > 0 then do; i=put(_N_,3. -L); call execute(cat('data temp_244; if 0 then set infolder.',strip(lookup_table),';', 'declare hash existing (hashexp:16, dataset:"infolder.',strip(lookup_table),'");', 'existing.definekey(all:"yes");', 'existing.definedone();', 'do until (done);', 'set ',strip(dataset), ' end=done;', 'if existing.check() ne 0 then output;end;stop;run;')); call execute(cat('proc sql noprint; create table flag_l2_244_',i,' as ', 'select b.flagid, b.flag_descr, b.flagtype, b.abortyn, a.count ', 'from (select sum(count) as count, "244" as checkid from temp_244) as a, temp_l2_flags(where=(checkid="244")) as b ', 'where a.checkid=b.checkid;')); end; run; %mend flag_244; /*********************************************************************************/ /* START ==> %flag_245 */ /*********************************************************************************/ /* Used to create dataset to check invalid combinations of variables meeting */ /* rate threshold */ /*-------------------------------------------------------------------------------*/ %macro flag_245; data _null_; set temp_l2_flags(where=(checkid ='245')); length fmtname $10; if _n_ > 0 then do; i=put(_N_,3. -L); fmtname=upcase(cats(TableID, CheckID, compress(TestID,'-'),'F')); call execute(cat('data ', strip(fmtname),';', 'set ', 'infolder.',strip(lookup_table),'; where FMTNAME = ',quote(strip(fmtname)),';run;')); call execute(cat('proc format cntlin = work.',strip(fmtname),';','quit;')); call execute(cat('data flag_l2_245_',i,';', 'length checkid $3 flagid $21 flagtype $4 abortyn $1 flag_descr $255;', 'set ',strip(dataset),';', 'checkid="245";', 'flagid=',quote(strip(flagid)),';', 'flag_descr=',quote(strip(flag_descr)),';', 'flagtype=',quote(strip(flagtype)),';', 'abortyn=',quote(strip(abortyn)),';', 'if upcase(put(rate,',strip(fmtname),'.)) = "FLAGGED";', 'rename rate=count;keep checkid flagid flag_descr flagtype abortyn rate; run;')); end; run; %mend flag_245; /*********************************************************************************/ /* START ==> %level2 */ /*********************************************************************************/ %macro level2; /* Exclude 230, 231, 232, 234 and 235 because it is called in the lab module separately */ data temp_l2_flags; set infolder.lkp_all_flags(where=(level='2' and abortyn='N' and ^index(tableid,'-') and substr(lowcase(tableid),1,3) = "&module" and substr(lowcase(tableid),5,3) in (' ', "&module") and checkid ^= '209' %if &module = lab %then %do; and checkid not in ('230', '231', '232', '234','235') %end; )); table1=substr(tableid,1,3); table2=substr(tableid,5,3); run; proc sort data = temp_l2_flags nodupkey out=unique_l2_flags; by checkid; run; data _null_; set unique_l2_flags; call execute(cats('%nrstr(%flag_',checkid,';)')); run; data dplocal.l2_flags_&module.; set flag_l2_:; run; proc datasets kill lib=work memtype=data nolist nowarn nodetails; quit; %mend level2; /*-------------------------------------------------------------------------------*/ /* END ==> %level2 */ /*-------------------------------------------------------------------------------*/ /*********************************************************************************/ /* START ==> %date_percentiles */ /*********************************************************************************/ %macro date_percentiles (libin=, dsin=, libout=, dsout=, vars=); proc means nolabels data=&libin..&dsin. (keep=&vars. n) missing vardef=weight StackODSOutput n min p1 P5 P25 median P75 P95 p99 max; var &vars.; weight n; ods output summary=&libout..&dsout.; run; data &libout..&dsout. (drop=var); length TabID $3 Variable $15; set &libout..&dsout. (rename=(variable=var)); TabID=upcase("&module."); variable=lowcase(var); format N best12. min--max yymmdd10.; run; %mend date_percentiles; /*-------------------------------------------------------------------------------*/ /* END ==> %date_percentiles */ /*-------------------------------------------------------------------------------*/ /*********************************************************************************/ /* PROC MEANS that sums numeric variable over a class of variables (NO OUTPUT) */ /*********************************************************************************/ %macro l2_procmeans_sum (libin=,dsin=,libout=,dsout=,keepvars=,vars=,classvars=,names=,numobs=); proc means noprint nway data=&libin..&dsin.(obs=&numobs. keep=&keepvars.) missing; var &vars.; class &classvars.; output out = &libout..&dsout.(drop=_:) &names.; run; %remove_labels(&libout.,&dsout.); %mend l2_procmeans_sum; /*********************************************************************************/ /* START ==> %snapshot_run */ /*********************************************************************************/ /* Defines parameters to bypass scdm_snapshot master file, runs */ /* scdm_snapshot program, and copies output to msoc/scdm_snapshot folder */ /*-------------------------------------------------------------------------------*/ %macro snapshot_run; data _null_; put 75*'-'; put ' '; put "==> Begin Execution of scdm_snapshot program"; put ' '; put 75*'-'; run; /* Note all scdm table name vars are populated in QA master file, but miltable is set to 'NA' */ /* Set miltable macro variable to blank for snapshot run */ %let MILTABLE= ; /* Define indata folder */ %let indata=&QADATA.; %soc_lib(INDATA, &INDATA, options=%str(access=readonly)) /* Redirect libraries to inputfiles/scdm_snapshot folder */ %redirect_libs(&SSroot.) /* Create clean output environment */; %kill_directory(kill_list=dplocal msoc) /* Initialize and execute Snapshot-specific modules */ %inc "&infolder.soc_scdm_snapshot_signature_module.sas" / nosource2; %inc "&infolder.soc_scdm_formats_agecat.sas" / nosource2; %inc "&infolder.macros/ms_macros.sas" / nosource2; %inc "&infolder.macros/ms_delpatients.sas" / nosource2; %inc "&infolder.macros/ms_delencounterids.sas" / nosource2; %inc "&infolder.macros/_mil_linkage_rates.sas" / nosource2; %inc "&infolder.macros/ms_delencounterids.sas" / nosource2; %include "&infolder.macros/compile_macros.sas"; %compile_macros; /* Execute the main Snapshot Program. Note: This program generates its own log */ %inc "&infolder.soc_snapshot_driver.sas" /nosource2; /* Redirect libraries back to QA package request id root folder */ %redirect_libs(&_root.) /* Reset miltable macro variable back to 'NA' */ %let MILTABLE=NA; /* Create msoc/scdm_snapshot directory */ %let MSOC_SS=&_root.msoc/scdm_snapshot; options dlcreatedir; libname MSOC_SS "&MSOC_SS."; options nodlcreatedir; /* Copy over snapshot output to msoc/scdm_snapshot folder */ %dircopy(indir=&INFOLDER.scdm_snapshot/msoc, outdir=&MSOC_SS) %mend snapshot_run; /*-------------------------------------------------------------------------------*/ /* END ==> %snapshot_run */ /*-------------------------------------------------------------------------------*/ /*********************************************************************************/ /* START ==> %cc_run */ /*********************************************************************************/ /* 1. Defines parameters to bypass qa_common_components master file, runs */ /* qa_common_components, and copies output to msoc/qa_common_components */ /* folder */ /* 2. Creates CC request id folder under QA package root directory (based on */ /* QA request id), copies entire CC package to CC request id folder */ /*-------------------------------------------------------------------------------*/ %macro cc_run; proc printto log="&msoc.qa_package.log"; run; data _null_; put 75*'-'; put ' '; put "==> Begin Execution of qa_common_components program"; put ' '; put 75*'-'; run; /* Create library for CC dp_metadata folder */ %soc_lib(QARESULT, &INFOLDER.qa_common_components/inputfiles/dp_metadata) /* Copy over necessary QA Package metadata datasets to CC dp_metadata folder */ proc copy in=msoc out=qaresult memtype=data; select all_l1_cont etl_version minmax_dates qa_cc_metadata; run; /* Redirect libraries to inputfiles/qa_common_components folder */ %redirect_libs(&CCroot.) /* Redefine infolder library to include cc_test folder */ %soc_lib(INFOLDER, &INFOLDER. &INFOLDER.cc_test, options=%str(access=readonly)) /* Execute the main Common Components file */ %inc "&infolder.01.0_run_cc.sas" /nosource2; data _null_; put 75*'-'; put ' '; put "==> Begin Execution of qa_common_components post processing"; put ' '; put 75*'-'; run; /* _ROOT macro variable is assigned in CC program, reassign back to QA package request id root folder */ %let _ROOT=%soc_clean_paths(&QApackage_root); %let _ROOT=&_root.&reqid./; /* Redirect libraries back to QA package request id root folder */ %redirect_libs(&_root.) proc printto log="&msoc.qa_package.log"; run; /* Create msoc/qa_common_components directory */ %let MSOC_CC=&_root.msoc/qa_common_components; options dlcreatedir; libname MSOC_CC "&MSOC_CC."; options nodlcreatedir; /* Copy over CC output to msoc/qa_common_components folder */ %dircopy(indir=&INFOLDER.qa_common_components/msoc, outdir=&MSOC_CC) /* Create CC request id */ %if %lowcase(&wptype.) = qmr %then %do; %let cc_wptype = ccb; %end; %else %do; %let cc_wptype = cca; %end; %let CCreqid=&ProjID._&cc_wptype._&wpid._&dpid._&verid.; /* Create CC request id folder */ %let CCdir=&_ROOT.&CCreqid.; options dlcreatedir; libname CCdir "&CCdir."; options nodlcreatedir; /* Copy over entire completed CC package from inputfiles folder to CC request id folder */ %dircopy(indir=&INFOLDER.qa_common_components, outdir=&CCdir) %mend cc_run; /*-------------------------------------------------------------------------------*/ /* END ==> %cc_run */ /*-------------------------------------------------------------------------------*/ *-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-; * End scdm_standard_macros.sas ; *-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-;