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

Hello,

 

I would like to know whether there is a way to replace duplicate space to single space for the value of macro variable.

 

For example:

%let _invar=A1 A2   A3;

Here you can see there are more than 1 space between A2 and A3. I would like to update _invar or build a new macro variable (_update) to 'A1 A2 A3'. Only 1 space between each word. What should I do.

 

In data step, I could do

COMPBL ("&_invar.")

 however I am not sure how to do the similar process for a macro variable. Could anyone guide me on this? Thanks.

1 ACCEPTED SOLUTION

Accepted Solutions
Tom
Super User Tom
Super User

You can use %SYSFUNC() in macro code to call many SAS functions.  It works for COMPBL().

%let varlist=A    b  C;
%let varlist=%sysfunc(compbl(&varlist));
%put &=varlist;

View solution in original post

9 REPLIES 9
Tom
Super User Tom
Super User

You can use %SYSFUNC() in macro code to call many SAS functions.  It works for COMPBL().

%let varlist=A    b  C;
%let varlist=%sysfunc(compbl(&varlist));
%put &=varlist;
SASJedi
Ammonite | Level 13

Consider using the %QCMPRES autocall macro provided with base SAS. 

Check out my Jedi SAS Tricks for SAS Users
Ksharp
Super User

Jedi,
Also %CMPRES autocall macro as well.

1    %let varlist=A    b  C;
2    %let varlist=%cmpres(&varlist);
3    %put &=varlist;
VARLIST=A b C
4    %let varlist=A    b  C;
5    %let varlist=%qcmpres(&varlist);
6    %put &=varlist;
VARLIST=A b C
Tom
Super User Tom
Super User

Note that those are left overs from before the %SYSFUNC() macro function was created.  Not really any reason to use them now.

SASJedi
Ammonite | Level 13

@Ksharp - true, but IMHO, %QCMPRES is generally a "safer" option. Because the results are returned pre-quoted, the macro processor will never process the returned text as additional macro code or references. In my decades of macro programming, about 80% of my troubleshooting efforts (correlating to about 80% of my hair loss 😁) have boiled down to under-quoted text being inadvertently resolved and reprocessed by the macro processor. So I always quote results unless I intend to use send the result back to the macro processor for further processing. For example, if I went with the answer provided by @Tom  I would have used %QSYSFUNC instead fo %SYSFUNC.

 

I guess it all depends on how much hair you are willing to sacrifice 😉 

 

Check out my Jedi SAS Tricks for SAS Users
Tom
Super User Tom
Super User

Macro quoting does not only "solve" problems.  It can also "cause" problems.

So use the version %QSYSFUNC() if you want macro quoting added and %SYSFUNC() if you want macro quoting removed.

SASJedi
Ammonite | Level 13

In my experience, less than 1% of macro program failures due to quoting issues have been caused by overquoting - so my default behavior is to quote. In situations where I am absolutely positive that processing the text will not produce characters that can be misinterpreted as code, will sometimes use the "non-Q" version of these functions. 

 

This example was obviously simplified by the OP to clarify the question. Not being sure of the ultimate application (and deeply desiring to preserve the OP's remaining hair 😉) I chose to recommend %QCMPRES and I have not changed my mind. His (and your) mileage may vary, of course, and we're all SAS coders  - free to make our own coding decisions. Having options provided is always nice. 

Check out my Jedi SAS Tricks for SAS Users
dxiao2017
Pyrite | Level 9

Hello, I have started to learn macro for a little while and I think this post is interesting and helpful. I tried both %sysfunc(compbl()) and %qcmpres() functions, they produce exactly the same results (see below) and %qcmpres saves a lot of typing. I have been used to use %sysfunc() when writing macro because I learnt it first and it is handy. I guess later on I will use functions such as %qcmpres(), %qscan(), and %qsysfunc() more.

Untitled3.png

SAS help cars; we are cars; that is why my default image;
Tom
Super User Tom
Super User

One of those things is not like the others.

%QSCAN() and %QSYSFUNC() are built in macro functions.  Part of the macro language.

%QCMPRES() is a user written macro. (actually four user written macros since it calls %QLEFT() and %QTRIM() macros and they call the %VERIFY() macro.)

It just happens to be supplied by SAS as part of their autocall library.

 

You can check out the source code yourself.  For example by using %INCLUDE with the /SOURCE2 option.

%include sasautos(qcmpres qleft qtrim verify) / source2;

 

If you want to save typing a few characters write your own macro with a shorter name.

%macro qb(string);
%qsysfunc(compbl(&string))
%mend;

And then use that macro instead.

 75         %put %qb(A   b  C);
 A b C

 

This version seems very robust.

%macro qcompbl / parmbuff;
%if %length(&syspbuff)>2 %then %qsysfunc(compbl(%quote&syspbuff));
%mend;

hackathon24-white-horiz.png

The 2025 SAS Hackathon Kicks Off on June 11!

Watch the live Hackathon Kickoff to get all the essential information about the SAS Hackathon—including how to join, how to participate, and expert tips for success.

YouTube LinkedIn

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
  • 9 replies
  • 2382 views
  • 12 likes
  • 5 in conversation