Assign a SAS macro variable with quotes to a data step var - sas

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

Related

Why return string format for FINFO function in SAS EG and SAS DI is different

I am trying to get file "modeified" datetime with
datetimeString = finfo(fid,'Last Modified');``
In SAS EG the return string looks like 12Jan2023:11:03:53
But in SAS DI the return string looks like 12 January 2023 11:03:28
I am trying to convert a string to a datetime like below and obviously it doesn't work for EG and throw invalid argument error.
moddate=input(finfo(fid,'Last Modified'),datetime20.);
I can fix this by writing bit of extra code in DI but would like to know why finfo(fid,'Last Modified'); return different string format?
I am working in data step.
Check the setting of the LOCALE option in the two different SAS sessions.
You can use the NLDATM informat to read the string generated by FINFO()
SAS Documentation on NLDATM informat
Example program that uses NLDATM informat to get datetime from FINFO() function.
Use a different in-format
37 data _null_;
38 x = '12 January 2023 11:03:28';
39 moddate=input(x,datetime20.);
40 moddate2=input(x,anydtdtm30.);
41 put 'NOTE: ' (mod:)(=datetime.);
42 run;
NOTE: Invalid argument to function INPUT at line 39 column 12.
NOTE: moddate=. moddate2=12JAN23:11:03:28

SAS: Why am I getting an 'Invalid data' error?

Why do I keep getting an invalid data error? I verified the numbers are in the correct columns and that the dates are structured in 'input' just as it is in 'datalines'.
data ThreeDates;
input #1 Date1 mmddyy10.
#12 Date2 mmddyy10.
#23 Date3 date9.;
format Date1
Date2
Date3 mmddyy10.;
datalines;
01/03/1950 01/03/1960 03Jan1970
05/15/2000 05/15/2002 15May2003
10/10/1998 11/12/2000 25Dec2005
;
run;
NOTE: Invalid data for Date1 in line 185 1-10.
NOTE: Invalid data for Date2 in line 185 12-21.
NOTE: Invalid data for Date3 in line 185 23-31.
RULE: ----+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9-
185 01/03/1950 01/03/1960 03Jan1970
Date1=. Date2=. Date3=. _ERROR_=1 _N_=1
NOTE: Invalid data for Date1 in line 186 1-10.
NOTE: Invalid data for Date2 in line 186 12-21.
NOTE: Invalid data for Date3 in line 186 23-31.
186 05/15/2000 05/15/2002 15May2003
Date1=. Date2=. Date3=. _ERROR_=1 _N_=2
NOTE: Invalid data for Date1 in line 187 1-10.
NOTE: Invalid data for Date2 in line 187 12-21.
NOTE: Invalid data for Date3 in line 187 23-31.
187 10/10/1998 11/12/2000 25Dec2005
Date1=. Date2=. Date3=. _ERROR_=1 _N_=3
NOTE: The data set WORK.THREEDATES has 3 observations and 3 variables.
NOTE: DATA statement used (Total process time):
real time 0.01 seconds
cpu time 0.01 seconds
Is it due to the space in front of each dataline? Make sure you also put the semicolon in column 1. Also, use datalines4 always as a habit.
The issue is clearly shown in the SAS log.
NOTE: Invalid data for Date1 in line 185 1-10.
NOTE: Invalid data for Date2 in line 185 12-21.
NOTE: Invalid data for Date3 in line 185 23-31.
RULE: ----+----1----+----2----+----3----+----4----+----5
185 01/03/1950 01/03/1960 03Jan1970
The RULE line with the dashes. plus sign and digits is there to help you understand exactly what was in the columns listed in the NOTE.
SAS only recognizes dates back to 1582, so trying to create dates in the year 195, 196 or 197 like on the first data line is not going to work.
You have misaligned your fixed column input with where the data is on the line. Probably because of the extra space you have added in front of every line of data, including the line with the semicolon that marks the end of the data (and also marks the end of the data step.)
Either remove the leading spaces or adjust the cursor movement to match the actual locations.
For this data you could also just use LIST MODE input instead of FORMATTED MODE and then the number of leading spaces or number of spaces between the values wouldn't matter. Adding the colon modifier in front of any in-line informats in the INPUT statement will insure the INPUT still operates in LIST MODE.
Note that in list mode the width specified for the informat is ignored, the whole next "word" on the line is used whatever its length.
Use a single period to indicate a missing value (numeric or character) when using LIST MODE input, The period will make sure that the values are used in the right order.
data ThreeDates;
input date1 :mmddyy. date2 :mmddyy. date3 :date.;
format date1-date3 yymmdd10.;
datalines;
01/03/1950 01/03/1960 03Jan1970
05/15/2000 05/15/2002 15May2003
10/10/1998 11/12/2000 25Dec2005
;
proc print;
run;
Results
You should get in the habit of starting both the DATALINES statement and the terminal line with the semicolon in first column to avoid getting column numbers confused.

