Executing PROC SOAP in a loop in SAS - web-services

Purpose of the code
Read a list of numbers from a SAS Dataset
Make a web-service call by substituting each number as a variable in
the XML envelope
Store the XML Response to a temporary/intermediate file
Parse the above file to retrieve essential information (i.e.,
Employee Name and Number) and create/append the dataset that ultimately
provides associated employee information for each of the
numbers from #1.
Code and Other information
Below code creates three sample numbers that need to be used sequentially to make the webservice call.
data cenis;
infile datalines;
input CENI 8.;
datalines;
13413745
12174391
8905899
;
The below code makes the webservice call for number (CENI) 13413745 and produces the output as shown in the snapshot.
filename request temp;
filename response "/mktg/prc203/abhee/output.txt";
data _null_;
file request;
input;
put _infile_;
datalines4;
<soapenv:Envelope xmlns:sch="http://www.XXXX.com/XXXXservice/schema"
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ndf="http://slsexxxdevt1.ute.XXXX.com:10149/XXXX/XXXXservice.wsdl">
<soapenv:Header/>
<soapenv:Body>
<sch:OwnerOnlyInquiryRequest>
<sch:RequestHeader>
<sch:ClientSystem>ePRS</sch:ClientSystem>
</sch:RequestHeader>
<sch:RequestParameterList>
<sch:RequestParam>13413745</sch:RequestParam>
</sch:RequestParameterList>
<sch:RequestType>CESEID</sch:RequestType>
<sch:PeckingOrder>Pricing</sch:PeckingOrder>
<sch:ViewType>Pricing</sch:ViewType>
</sch:OwnerOnlyInquiryRequest>
</soapenv:Body>
</soapenv:Envelope>
;;;;
proc soap in=request
out=response
url="http://slsexxxdevt1.ute.XXXX.com:10149/XXXX/XXXXservice.wsdl"
soapaction="";
run;
data output_dataset;
infile response dsd dlm = ' /';
input #"firstName=" firstName :$32. #"lastName=" lastName :$32. #"emplnbr=" emplnbr :8.;
run;
proc print data=output_dataset;
run;
Problem Statement
I need all of this to work in a macro that can be put in a loop. The final output should be three observations each corresponding to the respective number from the 'cenis' dataset. My attempt to create the macro is as below
%macro parse_single(ID_VAR);
filename request temp;
filename response "/mktg/prc203/abhee/output.txt";
data _null_;
file request;
input;
put _infile_;
datalines4;
<soapenv:Envelope xmlns:sch="http://www.xxxx.com/xxxxservice/schema"
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ndf="http://slsxxxxdevt1.ute.xxxx.com:10149/xxx/xxxxservice.wsdl">
<soapenv:Header/>
<soapenv:Body>
<sch:OwnerOnlyInquiryRequest>
<sch:RequestHeader>
<sch:ClientSystem>ePRS</sch:ClientSystem>
</sch:RequestHeader>
<sch:RequestParameterList>
<sch:RequestParam>&ID_VAR</sch:RequestParam>
</sch:RequestParameterList>
<sch:RequestType>CESEID</sch:RequestType>
<sch:PeckingOrder>Pricing</sch:PeckingOrder>
<sch:ViewType>Pricing</sch:ViewType>
</sch:OwnerOnlyInquiryRequest>
</soapenv:Body>
</soapenv:Envelope>
;;;;
proc soap in=request
out=response
url="http://slsxxxxdevt1.ute.xxxx.com:10149/xxxx/xxxxservice.wsdl"
soapaction="";
run;
data want;
infile response dsd dlm = ' /';
input #"Employee" #"firstName=" firstName :$32. #"lastName=" lastName :$32. #"emplnbr=" emplnbr :8.;
run;
proc print data=want;
run;
%mend parse_single;
The above macro compiles correctly without any errors. Then when I try to execute the same for a specific number manually like below it creates errors.
%parse_single(13413745);
run;
The log is
1 The SAS System 12:47 Wednesday, February 7, 2018
1 %_eg_hidenotesandsource;
5 %_eg_hidenotesandsource;
28
29 %parse_single(13413745);
NOTE: The file REQUEST is:
Filename=/var/xxxx/SAS/WORK/tmp/9.4/SAS_work75F400002FE8_mktpricing/#LN00038,
Owner Name=e0836441,Group Name=pricing,
Access Permission=-rw-r--r--,
Last Modified=07Feb2018:14:56:06
ERROR: The macro PARSE_SINGLE generated CARDS (data lines) for the DATA step, which could cause incorrect results. The DATA step
and the macro will stop executing.
NOTE: 0 records were written to the file REQUEST.
NOTE: DATA statement used (Total process time):
real time 0.01 seconds
cpu time 0.00 seconds
180: LINE and COLUMN cannot be determined.
NOTE: NOSPOOL is on. Rerunning with OPTION SPOOL might allow recovery of the LINE and COLUMN where the error has occurred.
ERROR 180-322: Statement is not valid or it is used out of proper order.
ERROR: The macro PARSE_SINGLE will stop executing.
30 run;
31
32
33 %_eg_hidenotesandsource;
45
46
47 %_eg_hidenotesandsource;
50
My first roadblock is to get the macro working correctly and the second roadblock is to make the %do loop work correctly. When attempted the loop I am getting the same CARDS error.

