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

I am not expert, but not sure about the format you mentioned  works for what I am looking. I am looking for if any variable that has the string that  contains a word "Missing" need highlight that cell in output. according to your format Variable has to have the only  word that mentioned in formats. where as I am looking for finding the word Missing in string then alert with color code. Let me know if My question make sense. also is it  any way we can create  a separate variable flag based on this logic and work around!

Cynthia_sas
SAS Super FREQ

Hi:

  My example exactly mimics your first posting, as shown below:

Cynthia_sas_0-1602168207932.png

 

Your second posting example has these issues that I have a hard time figuring out because there's no context for the data or the desired output:

1) data shown is screen shot, data structure is not explained and can't be used with only partial code provided

2) data is not explained. Is it a CSV file? Is it a SAS dataset? Why are there ODS ESCAPECHAR strings in the data?

3) there is no color coding in the example that is supposed to be Excel output. The 3rd picture doesn't look like Excel output. There are not any cell boundaries and no column headers.

 

  It is possible to do color coding with ODS EXCEL. I'm not sure that if you have multiple strings in a cell that you can do 2 different backgrounds in one cell but you CAN have 2 different font colors, as shown below:

Cynthia_sas_1-1602171423307.png

One thing I like to do is to remove SAS from the picture and see whether something is possible in native Excel. So for example, in this worksheet that I typed into Excel, I can change the entire background for one cell, no matter how many text strings are in the cell:

Cynthia_sas_0-1602171749631.png

  However, look at the cell B3, where I have highlighted just the word "number" in the cell, the button to change the background becomes grayed out and there's not a way to change the background color of just one piece of the string. I can still change the font color of the highlighted word, as shown below:

Cynthia_sas_1-1602171862003.png

  So if Excel won't let you change the background of just one piece of a text string, SAS won't be able to do it either.

 

Cynthia

SASuserlot
Barite | Level 11

Yes I totally agree with you. I am not looking to achieve both. I am fine with  if it just highlights the cells with color that contains the word "Missing". I am sorry if Initial post caused you any confusion.  I am  posting another, let me know if it clears to you.Capture.PNGOpenedWithImage.png

SASuserlot_0-1602173066143.png

 

Cynthia_sas
SAS Super FREQ
Hi:
What you posted in your top picture, you say is how the data looks in the SAS dataset -- but you show it as row 21 -- that looks like a screen shot from Excel for what your data resembles. It is impossible to understand your data structure from just one row and one cell. Several examples of how to write a data step program to make fake or dummy data into a SAS dataset for testing have been posted. It is nearly impossible to understand what your data looks like from the first picture which is essentially row 21 and just one cell on row 21.
Your second screen shot shows the words [Missing], Control, Food Effect and Treatment, and your comment says that this is how you want your data displayed in Excel. But again it looks like you are just showing 1 cell in column C in Excel. You don't show columns A and B. However your first screen shot looks like it is showing row 21, Column A, so did your data suddenly shift to Column C when you did your report? You had many more variables in your PROC REPORT code that you posted but these snippets show none of those variables or variable names and you haven't posted more than 1 or 2 cells. And in your last picture it shows continuous and continuous, content, etc. In other words, the first and second screen shots do not agree at all with what you say your data is and nothing looks like your PROC REPORT code will work with what you've posted.
Cynthia
SASuserlot
Barite | Level 11
option validvarname=upcase;
data scores;
   input Name$  Test_1$ Test_2$ Test_3$;
   datalines;
Bill stomach hepatic bacteria
Carlos . allery rashes
Monique stomach pain vomit
chris heart . .
jay . hepatic virus
. . heart hyp
;
run;
data t1;
length name test_1 test_2 test_3 $50 header cell1 cell2 cell3 $200;
set scores;
if name=" " then name="[Missing]";
if test_1=" " then test_1="[Missing]";
if test_2=" " then test_2="[Missing]";
if test_3=" " then test_3="[Missing]";

if test_1= "heart" then phase="Phase 1";
else if test_1= "stomach" then phase="Phase 2";
else phase="Phase 3";

/*using ^n as escapechar to read in the proc report each variable in separate line inside the excel sheet cell feel */
/*free to change*/

header=strip(phase)||" "||strip(test_1);
cell1=strip(name)||","||"^n"||" "||strip(test_1)||","||"^n"||" "||strip(test_3);
cell2=strip(name)||","||"^n"||" "||strip(test_2)||","||"^n"||" "||strip(test_3);
cell3=strip(name)||","||"^n"||" "||strip(test_1)||","||"^n"||" "||strip(test_2);
run;



 

