*** SELUNBOX PROGRAM Version 1.03: (SELUNBOX.SAS) ***; *** CREATED BY: Edward Cary Bean, Jr. ***; *** U.S. Bureau of Census, Office of the Director ***; *** DATE: July 25, 1990 ***; *** REVISED: Oct. 12, 1990 ***; *** REVISED: Oct. 14, 1997 ***; *** PURPOSE: Converts a "BOXED" ASCII text file into ***; *** a SAS Data Set with formats and Format Catalog. ***; *** NOTE: The "BOXED" input to this program is both data and information ***; *** defining the data. It is CRITICAL that this program and ***; *** the ASCII text file it reads not be modified by ***; *** program users. If modifications or corrections are required ***; *** contact the program creator so that the master program ***; *** can be modified or corrected. The key to proper data ***; *** transfer is CONSISTENCY! ***; *** USER INPUT: 1) Directory Location of Source "BOXED" File ***; *** 2) "BOXED" File Name ***; *** 3) Output Data Set Directory Location ***; *** 4) Output Format Catalog Directory Location ***; *** 5) Selection of ALL or Specific Variables to UNBOX ***; *** PGM OUTPUT: 1) A SAS Data Set (fully labeled and formatted) ***; *** 2) A SAS Format Catalog ***; *** REVISION 1 Fixed LRECL problem for PC's & smaller systems ***; *** REVISION 2 Fixed field input location problem for TEXTDEC variable ***; ************************************************************************; ****************************************************************; *** CRITICAL RUN TIME MACRO VARIABLES WHICH MUST BE ADJUSTED ***; *** ======== FOR THIS PROGRAM TO RUN PROPERLY!!!!!!!!!!!!!!! ***; ****************************************************************; %LET SWDIR=SYSWK1$:[E_BEAN.SAS606.BOX]; *** CRITICAL location of software catalog directory ***; *********************************************; *** MACRO VARIABLE INITIALIZATION SECTION ***; *** (NO adjustments required) ***; *********************************************; %LET BOXVERS=1.01;*** The Program Version Variable ***; %LET ANS=; *** Temporary Variable for users answers ***; %LET INPDIR=; *** Input Directory ***; %LET INPBOX=; *** Input Data Set Name ***; %LET INPSPEC=; *** Output File Specification ***; %LET FMTDIR=; *** Output Formats Directory ***; %LET OUTDIR=; *** Output Data Set Directory ***; %LET SELOPT=; *** Select Individual Variables Option ***; ************************************; *** MACRO INITIALIZATION SECTION ***; ************************************; *** Define the Generic Query Window ***; %window Query IROW=2 ROWS=18 #2 @5 ITM PROTECT=YES #4 @5 'QUESTION:' #6 @5 QUEST PROTECT=YES #8 @5 '>> ' #8 @8 ANS 40 #10 @5 'NOTE:' #12 @5 NOTE1 70 PROTECT=YES #13 @5 NOTE2 70 PROTECT=YES #14 @5 NOTE3 70 PROTECT=YES; run; *** Define Macro to run Query Window ***; %MACRO ASK(ARG1,ARG2); %let ANS=; run; *** Clear "ANS" MacroVar ***; %display Query; run; *** Run Query Window ***; %let TMPSTR=%QUOTE(&ARG1&ARG2); %GLOBAL &TMPSTR; %let &TMPSTR=&ANS; %let ITM=; run; *** Clear ITM ***; %let QUEST=; run; *** Clear QUEST ***; %MEND ASK; ***************************; *** BEGIN QUERY SECTION ***; ***************************; *** BEGIN QUERY 1 ***; %let QUEST=What is the INPUT Directory Specification?; %let NOTE1=Provide the FULL Operating System Directory Path Specification.; %let NOTE2=(DO NOT include the name of the "BOXFILE" in the Path.); %let NOTE3=EXAMPLE: WORK$:[homedir.subdir] or /u/username/subdir/; %ASK(INPDIR);RUN; %put &INPDIR;RUN; *** BEGIN QUERY 2 ***; %let QUEST=What is the name of the "BOXFILE"?; %let NOTE1=DO NOT include the ".box" portion of the name.; %let NOTE2=Only enter the portion preceeding the ".box" suffix.; %let NOTE3=EXAMPLE: MYFILE (NOT! /username/subdir/MYFILE.BOX); %ASK(INPBOX);RUN; %put &INPBOX;RUN; *** BEGIN QUERY 3 ***; %let QUEST=Where should the "UNBOXED" SAS Data Set be placed?; %let NOTE1=Provide a FULL Operating System Directory Path Specification.; %let NOTE2=(The location of the future SAS Data Set Library); %let NOTE3=EXAMPLE: user$[a_username.subdir] or /u/username/subdir/; %ASK(OUTDIR);RUN; %put &OUTDIR;RUN; *** BEGIN QUERY 4 ***; %let QUEST=Where should the "UNBOXED" SAS Format Catalog be placed?; %let NOTE1=Provide a FULL operating system Directory Path Specification.; %let NOTE2=(The location of the future SAS Format Library); %let NOTE3=EXAMPLE: USER$:[username.subdir] or /u/username/subdir; %ASK(FMTDIR);RUN; %put &FMTDIR;RUN; *** BEGIN QUERY 5 ***; %let QUEST=Automatically SELECT ALL VARIABLES for "UNBOXing"?; %let NOTE1=Enter a "Y" to UNBOX all variables.; %let NOTE2=Make NO ENTRY to be able to select individual variables!; %let NOTE3=; %ASK(SELOPT);RUN; %put "SELOPT='&SELOPT'";RUN; DATA _NULL_; call symput('SELOPT',upcase("&SELOPT")); RUN; **************************; *** START TEMP SECTION ***; **************************; /* %LET INPDIR=SYSWK1$:[E_BEAN.SAS606]; %LET INPBOX=BXNM; %LET OUTDIR=DIR$DATA:[E_BEAN.TMP]; %LET FMTDIR=DIR$DATA:[E_BEAN.TMP]; RUN; */ ************************; *** END TEMP SECTION ***; ************************; **************************; *** BEGIN MAIN PROGRAM ***; **************************; options obs=MAX; %let INPSPEC=&INPDIR&INPBOX%STR(.box); libname SWLIB "&SWDIR"; libname OUTLIB "&OUTDIR"; libname FMTLIB "&FMTDIR"; filename BOXFILE "&INPSPEC"; run; DATA GEN (KEEP= BOXVERS BOXTYPE NUMDS BOXNAME BOXLAB NCONV ) DST (KEEP= DRTYPE MEMNAME RECLEN NOBS REQOBS CRDATE MODATE IDXCOUNT ENGINE MEMLABEL ) VAR (KEEP= DRTYPE VARNUM NAME VTYPE TEXTPOS TEXTLEN TEXTDEC FORMAT LABEL SEL ) FMT (KEEP= DRTYPE FMTNAME START END LABEL MIN MAX DEFALT FUZZ PREFIX MULT FILL NOEDIT TYPE SEXCL EEXCL HLO ) ; INFILE BOXFILE LRECL=250 PAD; format BRTYPE 2. DRTYPE 3. BOXVERS 6.2 BOXTYPE 3. NUMDS 3. BOXNAME $CHAR8. BOXLAB $CHAR40. NCONV $CHAR8. ; FORMAT MEMNAME $CHAR8. RECLEN 12. NOBS 14. REQOBS 14. MEMLABEL $CHAR40. CRDATE $CHAR16. MODATE $CHAR16. IDXCOUNT 10. ENGINE $CHAR8. ; FORMAT VARNUM 6. NAME $CHAR8. ALIAS $CHAR20. VTYPE 1. TEXTPOS 6. TEXTLEN 4. TEXTDEC 2. FORMAT $CHAR8. LABEL $CHAR40. SEL $CHAR1. ; FORMAT FMTNAME $CHAR8. START $CHAR16. END $CHAR16. LABEL $CHAR40. MIN 3. MAX 3. DEFALT 3. FUZZ 16. PREFIX $CHAR2. MULT BEST12. FILL $CHAR1. NOEDIT 3. TYPE $CHAR1. SEXCL $CHAR1. EEXCL $CHAR1. HLO $CHAR3. ; *SEL=upcase("&SELOPT"); SEL="&SELOPT"; IF BRTYPE=99 THEN STOP; input BRTYPE 1-2 @; IF BRTYPE=1 THEN DO; INPUT BOXVERS 3-8 BOXTYPE 9-11 NUMDS 12-14 BOXNAME 15-34 BOXLAB 35-134 NCONV 135-154 ; OUTPUT GEN; END; IF BRTYPE=2 THEN DO; INPUT DRTYPE 3-5 MEMNAME 6-25 RECLEN 26-39 NOBS 40-53 REQOBS 54-67 CRDATE 68-83 MODATE 84-99 IDXCOUNT 100-109 ENGINE 110-129 MEMLABEL 130-229 ; OUTPUT DST; END; IF BRTYPE=3 THEN DO; INPUT DRTYPE 3-5 VARNUM 6-11 NAME 12-31 VTYPE 52-52 TEXTPOS 53-58 TEXTLEN 59-62 TEXTDEC 63-64 FORMAT 65-84 LABEL 88-187 ; OUTPUT VAR; END; IF BRTYPE=4 THEN DO; INPUT DRTYPE 3-5 FMTNAME 6-25 START 26-45 END 46-65 LABEL 66-165 MIN 166-168 MAX 169-171 DEFALT 172-174 FUZZ 175-190 PREFIX 191-192 MULT 193-204 FILL 205 NOEDIT 206-208 TYPE 209 SEXCL 210 EEXCL 211 HLO 212-214 ; OUTPUT FMT; END; RUN; data _NULL_; *** Get GENERAL INFO into macro vars ***; set GEN; if _N_=1 then do; call symput('BOXTYPE',trim(BOXTYPE)); call symput('NUMDS',trim(NUMDS)); call symput('NCONV',trim(NCONV)); end; RUN; data _NULL_; *** Get Longest Logical Record Lenght into macro var ***; set VAR END=EOVAR; retain maxpos maxlen 0 ; if (textpos gt maxpos ) then do; maxpos = textpos; maxlen = textlen; end; if EOVAR then do; lrl=maxpos + maxlen + 2; if (lrl lt 250 )then lrl = 250; call symput('MLRL', trim(left(lrl))); end; run; ********************************************************; %MACRO MAC1(ARGV1); %*** START OF MAC1 MACRO ******; %DO MCCNT=1 %TO &ARGV1 ; %*** START OF MACRO DO LOOP ***; %*******************************************************; %*****************************************************; %*** Put Data Set Information into Macro Variables ***; %*****************************************************; %GLOBAL DSNAM_&MCCNT ; %GLOBAL DSLAB_&MCCNT ; %LET DSNAM_&MCCNT=; %LET DSLAB_&MCCNT=; RUN; data _NULL_; set DST; %*** Read Data Set Infomation ***; if DRTYPE=&MCCNT then do; call symput("DSNAM_&MCCNT",trim(MEMNAME)); call symput("DSLAB_&MCCNT",trim(MEMLABEL)); stop; end; run; %*******************************************************; %END; %*** END OF MACRO DO LOOP ***; %MEND MAC1; %*** END OF MAC1 MACRO ******; ********************************************************; %MAC1(&NUMDS);RUN; %MACRO MACVIEW; %IF "&SELOPT" ^= "Y" %THEN %DO; proc FSVIEW MODIFY data=VAR(CNTLLEV=MEM) fromula=SWLIB.boxcat.unbox.formula; run; %END; %MEND MACVIEW; RUN; %MACVIEW;RUN; ********************************************************; %MACRO MAC2(ARGV1); %*** START OF MAC2 MACRO ******; %DO MCCNT=1 %TO &ARGV1 ; %*** START OF MACRO DO LOOP ***; %*******************************************************; %************************************************; %*** Split into Individual VAR Info Data Sets ***; %************************************************; DATA VAR_&MCCNT; format OUTTYPE $1. OUTDEC $1.; SET VAR; if VTYPE=2 then OUTTYPE="$"; else OUTTYPE=""; TEXTEND=TEXTPOS+TEXTLEN-1; if VTYPE=1 and TEXTDEC^=0 then OUTDEC=(put(TEXTDEC,1.)); else OUTDEC=""; if DRTYPE = &MCCNT and SEL ^= "" then OUTPUT; RUN; %*******************************************************; %END; %*** END OF MACRO DO LOOP ***; %MEND MAC2; %*** END OF MAC2 MACRO ******; ********************************************************; %MAC2(&NUMDS);RUN; filename TMP1 'unbox1.tmp';RUN; data _NULL_; file TMP1; put "/**** START OF FILE TMP1 GENERATED CODE ****/"; RUN; ********************************************************; %MACRO MAC3(ARGV1); %*** START OF MAC3 MACRO ******; %DO MCCNT=1 %TO &ARGV1 ; %*** START OF MACRO DO LOOP ***; %*******************************************************; data _NULL_; SET VAR_&MCCNT end= EOD; file TMP1 MOD; if _N_ = 1 then do; if &MCCNT = 1 then do; put "FILENAME BOXFILE '&INPSPEC';"; put "LIBNAME OUTLIB '&OUTDIR';"; put "OPTIONS OBS=MAX;"; put "DATA"; end; put " OUTLIB.&&DSNAM_&MCCNT"; put " ( KEEP ="; end; put " " NAME ; if EOD then do; put " )"; end; RUN; %*******************************************************; %END; %*** END OF MACRO DO LOOP ***; %MEND MAC3; %*** END OF MAC3 MACRO ******; ********************************************************; %MAC3(&NUMDS);RUN; ********************************************************; %MACRO MAC4(ARGV1); %*** START OF MAC4 MACRO ******; %DO MCCNT=1 %TO &ARGV1 ; %*** START OF MACRO DO LOOP ***; %*******************************************************; data _NULL_; set VAR_&MCCNT end=EOD; file TMP1 MOD; if _N_ = 1 then do; if &MCCNT = 1 then do; put ";"; put "INFILE BOXFILE LRECL=&MLRL;"; put "INPUT XAXAXAXA 1-2 @;"; put "IF XAXAXAXA = 99 then"; put "DO;"; put " INPUT XBXBXBXB 3-5 @;"; end; put " IF XBXBXBXB = &MCCNT then"; put " DO;"; put " INPUT"; end; put " " NAME OUTTYPE TEXTPOS +(-1) "-" TEXTEND OUTDEC; if EOD then do; put " ;"; put " OUTPUT OUTLIB.&&DSNAM_&MCCNT;"; put " END;"; end; RUN; %*******************************************************; %END; %*** END OF MACRO DO LOOP ***; %MEND MAC4; %*** END OF MAC4 MACRO ******; ********************************************************; %MAC4(&NUMDS);RUN; ********************************************************; %MACRO MAC5(ARGV1); %*** START OF MAC5 MACRO ******; %DO MCCNT=1 %TO &ARGV1 ; %*** START OF MACRO DO LOOP ***; %*******************************************************; data _NULL_; set VAR_&MCCNT end=EOD; file TMP1 MOD; if _N_ = 1 then do; if &MCCNT = 1 then do; put "END;"; end; put "PROC DATASETS LIBRARY=OUTLIB MEMTYPE=DATA;"; put " MODIFY &&DSNAM_&MCCNT (LABEL='&&DSLAB_&MCCNT');"; end; if LABEL^="" then do; put " LABEL " NAME +(-1) "='" LABEL +(-1) "';" ; end; if EOD then do; put "RUN;"; end; %*******************************************************; %END; %*** END OF MACRO DO LOOP ***; %MEND MAC5; %*** END OF MAC5 MACRO ******; ********************************************************; %MAC5(&NUMDS);RUN; ***********************************************; *** INCLUDE THE GENERATED CODE IN FILE TMP1 ***; ***********************************************; %INCLUDE TMP1;RUN; ******************************************; *** FIX RESERVE WORD "DEFAULT" PROBLEM ***; ******************************************; proc datasets memtype=DATA; modify FMT; rename DEFALT=DEFAULT; RUN; ****************************; *** BUILD FORMAT CATALOG ***; ****************************; proc format library=FMTLIB cntlin=FMT; RUN; ********************************************************; %MACRO MAC6(ARGV1); %*** START OF MAC6 MACRO ******; %DO MCCNT=1 %TO &ARGV1 ; %*** START OF MACRO DO LOOP ***; %*******************************************************; %let FMTSPC=&OUTDIR&&DSNAM_&MCCNT%STR(.fmt);RUN; %let OUTSPC=&OUTDIR&&DSNAM_&MCCNT;RUN; filename FMT1 "&FMTSPC";RUN; data _NULL_; set VAR_&MCCNT end=EOD; file FMT1; if _N_ = 1 then do; put "/* FILENAME = '&FMTSPC' */"; put "/* Include this file with a %INCLUDE satement in SAS programs */"; put "/* in order to use predefined VARIABLE FORMATS for: */"; put "/* COLLECTION = '&INPBOX' */"; put "/* DATA SET = '&OUTSPC' */"; put "/* This file AutoGenerated by SAS Program UNBOX.SAS Version '&BOXVERS' */"; put "/* E.C.Bean,Jr. - DIR - programmer */"; put ; put "FORMAT"; end; if FORMAT^="" then do; put " " NAME FORMAT +(-1) "."; end; if EOD then do; put "; /* END of %INCLUDE File for Data Set '&OUTSPC' */"; end; %*******************************************************; %END; %*** END OF MACRO DO LOOP ***; %MEND MAC6; %*** END OF MAC6 MACRO ******; ********************************************************; %MAC6(&NUMDS);RUN; *****************************; *** Reset Macro Variables ***; *****************************; %LET BOXVERS=; *** The Program Version Variable ***; %LET ANS=; *** Temporary Variable for users answers ***; %LET INPDIR=; *** Input Directory ***; %LET INPBOX=; *** Input Data Set Name ***; %LET INPSPEC=; *** Output File Specification ***; %LET FMTDIR=; *** Output Formats Directory ***; %LET OUTDIR=; *** Output Data Set Directory ***; %LET SELOPT=; *** Select Individual Variables Option ***; %LET SWDIR=; *** CRITICAL location of software catalog directory ***; ********************************; *** END of UNBOX.SAS PROGRAM ***; ********************************;