You cannot use CARDS/DATALINES in macro code. So do it some other way.
I would store the template in a file and use PROC STREAM to read the file and replace any macro expressions.
Or just pass the values to your data _null_ as string literals.
data _null_;
file request;
put
'<soapenv:Envelope xmlns:sch="http://www.xxxx.com/xxxxservice/schema"'
/' xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"'
/' xmlns:ndf="http://slsxxxxdevt1.ute.xxxx.com:10149/xxx/xxxxservice.wsdl">'
/'<soapenv:Header/>'
/' <soapenv:Body>'
/' <sch:OwnerOnlyInquiryRequest>'
/' <sch:RequestHeader>'
....
;
run;

Here is what worked. All credits to my lovely wife!
filename response "/mktg/prc203/abhee/output.txt";
data cenis;
infile datalines;
input CENI $;
datalines;
13413745
12174391
8905899
;
%macro abc;
proc sql noprint;
select count(*) into :cnt
from CENIS;
quit;
%do x=1 %to &cnt;
filename outfile "/mktg/prc203/abhee/input.txt";
data _null_;
set cenis(firstobs=&x obs=&x);
file outfile;
string1='<soapenv:Envelope xmlns:sch="http://www.xxxxx.com/xxxxxservice/schema"';
string2='xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"';
string3='xmlns:ndf="http://slsxxxxxdevt1.ute.xxxxx.com:10149/xxxxx/xxxxxservice.wsdl">';
string4=compress('<sch:RequestParam>'||CENI||'</sch:RequestParam>');
put string1;
put #25 string2;
put #25 string3;
put '<soapenv:Header/>' /
#10 '<soapenv:Body>' /
#15 '<sch:OwnerOnlyInquiryRequest>' /
#15 '<sch:RequestHeader>' /
#15 '<sch:ClientSystem>ePRS</sch:ClientSystem>' /
#15 '</sch:RequestHeader>' /
#15 '<sch:RequestParameterList>' /
#15 string4 /
#15 '</sch:RequestParameterList>' /
#15 '<sch:RequestType>CESEID</sch:RequestType>' /
#15 '<sch:PeckingOrder>Pricing</sch:PeckingOrder>' /
#15 '<sch:ViewType>Pricing</sch:ViewType>' /
#15 '</sch:OwnerOnlyInquiryRequest>' /
#10 '</soapenv:Body>' /
'</soapenv:Envelope>'
;
run;
proc soap in=outfile
out=response
url="http://slsxxxxxdevt1.ute.xxxxx.com:10149/xxxxx/xxxxxservice.wsdl"
soapaction="";
run;
data want;
infile response dsd dlm = ' /';
input #"Employee" #"firstName=" firstName :$32. #"lastName=" lastName :$32. #"emplnbr=" emplnbr :8.;
run;
proc append base=FINAL data=want;
run;
%end;
%mend;
%abc;
proc print data=final;
run;

Related

SAS Macro variable escaping apostrophe in variable name Proc Http

