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

I tried to use CARD/DATALINES inside a macro, and somehow complains. How to de-route this?! Thanks,

 

%macro loopit();
	data _temp;
	set sashelp.class;
	ind=_N_;
	run;quit;
	proc sql noprint;
	select age into: val_age 	from _temp having ind=max(ind); 
	select height into: val_height 	from _temp having ind=max(ind); 
	select weight into: val_weight 	from _temp having ind=max(ind); 
	quit;
	%put "val_age=&val_age.";

/*working below*/	
data _out_c;
input mvar $16.;
val_out_=dequote(resolve(quote(mvar)));
ind=_N_;
datalines;
[value]
&val_age
&val_height
&val_weight
run;quit;

	data _out_c;
	set _out_c;
	if ind>1 then	val_out_2=substr(mvar,2,length(mvar));
	else val_out_2=mvar;
	if ind>1 then val_out_final=trim(val_out_2)||"="||strip(val_out_);
	else  val_out_final=mvar;
	run;quit;
%mend;

%loopit();
MPRINT(LOOPIT):   data _out_c;
MPRINT(LOOPIT):   input mvar $16.;
MPRINT(LOOPIT):   val_out_=dequote(resolve(quote(mvar)));
MPRINT(LOOPIT):   ind=_N_;
MPRINT(LOOPIT):   datalines;

ERROR: The macro LOOPIT generated CARDS (data lines) for the DATA step, which could cause incorrect results.  The DATA step and the macro
       will stop executing.
NOTE: The data set WORK._OUT_C has 0 observations and 3 variables.
NOTE: DATA statement used (Total process time):
      real time           0.00 seconds
      cpu time            0.01 seconds
1 ACCEPTED SOLUTION

Accepted Solutions
Tom
Super User Tom
Super User

That is pretty trivial format to reproduce.

Let's take the first observation of SASHELP.CLASS as an example.

filename outfile temp;

data _null_;
  set sashelp.class (obs=1);
  file outfile ;
  put '[value]' (_all_) (=/);
run;

Resulting file:

[value]
Name=Alfred
Sex=M
Age=14
Height=69
Weight=112.5

View solution in original post

7 REPLIES 7
Reeza
Super User

Cards/Datalines are not supported in macros.

 

It looks like you're selecting the last row? I'm assuming since it's a max could possibly return multiple values.

 

There are much simpler ways of doing this.

 

But this seems like a XY problem, what are you trying to accomplish here?

 

 

PaigeMiller
Diamond | Level 26

@hellohere in your other thread, you marked correct an answer from @PeterClemmensen which said:

 

Why do you want to do this? Seems to be part of a bigger problem? In that case, describe your actual problem. There is probably a better way than this 

 

If your question is merely related to using macro variables in cards/datalines, read Example 12: Using Macro Variables within a CARDS or DATALINES Statement.

 

You have totally ignored this answer, which you marked as correct. Please explain your overall goal, explain WHY you are doing this and what you hope to achieve, as stated above. None of this requires code, give us an answer in words that explains the project and what you are trying to do. It is hard to see how to make progress until we get this explanation from you, and several people have asked. Don't keep asking the same question in a different thread — explain.

--
Paige Miller
hellohere
Pyrite | Level 9

Well, I did take the link to code correctly, without macro, to pass macro variables to DATALINES/DATA.

 

This is for production. What I need is to generate a text file(will be read by C++ code):

This 1st line, [value]

The 2nd/3rd/.. line: variable_name=variable's value

 

I do not need the values at each column. I need them with the format above, line-by-line.

Coding without Macro Loopit(), run well. But I need overwrite the file every n-second(values are updated),

so I use MACRO(I skip the do-loop in my macro), but seem MACRO does not allow DATALINES/DATA.

 

So how to generate the file, periodically?!

 

 

Tom
Super User Tom
Super User

That is pretty trivial format to reproduce.

Let's take the first observation of SASHELP.CLASS as an example.

filename outfile temp;

data _null_;
  set sashelp.class (obs=1);
  file outfile ;
  put '[value]' (_all_) (=/);
run;

Resulting file:

[value]
Name=Alfred
Sex=M
Age=14
Height=69
Weight=112.5
hellohere
Pyrite | Level 9
Wow, this is super neat and clean.
Tom
Super User Tom
Super User

If you want to make a dataset with the values your SQL is selecting then why not just make the dataset with the SQL code that is selecting those values?

 

proc sql;
create table _out_c as 
  select age,height,weight
  from _temp
  having ind=max(ind)
;
quit;

 

 

And if you want to find the last observation in a dataset just use a data step.

 

data _out_c;
  set sashelp.class end=eof;
  if eof;
run;

 

 

hellohere
Pyrite | Level 9
I see your code. It surely is better than mine. Thanks, I am more on whether/how it works.

SAS Innovate 2025: Save the Date

 SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!

Save the date!

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
  • 7 replies
  • 1658 views
  • 1 like
  • 4 in conversation