Loading...
Searching...
No Matches
loadfile.sas
Go to the documentation of this file.
1/**
2 @file loadfile.sas
3 @brief Loads a file
4 @details
5
6 <h4> SAS Macros </h4>
7 @li mddl_sas_cntlout.sas
8 @li mp_abort.sas
9 @li mf_getplatform.sas
10 @li mf_getuser.sas
11 @li mf_getvarlist.sas
12 @li mf_mkdir.sas
13 @li mf_verifymacvars.sas
14 @li mf_wordsinstr1butnotstr2.sas
15 @li dc_assignlib.sas
16 @li mpe_getgroups.sas
17 @li mp_lockfilecheck.sas
18 @li mpe_loader.sas
19 @li mp_cleancsv.sas
20 @li mp_binarycopy.sas
21 @li mp_validatecol.sas
22 @li mpeinit.sas
23
24 @version 9.2
25 @author 4GL Apps Ltd
26 @copyright 4GL Apps Ltd. This code may only be used within Data Controller
27 and may not be re-distributed or re-sold without the express permission of
28 4GL Apps Ltd.
29
30**/
31
32%global table dlm;
33%mpeinit(fetch=NO)
34
35%global _WEBIN_FILENAME1 _WEBIN_FILENAME2
36 _WEBIN_FILEREF _WEBIN_FILEREF1 _WEBIN_FILEREF2;
37%macro load();
38%if %mf_getplatform()=SASVIYA %then %do;
39 %global _webin_fileuri _webin_fileuri1 _webin_fileuri2;
40 %let _webin_fileuri1=%sysfunc(coalescec(&_webin_fileuri1,&_webin_fileuri));
41 %if "&_webin_fileuri1" ne "" %then %do;
42 %put &=_webin_fileuri1;
43 filename sjfref1 filesrvc "&_webin_fileuri1";
44 %let _WEBIN_FILEREF1=sjfref1;
45 %end;
46 %if "&_webin_fileuri2" ne "" %then %do;
47 %put &=_webin_fileuri2;
48 filename sjfref2 filesrvc "&_webin_fileuri2";
49 %let _WEBIN_FILEREF2=sjfref2;
50 %end;
51%end;
52%mend load;
53%load()
54
55%let _WEBIN_FILENAME1=%sysfunc(coalescec(&_WEBIN_FILENAME1,&_WEBIN_FILENAME));
56%let _WEBIN_FILEREF1=%sysfunc(coalescec(&_WEBIN_FILEREF1,&_WEBIN_FILEREF));
57
58%let abort=0;
59/* we do not know if the excel file will be first or second fileref */
60data _null_;
61 ext1=upcase(scan(symget('_WEBIN_FILENAME1'),-1,'.'));
62 ext2=upcase(scan(symget('_WEBIN_FILENAME2'),-1,'.'));
63 if ext1='CSV' then do;
64 csvname=symget('_WEBIN_FILENAME1');
65 csvref=symget('_WEBIN_FILEREF1');
66 xlsname=symget('_WEBIN_FILENAME2');
67 xlsref=symget('_WEBIN_FILEREF2');
68 end;
69 else if ext2='CSV' then do;
70 csvname=symget('_WEBIN_FILENAME2');
71 csvref=symget('_WEBIN_FILEREF2');
72 xlsname=symget('_WEBIN_FILENAME1');
73 xlsref=symget('_WEBIN_FILEREF1');
74 end;
75 else call symputx('abort',1);
76
77 call symputx('csvname',csvname);
78 call symputx('csvref',csvref);
79 call symputx('xlsname',xlsname);
80 call symputx('xlsref',coalescec(xlsref,'0'));
81run;
82
83%mp_abort(iftrue= (&abort=1)
84 ,mac=&_program
85 ,msg=%str(File "&csvname" or "&xlsname" must be a CSV!
86 (Comma separated with .csv extension))
87)
88
89
90%let user=%mf_getuser();
91
92%mp_abort(
93 iftrue=(%mf_verifymacvars(table)=0)
94 ,mac=&_program
95 ,msg=%str(Missing: table)
96)
97
98%let table=%upcase(%trim(&table));
99
100/* load parameters */
101data _null_;
102 libds=upcase(symget('table'));
103 call symputx('orig_libds',libds);
104 call symputx('orig_lib',scan(libds,1,'.'));
105 call symputx('orig_ds',scan(libds,2,'.'));
106 is_fmt=0;
107 if substr(cats(reverse(libds)),1,3)=:'CF-' then do;
108 libds=scan(libds,1,'-');
109 putlog "Format Catalog Captured";
110 libds='work.fmtextract';
111 call symputx('libds',libds);
112 call execute('%mddl_sas_cntlout(libds=work.fmtextract)');
113 is_fmt=1;
114 end;
115 else call symputx('libds',libds);
116 call symputx('is_fmt',is_fmt);
117 /* validate libds to prevent code injection */
118 %mp_validatecol(LIBDS,LIBDS,is_libds)
119 if is_libds=0 then do;
120 putlog 'ERR' 'OR: Invalid libds:' libds;
121 call symputx('bad_libds',1);
122 end;
123 else call symputx('bad_libds',0);
124 putlog (_all_)(=);
125run;
126
127%mp_abort(iftrue= (&bad_libds=1)
128 ,mac=&_program
129 ,msg=%str(Invalid libds supplied)
130)
131
132/* check that the user has the requisite access */
133%mpe_getgroups(user=&user,outds=groups)
134
135proc sql;
136create table accesscheck as
137select * from groups
138 where groupname="&mpeadmins"
139 or groupname in (select sas_group from &mpelib..mpe_security
140 where &dc_dttmtfmt. lt tx_to
141 and access_level="EDIT"
142 and (
143 (libref="&orig_lib" and dsn="&orig_ds")
144 or (libref="&orig_lib" and dsn="*ALL*")
145 or (libref="*ALL*" and dsn="*ALL*")
146 or (libref="*ALL*" and dsn="&orig_ds")
147 ));
148%let nobs=;
149select count(*) into: nobs from &syslast;
150%mp_abort(iftrue= (&nobs=0)
151 ,mac=&sysmacroname
152 ,msg=%str(&user not authorised to load &orig_libds per &mpelib..mpe_security)
153)
154
155%dc_assignlib(WRITE,&orig_lib)
156
157%mp_abort(iftrue= (&syscc ge 4)
158 ,mac=loadfile
159 ,msg=%str(Issue assigning library &orig_lib)
160)
161
162%global txfrom txto processed rk;
163
164data _null_;
165 set &mpelib..MPE_TABLES;
166 where libref="&orig_lib" and dsn="&orig_ds";
167 call symputx('txfrom',var_txfrom);
168 call symputx('txto',var_txto);
169 call symputx('processed',var_processed);
170 if not missing(RK_UNDERLYING) then call symputx('rk',buskey);
171run;
172
173%mp_lockfilecheck(libds=&orig_libds)
174
175data compare;
176 set &libds(drop=&txfrom &txto &processed &rk);
177 stop;
178run;
179
180%mp_abort(iftrue= (&syscc ne 0)
181 ,mac=&_program..sas
182 ,msg=%str(syscc=&syscc line 80)
183)
184
185/* get line terminator, assume it's the first cr, lf, or crlf */
186data _null_;
187 length text $32767 term $4;
188 call missing (of _all_);
189 fid=fopen("&csvref",'I',32767,'b');
190 rc=fread(fid);
191 rc2=fget(fid,text,32767);
192 cr=find(text,'0D'x );
193 lf=find(text,'0A'x );
194 crlf=find(text,'0D0A'x);
195 rc=fclose(fid);
196 if crlf>0 & cr<crlf then term='CR';
197 else if crlf>0 & crlf<lf then term='CRLF';
198 else if lf>0 & cr>0 & lf<cr then term='LF';
199 else if lf>0 then term='LF';
200 else term='CR';
201 call symputx('termstr',term);
202run;
203
204data _null_;
205 infile &csvref lrecl=32000 dsd termstr=&termstr;
206 input;
207 length incols_unsorted $32000 dlm $1;
208 incols_unsorted=compress(upcase(_infile_),"'"!!'"');
209 /* dlm has length 1 so will be the first non alpha / digit char */
210 /* expectation is that there will not be any crazy characters in first col! */
211 dlm=compress(incols_unsorted,'_ ','ad');
212 incols_unsorted=compress(incols_unsorted,dlm!!'_','kado');
213 incols_unsorted=tranwrd(incols_unsorted,dlm,' ');
214 call symputx('incols_unsorted',incols_unsorted);
215 call symputx('dlm',dlm);
216 putlog incols_unsorted=;
217 putlog dlm=;
218 stop;
219run;
220
221%mp_abort(iftrue= (&syscc ne 0)
222 ,mac=&_program..sas
223 ,msg=%str(syscc=&syscc line 99)
224)
225
226%let basecols=%upcase(%mf_getvarlist(work.compare,dlm=%str( )));
227
228%let missing_cols=%trim(
229 %mf_wordsInStr1ButNotStr2(
230 Str1=&basecols
231 ,Str2=&incols_unsorted
232 ));
233
234%let msg=
235 Expected cols: <b>&basecols</b>
236 </br>Received cols: <b>&incols_unsorted</b>
237 </br>Missing cols: <b>&missing_cols</b>
238;
239%mp_abort(iftrue= (%length(%trim(&missing_cols)) > 1 or &syscc ne 0)
240 ,mac=mpestp_loadfile.sas
241 ,msg=%superq(msg)
242)
243%let msg=0;
244
245
246
247PROC FORMAT;
248 picture yymmddhhmmss other='%0Y%0m%0d_%0H%0M%0S' (datatype=datetime);
249RUN;
250
251/* create a dataset key (datetime plus 6 digit random number plus PID) */
252%let mperef=DC%left(%sysfunc(datetime(),B8601DT19.3))_%substr(
253 %sysfunc(ranuni(0)),3,6)_%substr(%str(&sysjobid ),1,4);
254
255/* Create package folder and redirect the log */
256%let dir=&mpelocapprovals/&mperef;
257%mf_mkdir(&dir)
258
259/* clean embedded line breaks and force CRLF line endings */
260%mp_cleancsv(in=&csvref, out=&dir/&orig_libds..csv)
261%mp_abort(iftrue= (&syscc ne 0)
262 ,mac=&_program..sas
263 ,msg=%str(issue in mp_cleancsv)
264)
265
266%put; %put; %put log is being redirected;
267%let url=_program=%substr(&_program
268 ,1,%length(&_program)-8)getlog%nrstr(&)table=&mperef;
269%put to retrieve, visit this url:; %put;%put;
270%put &url;
271%put;
272
273/* proc printto log="&dir/weblog.txt";run; */
274libname approve "&dir";
275
276options mprint;
277%put &=mperef;
278%put &=termstr;
279%put &=dlm;
280
281%mpe_loader(mperef=&mperef
282 ,submitted_reason_txt=%quote(File upload: %superq(csvname))
283 ,dlm=%superq(dlm)
284 ,url=%superq(url)
285 ,termstr=CRLF
286 ,dc_dttmtfmt=&dc_dttmtfmt
287)
288/* mp_abort cannot exit cleanly from inside a %include, so an abort there
289 (eg in a hook script run via mp_include) only records the error in
290 work.mp_abort_errds. mode=INCLUDE picks that up and aborts properly here. */
291%mp_abort(mode=INCLUDE)
292
293%mp_abort(
294 iftrue= (%sysfunc(fileexist(%sysfunc(pathname(work))/mf_abort.error)) ne 0)
295 ,mac=&_program
296 ,msg=%nrstr(Problem occurred in &sysmacroname (mf_abort.error file found))
297)
298
299%mp_abort(iftrue= (&syscc ne 0)
300 ,mac=mpestp_loadfile.sas
301 ,msg=%str(syscc=&syscc)
302)
303
304filename outref "&dir/BKP_&xlsname";
305
306data _null_;
307 if "&xlsref" ne "0" then do;
308 rc=fcopy("&xlsref","outref");
309 end;
310run;
311
312/**
313 * if running 9.3 or older, delete step above and enable macro below
314%mp_binarycopy(iftrue=("&xlsref" ne "0"),inref=&xlsref,outref=outref)
315 */
316
317%mp_abort(iftrue= (&syscc ne 0)
318 ,mac=&sysmacroname
319 ,msg=%str(syscc=&syscc when backing up source file &xlsname)
320)
321
322data sasparams;
323 STATUS='SUCCESS';
324 DSID="&mperef";
325run;
326
327%webout(OPEN)
328%webout(OBJ,sasparams)
329%webout(CLOSE)
330
331
332%mpeterm()