Hello,
I am trying to create a set of XML files using sas version 9.1.3 with z/OS. Creating the files is not the problem I have been able to successfully create the files and use filename FTP to move them off the mainframe into a windows environment and open them successfully. Something like this:
FILENAME FTP1 FTP NAME1
.
.
.
RUN;
ODS TAGSETS.EXCELXP FILE=FTP1 STYLE=STYLES.CUSTOM
OPTIONS (...
RUN;
DATA _NULL_;
.
.
.
PUT _ODS_;
RUN;
PROC REPORT ...'
.
.
.
RUN;
ODS _ALL_ CLOSE;
Instead of FTP'ing the files I would like to email them, but I am having problems attaching the .XML file. Instead of writing them to FTP I thought I would create a TEMP space and write to that, then attach the file by using the fileref. Like so:
FILENAME F01 TEMP;
ODS TAGSETS.EXCELXP FILE=F01 STYLE=STYLES.CUSTOM
OPTIONS (...
RUN;
DATA _NULL_;
.
.
.
PUT _ODS_;
RUN;
PROC REPORT ...'
.
.
.
RUN;
ODS _ALL_ CLOSE;
FILENAME MYEMAIL EMAIL
FROM = ...
TO = ...
SUBJECT = "TEST STATE OF AR EMAILS FOR &AGENCY"
ATTACH = ("F01");
DATA _NULL_;
FILE MYEMAIL
PUT
// " HERE IS A TEST EMAIL, WITH ATTACHMENT";
RUN;
I keep getting an error stating "Invalid value for the ATTACH option." I have tried attaching several different ways but keep getting the same error. Can I attach a TEMP fileref in an email? All I am trying to accomplish is to generate the XML files without having to allocate and write to a physical file (dataset).
Thanks.
TEMP files won't last long enough for you - I think they are "too temp"!
Define f01
FILENAME F01 '&my.report' space=cyl(1,1) disp=(,pass) ;
It's been a while since my last zOS assignment so that definition of the FILENAME host options might not be entirely OK. Would be wise of you to check the SAS Companion for zOS.
I beleive the attach option does not accept a fileref, only a full file path, or a sas catalog. You can still do this with a temp file, you just need to add a step to collect the path of the temp file. You can collect this from the sashelp.vextfl table
proc sql noprint;
select xpath into :f01
from sashelp.vextfl
where fileref='F01';
quit;
filename myemail email from=... to=... subject="..." attach="&f01";
Thanks FriedEgg,
I plugged in your solution and it appeared to work becuase I was able to resolve my macro variable &F01 to a full file path, however I am getting this error:
WARNING: The quoted string currently being processed has become more than 262 characters long. You may have unbalanced quotation marks.
ERROR: System abend 0C4 occurred in module SASXAL function VXSPPTH at offset 00005C.
I have no idea where the unbalanced quotation marks are and was not getting them before or what the error message means, and ideas where to start?
It has been many years since I worked with SAS for z/OS so my skills are a bit rusty to that systems peculiarities. If you can send more information from the log and the value the &f01 resolved to.
I don't often use SQL so I changed my approach to be something I'm a little more familiar with. Here is what I did (from my log):
DATA _NULL_;
set sashelp.vextfl(keep=fileref xpath);
where fileref='F01';
call symputx('fpath',xpath,'l');
NOTE: There were 1 observations read from the data set SASHELP.VEXTFL. WHERE fileref='F01';
data _null_;
FILE MYEMAIL
SYMBOLGEN: Macro variable FPATH resolves to SYS11306.T163644.RA000.GP461ENR.R0107137
ATTACH = ("&fpath");
PUT "Test" ;
RUN;
NOTE: The file MYEMAIL is:
E-Mail Access Device
ERROR: Error opening attachment file SYS11306.T163644.RA000.GP461ENR.R0107137.
ERROR: Physical file does not exist, SYS11306.T163644.RA000.GP461ENR.R0107137.
I don't understand why I get an error stating the Physical file does not exist, when I can get my macro variable to resolve to it?
to attach a file you have to write it as a file not an email
So (I think) it is the definition of the file F01 that needs to change.
by the way, on all platforms (that I know, including zOS) the easiest way to obtain the physical path for logical reference is
%let physical = %sysfunc( pathname( &logical )) ;
Peter,
You are probably right in that it is the way I am defining F01, for clarification this is how I have been defining it:
FILENAME F01 TEMP;
Then I write my steps to produce my XML file, pointing my ODS to F01. It seems to be working except for I can not attach F01(the fileref) or the Physical file name of F01(%let physical = %sysfunc( pathname( &logical ));) to an email. Is my only option to allocate a dataset for every file I plan on creating, writing my XML to the dataset, then attaching the dataset?
What I am trying to achieve is a program that will create a variable number of XML files, dependent on the data, and email them all out
TEMP files won't last long enough for you - I think they are "too temp"!
Define f01
FILENAME F01 '&my.report' space=cyl(1,1) disp=(,pass) ;
It's been a while since my last zOS assignment so that definition of the FILENAME host options might not be entirely OK. Would be wise of you to check the SAS Companion for zOS.
Thanks Peter for your follow ups here, I agree that the issue seems to be that the temp file will not work for this situation and that a properly defined non-temp filename declaration would be better suited. For curiosity, OP, can you run something like this so I can see the log? Temp files should exist for the duration of the session, however maybe it has something to do with the ods close?
%macro sendmail;
%if g_fileexist=1 %then
%do;
filename eml email 'someone@work.com'
subject='File attachment test'
attach=("&g_fname" content_type='text/xml' name='attact_test' extension='xml');
data _null_;
file eml;
put 'This is a test...';
run;
%end;
%mend;
%global g_fname g_fileexist
%local fexist xpath xpathexist;
filename f01 temp;
ods listing close;
ods tagsets.excelxp file=f01 style=meadow;
proc print data=sashelp.class; run;
%let fexist=%sysfunc(fexist(f01));
data _null_;
set sashelp.vextfl;
where fileref='F01';
call symputx('xpath',xpath);
run;
%let g_fname=%sysfunc(pathname(f01));
%let g_fileexist=%sysfunc(fileexist(&g_fname));
%let xpathexist=%sysfunc(fileexist(&xpath));
%put NOTE: BEFORE ODS CLOSE;
%put NOTE: FEXIST=&fexist;
%put NOTE: FNAME=&g_fname XPATH=&xpath;
%put NOTE: FILEEXIST=&g_fileexist XPATHEXIST=&xpathexist;
%sendmail
ods tagsets.excelxp close;
%let fexist=%sysfunc(fexist(f01));
data _null_;
set sashelp.vextfl;
where fileref='F01';
call symputx('xpath',xpath);
run;
%let g_fname=%sysfunc(pathname(f01));
%let g_fileexist=%sysfunc(fileexist(&g_fname));
%let xpathexist=%sysfunc(fileexist(&xpath));
%put NOTE: AFTER ODS CLOSE;
%put NOTE: FEXIST=&fexist;
%put NOTE: FNAME=&g_fname XPATH=&xpath;
%put NOTE: FILEEXIST=&g_fileexist XPATHEXIST=&xpathexist;
%sendmail
FriedEgg,
I am not sure your code is working as expected. I am getting this error in my log:
15 %GLOBAL G_FNAME G_FILEEXIST;
16 %LOCAL FEXIST XPATH XPATHEXIST;
ERROR: The %LOCAL statement is not valid in open code.
Should %LOCAL FEXIST XPATH XPATHEXIST; be put in the data step?
Sorry, just remove those two statements, they are not necessary anyway.
Here it is, no email was sent:
2 %MACRO SENDMAIL;
3 %IF G_FILEEXIST=1 %THEN
4 %DO;
5 FILENAME EML EMAIL 'some.one@work.com'
6 SUBJECT='FILE ATTACHMENT TEST'
7 ATTACH=("&G_FNAME" CONTENT_TYPE='TEXT/XML' NAME='ATTACT_TEST'
8 EXTENSION='XML');
9 DATA _NULL_;
10 FILE EML;
11 PUT 'THIS IS A TEST...';
12 RUN;
13 %END;
14 %MEND;
15 %GLOBAL G_FNAME G_FILEEXIST;
16
17 FILENAME F01 TEMP;
18 ODS LISTING CLOSE;
19 ODS TAGSETS.EXCELXP FILE=F01 STYLE=MEADOW;
NOTE: Writing TAGSETS.EXCELXP Body file: F01
NOTE: This is the Excel XP tagset (Compatible with SAS 9.1.3 and above, v1.94
statement for more information.
20 PROC PRINT DATA=SASHELP.CLASS; RUN;
NOTE: There were 19 observations read from the data set SASHELP.CLASS.
21 %LET FEXIST=%SYSFUNC(FEXIST(F01));
22 DATA _NULL_;
23 SET SASHELP.VEXTFL;
24 WHERE FILEREF='F01';
25 CALL SYMPUTX('XPATH',XPATH);
26 RUN;
NOTE: There were 1 observations read from the data set SASHELP.VEXTFL.
WHERE FILEREF='F01';
27 %LET G_FNAME=%SYSFUNC(PATHNAME(F01));
28 %LET G_FILEEXIST=%SYSFUNC(FILEEXIST(&G_FNAME));
29 %LET XPATHEXIST=%SYSFUNC(FILEEXIST(&XPATH));
30 %PUT NOTE: BEFORE ODS CLOSE;
NOTE: BEFORE ODS CLOSE
31 %PUT NOTE: FEXIST=&FEXIST;
NOTE: FEXIST=1
32 %PUT NOTE: FNAME=&G_FNAME XPATH=&XPATH;
NOTE: FNAME=SYS11308.T164648.RA000.XXXENR.R0169855 XPATH=SYS11308.T164648.RA000.XXXENR.R0169855
33 %PUT NOTE: FILEEXIST=&G_FILEEXIST XPATHEXIST=&XPATHEXIST;
NOTE: FILEEXIST=0 XPATHEXIST=0
34 %SENDMAIL
35 ODS TAGSETS.EXCELXP CLOSE;
36 %LET FEXIST=%SYSFUNC(FEXIST(F01));
37 DATA _NULL_;
38 SET SASHELP.VEXTFL;
39 WHERE FILEREF='F01';
40 CALL SYMPUTX('XPATH',XPATH);
41 RUN;
NOTE: There were 1 observations read from the data set SASHELP.VEXTFL.
WHERE FILEREF='F01';
42 %LET G_FNAME=%SYSFUNC(PATHNAME(F01));
43 %LET G_FILEEXIST=%SYSFUNC(FILEEXIST(&G_FNAME));
44 %LET XPATHEXIST=%SYSFUNC(FILEEXIST(&XPATH));
45 %PUT NOTE: AFTER ODS CLOSE;
NOTE: AFTER ODS CLOSE
46 %PUT NOTE: FEXIST=&FEXIST;
NOTE: FEXIST=1
47 %PUT NOTE: FNAME=&G_FNAME XPATH=&XPATH;
NOTE: FNAME=SYS11308.T164648.RA000.XXXENR.R0169855 XPATH=SYS11308.T164648.RA000.XXXENR.R0169855
48 %PUT NOTE: FILEEXIST=&G_FILEEXIST XPATHEXIST=&XPATHEXIST;
NOTE: FILEEXIST=0 XPATHEXIST=0
49 %SENDMAIL
SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!
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.
Ready to level-up your skills? Choose your own adventure.