Can some one help me in using %input macro statement in SAS. I came to know by googling, that %input is a macro statement used to create macro variables.
%INPUT should only be used in legacy situations.
The documentation, if you read it, states the conditions for use.
DetailsThe macro processor interprets the line submitted immediately after a %INPUT statement as the response to the %INPUT statement. That line can be part of an interactive line mode session, or it can be submitted from within the Program Editor window during a windowing environment session.
This means you are typing in values from a console or submitting code in the Program Editor. %INPUT will cause an error when submitted from the default Enhanced Editor or to a SAS server.
Program Editor
%symdel a b c;
%input a b c;
123 456 pqr
%put NOTE: &=a &=b &=c;
--- LOG ---;
30 %input a b c;
31
32 %put NOTE: &=a &=b &=c;
NOTE: A=123 B=456 C=pqr
Enhanced Editor
%symdel a b c;
%input a b c;
123 456 pqr
%put NOTE: &=a &=b &=c;
--- LOG ---;
34 %input a b c;
35 123 456 pqr
---
180
ERROR 180-322: Statement is not valid or it is used out of proper order.
36
37 %put NOTE: &=a &=b &=c;
NOTE: A= B= C=
Related
When I run the following, it works fine:
%let mname = ABC<2>;
%put &mname;
ABC<2>
%let mname2 = %scan("&mname.", 2, '<>');
%put &mname2;
2
However, when I changed mname2 to the following, it gives the error:
%let mname2 = %scan("&mname.", 1, '<');
%put &mname2;
ERROR: Open code statement recursion detected.
Any idea what is causing it?
Since you added quotes around the value passed to the %SCAN() function and then only selected one of the quotes as the output you have generated unbalanced quotes.
In regular SAS code (and most programming languages) to allow the compiler to tell the difference between a variable name or a keyword and a string literal you add quotes around the string
But the macro processor language is different. To the macro processor everything is a string and it just looks for the & or % triggers to tell whether there is anything it needs to operate on.
49 %let mname = ABC<2>;
50 %put &=mname;
MNAME=ABC<2>
51 %put %scan(&mname,1,<>);
ABC
52 %put %scan(&mname,2,<>);
2
If you think it is possible the %SCAN() function will return unbalanced quotes or other things that might need macro quoting use the %QSCAN() function instead.
I've been using a code with seemingly no problem for a quite a while now, and today it stopped working and in a pretty weird way.
I have several SAS files in a folder and I want to export each of them into a CSV file, while keeping only some columns and if some condition is satisfied.
The file structure is folders called data_(year) and inside are several files called file_(region number)
%macro extract_data(year);
libname lib "c:\data_&year.";
%let file_names = 24 27 29;
%let nb_files = 3;
%do i=1 %to &nb_files.;
%let next_file = %scan(&file_names, &i);
data file&next_file. (keep = C1 C2);
set lib.file_&next_file.;
if C1 = &next_file.;
run;
proc export data = file&next_file.
outfile = "c:\Export\file&year._&next_file."
dbms = csv
replace;
%end;
%mend;
%extract_data(2010)
Today this stopped working and the error I get is for the FIRST file where I get an "ERROR 180-322: Statement is not valid or it is used out of proper order" underlining set. The really weird thing is that it does this only for the first file (ie in the example above 24) and then the other exports seem to go through. I tried with different triplets of file_names and now the one which didn't work before does (ie file_names = 12 24 27 and in this case 24 exported normally and it was 12 that didn't work).
Thank you very much for your help!
The most likely issue is invisible characters in your macro variable that is leading to invalid dataset names being generated by your macro.
Try retyping the list of values being assigned to FILE_NAMES macro variable to eliminate any strange characters.
Or to debug try looking at the hex code representation of the value by using a data step like:
data _null_;
string="&file_names";
put string $hex.;
run;
Spaces should show as hex code 20. Digits are the hex code 30 to 39. Any other codes like 09,0A,0D,A0 are invisible characters.
Tech: SAS 9.3
Currently working in SAS with a programming background vs a BI background.
Also running SAS from a scheduler, and not using EG or any SAS product to run my sas programs
This is what I want to see in my log file:
==================================================================
========================SAS Program Name==========================
==================================================================
Need to do this dynamically so that I can hand off the bit to our contractors to use so we have unified logs, instead of hardcoding it in each of the 500+ sas programs they're creating and modifying.
This is as far as I got
data _null_;
LL=%scan(%sysfunc(getoption(linesize,KEYWORD)),2,"=");
put 132*'=';
put "&progName";
put 132*'=';
run;
What I would is something that looks like this:
data _null_;
LL=%scan(%sysfunc(getoption(linesize,KEYWORD)),2,"=");
padding = (LL - %length("&progName"))/2;
padding = round(padding,1);
put LL*'=';
put padding*'=' "&progName" padding*'=';
put LL*'=';
run;
Is this possible using the put command?
34 %let progname=SAS Program Name.sas;
35 data _null_;
36 LL=input(getoption('linesize'),f8.);
37 put #;
38 _file_ = repeat('=',ll-1);
39 put;
40 progname=translate("&progname",'ff'x,' ');
41 put progname $varying256.-c ll #;
42 _file_ = translate(_file_,'=',' ',' ','ff'x);
43 put ;
44 _file_ = repeat('=',ll-1);
45 put;
46 run;
====================================================================================================================================
========================================================SAS Program Name.sas========================================================
====================================================================================================================================
You could make it a stored program... Update I changed double quoted macro variable reference to SYMGET in the stored version. Otherwise it would only print the program when it was compiled.
%let progname=SAS Program Name.sas;
data _null_ / pgm=work.banner;
LL=input(getoption('linesize'),f8.);
progname=translate(symget('progname'),'ff'x,' ');
put #;
_file_ = repeat('=',ll-1); put;
put progname $varying256.-c ll #;
_file_ = translate(_file_,'=',' ',' ','ff'x); put ;
_file_ = repeat('=',ll-1); put;
run;
data pgm=work.banner;
run;
This can be solved with simple math. If you ever took a typing class using a real typewriter then you may remember how to center titles on the paper.
In this case, I determine how many equals I need to pad the program name by subtracting the length of the program name from the line length. Then divide that number in half to determine how many before and after the program name. The cats function concatenates the equals string before and after the program name. Simple as that.
options linesize=65;
%let progname = My SAS Program;
data _null_;
ll = input(getoption('linesize'), 5.);
put #;
_file_ = repeat('=', ll-1);
put;
equals = repeat('=', (ll-length(strip("&progname"))-1)/2);
_file_ = cats(equals, "&progname", equals);
put;
_file_ = repeat('=', ll-1);
put;
run;
The output in the log:
=================================================================
==========================My SAS Program=========================
=================================================================
How to make below statement works?
%let qccomment= /n ORACLE execute error: ORA-20001: User xyxlll
does not have acccess to the gva BA_DEV ORA-06512: at
"M_UTIL", line 51 ORA-06512: at line 1. /nTable XY_XY does not exist
(Oracle extract data failed);
%put &qccomment;
data null;
i ="&qccomment";
put i;
run;
It return with error
ERROR 386-185: Expecting an arithmetic expression.
ERROR 200-322: The symbol is not recognized and will be ignored.
ERROR 76-322: Syntax error, statement will be ignored.
You can use the SYMGET() function to retrieve the value a macro variable without having to worry about any macro quoting (at least in the step that is doing the retrieval).
data _null_;
i = symget('qcomment');
put i= ;
run;
If you really did need to reference the macro variable's value and use it to generate a quoted string then use the QUOTE() function to insure that any embedded quotes are properly doubled so that the generated string is a valid string literal.
data _null_;
put %sysfunc(quote(&qcomment));
run;
You need to use macro quoting function to get around this,
/* Using %BQUOTE in let statement to quote the string */
%let qccomment= %bquote(/n ORACLE execute error: ORA-20001: User xyxlll
does not have acccess to the gva BA_DEV ORA-06512: at
"M_UTIL", line 51 ORA-06512: at line 1. /nTable XY_XY does not exist
(Oracle extract data failed));
%put &qccomment;
data null;
i ="&qccomment";
put i;
run;
LOG
11 %let qccomment= %bquote(/n ORACLE execute error: ORA-20001: User xyxlll
12 does not have acccess to the gva BA_DEV ORA-06512: at
13 "M_UTIL", line 51 ORA-06512: at line 1. /nTable XY_XY does not exist
14 (Oracle extract data failed));
15
16 %put &qccomment;
/n ORACLE execute error: ORA-20001: User xyxlll does not have acccess to the gva BA_DEV
ORA-06512: at "M_UTIL", line 51 ORA-06512: at line 1. /nTable XY_XY does not exist
(Oracle extract data failed)
17 data null;
18 i ="&qccomment";
19 put i;
20 run;
/n ORACLE execute error: ORA-20001: User xyxlll does not have acccess to the gva BA_DEV
ORA-06512: at "M_UTIL", line 51 ORA-06512: at line 1. /nTable XY_XY does not exist
(Oracle extract data failed)
NOTE: The data set WORK.NULL has 1 observations and 1 variables.
NOTE: DATA statement used (Total process time):
real time 0.08 seconds
cpu time 0.00 seconds
I try to write the labels of each variable to an Excelsheet in SAS. Im using the option DBLABEL=YESwhich allows you to print the labels as column headings in Excel. Unfortunately it seems that my Labels are too long. Does anybody has a solution? Here is the code I m using:
data test;
length a 3.
b 3.
c 3.;
input a b c;
label a = "this label is too long for writing it from sas to excel";
datalines;
18 20 15
25 20 80
63 72 14
run;
libname xls oledb provider="Microsoft.ACE.OLEDB.12.0"
preserve_tab_names=yes preserve_col_names=yes
datasource="f:my workspace\test_9.xls" provider_string="Excel 12.0";
data xls.test (dblabel=yes);
set test;
run;
libname xls clear;
This is ther error I receive.
ERROR: Error binding parameters: Invalid column name: this label is
too long for writing it from sas to excel
Thanks in advance
This doesn't appear to be a problem with proc export instead.
proc export data=test outfile="C:\test.csv" label;
run;