r f. ! , .. SAS-based verification of double entry data in a FOCUS® database. Introduction The verification of double entry data was looked at with a problem solving approach. This resulted in a SAS/AF®l application called VERIFY. The VERIFY application is a general purpose verification program that extracts data from double entry data files in Focus@f. It compares the two sets of data and produces printed reports of the verification steps. SETUP Andre Gravel Marion Merrell Dow Table I MAS file - Structure of the database FILENAME = ECGREAD, SUFFIX = FOC, SEGNAME = PAT_SEG, SEGTYPE = Sl, FIELDNAME = PATIENT, ALIAS = PAT FIELONAME =FML , ALIAS = FML FIELONAME =AGE , ALIAS = AGE FIELDNAME =SEX , ALIAS = SEX ACCEPT = 'M' 'F' '.' ,$ , FORMAT = A12,$ , FORMAT = A3,$ FORMAT = n,$ , FORMAT = A1, FIELDNAME =INV_NUM , ALIAS =CENTER , FORMAT = I2,$ SEGNAME = ECG_SEG, PARENT = PAT_SEG,SEGTYPE = Sl, FIELONAME = ENUM , ALIAS = ENUM ,FORMAT =I2 ,$ FIELDNAME = LISIBLE ,ALIAS = LISIB ,FORMAT =I2 , ACCEPT = 1 2 3 4 -1 ,$ FIELDNAME = ECG_OATE , ALIAS = EOATE FIELDNAME = ECG_TIME , ALIAS = ETIME FIELDNAME = HR , ALIAS = AHR FIELDNAME = PR , ALIAS = APR FIELDNAME = QRS , ALIAS = AQRS FIELONAME = QT , ALIAS = AQT FIELDNAME = QTC , ALIAS = AQTC FIELDNAME = NORMAL ,ALIAS = NORM ACCEPT = 'A' 'N' '.' ,$ , FORMAT =I6YMD,$ , FORMAT =P5.2,$ , FORMAT =I3 ,$ , FORMAT =I3 ,$ , FORMAT =I3 ,$ , FORMAT =I3 ,$ , FORMAT =I3 ,$ , FORMAT =Al , FIELDNAME = ECG1_COOE, ALIAS = ECOOEl , FORMAT =PS.2,$ FIELDNAME = ECG_COMl , ALIAS = ECOMl ,FORMAT =A60,$ FIELONAME = ECG_COM2 , ALIAS = ECOM2 ,FORMAT =A60, $ FIELDNAME = ECG_COMJ , ALIAS = ECOMJ FORMAT =A60,$ '=- euiaegmentl FOCUS® and SAS® software runs on a VAXTM 3100 model 80 . The host operating system is VMSTM 5.5 - 2H4. VT300™ emulation is used on PC workstations to connect to the hose. _1 "".2 _3 vor5 s"ubsegmetlt t I_I _I vo.2 -t _3 ._gmcnt2 vo.1 voof "".3 vo.4 Figure 1 - Segmentation 1 SASlAF®, SAS® software are registered trademarks of SAS InstiMe, Cary, NC, USA. 2 FOCUS® is a registered trademark of Information Builders Inc, 3 VT300™. VMSTM are trademarks of Digital Equipment Corporation. 937
22
Embed
FILENAME = ECGREAD, SUFFIX = FOC, SEGNAME = … System-based Verification...SAS-based verification of double entry data in a FOCUS® database. Introduction ... Emetic episodes, ...
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
r f.
! , ...
SAS-based verification of double entry data in a FOCUS® database.
Introduction
The verification of double entry data was looked at with a problem solving approach. This resulted in a SAS/AF®l application called VERIFY. The VERIFY application is a general purpose verification program that extracts data from double entry data files in Focus@f. It compares the two sets of data and produces printed reports of the verification steps.
SETUP
Andre Gravel Marion Merrell Dow
Table I MAS file - Structure of the database
FILENAME = ECGREAD, SUFFIX = FOC, SEGNAME = PAT_SEG, SEGTYPE = Sl, FIELDNAME = PATIENT, ALIAS = PAT FIELONAME =FML , ALIAS = FML FIELONAME =AGE , ALIAS = AGE FIELDNAME =SEX , ALIAS = SEX
ACCEPT = 'M' 'F' '.' ,$
, FORMAT = A12,$ , FORMAT = A3,$
FORMAT = n,$ , FORMAT = A1,
FIELDNAME =INV_NUM , ALIAS =CENTER , FORMAT = I2,$
ACCEPT = 1 2 3 4 -1 ,$ FIELDNAME = ECG_OATE , ALIAS = EOATE FIELDNAME = ECG_TIME , ALIAS = ETIME FIELDNAME = HR , ALIAS = AHR FIELDNAME = PR , ALIAS = APR FIELDNAME = QRS , ALIAS = AQRS FIELONAME = QT , ALIAS = AQT FIELDNAME = QTC , ALIAS = AQTC FIELDNAME = NORMAL ,ALIAS = NORM
ACCEPT = 'A' 'N' '.' ,$
, FORMAT =I6YMD,$ , FORMAT =P5.2,$ , FORMAT =I3 ,$ , FORMAT =I3 ,$ , FORMAT =I3 ,$ , FORMAT =I3 ,$ , FORMAT =I3 ,$ , FORMAT =Al ,
FIELDNAME = ECG1_COOE, ALIAS = ECOOEl , FORMAT =PS.2,$ FIELDNAME = ECG_COMl , ALIAS = ECOMl ,FORMAT =A60,$ FIELONAME = ECG_COM2 , ALIAS = ECOM2 ,FORMAT =A60, $ FIELDNAME = ECG_COMJ , ALIAS = ECOMJ FORMAT =A60,$
'=-euiaegmentl
FOCUS® and SAS® software runs on a VAXTM 3100 model 80 . The host operating system is VMSTM 5.5 - 2H4. VT300™ emulation is used on PC workstations to connect to the hose.
_1 "".2 _3 vo.~
vor5
s"ubsegmetlt t I_I _I vo.2 -t _3
._gmcnt2
vo.1 voof "".3 vo.4
Figure 1 - Segmentation
1 SASlAF®, SAS® software are registered trademarks of SAS InstiMe, Cary, NC, USA.
2 FOCUS® is a registered trademark of Information Builders Inc,
3 VAX"~, VT300™. VMSTM are trademarks of Digital Equipment Corporation.
937
'P"f --~~.,,~, ~~~~~~="~~~~ ....
I
,i 'I ~ '.
.'.,
"
DATABASE
The process of designing databases is divided into four steps. Together these steps will bring the database to a clean and final set of data.
The design of the database is assigned to a database analyst. The analyst is responsible for the process from the design of the databaSe to the production of the final set of data. The first step is design, which is closely linked to the data collection form (CRF) used by the clinical research department. This form is different for each study. The content of each form is linked to the data which is collected for a specific study.
PRINT AGE ECOMl ECOM2 ECOM3 BY PATIENT BY ENUM ON TABLE SAVE AS ECGl
END FIN
The analyst starts by defining all the variables that will be entered in the database. The analyst then start programming the structure of the database into a MAS file (see Table 1). Data is divided into segments. For example, demographic data values are usually stored in the first level of segrt;lentation of the database (e.g. the MAIN segment). The data is entered only once and is available from everywhere. Subsegments are then created for specific data in the CRF. If a study is conducted on many weeks, the analyst wil probably define a subsegment called WEEK. Subsubsegments may then be created under the MAIN segment or under the WEEK segment depending of the level for which it applies (e.g. ECGs, Vital signs, Emetic episodes, ... ). Figure 1 shows the segmentation of the data structure.
Once the programming of the database structure is done, the analyst writes input screens for data entry. Double data entry is then performed by data entry personnel. Once the database is completely entered, the analyst writes a verification program that is specific to is database structure. Verification is then applied to the database. After validation (data verification + data correction), the database is ready for analysis. The four steps of this work can be summarized as: database design, screen design, data entry Table IV - FfM file and validation.
PROBLEM
Looking at the situation with many different studies running at the same time and having many different databases, a question was raised: Is it possible to write an application that would allow people to compare FOCUS® data without having to write a verification program each time a new database is designed?
The first part of the project was the design of a screen. This screen contains (table 2) entry fields describing the information about the FOCUS® database (e.g. directories, file names, variable names, variable types and size). The second part of the project is the program. This part is divided into four parts: data extraction; SAS® working files, verification of data, printouts.
939
The data extraction section generates FEX files (executable command files) containing the extraction codes of the variables the user wants to analyse in the database. The table 3 show an example of a FEX file. Two FEX files are generated. Each file is
generated for each data entry (1st and 2nd). These FEX files are submitted interactively by the application using the following command:
X 'FOCUS -EX name·'
The -names is replaced by the actual name of the FEX generated file. The SAS® option NOXWAIT allows automatic return to the SAS® application after each FEX file is submitted. Each submission will generate a FTM file containing the data in ASCII format (table 4).
The next step is to read the ASCII data into working SAse files. This step uses the data description (screen level) to define the LENGTH, FORMAT and INPUT statements in the SAS® programs. Two programs are generated to read in the data that was extracted at the previous step. (see table 5 for an example of the generated SAS code). Once the programs are generated into ASCII files, they are interactively submitted to. the SAS® system.
Once the two working files are available the verification program is generated into an ASCII file (table 6) using the deSCription from the screen entry. Once this program is generated, it is submitted to the SAS® system.
The generated verification program uses the COMPARE procedure. Each COMPARE
940
procedure (up to three compare procedure are generated by the program) generates an output to the screen (table 7) that can be printed to a printer. If character strings longer than 10 character are tested by the verification program then a print procedure is generated by the program to print these strings (table 7). This part of the program is included since the COMPARE procedure only prints the first 12 character of each string.
Table vn - Verification SAS program
PROC SORT DATA=ECGl; BY PATIENT ENUM; RUN;
DATA ECGl; RETAIN CNTI CNT2; SET ECGl; IF LAG(PATIEN'I) "= PATIENT THEN
CNTl=l; ELSE CNTl+l; IF LAG(pATIEN'I) "= PATIENT THEN
CNT2=I; ELSE CNT2+1; RUN;
PROC SORT DATA=ECG2; BY PATIENT ENUM; RUN;
DATA ECG2; RETAIN CNTI CNT2; SET ECG2; IF LAG(PATIENT) "= PATIENT THEN
CNTl=l; ELSE CNT1+1; IF LAG(PATIEN'I) "= PATIENT THEN
ID PATIENT ENUM; TITI..El "&HEAD 1"; TITI..E2 "&HEAD2"; TITI..E4 'UNEQUAL VALUES BY PATIENT
ENUM'; FOOTNOTE "&FooTl"; RUN;
941
CONCLUSION
This application has saved many hours of coding and has reduced the number of encoding errors. Less error occurs because no encoding is needed by the database analyst on the verification process. This application reduces to a minimum the knowledge needed to do the verification step. All the analysts uses the same interface and get the same results from the analysis. The program is versatile and can be used on all kink of FOCUS® databases.
Still, there is a need to add filing facility to the application. The correction of character strings is still cumbersome and needs to be revisited.
The problem solving approach has given us the chance to tackle the problem of data verification. The VERIFY application is now used to verify all databases at our site. The SAS® software has helped us build a good solution.
942
1-· . • :- ... ,
~ ~. i:
l'; ;: 1. '~j
~ ! t~ ~2~ £1 ~! ~ }J 1,
I 'I ), ~,
t P: ~i l' ti r; e·
i to p " ~.
~ ,
I 'i
I \ t,
\.
~
I ~ ;-
SOURCE CODE
/****************************************************************************/ /* VERIFY - Focus extraction window for main entry and second entry */ /* COPYRIGHT 1993-94 Marion Merrell Dow, Strasbourg, FRANCE */ /*-==========================~=============================================-*/ /* Author: Andre Gravel, eng. * / /* oate created: September 1, 1993 */ /*-========================================================================-*/ /* Content: This program is used to extract data entry from a focus */ /* file with is double entry and then compare these values * / /* */ /* Internal ref: INIT, MAIN, TERM, PROCESS, CLEARUP */ /* */ /* Variables: (Uppercase variables are those used in the SAS */ /* file definition) * / /* file - Name of the FOCUS Study file * / /* drug - Drug number * / /* prefix - Used prefix in the protocol naming */ /* rc - return code from function calls * / /* source Source name given to working files */ /* fid - File ID pointer * / /* */ /* OR - Drug level */ /* * / /* FICHIERl - Study Identification number */ /* */ /* FICHIER2 - double entry Identification number * / /* */ /* SEGMENTl - Main variable for 1st segment to 6th segment * / /* SEG~6 */ /* * / /* SEGOOl-4S Variables to extract in all segments */ /* */ /* FOl-4S - Format of variables to extract */ /* * / /* LOl-4S - Length of each variables to extract */ /* */ /* vc Variable counter */ 1* j - Counter * / /* pass Flag */ /* choice - Selection variable */ /* * / /* */ ,,********-******************************************************************/
do; idvar = 'patient'; filename :: "; do i = 2 to dim(seg);
seg{i} = "; f{i} :: "; lei} :: blank;
end; cursor segmtl; cursor filename; status :: 'Reading'; refresh;
end; when (' PROCESS' )
do; status = 'Processing'; refresh; 1*** Test P ***1 if P :: •• then
do;
944
rc = field("erroron","P"); rc = field("cursor","P"); message = "Prefix of DRUG is needed for DATA extraction."; status = 'Reading'; refresh; return;
end;
/*** Test Main variables ***/ do i = 1 to dim(vars);
if vars{i} = "" then
end;
do; rc = field("erroron",varname{i}); rc = field("cursor",varname{i}); message = varname{i} II " must be specified!"; status = 'Reading'; refresh; return;
end;
/*** Test IDVAR ***/ if IDVAR "" then
do; rc field("erroron","IDVAR"); rc = field("cursor","IDVAR"); message = "At least one key variable must be specified!"; status = 'Reading'; refresh; return;
end;
/*** Verify if keyfields are valid ***/ n = 1; tempname = scan(idvar,n,' '); DO while (tempname "= "");
flag = 0; do i =.1 to dim(seg);
if tempname = seg{i} then flag 1; end; if flag = 0 then
do; rc = field("erroron","IDVAR"); rc = field("cursor","IDVAR"); message = "Listed .keyfie1ds are not all present " I I
"in list below, please modify!"; status = 'Reading'; refresh; return;
end; n = n + 1; tempname = scan (idvar,n, ' ');
end; link PAPIER; link PROCESS; if CLEAN = ' YES' then link CLEARUP; status = 'Reading'; refresh; alarm;
if ext cond A= " then call method("routines","PutWrite",fid,4,ext_cond);
status = 'Extracting'; rei'resh;
1***** Save file into "file.PBX" where file is GIVEN by user *****1 call method('routines','SAVEFOC',source2,fid); rc = sysrc(); if (rc) then call display('exit');
1***** SUBMIT the FOCUS file *****/ I~********************************I
rc = system('FOCUS EX" , II source2 II '"'); call method('routines.scl','VERZFY',
source2,'FTM',rc,drug,fichier2);
1*** if the focus file is not created then EXIT ***1 if (rc 0) then return;
status 'Processing'; refresh;
1*** 1***
Validate segment names and associated variable names ***1 before creating SAS variable names ***1
do i = 1 to dim(seg); if seg(i} ~= "" then
do; if indexc(seg(i},'01234567S9') = 1 then /* num in-~st pos */
do;
end; end;
seg(i} = '_' II seg{i}; if length(seg{i}) > S then
seg{i} = substr(seg{i},1,S); end;
I**********************************************~*****************/ 1***** CREATION of the SAS program files *****1 /**************************************************~*************/
status = 'Writing'; refresh; .
call display ( , screen' , "Creating Sas code for " II sourcel);
946
f·
1***** Assign the SAS file (Open it) *****1 call method('routines','CREATTMP',sourcel,fid,drug,fichier1);
1***** Define: Variable LENGTH, MISSING Values, PREDEFINED 1***** Values and INPUT STATEMENTS for EXTRACTION. do j = 1 to 3;
/**********************w****************************** *1 1***** We are now ready to submit the SAS Dataset *****/ /***.***-* •• *_ •• *****-****.**.**.****.*** •• ********.** *1 call display('screen' ,"Creating WORK." I I source1 I I
• data set."); submit continue ;
'include '&sourcel.SAS'; run;
endsubmit;
/** SAS file #2 **/
status = 'Writing'; refresh;
call display('screen','Creating Sas code for' I I source2);
1***** Assign the SAS file (Open it) *****1 call method('routines','CREATTMP' ,source2,fid,drug,fichier1);
/***** Define: Variable LENGTH, MISSING Values, PREDEFINED 1***** Values and INPUT STATEMENTS for EXTRACTION. doj=lto3;
rc = fput(fid,";"); 1***»>; at the end of each statement *1 rc = fwrite(fid);
end I call method('routines' ,'PutWrite' ,fid,4,
·+RUN; .);
rc = fclose(fid); status = 'Processing'; refreshl
/*************************.****************************/ 1***** We are now ready to submit the SAS Dataset *****1 /***************************************************** *1 call display('screen' ,"Creating WORK." I I source21 I " data set."); submit continue ;
%include '&source2.SAS'; run;
endsubmit;
1** SAS Compare file **1 status = 'Writing'; refresh; call display('screen' ,"Creating Sas Compare code"); refresh;
1** COMPUTE KEY to be selected for counter setup **1 i = 1; do while(scan(idvar,i) ~- , ');
i = i+l; end;
if i <= 2 then i=1; else i = i - 2;
1***** Assign the SAS file (Open it) *****1 call method('routines','SasWkTmp', 'compare',fid,drug,fichierl);
call method ( 'routines' , 'PutWrite' , fid, 1, "+PROC SORT DATA=" I I sourcel I I ";",
BY " II IDVAR I I ";", RUN;· ,
" + DATA " I I sourcel I I ";", RETAIN CNT1 CNT2;", SET " II source1 II ";", IF LAG{"IISCAN(IDVAR,i) I I") ~- "1ISCAN(IDVAR,i)ll" THEN CNT1=l;", ELSE CNT1+1;", IF LAG("IISCAN(IDVAR,1) I I") ~= "1ISCAN{IDVAR,1) II" THEN CNT2=1;", ELSE CNT2+1;", RUN;") ;
call method('routines','PutWrite' ,fid,1, "+PROC SORT DATA=" I I source2 I I ";",
BY " II IDVAR I I ";", RUN;· ,
"+DATA" II source2 II "I", RETAIN CNT1 CNT2;", SET " II source2 II "I", IF LAG{" I ISCAN(IDVAR,i) I I") A= "1ISCAN(IDVAR,i)ll" THEN CNT1=1;", ELSE CNT1+11", IF LAG("IISCAN{IDVAR,1) II") A= "1ISCAN(IDVAR,1)11" THEN CNT2=11", ELSE CNT2+1 I", RUN; ") I
name = getjpi('username'); call method{'routines','PutWrite',fid,1,
948
'HEAD2 = 'Title #2';', 'CALL SYMPUT('HEAD2',HEAD2);', '+HEAD3 = 'Observation to observation comparison';', 'HEAD3 = TRIM(HEAD3) I I REPEAT(' ','1 Iput(linesize,3.) I I
• - LENGTH(HEAD3»;', 'CALL SYMPUT('HEAD3' ,HEAD3) ;', '+FOOTl = 'SOURCE: • I I NAME I I ' (&. I I 'SYSDATE,&' II 'SYSTlME) ';', 'FOOTl = TRIM (FOOT1) I REPEAT(' '.'1 Iput(linesize,3.)
• - LENGTH(FOOT1»;', 'CALL SYMPUT('FOOT1',FOOT1);', ·+RUN; -) i
call method('routines', 'PutWrite' ,fid,l, '+OPTIONS PAGENO = 1;", "+PROC COMPARE BASE=' I I source1,
COMPARE=' I I source2, ListEqualVar Transpose' ,
ID TITLEl TITLE2 TITLE4
MaxPrint = 1200;', • I I IDVAR II ';',
'&HEAD1'; , , -&HEAD2· i ' I
'UNEQUAL VALUES BY "I IIDVARI I ";');
if ext cond ~= " then call method('routines','PutWrite',fid,6, 'TITLE6 "1 lext_condl I"i');
end; rc = fclose(fid); status = 'Comparing'; refresh; /.*****************************************************/ /***** We are now ready to submit the SAS Dataset *****/ I*********·*********~********************************* *1
call display('screen',"Comparing files');
submit continue ;
949
'include 'COMPARE.SAS'; run;
endsubmit;
1** SAS - PRINT file **1
1** First, verify if we need to do this step **1 1** Need at least one char variable that **1 1** is 11 character in length or more **1
1*** Test Main variables ***1
doit = 0; /* Nothing to do */ do i = VarStart to dim(seg);
if seg{i} A= •• then if f{i} = 'C' and l{i} > 11 then doit = 1; /* DO something 111*/
end;
if doit = 1 then do;
link RECTO; /* SET proper form */
status = 'Writing'; refresh;
call display('screen','Creating Character fields printout code·); refx-esh;
/***** Assign the SAS file (Open it) *****/ call method('routines','SasWkTmp','print',fid,drug,fichierl);
call method('routines','PutWrite',fid,l, '+OPTIONS PAGENO = 1;·, '+OATA • I I sourcel I I .;., • SET • II sourcel , • (KEEP = • II IOVAR);
do i if
end;
VarStart to dim(seg); seg{i} A= •• and f{i} = 'C' and l{i} > 11 call method('routines','PutWrite',fid,l,
• II UPCASE(seg{i}»;
call method('routines','PutWrite',fid,l,
then
) . " ·+TITLE4' 'FI~ • II sourcel I I ., 1st ENTRY.';', 'TITLE6 'VARIABLES WITH LENGTH LONGER THAN 10 CHARACTERS';', -RUN;· , "+PROC PRINT;RUN;");
/*** SECONOFILE ***/
call method('routines','Putwrite',fid,l, '+OPTIONS PAGENO = 1;·, "+OATA • I I source2 I I .;., • SET • II source2 , • (KEEP = • II IOVAR);
do i if
end;
VarStart to dim(seg); seg{i} A= •• and f{i} = 'C' and l{i} > 11 call method('routines','PutWrite',fid,l,
• II UPCASE(seg{i}»;
call method ( 'routines', 'PutWrite', fid,·l,
then
) .. ·+TITLE4' 'FILE· I I source2 II ., 2nd ENTRY.';·, ·TITLE6 'VARIABLES WITH LENGTH LONGER THAN 10 CHARA~;·, -RUN;· , ·+PROC PRINT;RUN;");
rc = fclose(fid);
status = ' Printing' ; refresh;
/******************************************************/ /***** We are now ready to submit the SAS Dataset *****/ /******************************************************/ call display ( , screen' , ·printing files·);
submit continue ; 'include 'PRINT.SAS'; run;
endsubmit;
END;
950
* call execcmd('End'); /*** Tell the system to close the window ***/ return;
/* DULEN: Routine expanding the resizing definition for FOCUS */ /* extracted variables. Variables a immediately extracted */ /* at the exact width needed for the new standard. * / I*******~********************************************* ***************/
method fid 8 etat $ variable $ type $; if (etat = 'E') then
when("C") substr(newform,l,l) = "A"; when ("Y") newform = "I6YMD"; otherwise;
end; rc = fput (fid. '
'/'
if rc if
, = ' (rc) then _msg_ = fwrite(fid); (rc) then _msg_
1\ upcase(variable) II upcase(newform) I upcase(variable) I sysmsg() ;
sysms~() ; end;
endmethod;
, i ' ) ;
VAREXT: /********************************************************************/ /* VAREXT: Routine expanding the TABLE definition in FOCUS to */ / * activate the extraction of needed variables. * / /,*******************************************************************/
method varcount 8 fid 8 etat $ variable $; if (etat = 'E') then
do; /* write varname into buffer */
rc fput(fid,upcase(variable) II ' '); if (rc) then _msg_ = sysmsg(); varcount = varcount + 1; if (varcount >= 6) then
do;
rc = fwrite(fid); if (rc) then _msg_ varcount = 0;
rc = £put (fid, ' if (rc) then J\sg_
end; end;
endmethod;
sysmsg() ;
') ; sysmsg() ;
/* flush buffer (full) */
/* set indentation */
CreatFoc: '*******************************************************'*******·**~*I /* CREATFOC: This routine Create (delete old files) a FEX file */ /* header for submission to the focus system. */ ,** ••• ***************************************************************1
method fichier $ fid 8 drug $ file $;
951
Name of the FEX file * I 1* fichier: 1* fid 1* drug
File id for FPUTs and FWRITEs *1 Drug number * I
1* file Drug file's study number *1 fname -, , 1***** Verify first if 'fichier'.FEX exists ... *****1 if (fileexist(fichier I I '.FEX'II then
do; f** *** Delete this FEX file ****.* f rc filename(fname,fichier I I '.FEX'I; rc fdelete(fnamel; rc filename(fname,' 'I;
end; fdata = ' ';
1* ... delete 1* Deassign
/***** Verify first if 'fichier'.FTM exists •.. *****1 if (fileexist(fichier I I '.FTM'II then
do; f***** Delete this FTM file *****1 rc filename(fdata,fichier II '.FTM'I; rc fdelete(fdatal; rc filename(fdata,' 'I;
end;
/* ... delete /* Deassign
*1 *1
*/ */
f***** Assign the file 'fichier'.FEX and prepare it for FOCUS *****/ fname = 'a'; rc = filename(fname,fichier I I '.FEX'I; /* Get fileref */ fid= fopen(fname,'O',lOO,'D'I; /* open file *1
endmethod;
SaveFoc: 1*·**·'·_*-*'**'··"·"·'·"·**'·"··'·"'·*···"·'·'·***************1 1* SaveFoc: Routine ends the trailing focus commands and then close *1 1* the file. *1 1****'·"*·*--**'**'·'·'·""*·'·""*··'·"***_·***" ***************/
method fichier $ 1* file : Name of the study file *1 fid 8; 1* fid : File id number to SAS *f
f***** Save file into file.FEX where file: given by user *****1 1***** Execute by emiting an END statement and QUIT *****1 call method ( 'routines' , 'PutWrite' ,fid,l,
" ON TABLE SAVE AS " II upcase(fichierl, -END- , "FIN"I;
1***** Close the file *****1 rc = fclose(fidl;
endmethod;
CreatTmp: 1******·_***-**·_---'--*_·_---**--**---**'-·_-_·_-*···***************/ 1* CreatTmp: This routine Create (delete old files) a SAS pgm file *1 1* header for submission to the SAS system. NULL file. * I 1*-"--"'·'--'-'--'-"""----'---"---"---"--_··_-*******.'*******/ method fichier $ fid 8 drug $ file $;
1* fichier: Name of the SAS file *1 f* fid File id for FPUTs and FWRITEs * / 1* drug Drug number * I f* file Drug file's study number *1
fname -, 'i
1*·*** Verify first if 'fichier'.SAS exists .•. *****1 if (fileexist(fichier II '.SAS'» then
do; 1***** Delete this SAS file *****1 rc filename (fname, fichier II '.SAS'); rc = fdelete(fnamel;
end; 1***** Assign the file 'fichier'.SAS and prepare it for SAS *****1 fname =' 'i rc = filename(fname,fichier I I '.SAS'); fid= fopen(fname,'O',lOO,'D'); /***** Set default working directory into call method('routines','PutWrite',fid,l,
1* Get fileref *1 1* open file *1
FOCUS *****j
"FILENAME • II fichier II • ,. II fiehier II ".FTM';·, "+DATA " I I fiehier I I .;., , INFILE' II fiehier II ' MISSOVER PAD ; 'I;
endmethod;
SasWkTmp: 1*"""""""""""""""""""""""'·'·"***************1 1* SasWkTmp: This routine Create (delete old files) a SAS pgm file *1 1* header for submission to the SAS system. NULL file. * / 1***************************************************** ***************/
method fiehier $ fid 8 drug $ file $; 1* fichier: Name of the SAS file *1 1* fid File id for FPUTs and FWRITEs *1 I" drug Drug number * I /* file Drug file's study number *1
fname - I , i f"**"* Verify first if 'fiehier'.SAS exists •.. "****1 if (fileexist(fiehier II '.SAS'») then
952
do; /***** Delete this SAS file *****/ rc filename(fname,fichier I I '.SAS'); rc = fdelete(fname); rc = filename(fname,' ');
end; /***** Assign the file 'fichier'.SAS and prepare it for SAS *****/ fname = ' '; rc = filename(fname,fichier II '.SAS'); fid= fopen(fname,'O',100,'D');
/* Get fileref */ /* open file */
endmethod;
length var $ 8;
SasVar: 1**-·""**"·"""""""""""""""""""" ***************/ /* SasVar: This routine creates the SAS Statements to define the */ /* LENGTH, MISSING Values, PREDEFINED Values and */ /* INPUT Statement to read the ASCII file generated by * / /* FOCUS. */ /********************************************************************/
fid 8 /* fid File id number to SAS */ etat $ /* etat State from screen selection */ var $ /* var Variable name */ vc 8 /* vc Counter to end of line */ long 8 /* long Length in new protocol */ type $ /* type Type in new protocol */
optional =forma t 8 /* format Format of the variable */ rlength 8 /* rlength:
/* ;
/***** Select pass number *****/ select (upcase(pass»;
when('E') if (etat = 'E') then 1* ONLY the extracted values *1
do; select (upcase(type));
1***** first, indicate if variable is num or char *1 when('C' )
do; rc = fput(fid,put(upcase(var),$8.) I I ' $ ');
1***** Then, fill end of line with field position **1 rc fput(fid,put(vc+l,4.) II '-' II
end;
when('Y') do;
rc = end;
when('T' ) do;
rc
end;
otherwise do;
left (put (vc+INT(long) ,4.)));
fput(fid,put(upcase(var) ,$8.) I I '
fput(fid,put(upcase(var) ,$8.) I I ' left (put (vc+int (long),!.)) II '.');
YYMMDD6.') ;
HHMM' II
rc = fput (fid, put (upcase (var J. $8.) II' , ) ;
end;
/***** Then, fill end of line with field position **1 rc fput(fid,put(vc+l,4.) II '-' II
left (put (vc+INT(long) ,4.»); end;
1***** write the whole thing *****1 rc = fwrite(fid); rc = fput(fid,' '); /* prepare for next line *1 vc vc + INT(long);
end; otherwise;
end;
endmethod;
DelFile: /********************************************************************/ 1* DelFile: This routine is used to clean the library after having *1 1* created intermediate files. * I 1* *1 I * usage: call method (' ',' DELFILE' , fichier, extent) ; * I 1********************************************************************1
method fichier $ 1* Name of the file to delete *1 extent $ 1* Extension of the file * I
fdata = ' '; 1***** Verify first if 'fichier'.'extent' exists ..• *****1
954
if (fileexist(fichier I I '.' I I extent)) then do;
1***** Delete the file *****1 rc filename(fdata,fichier II ' , II extent) ; rc fdelete(fdata); rc filename(fdata,' ');
end;
endmethod;
Verify:
1* ... delete 1* Deassign
*1 *1
/********************************************************************/ 1* Verify: This routine is used to VERIFY the existence of the FTM *1 1* file which would normaly be create by the FOCUS system * I 1* if no problem are encountered during file creation. *1 1* usage: call method('·','VERIFY',fichier,extent,rc); *1 /********************************************************************/
method fichier $ 1* Name of the file to delete */ extent $ /* Extension of the file * / rc 8 /* Return code value: I-file exist, */
drug file
$ $
/* O-file does not. */ / * drug number * I /* file number (study number) */
1***** Verify first if 'fichier'.'extent' exists ... *****/ rc = fileexist(fichier II ' , II extent); if (rc) then
1* I: Input variable, 0: Output variable 8 1* I File ID number 8 1* I Tabulation, if needed $ 1* I Character buffer $ /* I Supplementary buffer #2 $ 1* I Supplementary buffer #3 $ /* I Supplementary buffer #4 $ 1* I Supplementary buffer #S $ 1* I Supplementary buffer #6 $ 1* I Supplementary buffer #7 $ /* I Supplementary buffer #8 $ /* I Supplementary buffer #9 $ 1* I Supplementary buffer #10 $ 1* I Supplementary buffer #11 $ /* I Supplementary buffer #12 $ /* I Supplementary buffer #13 $ /* I Supplementary buffer #14 $ / * I Supplementary buffer US $ /* I Supplementary buffer #16
/*** Verify INPUT variables ***1 if bufferl = ' , then
PutWait: 1***************************************************** ***********************/ 1* PutWait: Write to a physical file without the end of line... *1 1**·*********-·*********************-*****-****·****** ***********************/
if ext cond ~= " then call method('routines','PutWrite',fid,4,ext_cond);
status = 'Extracting'; refresh;
/***** Save file into 'file.FEX' where file is GIVEN by user *****/ call method('routines','SAVEFOC',sourcel,fid); rc = sysrc(); if (rc) then call display('exit');
/***** SUBMIT the FOCUS file *****1 /*********************************/ rc = system ( 'FOCUS EX' , II sourcel II "'); call method('routines.scl', 'VERIFY' ,sourcel, 'FTM' ,rc,drug,fichierl);
1*** if the focus file is not created then EXIT ***/ if (rc = 0) then return;
status 'Processing'; refresh;
1************************************·/ /************ PHASE II ************/ 1********************'****************/
/*** /***
SET Working directory (TYPE) depending on type of data ***/ rep2 and file2 are set here ***/
status = 'Writing'; refresh;
call display('screen','Extracting FOCUS data.', 'File [' II rep2 II 'J" II file2);
/***** Assigner Ie fichier de reference *****/ call method("routines','CREATFOC',
source2,fid,drug,fichier2);
/***** Set default working directory into FOCUS *****1
call method("routines', "PutWrite',fid,l, "VMS SET DEFAULT directory structure", "SET MORE=OFF', 'DEFINE FILE' II file2);