BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
Ramya2
Calcite | Level 5

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;

1 ACCEPTED SOLUTION

Accepted Solutions
Patrick
Opal | Level 21

@Ramya2

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()

View solution in original post

15 REPLIES 15
Reeza
Super User
What is 'mints'?
Ramya2
Calcite | Level 5

It is 5 minutes.

Reeza
Super User
PS. I updated the title to better reflect the topic of your question. This helps others who are searching for solutions, since they can more easily find appropriate answers.
mkeintz
PROC Star

You need two things:

  1. What your operating system command is for delaying by 5 minutes (that's "5 mints", right?).  On my windows system, it is TIMEOUT
  2. How to call an operating system command from sas.  At the macro level it is %SYSEXEC.

 

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).

--------------------------
The hash OUTPUT method will overwrite a SAS data set, but not append. That can be costly. Consider voting for Add a HASH object method which would append a hash object to an existing SAS data set

Would enabling PROC SORT to simultaneously output multiple datasets be useful? Then vote for
Allow PROC SORT to output multiple datasets

--------------------------
Patrick
Opal | Level 21

@mkeintz

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;

 

 

Ramya2
Calcite | Level 5

@Patrick Wow it is working absolutely fine. Thank you so much.

Ramya2
Calcite | Level 5
Can you please explain what does that arguments inside sleep function for?
Ramya2
Calcite | Level 5
@Patrick
Ok got it. Thank you. I have tried using the code which you have provided. It executes the for all the subjects without a gap. so I provided sleep(60,1), for between each of the subjects it will have a break of 1 minutes. So, I want 3 subjects to be executed in one shot and then sleep for minutes. The process should continue till the all the subjects executes. I think I have to provide another do inside caller macro right? kindly suggest the code.
Patrick
Opal | Level 21

@Ramya2

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
Calcite | Level 5
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.
Reeza
Super User

@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.
  • Turn off other destinations, listing, HTML everything except PDF.
  • Make sure your log is clean, so that you have no warnings in the first place - NOTES about variables missing, or mismatch of types should also not be happening. 
  • You can turn off notes entirely once you're sure the program is working, errors will still end up in your log.
  • How many pages are in each PDF report? 
  • If each report takes 1 second, the total run time will be about 2 hours. If each report takes 30 seconds it will take a little over 2 days. How long does one report take to be created? Usually, I can create 5-6 PDF's a minute so about 10 seconds each which will take a full day for 6500, but that's running on a desktop machine with 32 GB of RAM, so not a server by any means. 
  • If you're running to a network drive, it'll also slow things down, so you should 

 

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

Ramya2
Calcite | Level 5
@Patrick
How do I create separate log files for the 3 pdfs which is creating in intervals?
mkeintz
PROC Star

@Patrick wrote:

@mkeintz

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.

--------------------------
The hash OUTPUT method will overwrite a SAS data set, but not append. That can be costly. Consider voting for Add a HASH object method which would append a hash object to an existing SAS data set

Would enabling PROC SORT to simultaneously output multiple datasets be useful? Then vote for
Allow PROC SORT to output multiple datasets

--------------------------

Ready to join fellow brilliant minds for the SAS Hackathon?

Build your skills. Make connections. Enjoy creative freedom. Maybe change the world. Registration is now open through August 30th. Visit the SAS Hackathon homepage.

Register today!
How to Concatenate Values

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.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 15 replies
  • 1483 views
  • 0 likes
  • 4 in conversation