SASuserlot_0-1602194225636.png

 

 

I created a dummy dataset  for you . This data will similar to my dataset and follows same programming method. I used ^n during concatenation because I  only know that way. If you have any other ideas please share. I am also attaching the excel output image. I am looking to produce the out put that looks like in the image. Yellow color highlight is for the cells that containing the word "[Missing]". If any typo errors please ignore, 

Cynthia_sas
SAS Super FREQ

Hi:

  I was working on this before you posted your information. Something like this should work. Just make a helper variable (in my example, called HILITE) that is used to perform the color coding of the cell:

Cynthia_sas_0-1602199139697.png

Cynthia

SASuserlot
Barite | Level 11
ods ESCAPECHAR = '^';
ods excel file='C:\Users\xxx\Desktop\New folder\xxx\exxx_c.xlsx' options(sheet_name='xxx'
 sheet_interval='none');
/* title1 j=c '#byvar(hline)';*/
 %macro xx(ph=,phx=);
   PROC REPORT data=sdsp5 nowindows
       style(report)=[font=("Times New Roman", 11pt) protectspecialchars=on]
      style(header)=[font=("Times New Roman", 11pt, bold) just=center protectspecialchars=on]
      style(column)=[font=("Times New Roman", 11pt) protectspecialchars=on];
/*	  by ph ;*/
	  where &ph;
      COLUMN ph Hline Study_Identifier brief_title Study_Design Study_status Study_start_date 
	   		 Exchange_standards terminology_standards h1 i1 j1 k1 l1 m1 n1 o1;
      DEFINE ph/ " " group noprint style=[just=c vjust=t cellwidth=2.745cm tagattr='type:String format:Text']; /*ph sorting order for study identifier*/
      DEFINE Hline/ " " group noprint style=[font=("Times New Roman",11pt)just=c vjust=t vjust=t cellwidth=2.745cm tagattr='type:String format:Text'];
/*hline is for horizontal heading for the group like below excel"phase 2 stomach"

%if &phx=1 %then %do; /*This line I created macro because I want to display main heading only once at the top like
phase, name test1 test 2 in the sample excel pic. this line will make run the first group *//

/* below are the columns to display in cells, h1-o1 are the flags created if sting has "[Missing]"
DEFINE Study_Identifier/"Study Identifier" display style=[just=l vjust=t cellwidth=2cm tagattr='type:String format:Text']; DEFINE brief_title/ "Brief Title" display style=[just=c vjust=t cellwidth=3.882cm tagattr='type:String format:Text']; DEFINE Study_Design/ "Study Design" display style=[just=c vjust=t cellwidth=5.882cm tagattr='type:String format:Text']; DEFINE Study_status /" Study Status" display style=[just=c vjust=t cellwidth=2.718cm tagattr='type:String format:Text']; DEFINE Study_start_date /"Study Start Date" display style=[just=c vjust=t cellwidth=2.818cm tagattr='type:String format:Text']; DEFINE Exchange_standards /"Exchange standards" display style=[just=c vjust=t cellwidth=3.212cm tagattr='type:String format:Text']; DEFINE terminology_standards /"Terminology Standards" display style=[just=c vjust=t cellwidth=4.643cm tagattr='type:String format:Text']; DEFINE h1/ display noprint; DEFINE i1/ display noprint; DEFINE j1/ display noprint; DEFINE k1/ display noprint; DEFINE l1/ display noprint; DEFINE m1/ display noprint; DEFINE n1/ display noprint; DEFINE o1/ display noprint; %end; %else %do; DEFINE Hline/ " " group noprint style=[font=("Times New Roman",11pt)just=c vjust=t cellwidth=2.745cm tagattr='type:String format:Text']; DEFINE Study_Identifier/"" display style=[just=l vjust=t cellwidth=2cm tagattr='type:String format:Text']; DEFINE brief_title/ "" display style=[just=c vjust=t cellwidth=3.882cm tagattr='type:String format:Text']; DEFINE Study_Design/ "" display style=[just=c vjust=t cellwidth=8.882cm tagattr='type:String format:Text']; DEFINE Study_status /" " display style=[just=c vjust=t cellwidth=2.718cm tagattr='type:String format:Text']; DEFINE Study_start_date /"" display style=[just=c vjust=t cellwidth=2.818cm tagattr='type:String format:Text']; DEFINE Exchange_standards /"" display style=[just=c vjust=t cellwidth=3.212cm tagattr='type:String format:Text']; DEFINE terminology_standards /"" display style=[just=c vjust=t cellwidth=4.643cm tagattr='type:String format:Text']; DEFINE h1/ display noprint; DEFINE i1/ display noprint; DEFINE j1/ display noprint; DEFINE k1/ display noprint; DEFINE l1/ display noprint; DEFINE m1/ display noprint; DEFINE n1/ display noprint; DEFINE o1/ display noprint; %end; compute before hline/ style=[font=("Times New Roman", 11pt, bold) ]; line @140 hline $100.; IF i1="Y" then do; call define ("hline","style","style={background=yellow}");/* I tried for one only to check but not succesful*/ end; endcomp; RUN; %mend; %xx(ph =%str(ph=1),phx=1); %xx(ph =%str(ph>1)); ods excel CLOSE; ods listing close;

