BookmarkSubscribeRSS Feed
☑ This topic is solved. Need further help from the community? Please sign in and ask a new question.
RJB_NZ
Obsidian | Level 7

Hi,

 

My code runs, yay! But doesn't get me the desired results...

I currently get:

RJB_NZ_2-1615178319172.png

 

 

But I'd like the top two header rows put into one.

And I'd like the last two of those column headers to be in red font and merged across 2 cells, to line up with the columns below them.

Like this:

RJB_NZ_3-1615178503749.png

 

I know that's a few things together, but I'm worried that they'll interact and so can't be considered separetly.

 

Thanks

Rodney

 

 

 

%let PathAndFile = 'c:\MyFolder\Shoes Test.xlsx';
data shoes_raw;
	set sashelp.shoes;
	where product in ('Sandal' 'Slipper' 'Sport Shoe');
run;

ODS excel 
	file = "&PathAndFile."
	options (	embedded_titles='OFF' /*On means text in TITLE statement of proc tabulate will show in excel file*/
				sheet_interval="none" /*when to split off to a new page - "none" means not at all*/
				sheet_name='Shoes Tests' /*Name of Sheet*/
				gridlines ='off' /*set printable gridlines*/
				absolute_column_width='23, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10' /*setting column widths*/
				absolute_row_height='15.75' /*setting column height*/
			);


	proc report data = shoes_raw missing;

		*stating columns to be in the report and their order;
		column region ('Products sold' stores,product)
					  ('Sales amount' Sales,product)
					  ('Sandal short' Sandal_Diff)
					  ('Shoe short' Shoe_Diff)
			    ;

		*define columns directly from dataset variables;
		define region  / 'Global region' group
								 style(header)=[just=left borderbottomstyle=solid bordertopstyle=solid];
		define stores  / ' ' analysis sum format=comma.
							   style(header)=[just=right borderbottomstyle=solid bordertopstyle=solid  tagattr='MERGEACROSS:2'];
		define Sales   / ' ' analysis sum format=dollar.2
							   style(header)=[just=right borderbottomstyle=solid bordertopstyle=solid  tagattr='MERGEACROSS:2'];
		define product / ' ' across order=internal
								 style(header)=[borderbottomstyle=solid bordertopstyle=solid just=right.];
		*define cumputed columns;
		define Sandal_Diff / "Slipper - Sandal" computed format=dollar.2
							   style(header)=[just=right borderbottomstyle=solid bordertopstyle=solid  tagattr='MERGEACROSS:2']
							   style(column)=[ tagattr='MERGEACROSS:2'];
		define Shoe_Diff / "Slipper - Sport Shoe" computed format=dollar.2
							   style(header)=[just=right borderbottomstyle=solid bordertopstyle=solid  tagattr='MERGEACROSS:2']
							   style(column)=[tagattr='MERGEACROSS:2'];


		*computing columns (that are based off other columns);
			*columns produced from the across option of the 'month' variable do not have a name so must be reffered to by their column number, as can be counted in the column statement;
		compute Sandal_Diff;
			Sandal_Diff = _c6_ - _c5_;
		endcomp;
		compute Shoe_Diff;
			Shoe_Diff = _c6_ - _c7_;
		endcomp;
	run;

ods excel close;

 

 

1 ACCEPTED SOLUTION

Accepted Solutions
RJB_NZ
Obsidian | Level 7

Thanks  Athenkosi,

That's certainly covered the first step of getting all the heading on the correct lines.

I then realised I could do all my header cell merging using the report level header style with a traffic lighting version of tagattr = mergeaccross.

This did bring about a strange quirk, when the last header (Slipper - Sport shoe) was merged across cells it did the same to cell A1

That's why I added a Dummy Value label and coloured it white.

 

The code below carries on from Athenkosi code, and answers everything I need (it doesn't have the red colouring, but that'll be easy enough... fingers crossed)

Thanks everyone

 

ODS excel 
       file = "C:\My Folder\Shoes Test.xlsx"
       options (     embedded_titles='OFF' 
                           sheet_interval="none" 
                           sheet_name='Shoes Tests' 
                           gridlines ='off' 
                           absolute_column_width='23, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10' 
                           absolute_row_height='15.75' 
                     );
 
       proc format;
              value $MergeAcross_Headers
                     'Sandal short' , 'Slipper - Sandal', 'Shoe short', 'Slipper - Sport shoe' = MERGEACROSS:2
              ;
              value $DummyWhiteOut
                     'Dummy Value' = white
              ;
       run;
 
       proc report data=sashelp.shoes
                                  style(header)=[tagattr=$MergeAcross_Headers. color=$DummyWhiteOut.];
              where product in ('Sandal' 'Slipper' 'Sport Shoe');
              column ('Dummy Value'(''('Global Regions' Region))) ('Products sold' Product),stores ('Sales amount' Product), sales 
              ('Sandal short' ('' ('Slipper - Sandal' Sandal_Diff)))  ('Shoe short' ('' ('Slipper - Sport shoe' Shoe_Diff)));
              define Region                / group order=internal;
              define Product               / across '';
              define Region                / '';
              define stores                / '';
              define sales                 / '';
              define Sandal_Diff    / computed format=dollar.2 ''
                                                          style(column)=[ tagattr='MERGEACROSS:2'];
              define Shoe_Diff      / computed format=dollar.2 ''
                                                          style(column)=[ tagattr='MERGEACROSS:2'];
              
              compute Shoe_Diff;
                           Shoe_Diff = _c6_ - _c7_;
                           Sandal_Diff = _c6_ - _c5_;
              endcomp;
       run;
 
