73%macro mp_jsonout(action,ds,jref=_webout,dslabel=,fmt=Y
79%local tempds colinfo fmtds i numcols numobs stmt_obs lastobs optval
80 tmpds1 tmpds2 tmpds3 tmpds4;
82%
if &maxobs ne MAX %then %let stmt_obs=%str(
if _n_>&maxobs then stop;);
84%
if &action=OPEN %then %
do;
86 data _null_;file &jref encoding=
'utf-8' lrecl=200;
87 put
'{"PROCESSED_DTTM" : "' "%sysfunc(datetime(),E8601DT26.6)" '"';
90%
else %
if (&action=ARR or &action=OBJ) %then %
do;
92 options validvarname=upcase;
95 filename _sjs1 temp lrecl=200 ;
96 data _null_; file _sjs1 encoding=
'utf-8';
97 put
", ""%lowcase(%sysfunc(coalescec(&dslabel,&ds)))"":";
101 infile _sjs1 lrecl=1 recfm=n;
102 file &jref mod lrecl=1 recfm=n;
103 input sourcechar $char1. @@;
104 format sourcechar hex2.;
105 put sourcechar char1. @@;
107 filename _sjs1 clear;
110 proc contents noprint data=&ds
111 out=_data_(keep=name type length format formatl formatd varnum label);
113 %let colinfo=%scan(&syslast,2,.);
114 proc sort data=&colinfo;
119 if _n_=1 then call symputx(
'numcols',nobs,
'l');
120 set &colinfo end=last nobs=nobs;
123 if type=2 or type=6 then
do;
126 if format=
'' then fmt=cats(
'$',length,
'.');
127 else if formatl=0 then fmt=cats(format,
'.');
128 else fmt=cats(format,formatl,
'.');
132 if format=
'' then fmt=
'best.';
133 else if formatl=0 then fmt=cats(format,
'.');
134 else if formatd=0 then fmt=cats(format,formatl,
'.');
135 else fmt=cats(format,formatl,
'.',formatd);
138 newname=
'sasjs'!!substr(cats(put(md5(name),$hex32.)),1,27);
140 call symputx(cats(
'name',_n_),name,
'l');
141 call symputx(cats(
'newname',_n_),newname,
'l');
142 call symputx(cats(
'length',_n_),length,
'l');
143 call symputx(cats(
'fmt',_n_),fmt,
'l');
144 call symputx(cats(
'type',_n_),type,
'l');
145 call symputx(cats(
'typelong',_n_),typelong,
'l');
146 call symputx(cats(
'label',_n_),coalescec(label,name),
'l');
148 if typelong=
'num' then call symputx(cats(
'fmtlen',_n_),200,
'l');
149 else call symputx(cats(
'fmtlen',_n_),min(32767,ceil((length+10)*1.5)),
'l');
152 %let tempds=%substr(_%sysfunc(compress(%sysfunc(uuidgen()),-)),1,32);
154 select count(*) into: lastobs from &ds;
155 %if &maxobs ne MAX %then %let lastobs=%sysfunc(min(&lastobs,&maxobs));
157 %if &engine=PROCJSON %then %do;
158 %if &missing=STRING %then %do;
159 %put &sysmacroname: Special Missings not supported in proc json.;
160 %put &sysmacroname: Switching to DATASTEP engine;
166 %if &fmt=N %then format _numeric_ best32.;;
168 filename _sjs2 temp lrecl=131068 encoding='utf-8';
169 proc json out=_sjs2 pretty
170 %if &action=ARR %then nokeys ;
171 ;export &tempds / nosastags fmtnumeric;
175 infile _sjs2 lrecl=1 recfm=n;
176 file &jref mod lrecl=1 recfm=n;
177 input sourcechar $char1. @@;
178 format sourcechar hex2.;
179 put sourcechar char1. @@;
181 filename _sjs2 clear;
183 %else %if &engine=DATASTEP %then %do;
185 %if %sysfunc(exist(&ds)) ne 1 & %sysfunc(exist(&ds,VIEW)) ne 1
187 %put &sysmacroname: &ds NOT FOUND!!!;
191 %if &fmt=Y %then %do;
199 %let tmpds1=%substr(fmtsum%sysfunc(compress(%sysfunc(uuidgen()),-)),1,32);
200 %let tmpds2=%substr(cntl%sysfunc(compress(%sysfunc(uuidgen()),-)),1,32);
201 %let tmpds3=%substr(cntl%sysfunc(compress(%sysfunc(uuidgen()),-)),1,32);
202 %let tmpds4=%substr(col%sysfunc(compress(%sysfunc(uuidgen()),-)),1,32);
204 create table &tmpds1 as
205 select cats(libname,'.',memname) as FMTCAT,
207 from dictionary.formats
208 where fmttype='F' and libname is not null
209 and fmtname in (select format from &colinfo where format is not null)
211 create table &tmpds2(
215 %local catlist cat fmtlist i;
216 select distinct fmtcat into: catlist separated by ' ' from &tmpds1;
217 %do i=1 %to %sysfunc(countw(&catlist,%str( )));
218 %let cat=%scan(&catlist,&i,%str( ));
220 select distinct fmtname into: fmtlist separated by ' '
221 from &tmpds1 where fmtcat="&cat";
222 proc format lib=&cat cntlout=&tmpds3(keep=fmtname length);
226 insert into &tmpds2 select distinct fmtname,length from &tmpds3;
230 create table &tmpds4 as
231 select a.*, b.length as MAXW
234 on cats(a.format)=cats(upcase(b.fmtname))
238 if not missing(maxw);
242 min(32767,ceil((max(length,maxw)+10)*1.5))
248 %let optval=%sysfunc(getoption(varlenchk));
249 options varlenchk=NOWARN;
250 data _data_(compress=
char);
253 %do i=1 %to &numcols;
259 %do i=1 %to &numcols;
266 %do i=1 %to &numcols;
270 %do i=1 %to &numcols;
271 %if &&typelong&i=num %then %do;
272 &&name&i=cats(put(&&newname&i,&&fmt&i));
275 &&name&i=put(&&newname&i,&&fmt&i);
279 call symputx('syscc',1012);
284 options varlenchk=&optval;
288 value bart (default=40)
289 %if &missing=NULL %then %do;
300 attrib _all_ label='';
301 %do i=1 %to &numcols;
302 %if &&typelong&i=
char or &fmt=Y %then %do;
303 length &&name&i $&&fmtlen&i...;
304 format &&name&i $&&fmtlen&i...;
307 %if &fmt=Y %then %do;
314 format _numeric_ bart.;
315 %do i=1 %to &numcols;
316 %if &&typelong&i=
char or &fmt=Y %then %do;
317 if findc(&&name&i,'"\'!!'0A0D09000E0F010210111A'x) then do;
319 prxchange('s/"/\\"/',-1,
320 prxchange('s/\x0A/\n/',-1,
321 prxchange('s/\x0D/\r/',-1,
322 prxchange('s/\x09/\\t/',-1,
323 prxchange('s/\x00/\\u0000/',-1,
324 prxchange('s/\x0E/\\u000E/',-1,
325 prxchange('s/\x0F/\\u000F/',-1,
326 prxchange('s/\x01/\\u0001/',-1,
327 prxchange('s/\x02/\\u0002/',-1,
328 prxchange('s/\x10/\\u0010/',-1,
329 prxchange('s/\x11/\\u0011/',-1,
330 prxchange('s/\x1A/\\u001A/',-1,
331 prxchange('s/\\/\\\\/',-1,&&name&i)
335 else &&name&i='"'!!trim(&&name&i)!!'"';
340 filename _sjs3 temp lrecl=131068 ;
342 file _sjs3 encoding='utf-8';
343 if _n_=1 then put "[";
345 if _n_>1 then put "," @; put
346 %if &action=ARR %then "[" ; %else "{
" ;
347 %do i=1 %to &numcols;
349 %if &action=OBJ %then """&&name&i
"":
" ;
350 "&&name&i
"n /* name literal for reserved variable names */
352 %if &action=ARR %then "]
" ; %else "}
" ; ;
354 /* close out the table */
356 file _sjs3 mod encoding='utf-8';
360 infile _sjs3 lrecl=1 recfm=n;
361 file &jref mod lrecl=1 recfm=n;
362 input sourcechar $char1. @@;
363 format sourcechar hex2.;
364 put sourcechar char1. @@;
366 filename _sjs3 clear;
370 drop table &colinfo, &tempds;
372 %if %substr(&showmeta,1,1)=Y %then %do;
373 filename _sjs4 temp lrecl=131068 encoding='utf-8';
377 put ",
""$%lowcase(%sysfunc(coalescec(&dslabel,&ds)))
"":{
""vars
"":{
";
379 name=quote(trim(symget(cats('name',i))));
380 format=quote(trim(symget(cats('fmt',i))));
381 label=quote(prxchange('s/\\/\\\\/',-1,trim(symget(cats('label',i)))));
382 length=quote(trim(symget(cats('length',i))));
383 type=quote(trim(symget(cats('typelong',i))));
384 if i>1 then put ",
" @@;
385 put name ':{"format
":' format ',"label
":' label
386 ',"length
":' length ',"type
":' type '}';
390 /* send back to webout */
392 infile _sjs4 lrecl=1 recfm=n;
393 file &jref mod lrecl=1 recfm=n;
394 input sourcechar $char1. @@;
395 format sourcechar hex2.;
396 put sourcechar char1. @@;
398 filename _sjs4 clear;
402%else %if &action=CLOSE %then %do;
403 data _null_; file &jref encoding='utf-8' mod ;