Making SOAP calls from SAS! Integrating with web services
One of the issues with SAS for many IT departments is the lack of integration with service oriented architecture (SOA). The good news is with many new features coming online with versions 9.X+ are service oriented.
Lets look quickly at the Proc SOAP procedure now available.
For those SAS programmers out there that aren't familiar with SOAP or services, get your basis here: SOAPUser-Basics
In a nutshell, SOAP is transporting XML data via a HTTP Post. In order to make a successful SOAP call from SAS you need a couple of things.
1. a request XML file
2. a repsonse XML file
3. a webservice URL and WSDL (Web Service Definition Language) -Think webservice users manual
Here is a simple example of a SOAP call we use on a daily job.
filename rqst_xml 'some file system reference';
* Create the XML;
data _null_;
set input_dataset;
file rqst_xml;
if first.records=1 then do;
put '<?xml version="1.0"?>
<soap:Envelope
xmlns:soap="http://www.w3.org/2001/12/soap-envelope"
soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding"><soap:Header>
<requestingSystem>SAS</requestingSystem><requestingFunction>DemoSasScript</requestingFunction>
</soap:Header><soap:Body>
<requestedData>';end;
datasetData;
if last.records=1 then do;
put '</requestedData>
</soap:Body></soap:Envelope>';
end;
run;
filename rspns_xml 'some file system reference';
%let URL=http://webservice_url/service;
proc soap in=rqst_xml
out=rspns_xml
url=&url;
run;
Upon executing the call, you can read in the rspns_xml data with the SAS XML engine.
This is meant to be a simple example with very limited scope. Service architecture can quickly get complicated with error and condition handling. Please let us know if you need help with your SAS architecture or coding.
Default value to macro variable
NOTE: This is a great one we picked up from our friends over at the SAS community.
We have run across this literally hundreds of times while programming SAS macros. You need to have a default value for a variable and you don't want to write another macro to set it if it doesn't exist.
This simple fix allows you to check for a value and set a default even in open SAS code.
%global myParameter; /* ensure it exists */ %let myParameter = %sysfunc(coalescec(&myParameter,default-value));
Pure awesomeness..
Credit goes to Don Henderson and the SAS community for this one.
http://www.sascommunity.org/wiki/Tip_of_the_Day:October_12
SAS: Where Also
Ever heard of 'where also'? Neither did we.
We have to give credit to the guys at the SAS Community.
'Where also' allows you to add a series of where statements. The use acts like a single where statement with the and condition.
Example:
Data new_data;
set old_data;
where number=6;
where also another_number=.;
run;
This is the same as where number=6 and another_number=.
SAS – Lowercase (lowcase) / Uppercase (upcase) / Proper Case (propcase)
We can't stress the importance handling character case correctly. Here are the two functions you need to know and use correctly.
In order to convert all characters in a sting to lowercase, use the LOWCASE function. Example:
data ds_2;
set ds_1;
*convert it to lowercase;
new_char_var=lowcase(OLD_CHAR_VAR);
run;
In order to convert all characters in a sting to uppercase, use the UPCASE function. Example:
data ds_2;
set ds_1;
*convert it to uppercase;
NEW_CHAR_VAR=upcase(old_char_var);
run;
We can't stress the importance of keeping this functionality in mind. Many a SAS script has gone awry because a developer didn't take character case into account when using conditional or search statements.
TIP: A solid programming practice is to convert everything to lowercase before storing it. There are exceptions to this (like names, etc), but they can be handled on a case basis.
Also note the PROPCASE function. It capitalizes the first letter of each word in a string. Example:
data ds_2;
set ds_1;
New_Prop_Var=propcase(old_char_var);
put New_Prop_Var;
run;
This Is The New Prop Var.
SAS DIM function – Counting the elements in an array
The DIM function returns the number of literal elements in an array. It functions against multi-dimensional arrays as well as one-dimensional arrays.
1-dimensional array example
DIM(array_name)
Multi-dimensional array examples
DIM(m_array) -> returns the number of elements in the first dimension of the array
DIM5(m_array) -> returns the number of elements in the 5th dimension of the array
DIM(m_array, 5) -> returns the number of elements in the 5th dimension of the array
The classic use case for the DIM function is to return the number of elements in an array for the upper bound of a do loop process. Example:
array array_name(5) var1 var2 var3 var4 var5;
do i=1 to dim(array_name);
some SAS statements here
end;
SAS DIF function – Comparing previous records
The SAS DIF function is another useful tool for operating on previous records.
Lets say you want to know the difference in the last year's revenue and this year's revenue. Here is the data:
Year Revenue
2001 10,000
2002 30,000
2003 60,000
2004 100,000
data revenue1;
set revenue;
Rev_increase=dif1(revenue);
run;
Year Revenue Rev_increase
2001 10,000 .
2002 30,000 20,000
2003 60,000 30,000
2004 100,000 40,000
The dif functions compares the current record to the nth previous record.
SAS LAG funciton
The LAG function is a powerful tool in the SAS programming toolset. It is also one that has unintentional results. First, lets demonstrate how to use it.
data new_ds;
set old_ds;
last_price=lag(price);
run;
The above will return the last value processed for the price variable. The resulting dataset may look like this.
obs price last_price
1 10 .
2 15 10
3 8 15
4 3 8
5 9 3
Now its misuse. Conditional processing will create unexpected results when incorporated with the lag function. Lag returns the last value processed even if it doesn't appear in the resulting dataset. It is also important to note that you shouldn't use lag if you aren't reading dataset records sequentially.
This function can be handy when calculating moving averages and the like.
The following calculates the sum of the last 5 periods:
data new_ds;
set old_ds;
last_5_periods=lag(price)+lag2(price)+lag3(price)+lag4(price)+lag5(price);
ave_5_periods=last_5_periods/5;
run;
Detecting the end of a SAS data set ( end= )
The END= option can help you determine when you have reached the last record in your dataset. Here is a syntax example:
data new_ds;
set old_ds end=end_var;
if end_var=1 then text='This is the last variable';
run;
The end= option creates a temporary variable, in the example it is end_var. This variable is not written to the output dataset. The variable is numeric and has a value of 1 to specify the last record.
Do not use this option with the point option.
This option is helpful when you only want to output the last record (good for summing data).
data new_ds (drop=transactional_record);
set old_ds end=last_record;
sum_var+transactional_record;
if last_record=1;
run;
How to remove characters with SAS COMPRESS
Compress is a string function in SAS. This function doesnt make your characters smaller but it does take some of them out. Here is the basic example.
data _null_;
string=Here is a string;
new_str=compress(string,'e'); /*now new_str= Hr is a string */
run;
Pretty simple huh? But wait, in SAS v9 there are new features. A third function argument even. Example? Sure:
data _null_;
string=Here is a string;
new_str= compress(string,'eia',"k"); /* now new_str=eeiai */
run;
This third argument breaks down like so:
a - all upper and lowercase letters
d - all numeric digits
i - ignores case
k - keeps the listed characters instead of removing them
s - adds all blank space to the list (like tabs, spaces, carriage returns)
p - adds all punctuation to the list
u - adds all uppercase letters
l - adds all lowercase letters
Suddenly this function is more useful than ever.
If you have some SAS code you would like help on, we are always available for short and long term consulting jobs. No project is too large or small.