I have been working on this for 3 days now and have tried all I can think of including %str(),%bquote(), translate() and tranwrd() to replace single apostrophe with double apostrophe or %’
The below data step and macro work fine until I hit a last name which contains an apostrophe e.g. O’Brien. I then encounter syntax errors due to un closed left parentheses. The below code I have left what I thought was closest to working with the tranwrd included.
Any assistance you can provide is greatly appreciated.
%macro put_data (object1,id);
Proc http
method=“put”
url=“https://myurl/submissionid/&id”
in=&object1;
Headers “content-type”=“application/json”;
Run;
%mend;
data _null_;
Set work.emp_lis;
call execute(catt(‘%put_data(‘,’%quote(‘’{“data”:{“employeeName”:”’,tranwrd(employeeName,”’’”,”’”),’”}}’’),’,id,’)’));
run;
Craig
There are a wide potential of problems in constructing or passing a json string in SAS macro. Proc JSON will produce valid json (in a file) from data and that file in turn can be specified as the input to be consumed by your web service.
Example:
data have;
length id 8 name $25;
input id& name&;
datalines;
1 Homer Simpson
2 Ned Flanders
3 Shaun O'Connor
4 Tom&Bob
5 'X Æ A-12'
6 Goofy "McDuck"
;
%macro put_data (data,id);
filename jsonfile temp;
proc json out=jsonfile;
export &data.(where=(id=&id));
write values "data";
write open object;
write values "name" name;
write close;
run;
proc http
method="put"
url="https://myurl/submissionid/&id"
in=jsonfile
;
headers "content-type"="application/json";
run;
%mend;
data _null_;
set have;
call execute(cats('%nrstr(%put_data(have,',id,'))'));
run;
I was able to find issue with my code with the tranwrd statement was backwards and it needed to be moved to the proc sql create table statement. I also needed to wrap &object1 in %bquote. This was the final code that worked.
When creating table wrap variables in tranwrd as below.
tranwrd(employeeName, “‘“,”’’”)
% macro put_data (object1,id);
Proc http
method=“put”
url=“https://myurl/submissionid/&id”
in=%bquote(&object1);
Headers “content-type”=“application/json”;
Run;
%mend;
data _null_;
Set work.emp_lis;
call execute(catt(‘%put_data(‘,’%quote(‘’{“data”:{“employeeName”:”’,employeeName,’”}}’’),’,id,’)’));
run;
Just use actual quotes and you won't have to worry about macro quoting at all.
So if your macro looks like this:
%macro put_data(object1,id);
proc http method="put"
url="https://myurl/submissionid/&id"
in=&object1
;
headers "content-type"="application/json";
run;
%mend;
Then the value of OBJECT1 would usually be a quoted string literal or a fileref. (There are actually other forms.) Looks like you are trying to generate a quoted string. So just use the QUOTE() function.
So if your data looks like:
data emp_lis;
input id employeeName $50.;
cards;
1234 O'Brien
4567 Smith
;
Then you can use a data step like this to generate one macro call for each observation.
data _null_;
set emp_lis;
call execute(cats
('%nrstr(%put_data)('
,quote(cats('{"data":{"employeeName":',quote(trim(employeeName)),'}}'))
,',',id
,')'
));
run;
And your SAS log will look something like:
NOTE: CALL EXECUTE generated line.
1 + %put_data("{""data"":{""employeeName"":""O'Brien""}}",1234)
NOTE: PROCEDURE HTTP used (Total process time):
real time 2.46 seconds
cpu time 0.04 seconds
2 + %put_data("{""data"":{""employeeName"":""Smith""}}",4567)
NOTE: PROCEDURE HTTP used (Total process time):
real time 2.46 seconds
cpu time 0.04 seconds

How to import a txt file with single quote mark in a variable and another in another variable, when there are also variables with null values

