SAS proc import .xls with several spreadsheet and append - sas

Situation: i have a workbook .xls with 4 spreadsheets named "SheetA", "SheetB", "SheetC", "SheetD".
For import one spreadsheet i do as following.
proc import
out = outputtableA
datafile = "C:\User\Desktop\excel.xls"
dbms = xls replace;
sheet = 'SheetA';
namerow = 3;
startrow = 5;
run;
All spreadsheet have same number of variables and format. I would like to combine all four outputtableX together using data step:
data combinedata;
set outputtableA outputtableB outputtableC outputtableD;
run;
I am new to SAS, i m thinking whether array and do-loop can help.

I would not use a do loop (as they're almost always overly complicated). Instead, I would make it data driven. I also would use Reese's solution if you can; but if you must use PROC IMPORT due to the namerow/datarow options, this works.
First, create the libname.
libname mylib excel "c:\blah\excelfile.xls";
We won't actually use it, if you prefer the xls options, but this lets us get the sheets.
proc sql;
select cats('%xlsimport(sheet=',substr(memname,1,length(memname)-1),')')
into :importlist separated by ' '
from dictionary.tables
where libname='MYLIB' and substr(memname,length(memname))='$';
quit;
libname mylib clear;
Now we've got a list of macro calls, one per sheet. (A sheet is a dataset but it has a '$' on the end.)
Now we need a macro. Good thing you wrote this already. Let's just substitute a few things in here.
%macro xlsimport(sheet=);
proc import
out = out&sheet.
datafile = "C:\User\Desktop\excel.xls"
dbms = xls replace;
sheet = "&sheet.";
namerow = 3;
startrow = 5;
run;
%mend xlsimport;
And now we call it.
&importlist.
I leave as an exercise for the viewers at home wrapping all of this in another macro that is able to run this given a filename as a macro parameter; once you have done so you have an entire macro that operates with little to no work to import an entire excel libname.

If you an xls file and are using a 32 bit version of SAS something like this would work:
libname inxls excel 'C:\User\Desktop\excel.xls';
proc datasets library=excel;
copy out=work;
run; quit;
libname inxls;
Then you can do your step above to append the files together. I'm not sure Proc Import with excel recognizes the option name row and start row so you may need to modify your code somehow to accommodate that, possibly using firstobs and then renaming the variables manually.

What you have will work assuming the variable names are the same. If they are not use the rename statement to make them all the same.
data combinedata;
set outputtableA(rename=(old_name1=new_name1 old_name2=new_name2 ... ))
outputtableB(...)
...
;
run;
Obviously, fill in the ellipses.

Related

After using proc import on an excel file, how am i able to use that data?

I've imported the excel file and it says the data file work.one has been created, but how am i able to manipulate this file?
What im trying to do is transform PSA to ln(PSA+1) in most analyses using PSA, where PSA is the excel file I imported. I am using base SAS.
This is my code so far
data excl;
proc import out = psa
datafile= "H:\MinitabFiles\Morrell\SAS-Data\psa.xls"
dbms = xls replace;
sheet = "psa";
getnames = yes;
run;
data logs;
set excl;
sheet = log(sheet+1);
run;'
What do you want to do with it?
You'll find it in the work library under the explorer tree assuming you are using Enterprise Guide. To 'manipulate' it, many of your most obvious options will be covered by proc sql; or a datastep.
Please elaborate on the question if you want a more useful answer:-
1 which sas product are you using? EG, Base, etc?
2 have you located the file and established it has been imported correctly?
3 `manipulate'? What does this mean? Filter, perform calculations, functions, conversions or one of many other things.
Welcome btw, but please provide plenty more detail.
You have issues with your current code. For example the data excl doesn't do anything. PROC IMPORT creates the data, the data step around the PROC IMPORT is useless.
data excl; *REMOVE THIS, DOES NOT DO ANYTHING;
proc import out = psa /*PSA is the name of the output data set*/
datafile= "H:\MinitabFiles\Morrell\SAS-Data\psa.xls"
dbms = xls replace;
sheet = "psa";
getnames = yes;
run; *THIS GOES WITH THE PROC IMPORT;
data logs;
set excl; *YOUR DATASET IS CALLED PSA, replace EXCL with PSA;
sheet = log(sheet+1); *This assumes your PSA data set has a variable with sheet;
run;'

SAS List of variables containing special characters

I am a novice for SAS programming and I am trying to create a list of old_variable names so I can work with them (subset, rename, spaces, etc.), however the variable names have funky characters (#, parenthesis, single quotes, numbers, you name it). Each variable is delimited-separated by ';' and the source file is in csv format. I need to do it for 44 different files and each file has about 199 variables.
So far, I have tried a macro where I create a list of the variables, however, the code fails when I try to use the macro &vars because of the special characters. I have checked SAS paper 005-2013, however I believe I am not really sure how to use the functions in my code.
Any insights or directions would be appreciated. Here is the code I tried so far:
1) Importing:
proc import datafile='file_oldname.csv'
dbms=csv
out= oldName
replace;
delimiter=',';
getnames=yes;
run;
2) Making my list of oldNames;
* A macro variable contanining the oldvariables names;
* Using Proc Contents and Proc SQL;
proc contents data=oldName out=listOldName;
run;
options VALIDMEMNAME=EXTEND;
proc sql noprint;
select distinct(name) into:vars separated by " " from listOldName;
quit;
%put &vars;
&vars contains the list of variables, however if I try to use it, it fails because of the special characters.
How can I wrap the &vars properly so that the variable names with special characters can be used? I want to further renamed them by new names.
Thanks a lot!
As your variable names contain special characters, they need to be referenced in "name literal!"n format.
Try:
options VALIDVARNAME=ANY;
proc sql noprint;
select distinct nliteral(name)
into:vars separated by ' '
from listOldName;
%put &=var;
More info on name literals in documentation.
Edit - as kindly pointed out by #Tom, the nliteral function handily covers the conversion you require! Documentation for that is here.
When Proc IMPORT runs it creates data sets with variable names that meet the VALIDVARNAME setting at import time. Thus, one alternative, would be to set the option prior to IMPORT to ensure 'clean' variable names, and reset it afterwards.
%let setting = %sysfunc(getoption(VALIDVARNAME));
options validvarname=v7;
Proc IMPORT ... ;
...;
run;
options validvarname = &SETTING;
Example
filename have temp;
data _null_;
file have;
put 'Name,"Age","Date of Birth",School:First,Surprise!,-Feedback';
put 'Abel,0,Yesterday,Eastern Acacdemy,Balloons!,None';
run;
options validvarname=any;
proc import file=have replace out=have_any dbms=csv;
getnames=yes;
run;
options validvarname=v7;
proc import file=have replace out=have_v7 dbms=csv;
getnames=yes;
run;
options validvarname=any;

Define Library in SAS where some of the Folder name will be change each time(When this SAS macro run from different users)

Topic: SAS Library
Difficulty: path(File name and Location) is changing after each run but only some of the details are changing but not the full path (as given in below example). we have also highlighted those field in Bold
I want to write only one code where I can cover all kind of change which happening in file name and location, is it possible?
%let path='C:\Data\variationstring\empcat**A**\person**34**_**1212**\persondata_empcatA_**34**';
libname test "&path";
proc import datafile="&path\Accounts_**34**.xls"
out=mydata
sheet="thefile";
getnames=no;
run;
When another user run that program then above path will be changed:
%let path='C:\Data\variationstring\empcat**A**\person**49**_**1684**\persondata_empcatA_**49**';
libname test "&path";
proc import datafile="&path\Accouns_**49**.xls"
out=mydata
sheet="thefile";
getnames=no;
run;
Can anyone help me for this, please?
Thanks
Try to put it in a macro like this:
%macro import (macro_var1,macro_var2,macro_var3);
%let path="C:\Data\variationstring\empcat**A**\person**&macro_var1.**_**&macro_var2.**\persondata_empcatA_**&macro_var3.**";
libname test "&path";
proc import datafile="&path\Accouns_**49**.xls"
out=mydata
sheet="thefile";
getnames=no;
run;
%mend;
%import (34, 1212, 34);
%imoprt (49, 1684, 49);
etc.
when defining path, don't forget to put it in double quotes (") insted of single (')
In addition to Grigory's excellent suggestion, it looks to me like you're doing something that would be well served utilizing a data-driven programming approach.
If you have, say, an excel spreadsheet with all of your personnel records - let's say the first number is store and the second is employeeID - and you want to run one report per employeeID, then you write the macro like Grigory suggested; but you call the report from the first dataset.
So here:
proc import file="C:\Data\employeeID.xlsx"
out=employees dbms=xlsx
replace;
run;
%macro get_employee(store=, employeeID=, empCat=);
%let path="C:\Data\variationstring\empcat&empcat.\person&store._&employeeID.\persondata_empcat&empcat._&store.";
libname test "&path";
proc import datafile="&path\Accouns_&store..xls"
out=mydata
sheet="thefile";
getnames=no;
run;
%mend get_employee;
proc sql; *this generates macro calls, look at output to see what the macro variable contains;
select cats('%get_employee(employeeid=',employeeID,',store=',store,',empcat=',empcat,')')
into :get_emp_list separated by ' '
from employees;
quit;
&get_emp_list.; *This actually runs all those macro calls;
You can read my paper, Writing Code With Your Data for more details, or find other similar papers online.

SAS: Exporting Data Subsets to Separate Workbook Tabs in Excel

Question: How can I export subsets of a data set to individual tabs of an Excel workbook (preferably .xlsx) without running PROC EXPORT several times?
My Solution
The data set contains 15 indicators. Unfortunately, the indicators do not have names which can be indexed. This means I cannot put the export procedure into a macro which loops over a counter 15 times and appends the name with the index. The indicators are (not really) things like "car", "truck", "bicycle", "dinosaur", etc.
The solution I came up with was like this:
proc export data = data_set
(where = (indicator = "car"))
outfile = "c:\workbook.xlsx"
dbms = xlsx replace;
sheet = car;
run;
...
proc export data = data_set
(where = (indicator = "dinosaur"))
outfile = "c:\workbook.xlsx"
dbms = xlsx replace;
sheet = dinosaur;
run;
However, this is obviously inefficient and begs for some sort of automation.
You can use the libname facility, which is what proc export uses in the background usually.
libname myexcel xlsx "c:\outwhatever\myfile.xlsx"; *can use XLSX if 9.4+ or EXCEL if earlier;
That gives you a regular libname just as if it were a SAS libname, and you can write to it like so:
data myexcel.sheetname;
set whatever;
run;
Or use PROC COPY or similar.
There are other options (using OLEDB or similar, for example), but libname is simplest. See the documentation for more details.
If you have SAS 9.4 ODS Excel is quite simple and nice, set the sheet_interval option to bygroup and add a prefix for the sheet name.
proc sort data=sashelp.class out=class;
by age;
run;
ods excel file='/folders/myfolders/sample.xlsx' options (sheet_interval='bygroup' sheet_label='Age');
proc print data=class noobs label;
by age;
run;
ods excel close;

Reading n files into SAS to create n datasets

I have just started learning SAS, and I'm using the following code to read xlsx files:
proc import out = data_lib.dataset_1
datafile = 'C:\data_folder\data_file_1.xlsx'
dbms = xlsx replace;
sheet = 'Sheet1';
getnames = yes;
run;
This has been working fine for me, but I'd like to supply the code with a list of filenames to read and a list of dataset names to create, so that the code need only appear once. I have looked at several instructional web pages about using macros, but I've been unable to translate that information into working code. Any help would be greatly appreciated. I'm using SAS 9.4, 64 bit.
I'd offer a modified version of kl78's suggestion, avoiding macros. Again, assuming you have the file names in a SAS data set, use a data step to read the list of file names and use call execute to run your proc import code for each file name.
data _null_;
set t_list;
call execute (
"proc import out = " || datasetname || "
datafile = '"|| filename ||"'
dbms = xlsx replace;
sheet = 'Sheet1';
getnames = yes;
run;");
run;
So, suppose you have your filenames and datanames in a table called t_list with variablename datasetname and filename, you could try something like this:
%macro readexcels;
data _null_;
set t_list (nobs=nobs);
call symputx(cat("libname_",_n_), datasetname);
call symputx(cat("filename_",_n_), filename);
if _n_=1 then
call symputx("nobs", nobs);
run;
%do i=1 %to &nobs;
proc import out = &&libname_&i;
datafile = "&&filename_&i"
dbms = xlsx replace;
sheet = 'Sheet1';
getnames = yes;
run;
%end;
%mend;
%readexcels;
In the datastep you read every entry of your table with datasetname and listname and create macrovariables with a numeric suffix. You only need to create a macrovariable for the number of entries once, so i did it when n = 1, you could also do this at eof.
Then you have a do loop, and with every loop you read the specific excel and write it in the specific dataset.
You need to write it like &&libname&i, because at first this resolves to &libname_1, and after this resolves to the variablevalue...