Proc append and addressing excel sheets - sas

I'm using this code to update an Excel sheet:
libname xls excel '..\append.xls' ver=2002;
proc datasets lib = xls nolist;
delete output;
quit;
data xls.output;
set Ongoing_SE;
run;
libname xls clear;
The above part creates the output file.
libname xls excel '..\append.xls' scan_text = no ver=2002 ;
proc append
base = xls.output
data = Ongoing_SE;
run;
libname xls clear;
I want to append data into specific sheets of the excel file but I don't know how to address excel sheets.
/Johan

Excel sheets are normally addressed as
libname.'SheetName$'n
So in yuor case,
xls.'Output$'n
The 'something'n construct is a 'named literal' which is equivalent to a non-quoted string - such as a variable name, a library name, etc. It's how you construct an otherwise-illegal name in SAS, such as the sheet name that contains a silent '$'.
If you created the sheet in SAS (such as with xls.Output), you can refer to it either as xls.output or xls.'output$'n. If it was created in Excel, you probably will have to use the second form.

Related

SAS: Capture a Specific Field in Text File

I'm writing a SAS program to interact with an API. I'm trying to use SAS to capture a specific field from a text file generated by the API.
The generated text "resp" looks like this:
{"result":{"progressId":"ab12","percentComplete":0.0,"status":"inProgress"},"meta":{"requestId":"abcde123","httpStatus":"200 - OK"}}
The field I want to capture is "progressID". In this case, it would be "ab12". If the length of progressID will change, what's the easiest way to capture this field?
My current approach is as follows:
/* The following section will import the text into a SAS table,
seperated by colon. The third column would be "ab12","percentCompelte"
*/
proc import out = resp_table
datafile= resp
dbms = dlm REPLACE;
delimiter = ':';
GETNAMES = NO;
run;
/* The following section will trim off the string ,"percentCompete"*/
data resp_table;
set resp_table;
Progress_ID = SUBSTR(VAR3,2,LENGTH(VAR3)-20);
run;
Do you have an easier/ more concise solution?
Thanks!
Shawn
You can use the JSON library engine to read a json document, and copy the contents to SAS datasets. Work with the data items that the engine creates.
Example:
filename myjson "c:\temp\sandbox.json";
data _null_;
file myjson;
input;
put _infile_;
datalines;
{"result":{"progressId":"ab12","percentComplete":0.0,"status":"inProgress"},"meta":{"requestId":"abcde123","httpStatus":"200 - OK"}}
run;
libname jsondoc json "c:\temp\sandbox.json";
proc copy in=jsondoc out=work;
run;
proc print data=work.Alldata;
where P1='result' and P2='progressId';
run;

Exporting data from SAS to Excel with a custom file name

I need to export a data set from SAS to Excel 2013 as a .csv file. However, I need the file name to be dynamic. In this instance, I need it to appear as:
in_C000000_013117_65201.csv
where the string, "in_C000000_" will remain constant, the string "013117_" will be the current day's date, and the string "65201" will be the row count of the data set itself.
Any help that you can provide would be much appreciated!
Thanks!
Here's a modified macro I wrote in the past that does almost exactly what you're asking for. If you want to replace sysdate with a date in your desired format, that's easy to do as well:
%let path = [[desired destination]];
%macro exporter(dataset);
proc sql noprint;
select count(*) into: obs
from &dataset.;
quit;
data temp;
format date mmddyy6.;
date = today();
run;
proc sql noprint;
select date format mmddyy6. into: date_formatted
from temp;
quit;
proc export data = &dataset.
file = "&path.in_C000000_&date_formatted._%sysfunc(compress(&obs.)).csv"
dbms = csv replace;
run;
%mend exporter;
%exporter(your_dataset_here);
Produces datasets in the format: in_C000000_020117_50000.csv

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;

SAS proc import .xls with several spreadsheet and append

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.

exporting in SAS multiple datasets

I have a set of datasets which I would like to output in an Excel File. Is there a way to do this quickly rather than calling proc export each time for each dataset
%let MyDS = ('out.Ids', 'out.Vars', 'out.Places')
%let MyDSname = (Ids, Vars, Places)
I would like to create a macro that check if each dataset exists and then output to an Excel spreadsheet with the Tab name as specified in the corresponding MyDSname ...
Something like... %macro Out(MySpreadsheetName, MyDS, MyDSname);
Thanks very much for your help
Assuming you have Access to PC Files licensed, the easiest way to do this (export several datasets to one workbook) is with a libname.
libname mywbk excel 'c:\pathtomyexcel\excelfile.xlsx';
data mywbk.nameoftab;
set dataset;
run;
In terms of conditionally creating this, you should look at how you're arriving at the list of names to export. In general, you should have a dataset that contains one row per dataset to export, and two columns - DS name and tab name. You can then merge that to sashelp.vtables or dictionary.tables which are views containing the list of tables in the current SAS session; memname is the name of the table, libname is the name of the library. Then create a macro call from that:
proc sql;
select cats('%out(',dsname,',',tabname,')') into :calllist separated by ' '
from joinedds;
quit;
libname ... ;
&calllist.;