This is a follow-up of my previous question:
How to import a txt file with single quote mark in a variable and another in another variable.
The solution there works perfectly until there is not a variable whose values could be null.
In this latter case, I get:
filename sample 'c:\temp\sample.txt';
data _null_;
file sample;
input;
put _infile_;
datalines;
001|This variable could be null|PROVA|MILANO|1000
002||'80S WERE GREAT|FORLI'|1100
003||'80S WERE GREAT|ROMA|1110
;
data want;
data prova;
infile sample dlm='|' lrecl=50 truncover;
format
codice $3.
could_be_null $20.
nome $20.
luogo $20.
importo 4.
;
input
codice
could_be_null
nome
luogo
importo
;
putlog _infile_;
run;
proc print;
run;
Is it possible to correctly load a file like the one in the example directly in SAS, without manually modifying the original .txt?
You will need to pre-process the file to fix the issue.
If you add quotes around the values then you will not have the problem.
002||"'80S WERE GREAT"|"FORLI'"|1100
IF you know that none of the values contain the delimiter then adding a space before every delimiter
002 | |'80S WERE GREAT |FORLI' |1100
will let you read it without the DSD option.
If lines are shorter than 32K bytes then it can be done in the same step that reads the data.
data test2 ;
infile sample dlm='|' truncover ;
input #;
_infile_ = tranwrd(_infile_,'|',' |');
input (var1-var5) (:$40.);
run;
proc print;
run;
Results:
Obs var1 var2 var3 var4 var5
1 001 This variable could be null PROVA MILANO 1000
2 002 '80S WERE GREAT FORLI' 1100
3 003 '80S WERE GREAT ROMA 1110
One way to test if you have the issue is to make sure each line has the right number of fields.
filename sample temp;
options parmcards=sample;
parmcards;
001|This variable could be null|PROVA|MILANO|1000
002||'80S WERE GREAT|FORLI'|1100
003||'80S WERE GREAT|ROMA|1110
;
data _null_;
infile sample dsd end=eof;
if eof then do;
call symputx('nfound',nfound);
putlog / 'Found ' nfound :comma11.
'problem lines out of ' _n_ :comma11. 'lines.'
;
end;
input;
retain expect nfound;
words=countw(_infile_,'|','qm');
if _n_=1 then expect=words;
else if expect ne words then do;
nfound+1;
if nfound <= 10 then do;
putlog (_n_ expect words) (=) ;
list;
end;
end;
run;
Example Results:
_N_=2 expect=5 words=4
RULE: ----+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8
2 002||'80S WERE GREAT|FORLI'|1100 32
_N_=3 expect=5 words=3
3 003||'80S WERE GREAT|ROMA|1110 30
Found 2 problem lines out of 4 lines.
PS Go tell SAS to enhance their delimited file processing: https://communities.sas.com/t5/SASware-Ballot-Ideas/Enhancements-to-INFILE-FILE-to-handle-delimited-file-variations/idi-p/435977
You need to add the DSD option to your INFILE statement.
https://support.sas.com/techsup/technote/ts673.pdf
DSD (delimiter-sensitive data) option—Specifies that SAS should treat
delimiters within a data value as character data when the delimiters
and the data value are enclosed in quotation marks. As a result, SAS
does not split the string into multiple variables and the quotation
marks are removed before the variable is stored. When the DSD option
is specified and SAS encounters consecutive delimiters, the software
treats those delimiters as missing values. You can change the default
delimiter for the DSD option with the DELIMTER= option.

ERROR 180-322: Statement is not valid or it is used out of proper

I have searched some info about this error,but it seems none match mine,may someone familiar with this error take a look.
"Code generated by a SAS macro, or submitted with a "submit selected" operation in your editor, can leave off a semicolon inadvertently." it is still abstruse for me to explore in my code by this comment.although I got this error,the outcomes is right.may someone give any advice..thanks!
%let cnt=500;
%let dataset=fund_sellList;
%let sclj='~/task_out_szfh/fundSale/';
%let wjm='sz_fundSale_';
%macro write_dx;
options spool;
data _null_;
cur_date=put(today(),yymmdd10.);
cur_date=compress(cur_date,'-');
cnt=&cnt;
retain i;
set &dataset;
if _n_=1 then i=cnt;
if _n_<=i then do;
abs_filename=&sclj.||&wjm.||cur_date||'.dat';
abs_filename=compress(abs_filename,'');
file anyname filevar=abs_filename encoding='utf8' nobom ls=32767 DLM='|';
put cst_id #;
put '#|' #;
put cust_name #;
put '#|' ;
end;
run;
%mend write_dx;
%write_dx();
and if I am not using macro,there is no error.
data _null_;
options spool;
cur_date=put(today(),yymmdd10.);
cur_date=compress(cur_date,'-');
cnt=&cnt;
retain i;
set &dataset;
if _n_=1 then i=cnt;
if _n_<=i then do;
abs_filename=&sclj.||&wjm.||cur_date||'.dat';
abs_filename=compress(abs_filename,'');
file anyname filevar=abs_filename encoding='utf8' nobom ls=32767 DLM='|';
put cst_id #;
put '#|' #;
put cust_name #;
put '#|' ;
end;
run;
--------------------------------update----------------------------------
I add % to the keyword,but still get the same error
%macro write_dx;
options spool;
data _null_;
cur_date=put(today(),yymmdd10.);
cur_date=compress(cur_date,'-');
cnt=&cnt;
retain i;
set &dataset;
%if _n_=1 %then i=cnt;
%if _n_<=i %then %do;
abs_filename=&sclj.||&wjm.||cur_date||'.dat';
abs_filename=compress(abs_filename,'');
file anyname filevar=abs_filename encoding='utf8' nobom ls=32767 DLM='|';
put cst_id #;
put '#|' #;
put cust_name #;
put '#|' ;
%end;
run;
%mend write_dx;
%write_dx();
Why did you add () to the macro call when the macro is not designed to accept any parameters? If you do that then the () are NOT processed by the macro processor and so are passed along to SAS to interpret. That is the same error message as you would get if you submitted (); by itself.
1 %macro xx ;
2 data _null_;
3 put 'Running data step in macro';
4 run;
5 %mend xx;
6 %xx();
Running data step in macro
NOTE: DATA statement used (Total process time):
real time 0.02 seconds
cpu time 0.00 seconds
6 %xx();
-
180
ERROR 180-322: Statement is not valid or it is used out of proper order.
7 ****;
8 ();
-
180
ERROR 180-322: Statement is not valid or it is used out of proper order.
But if you define it with 0 or more parameters.
%macro param();
generated code
%mend ;
%put |%param()|;
The macro processor will use the () and so they are not passed onto SAS to use.
|generated code|
Change
%macro write_dx;
to
%macro write_dx();
When creating a macro, you have to include the () even if no values are passed.

