Hi All,
I have some 'n' subjects. where in I need to create a pdf to all those subjects separately. The task is, I need 5 subjects to be executed as a group. and need a execution break for 5mints. Similarly next 5. give a 5mints break. Till the end of file. Here is a below code where pdf is getting created for all subjects. But please help me with a logic for above condition.
%macro looper(subject=);
options papersize = A4 orientation = landscape nodate center nonumber bottommargin = 0.25in
topmargin = 0.25in leftmargin = 0.25in rightmargin = 0.25in ;
ods listing close;
/*ods pdf body = "/ctshared/cdr/prod/a423_20110203/AMG423_20110203_Patient_Profile/rms32763/AMG423_20110203_&subject._Patient Profile.pdf";*/
ods pdf body = "/ctshared/cdr/dev/RAMYA/AMG423_20110203_&subject._Patient Profile.pdf";
ods noresults;
footnote2 justify=left height=0.5 "Report Creation Date/Time: &sysdate. &systime. AM PDT" ;
footnote3 justify=left height=0.5 "For Internal Use Only. Amgen Confidential.";
Title1 Bold "AMG423_20110203_&subject._Patient Profile";
Title4 italic justify=left "Demographics";
PROC REPORT DATA=demo NOWD split='*' ;
where subject in ("&subject" "Subject");
column ("Demographics" site subject age_y_c sex svstdt_raw);
define site / Center Display "Site" style=[cellwidth=15mm];
define subject / Center Display "Subject" style=[cellwidth=22mm];
define age_y_c / Center Display "Age" style=[cellwidth=20mm];
define sex / Center Display "Sex" style=[cellwidth=20mm];
define svstdt_raw / Center Display "Screening Date" style=[cellwidth=20mm];
run;
ods PDF close; /* must close tagsets.ExcelXP here*/
ods listing;
ods results;
ods listing;;
%mend looper ;
**************************** Looping through for all subjects******************************;
%macro caller;
%do j=1 %to &npts;
%looper(subject=&&pt&j.)
%end;
%mend caller;
%caller;
Not sure why you want to do what you want to do. Below based on your code and also what @mkeintz already provided.
data demo;
do subject=1 to 20;
output;
end;
stop;
run;
proc sql noprint;
select subject into :pt1-:pt999999999
from demo
;
quit;
%let npts=&SQLOBS;
%macro looper(subject=);
title "subject: &subject";
proc print data= demo;
where subject in (&subject);
run;
%mend;
%macro caller();
%do j=1 %to &npts;
%looper(subject=&&pt&j.)
%if %sysfunc(mod(&j,3))=0 %then
%do;
%let rc=%sysfunc(sleep(1,5));
%end;
%end;
%mend caller();
%caller()
It is 5 minutes.
You need two things:
Then modify your caller macro to run the %SYSEXEC/TIMEOUT combination whenever iterator J has a zero remainder when divided by five:
%macro caller;
%do j=1 %to &npts;
%looper(subject=&&pt&j.)
%if %sysfunc(mod(&j,5))=0 %then %sysexec timeout /t 3 /nobreak;
%end;
%mend caller;
The TIMEOUT command above is asking for 3 seconds, not 3 minutes (you would need /T 300). I suggest you test with a small wait time first. The "/nobreak" option tells TIMEOUT that there should be no ordinary keyboard entry that will interrupt the wait time (but ctrl-C would still interrupt).
The MOD function yield the remainder after dividing &J by 5. But MOD is a SAS function, not a macro function, so it has to be embedded in the %SYSFUNC macro function).
Why go for an OS command if there is CALL SLEEP()?
...or if you want it on macro level use the sleep() function
%let rc= %sysfunc(sleep(1,5));
%put &=rc;
@Patrick Wow it is working absolutely fine. Thank you so much.
The SAS docu explains that better than I ever could.
Not sure why you want to do what you want to do. Below based on your code and also what @mkeintz already provided.
data demo;
do subject=1 to 20;
output;
end;
stop;
run;
proc sql noprint;
select subject into :pt1-:pt999999999
from demo
;
quit;
%let npts=&SQLOBS;
%macro looper(subject=);
title "subject: &subject";
proc print data= demo;
where subject in (&subject);
run;
%mend;
%macro caller();
%do j=1 %to &npts;
%looper(subject=&&pt&j.)
%if %sysfunc(mod(&j,3))=0 %then
%do;
%let rc=%sysfunc(sleep(1,5));
%end;
%end;
%mend caller();
%caller()
@Ramya2 wrote:
Thanks for your quick response.
It is working for me.From past 4 days I was struggling on this. This really helped me.
Actually, I have around 6500 subjects for each of those pdf is getting created, to complete this execution it is taking 3 to 4 days and also it consumes high space disk. Around 5gb of log is getting created. So inorder to overcome this, I thought of splitting the executiion and once after a set of execution completes, A log will be moved to some shared location and current log will be cleared. So asked an help.
Thank you. Much appreciate your time spent on this.
An example of creating custom reports can be found here, note this is HTML, not PDF, but that's a relatively small change.
https://github.com/statgeek/SAS-Tutorials/blob/master/Turning%20a%20program%20into%20a%20macro.md
@Patrick wrote:
Why go for an OS command if there is CALL SLEEP()?
...or if you want it on macro level use the sleep() function
%let rc= %sysfunc(sleep(1,5));
%put &=rc;
Why indeed? Because I was blissfully unaware of call sleep. Very nice.
SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!
Learn how use the CAT functions in SAS to join values from multiple variables into a single value.
Find more tutorials on the SAS Users YouTube channel.
Ready to level-up your skills? Choose your own adventure.