BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
Junyong
Pyrite | Level 9

In the following MWE, CARDS is only reading the first 80 characters.

%let t=^dji mmm axp amgn aapl ba cat cvx csco ko dow gs hd hon ibm intc jnj jpm mcd mrk msft nke pg crm trv unh vz v wba wmt dis;

data i;
	input @@;
	_infile_=resolve(_infile_);
	input t $ @@;
cards;
^gspc ^irx &t
;

Though I am using a macro variable t here, my real code is using a SAS system option -SET to define an environmental variable t instead and using %SYSGET to read it.

1 ACCEPTED SOLUTION

Accepted Solutions
RichardDeVen
Barite | Level 11

You can't change the LRECL of CARDS

RichardADeVenezia_0-1608058267347.png

 

Tricks that run into limitations need new tricks. 

 

You can either SCAN through the tokens (presuming you are only parsing out space separated items) or write the value as data in a temporary file and read it back in using INPUT (as might be done if the parsing of the environment variable is more complicated)

 

Example:

 

%let t=^dji mmm axp amgn aapl ba cat cvx csco ko dow gs hd hon ibm intc jnj jpm mcd mrk msft nke pg crm trv unh vz v wba wmt dis;

data want(keep=token);
  length string $1000;
  string = "^gspc ^irx " || symget('t'); * sysget('environment-variable');
  
  do _n_ = 1 to countw(string,' ');
    token = scan(string,_n_,' ');
    output;
  end;
run;


filename sandbox temp;

data _null_;
  file sandbox lrecl=1000;
  put "^gspc ^irx " @@;
  put "&t";
  * put "%sysget('env');
run;

data want;
  infile sandbox lrecl=1000;
  length token $8;
  input token @@;
run;

View solution in original post

5 REPLIES 5
ballardw
Super User

It isn't just the length of the line. It is the macro variable.

 

 

From documentation of macro examples:

Macro variables are not allowed within the CARDS or DATALINES statements. 
This example shows a trick that uses the RESOLVE function to avoid this limitation. Program %let dog=Golden Retriever; data example; input text $40.; textresolved=dequote(resolve(quote(text))); datalines; John's &dog My &dog is a female That's Amy's &dog puppy ; proc print; run;
Junyong
Pyrite | Level 9

I am already using RESOLVE. It seems it's about RESOLVE rather than CARDS or the macro variable since

data i;
	input @@;
	_infile_=resolve(_infile_);
	input t $ @@;
cards;
^gspc ^irx ^dji mmm axp amgn aapl ba cat cvx csco ko dow gs hd hon ibm intc jnj jpm mcd mrk msft nke pg crm trv unh vz v wba wmt dis
;

still shows the problem while

data i;
	input t $ @@;
cards;
^gspc ^irx ^dji mmm axp amgn aapl ba cat cvx csco ko dow gs hd hon ibm intc jnj jpm mcd mrk msft nke pg crm trv unh vz v wba wmt dis
;

does not.

Tom
Super User Tom
Super User

It is because the LRECL for the line is already set too short to hold all of the macro variable.  

Use PARMCARDS instead.  In this code the first data step reads 4 values.  The second one reads 24 since the macro variable reference is replaced with 21 copies of xxxx.

options parmcards=text ;
filename text temp;
parmcards;
aaa bbb ccc &mvar
;

%let mvar=xxx;

data test1;
  infile text lrecl=32767 ;
	input @@;
  _infile_=resolve(_infile_);
	input t $ @@;
run;

%let mvar=%sysfunc(repeat(%str(xxxx ),20));

data test2;
  infile text lrecl=32767 ;
	input @@;
  _infile_=resolve(_infile_);
	input t $ @@;
run;

 

Or better still just use PROC STREAM.

 

RichardDeVen
Barite | Level 11

The core problem is that OP wanted to input @@ from the resolved value as _infile_.  Thus, the _infile_ length limit makes it infeasible to stuff the >80 character resolved value back into _infile_.

RichardDeVen
Barite | Level 11

You can't change the LRECL of CARDS

RichardADeVenezia_0-1608058267347.png

 

Tricks that run into limitations need new tricks. 

 

You can either SCAN through the tokens (presuming you are only parsing out space separated items) or write the value as data in a temporary file and read it back in using INPUT (as might be done if the parsing of the environment variable is more complicated)

 

Example:

 

%let t=^dji mmm axp amgn aapl ba cat cvx csco ko dow gs hd hon ibm intc jnj jpm mcd mrk msft nke pg crm trv unh vz v wba wmt dis;

data want(keep=token);
  length string $1000;
  string = "^gspc ^irx " || symget('t'); * sysget('environment-variable');
  
  do _n_ = 1 to countw(string,' ');
    token = scan(string,_n_,' ');
    output;
  end;
run;


filename sandbox temp;

data _null_;
  file sandbox lrecl=1000;
  put "^gspc ^irx " @@;
  put "&t";
  * put "%sysget('env');
run;

data want;
  infile sandbox lrecl=1000;
  length token $8;
  input token @@;
run;

hackathon24-white-horiz.png

2025 SAS Hackathon: There is still time!

Good news: We've extended SAS Hackathon registration until Sept. 12, so you still have time to be part of our biggest event yet – our five-year anniversary!

Register Now

How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

Find more tutorials on the SAS Users YouTube channel.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 5 replies
  • 1576 views
  • 1 like
  • 4 in conversation