SAS Macro using multiple lists for conditions

I have a condition table that I want to use to create my other tables. Now I want my code to go through my condition table taking into consideration both condition. My data looks as follow.
Month Date1 Date2 Line
Jan2010 01Jan2010 31Jan2010 PL
Feb2010 01Feb2010 28Feb2010 CB
Feb2010 01Feb2010 28Feb2010 HB
Mar2010 01Mar2010 31Mar2010 PL
Current Code
%Macro Split_Data(Month,BeginDate,EndDate,Line);
Data Want_&Month._&Line.;
Set Have;
Where Date > &BeginDate and Date <&EndDate and Line = '&Line.';
Quit;
%Mend;
%Split_Data(Jan2010,'01JAN2010'd,'31JAN2010'd,PL);
%Split_Data(Jan2010,'01JAN2010'd,'31JAN2010'd,CB);
I don't want to list the macro like this. I would much rather have a table the macro calls up and condition on. Is this possible? How can I create a less manual method. So I can update my condition table without having to update my SAS code.
I think the dates could complicate things. That being said, you can pass the SAS date values across without quotation marks and your macro would still work. If you have other area's that use the date you would have to confirm that it met your requirements. I would usually use a data _null_ step but I saved it to a data set WANT here so you can see the string, if desired.
data want;
set have;
str = catt('%split_data(', put(month, yymon7.), ",", date1, ",", date2, ",", line, ");");
call execute(str);
run;
Use your metadata to generate the code you need.
First set some macro variables (or make a macro with parameters).
%let inds=HAVE;
%let base=WANT ;
%let metadata=METADATA;
Then use the metadata to generate a single data step to write all of the output datasets.
filename code temp;
data _null_;
set &metadata end=eof;
file code ;
if _n_=1 then put 'DATA';
dsname= catx('_',symget('base'),month,line);
put #2 dsname ;
if eof then put ';' / #2 "set &inds;" ;
run;
data _null_;
set &metadata end=eof;
file code mod;
dsname= catx('_',symget('base'),month,line);
put #2 'IF date > "' date1 date9. '"d and date < "' date2 date9. '"d and line=' line :$quote.
'then output ' dsname ';'
;
if eof then put 'run;' ;
run;
Then include the generated code to run it.
%inc code / source2 ;
So for your example the generated code would look like this:
DATA
WANT_Jan2010_PL
WANT_Feb2010_CB
WANT_Feb2010_HB
WANT_Mar2010_PL
;
set HAVE;
IF date > "01JAN2010"d and date < "31JAN2010"d and line="PL" then output WANT_Jan2010_PL ;
IF date > "01FEB2010"d and date < "28FEB2010"d and line="CB" then output WANT_Feb2010_CB ;
IF date > "01FEB2010"d and date < "28FEB2010"d and line="HB" then output WANT_Feb2010_HB ;
IF date > "01MAR2010"d and date < "31MAR2010"d and line="PL" then output WANT_Mar2010_PL ;
run;

