DDE SAS using VBA Commands - sas

I am trying to write a code using dde in sas which would generalise my cells in excel that is previously formatted to number with 2 decimal places. I don't get any error message in the log but my excel sheet is overwritten with the code that is in the put statement that is RANGE("A1:A3").NumberFormat="General" instead of applying the format to it. I am not sure where I am going wrong. Could someone please help?
Here is my sample code,
NOTE: The Excel engine is opened before I run this code
filename ddeopen dde "EXCEL|System";
options noxwait noxsync;
data _null_;
x=sleep(3);
run;
/* Opens the desired file in Excel*/
DATA _null_;
file ddeopen;
PUT "[OPEN(%bquote("C:\Documents and Settings\S\Desktop\test1.xls"))]";
x=sleep(3);
run;
/* Format the cells to general in the opened Excel sheet*/
filename ddeopen dde "EXCEL|Sheet1!r1c1:r3c1";
data _null_;
file ddeopen;
x=sleep(3);
PUT "[%bquote(RANGE("A1:A3").NumberFormat="General")]";
RUN;
Many Thanks
Simi

I think you need to select your range first using the 'R1:C1' style like so:
put ‘[select("r1c2:r100c2")]’;
Then you can format that selection with the following command:
put '[Format.Number("General")]';
This should then uses the 'General' formatting style for the cells before you export your data.

Related

write to the default HTML output in SAS EG with a put statement from a data step

I sometimes want to add some paragraphs to my output in Enterprise Guide or in a stored process to explain the results.
Last century on mainframe, when I was working on mainframe, I just did that with
data _null_;
set remarks;
file list;
put remark;
run;
I figured out the default html output of SAS EG is called EGHTML, but the following
data _null_;
set remarks;
file EGHTML;
put remark;
run;
gives ERROR: File is in use, G:\Work\_TD13868_VSRVDCF7055_\#LN00104.
Is there a way around?

SAS Problem: Data infile leads to 0 observations

I'm having an issue with SAS 9.4. See code below;
data myData;
infile 'D:\folder1\folder2\myData.xlsx';
input var1 var2 var3;
This results in SAS executing this successfully, recognizing the 3 variables but containing 0 observations. Is there something wrong with how the code is written? Has anyone encountered this issue? Thank you in advance.
Since an XLSX file is binary (in particular it is just a ZIP file) your data step is not finding any lines of text to read. Most likely the reason you got 0 observations is that when searching for the second or third space delimited word to read it went past the end of the file. So the data step stopped at the INPUT statement and never reached the end of the first iteration to write an observation.
You will need to either use PROC IMPORT or a LIBNAME statement using the XLSX engine to read an XLSX file. Or use Excel to save the file as a delimited text file, then you could read using a simple data step.
If your data is in an Excel format, you should be able to do PROC IMPORT to read it in.
PROC IMPORT DATAFILE="D:\folder1\folder2\myData.xlsx" DBMS=XLSX OUT=myData;
RUN;

exporting sas stored process output