ods excel close;

View solution in original post

9 REPLIES 9
ghosh
Barite | Level 11

report.png

For the last two columns, I could not get a second set of labels (what you have shown in red).  I guess you could do a combined label spanning the two columns.

 

	proc report data = shoes_raw missing;
		*stating columns to be in the report and their order;
		column region ('Products sold' stores, product)
					  ('Sales amount' Sales, product)
/* 					
					  ('Sandal short' Sandal_Diff)
					  ('Shoe short' Shoe_Diff)
	     */
					 ( Sandal_Diff Shoe_Diff)
			    ;

		*define columns directly from dataset variables;
		define region  / group  'Global region' 
								 style(header)=[just=left borderbottomstyle=solid bordertopstyle=solid];
		define stores  /  analysis sum format=comma. ''
							   style(header)=[just=right borderbottomstyle=solid bordertopstyle=solid  tagattr='MERGEACROSS:2'];
		define Sales   /  analysis sum format=dollar.2 ''
							   style(header)=[just=right borderbottomstyle=solid bordertopstyle=solid  tagattr='MERGEACROSS:2'];
		define product / across order=internal ''
								 style(header)=[borderbottomstyle=solid bordertopstyle=solid just=right.];
		*define cumputed columns;
		define Sandal_Diff / "Slipper - Sandal" computed format=dollar.2
							   style(header)=[just=right borderbottomstyle=solid bordertopstyle=solid  tagattr='MERGEACROSS:2']
							   style(column)=[ tagattr='MERGEACROSS:2'];
		define Shoe_Diff / "Slipper - Sport Shoe" computed format=dollar.2
							   style(header)=[just=right borderbottomstyle=solid bordertopstyle=solid  tagattr='MERGEACROSS:2']
							   style(column)=[tagattr='MERGEACROSS:2'];

		*computing columns (that are based off other columns);
			*columns produced from the across option of the 'month' variable do not have a name so must be reffered to by their column number, as can be counted in the column statement;
		compute Sandal_Diff;
			Sandal_Diff = _c6_ - _c5_;
		endcomp;
		compute Shoe_Diff;
			Shoe_Diff = _c6_ - _c7_;
		endcomp;
	run;
ods excel close;
RJB_NZ
Obsidian | Level 7

Thanks ghosh,

 

I actually want individual titles for Sandal_Diff and Shoe_Diff (as per my original code).

I just want the whole of Sandal_Diff (data, and 2 levels of header) to span 2 Excel columns. And then likewise for Shoe_Diff.

 

The reason is that when using my real world (confidential) data then I need the header words to be across 2 columns to fit the words into the cells.

But I don't want to change the column width as that will muck up subsequent tables on the same sheet.

 

Frustratingly, this all looks fine in the SAS (HTML) output, it's just when I open the Excel spreadsheet that it doesn't work.

ghosh
Barite | Level 11

If you just need to fit in a long label just use the split option on the proc report line and embed the chosen split character in the label

RJB_NZ
Obsidian | Level 7
Unfortunately no, I'm not looking for alternativew ways to lay out the report.
Please go back to my original question to see the layout I need to recreate.
RJB_NZ
Obsidian | Level 7
Though I'd be happy enough if a solution were to introduce more rows (perhaps merging across those.)
RJB_NZ
Obsidian | Level 7

Sorry I inserted the wrong code, and accepted it as the solution, doh!!!

 

This is the correct solution:

ODS excel 
	file = "C:\My Folder\Shoes Test.xlsx"
	options (	embedded_titles='OFF' 
				sheet_interval="none" 
				sheet_name='Shoes Tests' 
				gridlines ='off' 
				absolute_column_width='23, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10' 
				absolute_row_height='15.75' 
			);

	proc format;
		value $MergeAcross_Headers
			'Sandal short' , 'Slipper - Sandal', 'Shoe short', 'Slipper - Sport shoe' = MERGEACROSS:2
		;
		value $DummyWhiteOut
			'Dummy Value' = white
		;
	run;

	proc report data=sashelp.shoes
					style(header)=[tagattr=$MergeAcross_Headers. color=$DummyWhiteOut.];
		where product in ('Sandal' 'Slipper' 'Sport Shoe');
		column ('Dummy Value'(''('Global Regions' Region))) ('Products sold' Product),stores ('Sales amount' Product), sales 
		('Sandal short' ('' ('Slipper - Sandal' Sandal_Diff)))  ('Shoe short' ('' ('Slipper - Sport shoe' Shoe_Diff)));
		define Region  		/ group order=internal;
		define Product 		/ across '';
		define Region  		/ '';
		define stores  		/ '';
		define sales   		/ '';
		define Sandal_Diff 	/ computed format=dollar.2 ''
								   style(column)=[ tagattr='MERGEACROSS:2'];
		define Shoe_Diff 	/ computed format=dollar.2 ''
								   style(column)=[ tagattr='MERGEACROSS:2'];
		
		compute Shoe_Diff;
				Shoe_Diff = _c6_ - _c7_;
				Sandal_Diff = _c6_ - _c5_;
		endcomp;
	run;

ods excel close;
Athenkosi
Obsidian | Level 7

Try this.

ODS excel 
	file = "c:\MyFolder\Shoes Test.xlsx"
	options (	embedded_titles='OFF' 
				sheet_interval="none" 
				sheet_name='Shoes Tests' 
				gridlines ='off' 
				absolute_column_width='23, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10' 
				absolute_row_height='15.75' 
			);

proc report data=sashelp.shoes;
	where product in ('Sandal' 'Slipper' 'Sport Shoe');
	column ('Global Regions' Region) ('Products sold' Product),stores ('Sales amount' Product), sales 
	('Sandal short' ('' ('Slipper - Sandal' Sandal_Diff)))  ('Shoe short' ('' ('Slipper - Sport shoe' Shoe_Diff)));
	define Region  		/ group order=internal;
	define Product 		/ across '';
	define Region  		/ '';
	define stores  		/ '';
	define sales   		/ '';
	define Sandal_Diff 	/ computed format=dollar.2 '';
	define Shoe_Diff 	/ computed format=dollar.2 '';
	
	compute Shoe_Diff;
			Shoe_Diff = _c6_ - _c7_;
			Sandal_Diff = _c6_ - _c5_;
	endcomp;
run;

ods excel close;
RJB_NZ
Obsidian | Level 7

Thanks  Athenkosi,

That's certainly covered the first step of getting all the heading on the correct lines.

I then realised I could do all my header cell merging using the report level header style with a traffic lighting version of tagattr = mergeaccross.

This did bring about a strange quirk, when the last header (Slipper - Sport shoe) was merged across cells it did the same to cell A1

That's why I added a Dummy Value label and coloured it white.

 

The code below carries on from Athenkosi code, and answers everything I need (it doesn't have the red colouring, but that'll be easy enough... fingers crossed)

Thanks everyone

 

ODS excel 
       file = "C:\My Folder\Shoes Test.xlsx"
       options (     embedded_titles='OFF' 
                           sheet_interval="none" 
                           sheet_name='Shoes Tests' 
                           gridlines ='off' 
                           absolute_column_width='23, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10' 
                           absolute_row_height='15.75' 
                     );
 
       proc format;
              value $MergeAcross_Headers
                     'Sandal short' , 'Slipper - Sandal', 'Shoe short', 'Slipper - Sport shoe' = MERGEACROSS:2
              ;
              value $DummyWhiteOut
                     'Dummy Value' = white
              ;
       run;
 
       proc report data=sashelp.shoes
                                  style(header)=[tagattr=$MergeAcross_Headers. color=$DummyWhiteOut.];
              where product in ('Sandal' 'Slipper' 'Sport Shoe');
              column ('Dummy Value'(''('Global Regions' Region))) ('Products sold' Product),stores ('Sales amount' Product), sales 
              ('Sandal short' ('' ('Slipper - Sandal' Sandal_Diff)))  ('Shoe short' ('' ('Slipper - Sport shoe' Shoe_Diff)));
              define Region                / group order=internal;
              define Product               / across '';
              define Region                / '';
              define stores                / '';
              define sales                 / '';
              define Sandal_Diff    / computed format=dollar.2 ''
                                                          style(column)=[ tagattr='MERGEACROSS:2'];
              define Shoe_Diff      / computed format=dollar.2 ''
                                                          style(column)=[ tagattr='MERGEACROSS:2'];
              
              compute Shoe_Diff;
                           Shoe_Diff = _c6_ - _c7_;
                           Sandal_Diff = _c6_ - _c5_;
              endcomp;
       run;
 
ods excel close;
Daily1
Quartz | Level 8

can i get this output on this format column first merge with cells 

Daily1_0-1651514650184.png

 

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!
What is Bayesian Analysis?

Learn the difference between classical and Bayesian statistical approaches and see a few PROC examples to perform Bayesian analysis in this video.

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
  • 9 replies
  • 5851 views
  • 2 likes
  • 4 in conversation