BookmarkSubscribeRSS Feed
Leondou
Calcite | Level 5

I've got some code that assigns a unique ID to observations in a SAS table. This unique ID is then used to generate graphs using SGPLOT corresponding to that ID, and insert them as .PNG files into an email.

 

This code runs fine in SAS 7.11 but I'm migrating the existing code to SAS 8.3, and SAS 8.3 appears to behave differently.

 

  1. First, the 'volume' observations get an image ID equal to ((_n_ * 4)-3) and the 'percentage' observations get an image ID equal to ((_n_ * 4)-1).

 

	id_num=_N_;  /* Images generate skipping every second number, the formulas below align the numbers to the charts so we know whats what when building the email. */
	Volume_ImageID = ((_n_ * 4)-3);
	Percent_ImageID = ((_n_ * 4)-1);

	Volume_text=compress(put(Volume_ImageID,best3.));
	Percent_text=compress(put(Percent_ImageID,best3.));
	Volume_attach_text=catt('"/email',compress(put(Volume_ImageID,best3.)),'.png"'," inlined='image",compress(put(Volume_ImageID,best3.)),"'");
	Percent_attach_text=catt('"/email',compress(put(Percent_ImageID,best3.)),'.png"'," inlined='image",compress(put(Percent_ImageID,best3.)),"'");

 

2. The dataset generated from above gives me the following, which is correct:

Leondou_0-1692260298310.png

3. I then have a macro which outputs the generated graphs for each unique ID. The full macro code is further down below.

	ods listing gpath="&workdir.";
	ods graphics on / /*reset=index(1)*/ outputfmt=png imagename='email';

4. In SAS 7.11, the code above somehow spits out the following .png files, which is correct:

email1.png

email3.png

and so on, based on the number of loops/observations.

 

5. In SAS 8.3, it spits out:

email.png

email1.png

 

which generates a file not found error when the email macro tries to insert email3.png or any additional .PNGs.

 

6. I've looked around resetting indexes (starting the index from 1 doesn't solve the fact that the files named using increments of 2), using BY values, but I'm a bit over my head as the code was written by a former employee. I'm hoping there's an easier way of assigning an ID to the observations which will also make outputting the .PNG files easier. 

 

Any help would be greatly appreciated, please let me know if you need more sample code or data.

 

Full macro code from Point 3, which generates the charts using SGPLOT and outputs them as .PNG files.

%macro generate_charts(sel_QMBL, sel_category);
%let max_total_count=0;
%let max_queue_est_count=0;
%let max_outer_high=0;
%let vol_max_count=0;

	DATA VRNTCLK.CC_DATA_TEST;
	SET VADROP.UC9_SA_VERINT_CC;
	Category=TRANWRD(category,'z_','');
	Category=TRANWRD(category,'T_','');
	where (TRANWRD(category,'z_','')=&&sel_category or TRANWRD(category,'T_','')=&&sel_category)
		  and MBL = &&sel_QMBL
		  and segment='Total MBL Cat'
		  and ddate between &st_date and &_repdate3;
	RUN;

	proc sort data=VRNTCLK.CC_DATA_TEST;
	by ddate MBL;
	run;

	/* max chart values */
	PROC SQL noprint;
		select 	max(total_count) as v1, 
				max(queue_est_count) as v2, 
				max(outer_high) as v3,
				round(max((calculated v1), (calculated v2), (calculated v3)) + 4,10) as v4 
		into 	:max_total_count, 
				:max_queue_est_count, 
				:max_outer_high,
				:vol_max_count 
		from VRNTCLK.CC_DATA_TEST;
	QUIT;


	ods listing gpath="&workdir.";
	ods graphics on / /*reset=index(1)*/ outputfmt=png imagename='email';

	title &sel_category ' on ' &sel_QMBL;

	proc sgplot data=VRNTCLK.CC_DATA_TEST noautolegend noborder pad=0;
	/* title1 Volume Control Chart for &_repdate2;
	title2 &sel_category ' on ' &sel_QMBL; */
	 	styleattrs 	datasymbols=(circlefilled)
					datalinepatterns=(solid); 
	  	band x=ddate lower=outer_low upper=outer_high /fillattrs=(color='#c9f1ff');
	 	band x=ddate lower=middle_low upper=middle_high /fillattrs=(color='#82d0f8');
		band x=ddate lower=inner_low upper=inner_high /fillattrs=(color='#00b0f0');
		series y=Day20MA x=ddate /group=category  lineattrs=(Color='#9b0503' thickness=3 pattern=longdash);
		series y=Queue_Est_Count x=ddate /group=category  lineattrs=(color='#3d5aae' thickness=3);
		format ddate date9.;
	   	xaxis min=&st_date max=&_repdate3 offsetmin=0 offsetmax=0 display=(nolabel) type=time interval=day /* grid */;
	   	yaxis display=(nolabel) min=0 /*values=(0 to &vol_max_count)*/ /* grid */;
		INSET "&&sel_category. on &&sel_QMBL." / POSITION = TOPRIGHT BORDER; 
	run; 

	proc sgplot data=VRNTCLK.CC_DATA_TEST noautolegend noborder pad=0;
	/* title1 Percentage Control Chart for &_repdate2;
	title2 &sel_category ' on ' &sel_QMBL; */
		styleattrs 	datasymbols=(circlefilled)
					datalinepatterns=(solid); 
	  	band x=ddate lower=outer_low_perc upper=outer_high_perc /fillattrs=(color='#c9f1ff');
	 	band x=ddate lower=middle_low_perc upper=middle_high_perc /fillattrs=(color='#82d0f8');
		band x=ddate lower=inner_low_perc upper=inner_high_perc /fillattrs=(color='#00b0f0');
		series y=Day20MA_perc x=ddate /group=category  lineattrs=(Color='#9b0503' thickness=3 pattern=longdash);
		series y=perc_rcvd x=ddate /group=category  lineattrs=(color='#3d5aae' thickness=3);
		format ddate date9.;
	   	xaxis min=&st_date max=&_repdate3 offsetmin=0 offsetmax=0 display=(nolabel) type=time interval=day /* grid */;
	   	yaxis display=(nolabel) min=0 /* grid */;
		format Day20MA_Perc percent8.4; 
		Format Day20StdDev_Perc percent8.4; 
		Format Inner_High_Perc percent8.4; 
		Format Inner_Low_Perc percent8.4; 
		Format Middle_High_Perc percent8.4; 
		Format Middle_Low_Perc percent8.4; 
		Format Outer_High_Perc percent8.4; 
		Format Outer_Low_Perc percent8.4; 
		Format Perc_Rcvd percent8.4; 
		Format queue_ans_perc percent8.4;
		INSET "&&sel_category. on &&sel_QMBL." / POSITION = TOPRIGHT BORDER;
	run;