Thanks Cynthia.  I understand it clearly now. Thanks for taking your time to explain. If it possible for you can you please check my Proc report code and tell me if any thing that cause errors. However I am still facing issue with displaying the color, I able to do flags in my final dataset before proc report and I can able to see the flags in the report if I ran without "noprint"option. I believe some thing in my proc report code making issue.

SASuserlot_0-1602194225636.png

Cynthia_sas
SAS Super FREQ

Hi:
You should be able to tell whether there are errors. What do you see in the SAS Log?

Your comment says that you tried something but it was not successful. However, you clearly have color coding in the cells of the table. Did your program produce that color coding? That looks successful to me.

If you also want color-coding in the compute before block which is the cell that says Phase 1, Phase 2 and Phase 3 I'm not sure you can do that with flags the way you are trying to do it. And, that requirement wasn't part of what you originally asked for. It looks to me like you are getting the color coding you wanted in the data cells. Is this all your code? It seems to me there should be more code, but with your code complicated by macro programming it's hard to tell. And I'm not sure you need macro program to suppress the headers the way you envision. For example. consider this simple example using a small subset of SASHELP.PRDSALE:

Taking all macro out of the picture and taking highlighting and color coding out of the picture, let's look at how PROC REPORT works when you use NOPRINT and the LINE statement to control the separation of groups. Notice that the headers are NOT repeated for the groups. Your macro seems to be trying to re-create the default PROC REPORT behavior when you have break processing on a GROUP or ORDER item using a COMPUTE BEFORE.

Cynthia_sas_0-1602271500660.png

 



This user group paper might help you understand break processing and COMPUTE blocks better: https://support.sas.com/resources/papers/proceedings17/SAS0431-2017.pdf

Also techniques like @140 are LISTING only options and are ignored by ODS RTF, ODS PDF, ODS HTML, ODS EXCEL, etc. There's not the ability to use column pointers with ODS in the same way there could be with LISTING (monospace) output.

Hope this helps. At some point, you might want to consider opening a track with Tech Support. They could look at all of your code and all of your data (including the program that you use to set the variable values for the color coding flags) and they might have some suggestions.

If I were going to make any suggestions, I'd suggest getting everything to work with one subset without using any macro programming and making sure that you got what you wanted without using macro coding. I'm not convinced that you even need macro programming. But since you don't show this new data, with the new flags, nobody could run your code. And the other issue is that when I try to paste your code into an editor, it appears that you have a comment that is not ended because in my editor, most of the program looks like a comment (in my editor, comments are green):

Cynthia_sas_1-1602271563787.png

 

So that would be the first thing I'd recommend fixing. The next thing would be to "unmacroize" and simplify your program and make sure it works correctly without using macro programming. And, make sure that you even need macro logic to build your PROC REPORT because I don't see that it is necessary.

Hope this helps,
Cynthia

SASuserlot
Barite | Level 11

I don't know How can I express my thanks to you. Thanks for taking your time. I will rework on my proc report , the way you shown with example. Thank you very much. I hope I will get right this time. Thanks . if possible can you please share the dataset or code  for the dataset b4 you doing the proc report where you have countries like USA , gemany etc in horizontal headers. that gives me Idea how I can arrange variables in the dataset.

Thanks again

Cynthia_sas
SAS Super FREQ
Hi:
The code is in the screen shot. My program uses SASHELP.PRDSALE -- you should have access to this data in the SASHELP library, which is part of every SAS install. And then, the WHERE statement generates just a small number of rows for each value of COUNTRY -- I just wanted enough rows to show a few rows underneath each break.

