Thank you @Cynthia_sas and thank you @Ksharp for your replies which are helpful as always!
I think the proposed solutions work fine if you have the same pattern of tables repeating over and over again (e. g. you always need 20 lines per table) or if you have one big table which you want to split at a given point like described in the Shan (2012) paper. Unfortunately, I am having trouble with implementing this logic into my macro/do loop.
I think my problem is, that I would need to calculate the overall lines available per page (sth. around 45) and then tell proc report to write the upcoming dataset on a new page if the available space is exceeded by this dataset. For that, I would need to automatically calculate the lines per dataset and tell SAS to check if the lines per dataset still fit as a whole on the page (and if not skip to the next page). Or at least I think that could be a solution. I have tried to implement your solutions in my code, but I did not even manage to generate a simple page break with the pgbrk variable method from Cynthia. Furthermore, I would need to insert the page breaks not just for the "VariableInfo" data, but also for the freq and mean datasets. My Code looks like this (I know its rubbish data, but it does the job to show my problem). I have added some comments as well:
proc datasets lib=work nolist; delete sample_data input_data mean: VariableInfo freq: ;run ;quit;
%let yourpath=c:\;
ods listing;
/*** Example Data ***/
data work.sample_data;
input EZGH25A EZGH25B EZGH25C EZGH25D EZGH25E AGHK50A AGHK50B AGHK50C BGKO28A BGKO28B;
datalines;
10 20 30 40 50 1 2 3 2 3
15 25 35 45 55 1 3 4 3 2
5 10 15 20 25 2 2 3 3 2
20 30 40 50 60 4 3 2 1 1
25 35 45 55 65 1 1 1 2 3
5 10 15 20 25 2 2 3 3 2
20 30 40 50 60 4 3 2 1 1
25 35 45 55 65 1 1 1 2 3
;
run;
data work.input_data;
length Info1 $1000 Info2 $1000;
input Info1 $ Info2 $ Sort;
infile datalines delimiter=",";
datalines;
Variable,Answer your Item Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test,1
AGHK50A,Item A Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test,1
AGHK50B,Item B Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space,1
AGHK50C,Item C Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test SpaceTest,1
Variable,Answer your Item Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space,2
BGKO28A,Item A Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space,2
BGKO28B,Item B Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space,2
Variable,Answer your Item Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space,3
EZGH25A,Item A Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space,3
EZGH25B,Item B Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space,3
EZGH25C,Item C Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space,3
EZGH25D,Item D Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space,3
EZGH25E,Item E Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space Test Space,3
;
/* Using proc sql for a Sorting Variable which is used to iterate trough the do-loop */
proc sql noprint;
select distinct Sort into :Sort separated by " "
from work.input_data;
quit;
%put &Sort;
%let varlistE = EZGH25A EZGH25B EZGH25C EZGH25D EZGH25E;
%let varlistA = AGHK50A AGHK50B AGHK50C BGKO28A BGKO28B;
/* Mean Calculation */
proc means data=work.sample_data noprint;
var &varlistE;
output out=work.mean_ezgh;
run;
%macro meandata;
%do i = 1 %to %sysfunc(countw(&varlistE));
%let vmean = %scan(&varlistE, &i);
data work.mean&vmean;
set work.mean_ezgh (keep=&vmean);
run;
%end;
%mend meandata;
%meandata;
/* Freq calculation */
%macro freqdata;
%do i = 1 %to %sysfunc(countw(&varlistA));
%let vfreq = %scan(&varlista, &i);
proc freq data=work.sample_data;
tables &vfreq/ out=work.freq&vfreq;
run;
%end;
%mend freqdata;
%freqdata;
/*** Macro Loop ***/
%macro Testloop;
%do i = 1 %to %sysfunc(countw(&Sort.));
%let SortID = %scan(&sort, &i);
%let VariableA = %scan(&varlistA, &i);
%let VariableE = %scan(&varlistE, &i);
/* Compute Variable Information for each Variable */
data VariableInfo;
set work.input_data;
if sort eq &i then pgbrk=&i;
if pgbrk le 3 then output;
where Sort = &SortID.;
drop Sort;
run;
%local Info1Items;
%let Info1Items=;
PROC SQL noprint;
SELECT distinct Info1 INTO :Info1Items SEPARATED BY " "
FROM work.input_data
WHERE Sort = &SortID.
AND Info1 not in ('' 'Variable');
QUIT;
ods pdf startpage=no; /* Not sure if the startpage option is causing problems with the explicit page breaks - but I guess it should not */
ods layout gridded columns=1;
ods region;
/* Report Variable Information for each Variable */
proc report data=VariableInfo noheader;
column pgbrk Info1 Info2;
define pgbrk / group noprint;
break after pgbrk / page; /* I do not unterstand why it does not insert a page break afterwards. Maybe because the pgbrk variable is the last and not the first variable in the dataset? */
run;
ods layout end;
%MACRO PrinItemStats(Item=,colPosition=);
ods layout gridded columns=1;
ods region;
%if %sysfunc(exist(freq&Item.)) %then %do;
/* Print Frequency Table */
proc report data=freq&Item.; /* How could I implement the page breaks when I add several proc report steps like here? */
column &Item. COUNT PERCENT;
define &Item / display "&Item.";
define COUNT / display "Absolut";
define PERCENT / display "Percent";
run;
%end;
%if %sysfunc(exist(mean&Item.)) %then %do;
/* Print Mean Table */
proc report data=mean&Item.;
column &Item.;
run;
%end;
ods layout end;
%MEND PrinItemStats;
%local j currItem;
%LET j=1;
%LET currItem=%SCAN(&Info1Items.,&j.,%STR( ));
%DO %WHILE(%LENGTH(&currItem.)>0);
%PrinItemStats(Item=&currItem.);
%LET j=%EVAL(&j.+1);
%LET currItem=%SCAN(&Info1Items.,&j.,%STR( ));
%END;
%end;
%mend Testloop;
ods _all_ close;
options papersize=a4 orientation=portrait leftmargin=1.5cm rightmargin=1.5cm topmargin=1.5cm bottommargin=1.5cm nodate nonumber;
ods pdf file="&yourpath.\Loop.pdf";
%Testloop;
ods pdf close;
... View more