read txt file where the same variables are listed in multiple columns using sas

I'm new to SAS. I'm trying to read a txt file where the same variables are listed in multiple columns.
The first variable is the date. The second one is time, and the last one is Blood Glucose. Thanks a lot for your kindness and help.
Sincerely
Wilson
The data can be read using a list input statement with the : (format modifier) and ## (line hold) features specified.
glucose-readings.txt (data file)
01jan16 14:46 89 03jan16 11:27 103 04jan16 09:40 99
05jan16 09:46 105 11jan16 10:58 108 13jan16 10:32 109
14jan16 10:49 90 18jan16 09:32 110 25jan16 10:37 100
Sample program
data want;
infile "c:\temp\glucose-readings.txt";
input
datepart :date9.
timepart :time5.
glucose
##;
datetime = dhms(datepart,0,0,timepart);
format
datepart date9.
timepart time5.
datetime datetime19.
glucose 3.
;
;
proc print; run;
From the documentation INPUT Statement: List
:
... For a numeric variable, this format modifier reads the value from the next non-blank column until the pointer reaches the next blank column or the end of the data line, whichever comes first.
...
##
holds an input record for the execution of the next INPUT statement across iterations of the DATA step. This line-hold specifier is called double trailing #.
...
Tip The double trailing # is useful when each input line contains values for several observations.
Be sure to read the documentation, that is were you will find detailed explanations and useful examples.

Wanna know how to implement %input in SAS Macros?

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=

Import text file into SAS

I'm importing a text file into SAS, using the code below :
proc import datafile="C:\Users\Desktop\data.txt" out=Indivs dbms=dlm replace;
delimiter=';';
getnames=yes;
run;
However, I get error messages in the log and certain fields are populated with "." in place of the real data and I don't know what is the problem.
The error message is :
Invalid data for DIPL in line 26 75-76.
Invalid data for DIPL in line 28 75-76.
Invalid data for DIPL in line 31 75-76.
Invalid data for DIPL in line 34 75-76.
A sample of the data is available here http://m.uploadedit.com/b029/1392916373370.txt
Don't use PROC IMPORT in most cases for delimited files; you should use data step input. You can use PROC IMPORT to generate initial code (to your log), but most of the time you will want to make at least some changes. This sounds like one of those times.
data want;
infile "blah.dat" dlm=';' dsd lrecl=32767 missover;
informat
trans $1.
triris $1.
typc $6.
;
input
trans $
triris $
typc $
... rest of variables ...
;
run;
PROC IMPORT generates code just like this in your log, so you can use that as a starting point, and then correct things that are wrong (numeric instead of character, add variables if it has too few as the above apparently does, etc.).
I copied the text file from your link, and ran your code (without the apostrophe):
proc import datafile="C:\temp\test.txt" out=Indivs dbms=dlm replace;
delimiter=';';
getnames=yes;
run;
And it worked fine despite the following:
Number of names found is less than number of variables found.
Result:
NOTE: WORK.INDIVS data set was successfully created.
NOTE: The data set WORK.INDIVS has 50 observations and 89 variables.
NOTE: PROCEDURE IMPORT used (Total process time):
real time 0.30 seconds
cpu time 0.26 seconds
If log has this "Number of names found is less than number of variables found."
then it creates new variables which have blank values.