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)
334 else &&name&i=quote(cats(&&name&i));
339 filename _sjs3 temp lrecl=131068 ;
341 file _sjs3 encoding='utf-8';
342 if _n_=1 then put "[";
344 if _n_>1 then put "," @; put
345 %if &action=ARR %then "[" ; %else "{
" ;
346 %do i=1 %to &numcols;
348 %if &action=OBJ %then """&&name&i
"":
" ;
349 "&&name&i
"n /* name literal for reserved variable names */
351 %if &action=ARR %then "]
" ; %else "}
" ; ;
353 /* close out the table */
355 file _sjs3 mod encoding='utf-8';
359 infile _sjs3 lrecl=1 recfm=n;
360 file &jref mod lrecl=1 recfm=n;
361 input sourcechar $char1. @@;
362 format sourcechar hex2.;
363 put sourcechar char1. @@;
365 filename _sjs3 clear;
369 drop table &colinfo, &tempds;
371 %if %substr(&showmeta,1,1)=Y %then %do;
372 filename _sjs4 temp lrecl=131068 encoding='utf-8';
376 put ",
""$%lowcase(%sysfunc(coalescec(&dslabel,&ds)))
"":{
""vars
"":{
";
378 name=quote(trim(symget(cats('name',i))));
379 format=quote(trim(symget(cats('fmt',i))));
380 label=quote(prxchange('s/\\/\\\\/',-1,trim(symget(cats('label',i)))));
381 length=quote(trim(symget(cats('length',i))));
382 type=quote(trim(symget(cats('typelong',i))));
383 if i>1 then put ",
" @@;
384 put name ':{"format
":' format ',"label
":' label
385 ',"length
":' length ',"type
":' type '}';
389 /* send back to webout */
391 infile _sjs4 lrecl=1 recfm=n;
392 file &jref mod lrecl=1 recfm=n;
393 input sourcechar $char1. @@;
394 format sourcechar hex2.;
395 put sourcechar char1. @@;
397 filename _sjs4 clear;
401%else %if &action=CLOSE %then %do;
402 data _null_; file &jref encoding='utf-8' mod ;