Need to repeate data reading from multiple files using sas and run freqs on separate dataset created from separate files

I am new to SAS and facing few difficulties while creating following program.
My requirement is to pass the filename generated dynamically and read it so that don't have to write code five times to read data from 5 different files and then run freqs on the datasets.
I have provided the code below and have to write this code for more than 50 files:
Code
filename inp1 '/chshttp/prod/clients/coms/raw/coms_coms_relg_f1102_t1102_c10216_vEL5535.raw';
filename inp2 '/chshttp/prod/clients/coms/raw/coms_coms_relg_f1103_t1103_c10317_vEL8312.raw';
filename inp3 '/chshttp/prod/clients/coms/raw/coms_coms_relg_f1104_t1104_c10420_vEL11614.raw';
filename inp4 '/chshttp/prod/clients/coms/raw/coms_coms_relg_f1105_t1105_c10510_vEL13913.raw';
filename inp5 '/chshttp/prod/clients/coms/raw/coms_coms_relg_f1106_t1106_c10628_vEL17663.raw';
data test;
Do i = 1 to 5;
infile_name = 'inp' || i;
infile infile_name recfm = v lrecl=1800 end=eof truncover;
INPUT
#1 E_CUSTDEF1_CLIENT_ID $CHAR5.
#1235 E_MED_PLAN_CODE $CHAR20.
#1090 MED_INS_ELIG_COVERAGE_IND $CHAR20.
#1064 MED_COVERAGE_BEGIN_DATE $CHAR8.
#1072 MED_COVERAGE_TERM_DATE $CHAR8.
;
if E_CUSTDEF1_CLIENT_ID ='00002' then
output test;
end;
run;
proc freq data = test;
tables E_CUSTDEF1_CLIENT_ID*E_MED_PLAN_CODE / list missing;
run;
Please help!!
Here's an example you can adapt. There are different ways to do this, but this is one- depending no how you want the frequencies.
Step 1: Create a dataset, 'my_filenames', that stores the filename you want to read in, one per line, in a variable FILE_NAME.
Step 2: Read in the files.
data my_data;
set my_filenames;
infile a filevar=file_name <the rest of your options>;
<your input statement>;
run;
proc freq data=mydata;
by file_name;
<your table statements>;
run;
This is simple, data driven code that doesn't require macros or storing large amounts of data in things that shouldn't have data in them (macro variables, filenames, etc.)
To directly answer your question, here is a SAS macro to read each file and run PROC FREQ:
%macro freqme(dsn);
data test;
infile "&dsn" recfm = v lrecl=1800 end=eof truncover;
INPUT #1 E_CUSTDEF1_CLIENT_ID $CHAR5.
#1235 E_MED_PLAN_CODE $CHAR20.
#1090 MED_INS_ELIG_COVERAGE_IND $CHAR20.
#1064 MED_COVERAGE_BEGIN_DATE $CHAR8.
#1072 MED_COVERAGE_TERM_DATE $CHAR8.
;
if E_CUSTDEF1_CLIENT_ID = '00002';
run;
proc freq data=test;
tables E_CUSTDEF1_CLIENT_ID*E_MED_PLAN_CODE / list missing;
run;
proc delete data=test;
run;
%mend;
%freqme(/chshttp/prod/clients/coms/raw/coms_coms_relg_f1102_t1102_c10216_vEL5535.raw);
%freqme(/chshttp/prod/clients/coms/raw/coms_coms_relg_f1103_t1103_c10317_vEL8312.raw);
%freqme(/chshttp/prod/clients/coms/raw/coms_coms_relg_f1104_t1104_c10420_vEL11614.raw);
%freqme(/chshttp/prod/clients/coms/raw/coms_coms_relg_f1105_t1105_c10510_vEL13913.raw);
%freqme(/chshttp/prod/clients/coms/raw/coms_coms_relg_f1106_t1106_c10628_vEL17663.raw);
Note that I added a PROC DELETE step to delete the SAS data set after creating the report. I did that more for illustration, since you don't say you need the file as a SAS data set for subsequent processing.
You can use this as a template for other macro programming.