BookmarkSubscribeRSS Feed
KevinQin
Obsidian | Level 7
Hi,

I think REPLACE statement is very useful. It can update a style element and do not affect other style elements. However, it has been removed from SAS 9.2

Here is my question:
How can I substitue REPLACE statement in SAS 9.2

In my opinion, if I want to modify style element A, I have to follow the steps at below:
1. identify what style elements inherit from A.
2. create a new duplicate style element A_dup and switch all inheritance relationship from A to A_dup
3. modify style element A using CLASS statement.

What is your opinion?
4 REPLIES 4
Cynthia_sas
SAS Super FREQ
Hi:
In the documentation for the REPLACE statement, it says that:
If you use the REPLACE statement to create a style element in the new style definition, all style elements that inherit from that element inherit the definition that is in the new style definition. If you want to keep any attributes that are specified in the definition that is in the parent, you must respecify them in the definition that you create in the child style definition.
From the 9.1.3 doc as outlined here:
http://support.sas.com/rnd/base/early-access/odsdoc2/sashtml/tw5195/z1072349.htm

One reason for using REPLACE in 9.1.3 is that if you used the STYLE statement WITHOUT the correct FROM, inheritance did not cascade down to all the child elements, especially in situations with multiple parent templates involved. The use of REPLACE, especially with respecifying, allowed inheritance to happen after the style changes were applied. For example, if you only needed to change 2 colors in the color list, if you used REPLACE, and only specified the 2 colors, all the other colors in the color list would be undefined and would take on a default value. If you used REPLACE, you had to respecify ALL the colors including the 2 colors you wanted to change.

I'm not clear on why you think that the CLASS statement is -more- work than the REPLACE statement. In prior versions of SAS, you -did- have to trace inheritance. In SAS 9.2, I find that I do NOT have to do much inheritance tracing at all, in order to make my change. I just have to know what the style element is that needs to change. Compare these ways to make the header foreground color purple:
[pre]
** 9.2 syntax:
style Header /
foreground=purple;

class Header /
foreground=purple;

style Header from _self_/
foreground = purple;

** 9.1.3 syntax:
style Header from HeadersandFooters /
foreground = purple;

replace Header /
foreground=purple
background=white
font= fonts('HeadingFont');
[/pre]

You should find in SAS 9.2 that every element that inherits from Header will now show a color of purple, no matter which statement form you use. In SAS 9.1.3, different ways of specifying STYLE or REPLACE would have an adverse impact on inheritance -- sometimes you'd get purple, sometimes you wouldn't. That's the reason that REPLACE went away. For more information about the new syntax, refer to:
http://www2.sas.com/proceedings/sugi31/053-31.pdf

For help with a specific style template or the conversion of a 9.1.3 style template to a 9.2 style template, you might wish to work with Tech Support. In my experience, when converting from SAS 9.1.3 to SAS 9.2 syntax, my templates got shorter using the CLASS statement.

You say you find it useful to update a style element, but not have an impact on other style elements. That seems to defeat the purpose of having inheritance in the first place. I'm not sure you have an issue with the REPLACE statement. It sounds to me like you need to define an entirely new style element and then point to that style element for the report pieces where you don't want any impact from inheritance.

cynthia
KevinQin
Obsidian | Level 7
Cynthina,
Thank you for the explanation.

Here is my question:
If style element A inherits from style element B.
Can I change the attribute of B but do not affect A.

If 9.2, if I change the foreground color of B, A will change accordingly.
I remember 9.1 can do it (using STYLE or REPLACE? I am not sure which one is the right statement.).

May be I am wrong.

My question is how to change B's specific attribute while do not affect child style element A in SAS 9.2.

-Kevin Message was edited by: Kevin Qin
Cynthia_sas
SAS Super FREQ
Hi:
The fact that you could bypass inheritance depending on whether you used a STYLE statement or a REPLACE statement was considered to be unacceptable/undesirable behavior by most style template writers. So the underlying assumption (in making REPLACE go away) was to make sure that inheritance was resolved in style templates more like the resolution in CSS (Cascading Style Sheets). The intent is to make sure that a child element changes when a parent element changes -- that's the whole point of inheritance.

If you wanted a child element NOT to change when a parent element changed, that would bypass the inheritance entirely. You could accidentally achieve this behavior in earlier versions of SAS -- usually, by using a STYLE statement without a FROM.