The example I posted should be easily re-created since everyone has access to SASHELP.PRDSALE.

Cynthia
SASuserlot
Barite | Level 11
ods ESCAPECHAR = '^';
ods excel file='C:\Users\xx\Desktop\New folder\xx\rxx.xlsx' options(sheet_name='xx'
 sheet_interval='none');

   PROC REPORT data=sdsp5 nowindows
       style(report)=[font=("Times New Roman", 11pt) protectspecialchars=on]
      style(header)=[font=("Times New Roman", 11pt, bold) just=center protectspecialchars=on]
      style(column)=[font=("Times New Roman", 11pt) protectspecialchars=on];
/*Ph variable created for sorting order purpose so that phase 1 comes first then phase 2 etc*/
      COLUMN ph Hline xx yy zz kk mm nn cc;
      DEFINE ph/ " " group noprint style=[just=c vjust=t cellwidth=2.745cm tagattr='type:String format:Text'];
      DEFINE Hline/ order  style=[font=("Times New Roman",11pt)just=c vjust=t vjust=t cellwidth=2.745cm tagattr='type:String format:Text'];
      DEFINE Study_Identifier/"XX" display style=[just=l vjust=t cellwidth=2cm tagattr='type:String format:Text'];
      DEFINE brief_title/ "yy" display style=[just=c vjust=t cellwidth=3.882cm tagattr='type:String format:Text'];
      DEFINE Study_Design/ "zz" display style=[just=c vjust=t cellwidth=5.882cm tagattr='type:String format:Text'];
      DEFINE Study_status /"kk"display style=[just=c vjust=t cellwidth=2.718cm tagattr='type:String format:Text'];
      DEFINE Study_start_date /"mm" display style=[just=c vjust=t cellwidth=2.818cm tagattr='type:String format:Text'];
      DEFINE Exchange_standards /"nn" display style=[just=c vjust=t cellwidth=3.212cm tagattr='type:String format:Text'];
      DEFINE terminology_standards /"cc" display style=[just=c vjust=t cellwidth=4.643cm tagattr='type:String format:Text'];
	compute before hline/ style={just=c fontweight=bold};
	line hline lenght $50.;
	endcomp;
	run;
	ods excel close;
	ods listing close;

I did what you suggested , but I am unable to achieve the horizontal heading , please guide me where I am doing wrong in code, I am also providing my excel output.  If you  see the  I just  did not given the option "norprint" for "hline" variable to show in Excel file, so that I can explain it better. In the excel file  Column A has "hline "vairable  and row 2 has the value "Phase1" , row 4-"phase 2" and row 6- phase 3.  What I am expecting is like to achieve how you achieved the countries you provided. I looking to get the "hline" values in horizontal headers just line one you provided.  Ex: Phase1 header is above the below  row 1, phase 2 is above row4, phase4 above 6 just like yours. Please help me out on this. Thank you

Capture.PNG

SASuserlot
Barite | Level 11

sorry I missed  to change the column statement names in define statement.  I think I cannot delete and place the new one. But in original code . I have the  same names (column statement) that were mentioned in the define statement. Please ignore that mistake

Cynthia_sas
SAS Super FREQ

Hi: This is almost exactly like the SASHELP.PRDSALE example I posted previously. My guess is that something about your PH variable is preventing break processing from working. You don't show what the PH variable values are (your GROUP/NOPRINT) -- we only see what the HLINE variable is.

If you notice in my example, COUNTRY is the very first item on the COLUMN statement and I am doing a COMPUTE BEFORE COUNTRY. In your example, PH is the first item on the COLUMN statement and you are doing a COMPUTE BEFORE HLINE, which is the 2nd item on the COLUMN statement.

Since you do not seem to want to post any data in readable form, no one can work with your code. Look again at my example with SASHELP.PRDSALE, where I have COUNTRY, you should have HLINE. I have zero idea what your PH variable represents or why it's even on your report. But, my example works with COUNTRY as the first item.

Also, your code doesn't make sense. The variables on the COLUMN statement do NOT match the variables in the DEFINE statements.Here's your code highlighted where it doesn't make sense. Green items are matches between the COLUMN statement and the DEFINE statements. Pink highlights are the items listed on the COLUMN statement, but do not appear on DEFINE statements (which can be OK if the variables exist in the data and you want to take all the defaults). Yellow highlights are variables on the DEFINE statements, but not in the COLUMN statement -- which is not OK with PROC REPORT:

Cynthia_sas_1-1602344108870.png

The variables on the COLUMN statement should be either variables in your data or they are COMPUTED items or statistic names. Otherwise you get warnings. Now, you might actually have items named xx yy zz kk mm nn cc in your data, but nobody knows whether you do because you don't post your data or any sample data that corresponds to your code.

 

Here's a simple example that mimics your code technique using SASHELP.CLASS. SASHELP.CLASS has 5 variables: NAME, SEX, AGE, HEIGHT, WEIGHT. So when I use your SAME technique, I  generate WARNINGS and the output only shows NAME from SASHELP.CLASS:

Cynthia_sas_0-1602343879961.png

 

 But the bottom line is that what you show in your screen shot as what you want is exactly like my SASHELP.PRDSALE example. But the code you've posted is nothing equivalent to the code I posted. There's the issue of the variables on the COLUMN not matching the variables on the DEFINE and then theres the issue of HLINE not being the first item on the COLUMN statement .

Cynthia

SASuserlot
Barite | Level 11

Thanks for your patience. I able to get the excel format the way I want with your guidance . Thanks for that. I am still having the problem with color code. Can you please check what's wrong with my code to get the color. I did not see any errors in the log files

/*I want to color the SOFA with Yellow background and remain with red background*/

data sales;
set  SASHELP.PRDSALE;
where actual gt 850 and predict gt 900;
if product="SOFA" then flag="Y";
else flag="N";
run;
 ods excel file='C:\Users\xx\Desktop\New folder\xx\report_modified.xlsx';
 proc report data=sales;
 column region country prodtype product actual predict flag;
 define region /order noprint;
 define country/order;
 define prodtype/display;
 define product/display;
 define actual/display f= dollar12.;
 define predict/display f= dollar12.;
 define flag/ display;*noprint;
 compute before region/style={just=c fontweight=bold};
 line region $varying80.;
 if	flag="Y" then do;
		CALL DEFINE('Product', 'style', 'STYLE={BACKGROUND=yelllow}');
 end;
 else if flag='N' then  do;CALL DEFINE('Prodcut', 'style', 'STYLE={BACKGROUND=red}');
 end;
 endcomp;
 run;
 ods excel close;
Cynthia_sas
SAS Super FREQ

Hi:
You are using the COMPUTE BEFORE and the CALL DEFINE on the wrong variables. There are no variables on the break line written with the LINE statement. Did you review my paper on break processing that I posted: https://support.sas.com/resources/papers/proceedings17/SAS0431-2017.pdf -- the LINE statement writes EXTRA break lines, but the row from the LINE statement spans the entire table. There are NOT any data cells when you use a LINE statement.
So here are my numbered comments that correspond to the output below -- Your original code produced this output with all the color coding attempts removed. I made flag visible so you could see that it did not exist on the row written by the LINE statement:

Cynthia_sas_0-1602379233082.png


1) in your CALL DEFINE, you are changing the color for the PRODUCT cell. Your LINE statement is writing out REGION, but you're changing the color of the PRODUCT cell. The LINE statement is writing 1 report row -- PRODUCT is NOT a column on this report row. FLAG is not a column on this report row. You can't color code PRODUCT on this row and you can't test FLAG on this row. At the point in time where the COMPUTE block before region is EXECUTING, the FLAG variable is not visible on the report row.
2) FLAG appears on every report row for data so you could have a COMPUTE block for FLAG that changed the background color of PRODUCT on each data row..
3) you spelled yellow incorrectly as yelllow, so the color will not be recognized when it does work.

Here's a reworked version of your program showing color coding that works on every data row and also shows how to color the LINE statement rows.

Cynthia_sas_1-1602379292203.png

Notice that I have a separate COMPUTE block for FLAG and I test that value on every row where FLAG appears. Then I use the value of flag to determine the background color of the PRODUCT cell on that same row.

 

Just because EAST and WEST are underneath the PRODUCT column header, does not mean that you can use the CALL DEFINE in the COMPUTE BEFORE REGION to change the color of EAST or WEST. Notice that in the COMPUTE BEFORE REGION statement, I have added background= to the style override on the COMPUTE statement. The ONLY thing that touches the LINE output row is the style override that you have on the COMPUTE block (but there are NOT any data cells on that row, there's only what you write with the LINE statement).

 

Cynthia

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