%mend generate_charts;

 

10 REPLIES 10
JosvanderVelden
SAS Super FREQ
The versions you mention (7.11 and 8.3) are for SAS Enterprise Guide. Do you know if the SAS server installation was upgraded with the change from guide 7.11 to guide 8.3? If yes what were the versions of SAS installed on the server?
Leondou
Calcite | Level 5

Correct, this is for SAS EG - both SAS EG 7.12 HF2 and SAS EG 8.3 are installed locally.

 

The 7.12 HF2 server has this:

Leondou_0-1692314863023.png

 

and the 8.3 server has this:

Leondou_1-1692314890822.png

 

Is this what you were referring to?

 

 

Tom
Super User Tom
Super User

Those look like version for the metadata servers.

The question is what version of SAS are you using to run the SAS code.  Enterprise Guide is just a front end tool to help you create the SAS code.  You have to use an actual copy of SAS itself to run the code that could call ODS to make an PNG file.

 

Just run the following code to see the SAS version printed in the log.

%put &=sysvlong;

Or run PROC SETINIT.

 

You also might have changed some system options between the two versions of SAS that could impact how PNG files are generated.

Leondou
Calcite | Level 5

Thanks for clarifying. 

This is the log for SAS 7.11:

 

 

1          ;*';*";*/;quit;run;
2          OPTIONS PAGENO=MIN;
3          %LET _CLIENTTASKLABEL='Program';
4          %LET _CLIENTPROCESSFLOWNAME='Process Flow';
5          %LET _CLIENTPROJECTPATH='P:\Use cases\Current\UC9\Leon - SAS\EMS Duration and Hold Analysis.egp';
6          %LET _CLIENTPROJECTNAME='EMS Duration and Hold Analysis.egp';
7          %LET _SASPROGRAMFILE=;
8          
9          ODS _ALL_ CLOSE;
10         OPTIONS DEV=ACTIVEX;
11         GOPTIONS XPIXELS=0 YPIXELS=0;
12         FILENAME EGSR TEMP;
13         ODS tagsets.sasreport13(ID=EGSR) FILE=EGSR
14             STYLE=HtmlBlue
15             STYLESHEET=(URL="file:///C:/ProgramData/App-V/121B6453-3B52-4AA7-A575-9FD35C2CDB45/5C2E6C51-2BE5-4400-8ABA-7F5C9138EE
15       ! 81/Root/VFS/ProgramFilesX64/SASHome/SASEnterpriseGuide/7.1/Styles/HtmlBlue.css")
16             NOGTITLE
17             NOGFOOTNOTE
18             GPATH=&sasworklocation
19             ENCODING=UTF8
20             options(rolap="on")
21         ;
NOTE: Writing TAGSETS.SASREPORT13(EGSR) Body file: EGSR
22         
23         GOPTIONS ACCESSIBLE;
24         %put &=sysvlong;
SYSVLONG=9.04.01M2P072314
25         
26         GOPTIONS NOACCESSIBLE;
27         %LET _CLIENTTASKLABEL=;
28         %LET _CLIENTPROCESSFLOWNAME=;
29         %LET _CLIENTPROJECTPATH=;
30         %LET _CLIENTPROJECTNAME=;
31         %LET _SASPROGRAMFILE=;
32         
33         ;*';*";*/;quit;run;
34         ODS _ALL_ CLOSE;
35         
36         
37         QUIT; RUN;
38         

and the same for 8.3:

 

 

1                                                          The SAS System                        Friday, August 18, 2023 10:50:00 AM

1          ;*';*";*/;quit;run;
2          OPTIONS PAGENO=MIN;
3          %LET _CLIENTTASKLABEL='Program';
4          %LET _CLIENTPROCESSFLOWNAME='Standalone Not In Project';
5          %LET _CLIENTPROJECTPATH='';
6          %LET _CLIENTPROJECTPATHHOST='';
7          %LET _CLIENTPROJECTNAME='';
8          %LET _SASPROGRAMFILE='';
9          %LET _SASPROGRAMFILEHOST='';
10         
11         ODS _ALL_ CLOSE;
12         OPTIONS DEV=PNG;
13         GOPTIONS XPIXELS=0 YPIXELS=0;
14         %macro HTML5AccessibleGraphSupported;
15             %if %_SAS_VERCOMP_FV(9,4,4, 0,0,0) >= 0 %then ACCESSIBLE_GRAPH;
16         %mend;
17         
18         %put &=sysvlong;
SYSVLONG=9.04.01M7P080620
19         
20         %LET _CLIENTTASKLABEL=;
21         %LET _CLIENTPROCESSFLOWNAME=;
22         %LET _CLIENTPROJECTPATH=;
23         %LET _CLIENTPROJECTPATHHOST=;
24         %LET _CLIENTPROJECTNAME=;
25         %LET _SASPROGRAMFILE=;
26         %LET _SASPROGRAMFILEHOST=;
27         
28         ;*';*";*/;quit;run;
29         ODS _ALL_ CLOSE;
30         
31         
32         QUIT; RUN;
33         

I'll compare the system options between the 2 and make sure they're aligned.

 

Leondou
Calcite | Level 5

Sorry my last message timed out.

 

For SAS 7.1, the server version is SYSVLONG=9.04.01M2P072314.

The server which SAS EG 8.3 connects to is down for the moment, but it was definitely something like SAS GRID 9.4 M7.

 

I've also aligned the options between the two EGs as best I can; the only relevant difference I could tell was that I enabled the 'embed handcoded ODS results in EG project' option under Results General in 8.3. Will try running the code again soon to see if there's any change.

JosvanderVelden
SAS Super FREQ

Can you please run a test with both servers with the code below and verify if the imagenames are the same on both. You'll have to set the path to a path that works for you (1st line in the program).

 

%let path = /home/&sysuserid/4tests; 
ods listing close;
ods html close;
ods graphics off;
ods html body="test.html" path="&path.";
ods graphics on / reset=index(1) imagename="test" height=80px width=160px border=off;
ods listing style=htmlblue gpath="&path.";
proc sgplot data=sashelp.class noborder noautolegend;
   ods html exclude sgplot;
   styleattrs datacolors=(pink blue) datasymbols=(circlefilled);
   hbar sex / barwidth=0.5 group=sex baselineattrs=(thickness=0px)
              outlineattrs=(color=black) dataskin=gloss;
   yaxis display=(nolabel noticks noline);
   xaxis display=(nolabel) offsetmax=0;
run;
proc sgplot data=sashelp.class noborder noautolegend;
   ods html exclude sgplot;
   styleattrs datacolors=(pink blue) datasymbols=(circlefilled);
   hbar sex / barwidth=0.5 group=sex baselineattrs=(thickness=0px)
              outlineattrs=(color=black) dataskin=gloss;
   yaxis display=(nolabel noticks noline);
   xaxis display=(nolabel) offsetmax=0;
run;
ods listing close;
ods html close;
ods graphics off;

NOTE: reset=index(1) should set starting imagename to test1.

Leondou
Calcite | Level 5

Thanks, ran the code and the filenames somehow aren't working as expected.

 

In 8.3:

I get test.html, test2.png, and test4.png

 

Log:

1                                                          The SAS System                        Monday, August 21, 2023 12:03:00 PM

1          ;*';*";*/;quit;run;
2          OPTIONS PAGENO=MIN;
3          %LET _CLIENTTASKLABEL='Program';
4          %LET _CLIENTPROCESSFLOWNAME='Standalone Not In Project';
5          %LET _CLIENTPROJECTPATH='';
6          %LET _CLIENTPROJECTPATHHOST='';
7          %LET _CLIENTPROJECTNAME='';
8          %LET _SASPROGRAMFILE='';
9          %LET _SASPROGRAMFILEHOST='';
10         
11         ODS _ALL_ CLOSE;
12         OPTIONS DEV=ACTIVEX;
13         GOPTIONS XPIXELS=0 YPIXELS=0;
14         %macro HTML5AccessibleGraphSupported;
15             %if %_SAS_VERCOMP_FV(9,4,4, 0,0,0) >= 0 %then ACCESSIBLE_GRAPH;
16         %mend;
17         FILENAME EGSR TEMP;
18         ODS tagsets.sasreport13(ID=EGSR) FILE=EGSR
19             STYLE=HTMLBlue
20             NOGTITLE
21             NOGFOOTNOTE
22             GPATH=&sasworklocation
23             ENCODING=UTF8
24             options(rolap="on")
25         ;
NOTE: Writing TAGSETS.SASREPORT13(EGSR) Body file: EGSR
26         
27         %let path = /sasdata/dev/VEA1007/Data/Raw/Verint/temp/control_charts;
28         ods listing close;
29         ods html close;
30         ods graphics off;
31         ods html body="test.html" path="&path.";
NOTE: Writing HTML Body file: test.html
32         ods graphics on / reset=index(1) imagename="test" height=80px width=160px border=off;
33         ods listing style=htmlblue gpath="&path.";
34         proc sgplot data=sashelp.class noborder noautolegend;
35            ods html exclude sgplot;
36            styleattrs datacolors=(pink blue) datasymbols=(circlefilled);
37            hbar sex / barwidth=0.5 group=sex baselineattrs=(thickness=0px)
38                       outlineattrs=(color=black) dataskin=gloss;
39            yaxis display=(nolabel noticks noline);
40            xaxis display=(nolabel) offsetmax=0;
41         run;

NOTE: PROCEDURE SGPLOT used (Total process time):
      real time           0.11 seconds
      cpu time            0.05 seconds
      
NOTE: This graph has ATTRPRIORITY=COLOR in effect. The cycling of your custom symbols and/or line patterns is based on color 
      priority. Please see ODS Graphics documentation on ATTRPRIORITY= option.
NOTE: This graph has ATTRPRIORITY=COLOR in effect. The cycling of your custom symbols and/or line patterns is based on color 
      priority. Please see ODS Graphics documentation on ATTRPRIORITY= option.
NOTE: Listing image output written to /sasdata/dev/VEA1007/Data/Raw/Verint/temp/control_charts/test2.png.
NOTE: There were 19 observations read from the data set SASHELP.CLASS.
NOTE: MVA_DSIO.OPEN_CLOSE| _DISARM|         STOP| _DISARM| 2023-08-21T14:16:31,998+10:00| _DISARM| WorkspaceServer| _DISARM| | 
      _DISARM| | _DISARM| | _DISARM| 41324544| _DISARM| 13| _DISARM| 13| _DISARM| 624| _DISARM| 4416| _DISARM| | _DISARM| | 
      _DISARM| | _DISARM| | _DISARM| | _DISARM| | _ENDDISARM 
NOTE: PROCEDURE| _DISARM|         STOP| _DISARM| 2023-08-21T14:16:31,998+10:00| _DISARM| WorkspaceServer| _DISARM| | _DISARM| | 
2                                                          The SAS System                        Monday, August 21, 2023 12:03:00 PM

      _DISARM| | _DISARM| 41324544| _DISARM| 13| _DISARM| 13| _DISARM| 624| _DISARM| 4416| _DISARM| | _DISARM| | _DISARM| | 
      _DISARM| | _DISARM| | _DISARM| | _ENDDISARM 

42         proc sgplot data=sashelp.class noborder noautolegend;
43            ods html exclude sgplot;
44            styleattrs datacolors=(pink blue) datasymbols=(circlefilled);
45            hbar sex / barwidth=0.5 group=sex baselineattrs=(thickness=0px)
46                       outlineattrs=(color=black) dataskin=gloss;
47            yaxis display=(nolabel noticks noline);
48            xaxis display=(nolabel) offsetmax=0;
49         run;

NOTE: PROCEDURE SGPLOT used (Total process time):
      real time           0.07 seconds
      cpu time            0.02 seconds
      
NOTE: This graph has ATTRPRIORITY=COLOR in effect. The cycling of your custom symbols and/or line patterns is based on color 
      priority. Please see ODS Graphics documentation on ATTRPRIORITY= option.
NOTE: This graph has ATTRPRIORITY=COLOR in effect. The cycling of your custom symbols and/or line patterns is based on color 
      priority. Please see ODS Graphics documentation on ATTRPRIORITY= option.
NOTE: Listing image output written to /sasdata/dev/VEA1007/Data/Raw/Verint/temp/control_charts/test4.png.
NOTE: There were 19 observations read from the data set SASHELP.CLASS.
NOTE: MVA_DSIO.OPEN_CLOSE| _DISARM|         STOP| _DISARM| 2023-08-21T14:16:32,075+10:00| _DISARM| WorkspaceServer| _DISARM| | 
      _DISARM| | _DISARM| | _DISARM| 41324544| _DISARM| 13| _DISARM| 13| _DISARM| 360| _DISARM| 4776| _DISARM| | _DISARM| | 
      _DISARM| | _DISARM| | _DISARM| | _DISARM| | _ENDDISARM 
NOTE: PROCEDURE| _DISARM|         STOP| _DISARM| 2023-08-21T14:16:32,075+10:00| _DISARM| WorkspaceServer| _DISARM| | _DISARM| | 
      _DISARM| | _DISARM| 41324544| _DISARM| 13| _DISARM| 13| _DISARM| 360| _DISARM| 4776| _DISARM| | _DISARM| | _DISARM| | 
      _DISARM| | _DISARM| | _DISARM| | _ENDDISARM 

50         ods listing close;
51         ods html close;
52         ods graphics off;
53         
54         %LET _CLIENTTASKLABEL=;
55         %LET _CLIENTPROCESSFLOWNAME=;
56         %LET _CLIENTPROJECTPATH=;
57         %LET _CLIENTPROJECTPATHHOST=;
58         %LET _CLIENTPROJECTNAME=;
59         %LET _SASPROGRAMFILE=;
60         %LET _SASPROGRAMFILEHOST=;
61         
62         ;*';*";*/;quit;run;
63         ODS _ALL_ CLOSE;
64         
65         
66         QUIT; RUN;
67         

And in 7.11, I get a weird syntax error whenever I put a number in reset=index(int), even after manually re-typing all of the code. reset=index by itself worked fine though, oddly.

 

NOTE: Writing TAGSETS.SASREPORT13(EGSR) Body file: EGSR
NOTE: Writing HTML Body file: test.html
29         ods graphics on / reset=index(1) imagename="test" height=80px width=160px border=off;
                                        _
                                        22
                                        200

ERROR 22-322: Syntax error, expecting one of the following: ;, ANTIALIAS, ANTIALIASMAX, ATTRPRIORITY, BORDER, BYLINE, DATASKINMAX, 
              DISCRETEMAX, DRILLTARGET, GROUPMAX, HEIGHT, IMAGEMAP, IMAGENAME, LABELMAX, LABELPLACEMENT, LOESSMAXOBS, 
              MAXLEGENDAREA, NOANTIALIAS, NOBORDER, NOIMAGEMAP, NOSCALE, NOSCALEMARKERS, OUTPUTFMT, PANELCELLMAX, RESET, SCALE, 
              SCALEMARKERS, TIPMAX, WIDTH.  

ERROR 200-322: The symbol is not recognized and will be ignored.

Although it didn't output "test1.html" as expected, it did output test.html, SGPlot1.png and SGPlot3.png.

 

JosvanderVelden
SAS Super FREQ
The ods graphics option RESET=INDEX<(positive-integer)> was introduced with SAS 9.4M3. I assume the server used for eguide 7.11 is a previous version of SAS. If you want to verify you can run the statement: "%put &sysvlong;" from eguide 7.11. The log should display the running sas version. I will investigate options to analyze the imagenumbering issue you are experiencing. If you need a quick answer please open a ticket with SAS Technical support. https://support.sas.com/en/technical-support/submit-a-support-request.html
Leondou
Calcite | Level 5

@JosvanderVelden Thanks, I'll look into going thru support. 

 

@Kurt_Bremser Thanks, could you clarify this a bit more for me please? Currently both pieces of code are in the same program in terms of the process flow. 

sas-innovate-2024.png

Available on demand!

Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.

 

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