I guess I'd do a couple of different things if you needed a PARENT element to have one set of characteristics and wanted the child element to have another set of characteristics. Let's say you have specifically Header and RowHeader. RowHeader inherits from Header. Note that I am picking "concrete" elements -- these are elements whose color changes you can see in the resulting output. It is harder to give a practical example when talking about "abstract" elements like Cell or Container. Since I don't know -specifically- which elements you do or don't want to change, I picked elements that are quickly visible in an output table. Header controls the Header style of the columns going from left to right in the output results. RowHeader controls the style of the rightmost area, where the OBS column is in PROC PRINT or the row headers and class levels are in PROC TABULATE.

The code below shows the following:
1 - Use inheritance to change both Header and RowHeader. Style template only explicitly changes Header.
2 - Change Header colors down in the CLASS statement and point RowHeader to the color list for the original colors.
3 - Change the color_list element, which both Header and RowHeader inherit from -- so Header gets one set of colors and RowHeader gets another set of colors.
4 - Change Header colors directly in the CLASS statement, but point RowHeader to the HeadersandFooters element, which still points to the original colors.
5 - Don't use inheritance at all and define a style template from "scratch" -- this was much harder to do in SAS 9.1.3 -- but is easy to do in SAS 9.2 because you only have to define the style elements you need.

If you need help converting a 9.1.3 style template to a 9.2 style template in order to achieve specific results for a particular destination, your best resource is to open a track with Tech Support.

cynthia
[pre]
ods path work.temp(update)
sashelp.tmplmst(read);
ods listing close;

**1;
proc template;
define style styles.same;
parent=styles.sasweb;
class Header/
background=pink
foreground=purple;
end;
run;

ods html file='c:\temp\make_same.html' style=styles.same;

proc tabulate data=sashelp.class;
title '1 - Using STYLES.SAME';
class age;
var height;
table age,
height*(min mean max);
run;

proc print data=sashelp.class(obs=2);
run;

ods html close;

**2;
proc template;
define style styles.diff;
parent=styles.sasweb;
class Header/
background=pink
foreground=purple;
class RowHeader /
background=color_list('bgA1')
foreground=color_list('bgA');
end;
run;

ods html file='c:\temp\make_diff.html' style=styles.diff;

proc tabulate data=sashelp.class;
title '2 - Using STYLES.DIFF';
class age;
var height;
table age,
height*(min mean max);
run;

proc print data=sashelp.class(obs=2);
run;

ods html close;

**3;
proc template;
define style styles.altdiff;
parent=styles.sasweb;
class color_list /
'bgA1' = cx6495ED
'bgA' = cxffffff
'newfg' = purple
'newbg' = pink;
class Header /
background=color_list('newbg')
foreground=color_list('newfg');
class RowHeader /
background=color_list('bgA1')
foreground=color_list('bgA');
end;
run;

ods html file='c:\temp\make_altdiff.html' style=styles.altdiff;

proc tabulate data=sashelp.class;
title '3 - Using STYLES.ALTDIFF';
class age;
var height;
table age,
height*(min mean max);
run;

proc print data=sashelp.class(obs=2);
run;

ods html close;

** 4;
proc template;
define style styles.othrdiff;
parent=styles.sasweb;
class Header /
background=pink
foreground=purple;
class RowHeader from HeadersandFooters/;
end;
run;

ods html file='c:\temp\make_othrdiff.html' style=styles.othrdiff;

proc tabulate data=sashelp.class;
title '4 - Using STYLES.OTHRDIFF';
class age;
var height;
table age,
height*(min mean max);
run;

proc print data=sashelp.class(obs=2);
run;

ods html close;

** 5;
proc template;
define style styles.scratch;
class Header /
background=pink
foreground=purple
font=(", Helvetica, sans-serif",2,bold);
class RowHeader /
background=cx6495ED
foreground=white
font=(", Helvetica, sans-serif",2,bold);
class SystemTitle /
foreground = cx003399
background=white
font=(", Helvetica, sans-serif",4,bold);
class Body /
background=white;
class Data /
foreground=black
background=white
font=(", Helvetica, sans-serif",2,medium);
class Table /
backgroundcolor = cxcccccc
rules = none
frame = box
borderspacing = 1
bordercollapse = separate
bordercolor = black
cellpadding = 7;
end;
run;

ods html file='c:\temp\make_scratch.html' style=styles.scratch;

proc tabulate data=sashelp.class;
title '5 - Using STYLES.SCRATCH (no Parent Statment and no inheritance)';
class age;
var height;
table age,
height*(min mean max);
run;

proc print data=sashelp.class(obs=2);
run;

ods html close;

title;
footnote;


[/pre]
KevinQin
Obsidian | Level 7
Cynthia,
Yeah, it works.
Thank you.

-Kevin

sas-innovate-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

Register now!

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