I created a stored process but I want to export the output to Excel. My usual export statement doesn't work in the stored process.
%let _ODSDEST=none;
%STPBEGIN();
data x;
set sashelp.class;
run;
proc export data=x outfile = "//my documents/sp_test.xlsx" dbms=xlsx replace;
sheet="table1";
run;
* Begin EG generated code (do not edit this line);
;*';*";*/;quit;
%STPEND;
Is there a way to get this to work in the stored process?
One way to have a stored process return an excel file (actually in this case it's an xml file that excel will happily open) is to use ODS to output tagsets.excelxp (xml).
When you do this, you can use stpsrv_header to modify the HTML header. The first statement tells the browser to open the file with excel, the second tells it the file name. I believe for this header modification to work the stored process needs to deliver streaming results, not package results. But I could be wrong.
When I run below, I get a file download dialog box from the browser, allowing me to open or save the file. I'm running from Stored Process Web App, but should work fine when called from Information Delivery Portal.
%let _odsdest=tagsets.excelxp;
%let rc=%sysfunc(stpsrv_header(Content-type,application/vnd.ms-excel));
%let rc=%sysfunc(stpsrv_header(Content-disposition,attachment%str(;) filename=MyExcelFile.xls));
%stpbegin()
proc print data=sashelp.shoes (obs=&obs);
run;
%stpend()
did u check with your spelling proc exportd and outfile='mypath/my documents/myoutpt.xlsx' dbms=xlsx or outfile='mypath/my documents/myoutpt.xls' dbms=xls?? U can try with ODS also.
You can also try setting your STP up as a streaming web service, removing the %STPBEGIN and %STPEND macros, and sending to _webout using this macro: https://core.sasjs.io/mp__streamfile_8sas.html
The benefit of this, is that your code will subsequently work on Viya as well.

How to create "standardized" Excel workbooks using SAS

I have a "wide" SAS data sets that must be exported into a new Excel workbook every week. I want to preserve the column widths and other Excel attributes every week, but I'm having problems getting it to work. Here's what I'm attempting.
I used PROC EXPORT to create a new workbook (using sheet="New_TACs").
I manually adjusted the column widths and other sheet attributes
(like "filters", column widths, wrap, alignment, and "freeze panes").
I deleted all the data rows (leaving the first row with the column
names) and saved it as a new workbook named "template.xlsx".
Using a SAS system call, I copy "template.xlsx" to "this_week.xlsx".
I use PROC EXPORT again to try and update the new workbook, but I
get warnings. The result contains a sheet named "New_TACS1".
Here is the SAS log:
720 proc export data=new_tacs
721 outfile="\\server-path\this_week.xlsx"
722 replace;
723 sheet='New_TACs';
724 run;
WARNING: The target file may contain unmatched range name and sheet name.
WARNING: The target file may contain unmatched range name and sheet name.
WARNING: File _IMEX_.New_TACs.DATA does not exist.
WARNING: Table _IMEX_."New_TACs" has not been dropped.
NOTE: "New_TACs" range/sheet was successfully created.
NOTE: PROCEDURE EXPORT used (Total process time):
real time 23.88 seconds
cpu time 1.80 seconds
I'm at a loss as to what to do and would appreciate any ideas or suggestions.
I think the issue is that with zero rows, SAS isn't properly dealing with the data. I can't get PROC EXPORT to work at all, but with a single dummy row I can at least get it to behave with libname and PROC APPEND. I wouldn't be surprise if the filters are in part responsible for this.
After creating the blank excel file with the SASHELP.CLASS columns, adding a filter, adding one row of dummy data, and saving/closing, I do: (SCANTEXT=NO is mandatory here for update access)
libname newtac "c:\temp\test.xlsx" scantext=no getnames=yes;
proc append base=newtac.'New_TACs$_xlnm#_FilterDatabase'n data=sashelp.class force;
run;
libname newtac clear;
That gets close, at least. I'm getting some blank rows for some reason, perhaps due to other things I did in looking at this.
Your best solution may well be to wait for 9.4 TS1M0 and ODS EXCEL, which will let you do all these things from SAS directly; or to use DDE.
I would recommend checking out SaviCells. http://www.sascommunity.org/wiki/SaviCells. It provides much better SAS to Excel functionality, including creating a template with all your Excel formatting and using that with new data.
Use DDE in SAS to achieve this.
You can create your excel template the way you want it to appear.
Using DDE you would then:
Open Excel
Open the excel file you want to use as the template
Populate it with the updated data
Save the file as a new filename
It's a bit of an antiquated technology but it gets the job done.
Googling for SAS and DDE will find you plenty of code exmaples and tutorials.

Import data from European Social Survey

I need to import data from European Social Survey databank to SAS.
I'm not very good at using SAS so I just naively tried importing the text file one gets but it stores it all in one variable.
Can someone maybe help me with what to do? Since there doesn't seem to be a guide on their webpage I reckon it has to be pretty easy.
It's free to register (and takes 5 secs) and I need all possible data for Denmark.
Edit: When downloading what they call a SAS file, what i get is a huge proc format and the same text file as one gets by choosing text.
The data in the text file isn't comma separated and the first row does not contain variable names.
Download it in SAS format. Save the text file in a location you can remember, and open the SAS file. It's not just one big proc format; it's a big proc format followed by a datastep with input code. It was probably created by SPSS (it fits the pattern of an SPSS saved .sas file anyhow). Look for:
DATA OUT.ESS1_4e01_0_F1;
Or something like that (that's what it is when I downloaded it). It's probably about 3/4 of the way down the page. You just need to change the code:
INFILE 'ESS1_4e01_0_F1.txt';
or similar, to be the directory you placed the text file in. Create a LIBNAME for OUT that goes to wherever you want to permanently save this, and do that at the start of the .sas file, replacing the top 3 lines like so.
Originally:
LIBNAME LIBRARY '';
LIBNAME OUT '';
PROC FORMAT LIBRARY=LIBRARY ;
Change these to:
libname out "c:\mystuff\"; *but probably not c:\mystuff :);
options fmtsearch=(out);
proc format lib=out;
Then run the entire thing.
This is the best solution if you want the formatted values (value labels) and variable labels. If you don't care about that, then it might be easier to deal with the CSV like Bob shows.
But the website says yu can download SAS format, why don't you?
You need a delimiter if all goes into one column.
data temp;
length ...;
infile 'file.csv' dlm=',';
input ...;
run;
As Dirk says, the web site says you can download a SAS dataset directly. However, if there's some reason you don't want to do that, choose a comma separated file (CSV) and use PROC IMPORT. Here is an example:
proc import out=some_data
datafile='c:\path\somedata.csv'
dbms=csv replace;
getnames=yes;
run;
Of course, this assumes the first row contains column names.