BookmarkSubscribeRSS Feed
Aman4SAS
Obsidian | Level 7

Hi friends,

I am facing problem in using cats in macro i.e

when i m using this [below] its giving me correct result[here value of &x is being vary by do loop]

%let jb= %qsysfunc(cats(&jb,%str(,),&x));

But when i try to use: %let jb= %sysfunc(cats(&jb,%str(|),&x));

In this case result is only last variable.

Can u please help me on this , I have solved by didnt use any function i.e : %let jb= &jb|&x;

But i m looking for solution with function.

7 REPLIES 7
RW9
Diamond | Level 26 RW9
Diamond | Level 26

This works fine for me:

%let jb=eee|bbb;

%let x=ccc;

%let jb= %sysfunc(cats(&jb,%str(|),&x));

%put &jb.;

=eee|bbb|ccc

Please supply and example with data as perhaps that is causing your issue (i.e. maybe quotes?).

Aman4SAS
Obsidian | Level 7

data test;

input x $;

datalines;

a

b

c

d

e

f

g

;

run;

%let jb=;

data _null_;

set test;

if _n_=1 then; do;

call symput("x",x);

%let jb= %qsysfunc(cats(&jb,%str(,),&x));

end;

run;

%put &jb;

RW9
Diamond | Level 26 RW9
Diamond | Level 26

Ah, I see.  You can't do the %let statement in datasteps like that.  What you need is call symput, something like:

data test;
input x $;
datalines;
a
b
c
d
e
f
g
;
run;

data _null_;
  attrib lstx format=$2000.;
  set test end=last;
  retain lstx;
  if _n_=1 then lstx=x;
  else lstx=strip(lstx)||","||strip(x);
  if last then do;
    call symput('jb',lstx);
  end;
run;

%put &jb;

Aman4SAS
Obsidian | Level 7

My apology for providing you not exact example, actually program and dataset is very large, I would like to try to provide a portion of programe where i m facing issue.

here jobno, is number of unique subject

jlist is list of subject ie X|Y|Z|......

jobmax is largest one..

in bold where i m facing issue.

%macro findjb();

%do i = 1 %to &jobno;

%let x= %scan(&jlist,&i,%str(|));

proc sort data = jobs_&jobmax; by hash state; run;

proc sort data = jobs_&x; by hash state; run;

data comb;

merge jobs_&jobmax(in=var1) jobs_&x(in=var2);

by hash state;

if var1=0 and var2=1;

run;

proc sql ;

select count(*) into :ctno from comb;

quit;

%put &ctno;

%if &z=1 and &ctno=0 %then %do;

%let jb= &x;

%let z=%eval(&z+1);

%put &jb;

%end;

%else %if &z ne 1 and &ctno =0 and &x ne &jobmax %then %do;

%let jb= %sysfunc(cats(&jb,%str(|),&x));

%put &jb;

%end;

%end;

%put &jb;

data finaljb;

set testjobs;

if jobboardid in (&jb);

run;

%mend findjb;

%findjb;

RW9
Diamond | Level 26 RW9
Diamond | Level 26

Mmm, having some difficulty following what you are trying to do there.  May I suggest to add these couple of lines in:

---

    %else %if &z ne 1 and &ctno =0 and &x ne &jobmax %then %do;

%put X: &x.;

%put JB: &jb.;

      %let jb= %sysfunc(cats(&jb,%str(|),&x));

      %put &jb;

    %end;

---

And see what comes out - make sure to have moptions mprint and symbolgen on.  It maybe something simple, perhaps try putting double quotes around the &x and &jb for instance = %sysfunc(cats("&jb.",%str(|),"&x."));

Tom
Super User Tom
Super User

If you want to generate | delimited list of values from a dataset into a macro variable then PROC SQL can do that directly.

proc sql noprint ;

  select jobid into :joblist separated by '|'

  from mydata

;

quit;

Tom
Super User Tom
Super User

Why would you be using CATS() function with macro variables?

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
  • 7 replies
  • 2082 views
  • 0 likes
  • 3 in conversation