Attaching file for a SAS program - sql

I am new to SaS and i tried performing a simple query on sas enterprise guide.
The program is as follows:
libname ISS meta library="SQL - ISS" metaout=data;
Proc Sql;
select *
from MARKET_OPTION_DAY
where contract_market_code = '023A61'
and REPORT_DATE between '1/1/13' and '6/30/15';
QUIT;
the error im getting is the following : FILE work.MARKET_OPTION_DAY.DATA does not exist.
I dont understand whats wrong because i can view the file in the "SQL-ISS" library

If a file is located in a library, then you need to prefix with the library name.
proc sql;
select * from ISS.market_option_day
/* other stuff here ...*/
;
quit;
For example.

Related

How to read & run SQL(on Snowflake) from a .txt file in a folder using SAS Studio and export the o/p to excel?

I have some .txt files with SQL code in them for Snowflake database in a folder on SAS Studio. I need my logic to pick and read the .txt files from the folder and run-on snowflake using SAS Studio and need the output of the code in excel files.
Expecting help with the process and detailed steps on how to achieve this? I am new to SAS and good with SQL.
With the help of the below code I was able to read SQL from a text file, run out SAS and export the output to a .csv file. But I need to read multiple text file from a folder and create .csv output for all of them separately. Please see the code below and help me how to achieve this for multiple text files.
data _null_; *reading the SQL script into a variable, hopefully under 32767?;
infile "/dslanalytics-shared/dgupt12/SQLs/Query.txt" recfm=f lrecl=32767 pad;
input #1 sqlcode $32767.;
call symputx('sqlcode',sqlcode); *putting it into a macro variable;
run;
proc sql;
connect to odbc as mycon (complete="DRIVER={SnowflakeDSIIDriver};
SERVER=;
UID=&usr.;
PWD=&pwd.;
WAREHOUSE=;
DATABASE=;
SCHEMA=;
dbcommit=10000 autocommit=no
readbuff=200 insertbuff=200;");
create table final_export as
select * from connection to mycon(&sqlcode.);
disconnect from mycon;
quit;
proc export data = work.final_export
outfile = "/dslanalytics-shared/dgupt12/Report/final_report.csv"
DBMS = csv REPLACE;
run;
You can do this for multiple files by defining and using a SAS macro:
%macro file_input (INPUTXT=,OUTPUTCSV=);
data _null_;
infile "&INPUTTXT." recfm=f lrecl=32767 pad;
input #1 sqlcode $32767.;
call symputx('sqlcode',sqlcode); *putting it into a macro variable;
run;
proc sql;
connect to odbc as mycon (complete="DRIVER={SnowflakeDSIIDriver};
SERVER=;
UID=&usr.;
PWD=&pwd.;
WAREHOUSE=;
DATABASE=;
SCHEMA=;
dbcommit=10000 autocommit=no
readbuff=200 insertbuff=200;");
create table final_export as
select * from connection to mycon(&sqlcode.);
disconnect from mycon;
quit;
proc export data = work.final_export
outfile = "&OUTPUTCSV."
DBMS = csv REPLACE;
run;
%mend;
/* 3 Examples for macro calls */
%file_input (INPUTTXT=%str(/dslanalytics-shared/dgupt12/SQLs/Query.txt),
OUTPUTCSV=%str(/dslanalytics-shared/dgupt12/Report/final_report.csv));
%file_input (INPUTTXT=%str(/dslanalytics-shared/dgupt12/SQLs/Query2.txt),
OUTPUTCSV=%str(/dslanalytics-shared/dgupt12/Report/final_report2.csv));
%file_input (INPUTTXT=%str(/dslanalytics-shared/dgupt12/SQLs/Query3.txt),
OUTPUTCSV=%str(/dslanalytics-shared/dgupt12/Report/final_report3.csv));

How to run VB.NET with X command in SAS through Enterprise

I am trying to use the following sas programs to convert multiple rtf files into pdf files by using the VB.NET (X command). It worked perfectly in PC sas. However, while using it in the SAS Enterprise, it gave no error message but didn't perform the pdf convertion.
Does anyone know what's happening in here? What should I do to make this work again? Thanks!
%macro vbs_pdf(rtfname=,pdfname=);
data _null_;
length vbscmd $ 400;
file "temp.vbs";
put 'Dim ObjWord';
put 'set objWord = CreateObject("Word.Application")';
put 'objWord.Visible = True';
vbscmd='objWord.Documents.Open("'|| "&rtfname" ||'")';
put vbscmd;
vbscmd='objWord.ActiveDocument.SaveAs "'||"&pdfname"||'", 17';
put vbscmd;
put 'objWord.ActiveDocument.Close(False)';
put 'objWord.Application.Quit(False)';
run;options noxwait;
data _null_;
command="START /WAIT CScript temp.vbs //NoLogo";
call system(command);
command2="DEL temp.vbs ";
call system(command2);
run;
%mend;
options noxwait;
data &prefix._toc;
set &prefix._toc;
call symput('count',compress(put(_n_,best.)));
run;
proc sql noprint;
select filename
into : rtf1- :rtf&count
from &prefix._toc;
run;
%macro cvtpdfs;
%do i=1 %to &count;
%let mypdf=%scan(&&rtf&i,1,'.');
%vbs_pdf(rtfname=&file2path./&&rtf&i,pdfname=&curpath/documents/pdf/&mypdf..pdf);
%end;
%mend;
%cvtpdfs;
By default SAS EG has X commands disabled. In your SAS configuration files for EG you will see -NOXCMD. You will see more here: https://blogs.sas.com/content/sasdummy/2009/11/19/using-the-x-and-systask-commands-from-sas-enterprise-guide/

Automate SAS program for different sites using %include

The problem I have is, I use the same program for reports on multiple sites. I have to run the code for each of them individually. I'm looking to automate my process to call the code and run for all sites in a go. This is the code I tried using but it is not working.
data _null_;
array sites {2} _temporary_ (SiteA SiteB);
do k = 1 to dim(sites);
%let site = sites(k);
%include '...path\SitesWait.sas';
end; run;
The code in SiteWait works perfectly on its own. I defined a macro variable called site, which sets the site for the code to run.
The error I keep getting is 'ERROR 117-185: There was 1 unclosed DO block.'
Thanks
You cannot include another multi-step program into the middle of a DATA step. %include just puts lines from the file into the program stream as if the lines had been typed into program. When SAS sees the first DATA or PROC statement in the included file it will stop compiling the DATA step in your main program and run it. That is why your DO loop is not seeing the END statement.
You could just use a data step to generate code that sets the parameter and includes the program.
data _null_;
length site $20 ;
do site='SiteA','SiteB' ;
call execute(cats('%nrstr(%let) site=',site,';'));
call execute("%include '...path\SitesWait.sas';");
end;
run;
What you have created is basically a macro with a single parameter named SITE. In fact you could possible just use %INCLUDE as the body of the macro definition. Then you could just code the calls you want instead of trying to process some list of values.
%macro siteswait(site);
%include '...path\SitesWait.sas';
%mend;
%siteswait(SiteA)
%siteswait(SiteB)
So you wish to include different files based on prior dataset. I suggest you create the file instead of reading it from array, but keeping with the spirit of your initial request:
%let basePath= c:\foo;
data _NULL_;
array sites {2} $5. ('SiteA' , 'SiteB');
do k = 1 to dim(sites);
site = sites(k);
call execute('%nrstr(%put &basePath.\'||site||';)');
end;
run;
This produces
c:\foo\SiteA
c:\foo\SiteB
You can easily replace the %put command with %include to accomplish what you wish.
Edit: What I suggest you try to do instead is something like this:
data includes;
format path $30. file $10.;
input path $ file $;
cards;
c:\foo\ file1.sas
c:\foo\ file2.sas
c:\Bar\ file1.sas
c:\Bar\ file2.sas
; run;
data _null_;
set includes;
call execute('%nrstr(%put '||strip(path)||''||strip(file)||';)');
run;
You should do like this :
main.sas
%macro ProcessList;
%let list_of_site=SiteA|SiteB|SiteC;
%let k=1;
%do %while (%qscan(&list_of_site, &k,|) ne );
%let site = %scan(&list_of_site, &k,|);
%include 'H:\desktop\SAS\test_inc.sas';
/*%put site=&site;*/
%let k = %eval(&k + 1);
%end;
%mend ProcessList;
%processList;
test_inc.sas
%put site=&site;
Result:
site=SiteA
site=SiteB
site=SiteC
With a macro fonction it is simple. You can replace %include with %put.
You can get the list of site from a dataset with this technic :
data test;
infile datalines dsd;
input site : $200. ;
datalines;
SiteA,
SiteB,
SiteC,
SiteD,
SiteE,
SiteF,
;
run;
proc sql noprint;
select quote(trim(site), "'") into : list_of_site separated by "|" from work.test;
quit;
Regards
If the sites don't change often, and if there are not too many of them, this may be the simplest approach:
%let site=siteA;
%include '...path\SitesWait.sas';
%let site=siteB;
%include '...path\SitesWait.sas';
%let site=siteC;
%include '...path\SitesWait.sas';
Be careful though. You may want to include code at the top of SitesWait.sas that 'resets' you SAS session. ie. clears any macro values you plan on using, deletes any datasets in your work folder etc. Otherwise the second call to SitesWait.sas may be affected by the prior run.

SAS: How to run a loop on a set of input variables for a function

I'm basically trying to make a program that can extract the relevant variables from a CSV file and perform stationarity tests on these timeseries variables without having to type out the variable names manually. I'm fairly new and maybe there's redundancies, but I've basically embeded the variable names into variable1, variable2, etc...
So when I've tested the ADF macro and input the variable as:
proc arima data=&y;
identify var= &variable1 stationarity =(adf = 3);
run;
it works, but I'm struggling to automate this process and would appreciate any help you could offer. Thanks.
Here is what I have to far:
proc import datafile=".....csv"
out=data
dbms=csv
replace;
getnames=yes;
run;
proc contents data=data out=contents noprint;
run;
data contents;
set contents(keep = name);
if Name = "Quarter" then delete;
run;
data _NULL_;
set contents;
call symputx(cats('variable',strip(_n_)),name);
run;
data want;
do i=1 to 4;
expert=symget(cats('variable',i));
output;
end;
run;
%macro ADF(y = ,x = );
proc arima data=&y;
identify var= &x stationarity =(adf = 3);
run;
%mend ADF;
You're very close... You just need to look into call execute. It will allow you to build commands and have them execute after the datastep finishes.
In the below code we're building the calls to the macro that we want to run. They will be exected as instructions after the datastep has finished processing. This will allow us to use values within the datastep to build the commands:
data want;
do i=1 to 4;
expert=symget(cats('variable',i));
call execute (cats('%ADF(y=data,x=',expert,');'));
end;
run;
There are other ways to do it but this is the simplest based on what you already have in place.
Just make sure your macro is defined prior to running the datastep.

SAS: Using the Put statement to create dynamic code

I'd like to create dynamic code using the PUT statement. According to this document from SUGI 29 (http://www2.sas.com/proceedings/sugi29/175-29.pdf),
put
"data XXXXX; "
/ 'infile "&datadir/&compid&filetype" missover ls=' tbla_fle
';' / 'input'
;
is equivalent to running
data onecomp ;
infile
"&datadir/&compid&filetype"
missover ls = 268 ;
input
However, when I try something similar to their example, the code enclosed in the PUT statement doesn't run and is instead written to the SAS Output Log:
data _NULL_;
put // "data put_test;" / "b=2;" / "run;";
run;
In Output Log:
data put_test;
b=2;
run;
I've checked the SAS documentation, and it seems that PUT is only used to "Write lines to the SAS log, to the SAS output window, or to an external location that is specified in the most recent FILE statement." Nowhere does it say that it can be used to create dynamically generated code.
I know that I must be missing something, but I'm not sure what. I'm using SAS Enterprise Guide 4.1.
Thank you!
The idea is to use put to write your generated code to a file. You then %include the file into your SAS session to run it. What you're missing is a file statement and the %include directive.
data _null_;
file 'temp.sas'; /* redirects put to a file instead of the SAS log */
put
"data XXXXX; "
/ 'infile "&datadir/&compid&filetype" missover ls=' tbla_fle
';' / 'input'
;
run;
%include 'temp.sas';