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

Hello

I have a macro variable called allv_y that contain many Var(field) names.

I want to add single quote for each the fields names (each component) in macro var allv_y.

The required macro variable is called b_allv_y

The problem- When I create the new macro var I dont see all components!!

Some of them disappeared

 

 



%let allv_Y=LAKOACH AB_PA_IND_bad_ANYBAD AB_PA_MKR_TASHLUM AB_PA_AGE_VETEK_MASHK AB_PA_Y_TAS_SUMLLL_TYPE AB_PA_BITCHONOT 
AB_NEWC_Y_NIZHOS AB_NEWC_Y_NIZMISGOSH_HARIGA AB_NEWC_AKM_HZR AB_NEWC_MASHKANTA AB_NEWC_INC_COMPONENT AB_NEWC_INC_TREND 
AB_NEWC_CDO_CCSCR AB_NEWC_Y_NIZMISGCRD AB_NEWC_OSHER_HOS AB_NEWC_IND_bad_ANYBAD AB_NEWC_Y_HOVA_ZHUT AB_NEWC_LLL_LEUMI_HUZB 
AB_NEWC_MESHIHOT_MEZMEZ AB_NEWC_AGE_BALUT AB_OFI1MB_Y_NIZMISGOSH_HARIGA AB_OFI1MB_SMLHOV_PIG_AKM AB_OFI1MB_CDO_CCSCR 
AB_OFI1MB_Y_ECHZERLOANINC AB_OFI1MB_MESHIHOT_MEZMEZ AB_OFI1MB_IND_bad_ANYBAD AB_OFI1MB_Y_NIZHOS_INC AB_OFI1MB_Y_HOVA_ZHUT 
AB_OFI1MB_VETEK_AGE_BALUT AB_OFI1MB_MESHIHOT_CHCK AB_OFI1MB_HUZB AB_OFI1MB_LOAN_BIT AB_YNG_Y_NIZMISGOSH_HARIGA AB_YNG_AKM_HZR 
AB_YNG_INC_COMPONENT AB_YNG_CDO_CCSCR AB_YNG_Y_NIZMISGCRD AB_YNG_Y_HOVA_ZHUT AB_YNG_IND_bad_ANYBAD AB_YNG_MESHIHOT_MEZMEZ 
AB_YNG_HUZB AB_YNG_SMLHOV AB_YNG_VETEK_AGE_BALUT AB_YNG_Y_NIZHOSBIT AB_ACTV_AGE_BALUT AB_ACTV_VETEK AB_ACTV_Y_NIZMISGCRD 
AB_ACTV_CDO_CCSCR AB_ACTV_MASHKANTA AB_ACTV_MESHIHOT_MEZMEZCHCK AB_ACTV_HUZB AB_ACTV_SMLHOV AB_ACTV_AKM_HZR 
AB_ACTV_IND_bad_ANYBAD AB_ACTV_OSHER AB_ACTV_Y_NIZMISGOSH_HARIGA AB_ACTV_Y_NIZHOSBIT AB_ACTV_Y_ECHZERLOANINC_RINC 
AB_ACTV_Y_HOVA_ZHUT_INCCOMP VALID_FROM_DTTM POP_LOMEFORAT_WPPR POP_LOMEFORAT_NOPPR VCT_AB_SIBAT_OR TEUR_BAD_TYPE_AB 
TEUR_REJ_TYPE_AB WWW_6_AMT AVG_WAGE_3_MONTH_AMT AGE_VALUE AKM_ABSH_1_CNT AKM_ABSH_2_CNT AKM_ABSH_3_CNT AKM_ABSH_4_CNT 
AKM_ABSH_5_CNT ANOEXTAS_HOD_LLL_AMT BITCHONOT_KVUIM_6_AMT BITCHONOT_NEZILIM_6_AMT D5MACHZOR_MTI_AMT HARIGA_MISGERET_1_AMT 
HARIGA_MISGERET_2_AMT HARIGA_MISGERET_3_AMT HARIGA_MISGERET_4_AMT HARIGA_MISGERET_5_AMT HZR_HIUV_1_CNT HZR_HIUV_2_CNT 
HZR_HIUV_3_CNT HZR_HIUV_4_CNT HZR_HIUV_5_CNT HZR_HIUV_6_CNT balance_MESHU_LLL_PIG_MTH_1_AMT balance_MESHU_LLL_PIG_MTH_2_AMT 
balance_MESHU_LLL_PIG_MTH_3_AMT balance_MESHU_LLL_PIG_MTH_4_AMT balance_MESHU_LLL_PIG_MTH_5_AMT balance_MESHU_LLL_PIG_MTI_1_AMT 
balance_MESHU_LLL_PIG_MTI_2_AMT balance_MESHU_LLL_PIG_MTI_3_AMT balance_MESHU_LLL_PIG_MTI_4_AMT balance_MESHU_LLL_PIG_MTI_5_AMT 
balance_MESHU_LLL_PIG_MTI_6_AMT balance_MESHU_LLL_PIG_MTH_6_AMT MACHZOR_NOEXT_AMT MAX_HARIGA_1_5_AMT MAX_PIGUR_1_5_AMT 
MAX_TAUN_check_NO_20_21_CD MISGERET_CARTIS_ASHRAI_6_AMT MISGERET_OSH_6_AMT MISPAR_D_HARIGA_1_CNT MISPAR_D_HARIGA_2_CNT 
MISPAR_D_HARIGA_3_CNT MISPAR_D_HARIGA_4_CNT MISPAR_D_HARIGA_5_CNT MISPAR_D_HARIGA_6_CNT NITZUL_6_AMT 
NITZUL_CARTIS_ASHRAI_6_AMT NIZUL_BAOSH_6_AMT OSHER_AMT WWW_1_AMT WWW_2_AMT WWW_3_AMT WWW_4_AMT WWW_5_AMT 
SEMEL_CHOV_1_CD SEMEL_CHOV_2_CD SEMEL_CHOV_3_CD SEMEL_CHOV_4_CD SEMEL_CHOV_5_CD SEMEL_CHOV_6_CD SUG_CARTIS_ASHRAI_6_CD 
TAUN_check_1_CD TAUN_check_2_CD TAUN_check_3_CD TAUN_check_4_CD TAUN_check_5_CD TAUN_check_6_CD TAUN_check_NO_20_21_6_CD 
VETEK_6_VALUE ANY_BAD AKM_ABSH_6_CNT D5WWW_AMT HASIMOT_6_CNT HSMVISA_KASPOMAT_1_6_CNT balance_MESHU_LLL_PIG_1_5_IND 
balance_MESHU_LLL_PIG_6_AMT balance_MESHU_LLL_PIG_6_IND MAX_TAUN_check_MODEL_1_6_CD MESHIHOT_SHKIM_1_AMT MESHIHOT_SHKIM_2_AMT 
MESHIHOT_SHKIM_3_AMT MESHIHOT_SHKIM_4_AMT MESHIHOT_SHKIM_5_AMT MESHIHOT_SHKIM_6_AMT MESHIHOT_SHKIM_6_CNT NIT_HOSEN_BIT_AMT 
SEMEL_BALUT_CD TAS_HOD_LLL_REGILA_6_AMT TAUN_check_MODEL_6_CD;



data _null_;
length b_allv_Y $2500;
b_allv_Y = "'" || tranwrd("&allv_Y", " ", "' '") || "'";
call symputx('b_allv_Y', b_allv_Y);
run;

 

 

1 ACCEPTED SOLUTION

Accepted Solutions
LinusH
Tourmaline | Level 20

You macro variable is over 3100, so $2500 is not enough.

I see that you also have double spaces, added compbl() if you want to get rid of those.

data _null_;
	length b_allv_Y $4000;
	b_allv_Y = "'" || tranwrd(compbl("&allv_Y"), " ", "' '") || "'";
	call symputx('b_allv_Y', b_allv_Y);
run;
Data never sleeps

View solution in original post

5 REPLIES 5
LinusH
Tourmaline | Level 20

You macro variable is over 3100, so $2500 is not enough.

I see that you also have double spaces, added compbl() if you want to get rid of those.

data _null_;
	length b_allv_Y $4000;
	b_allv_Y = "'" || tranwrd(compbl("&allv_Y"), " ", "' '") || "'";
	call symputx('b_allv_Y', b_allv_Y);
run;
Data never sleeps
Patrick
Opal | Level 21

The code I've posted here will also work for this macro variable. I wouldn't directly change the macro var itself but create a new one.

%let allv_y2=%sysfunc(prxchange(s/(\w+)/'$1'/,-1,&allv_y));
%put &=allv_y2;

And if you also want to replace multiple blanks with a single blank then below should do.

%let allv_y3=%sysfunc(prxchange(s/(\w+)( *)/'$1' /,-1,&allv_y));
%put &=allv_y3;

 

For your data step syntax: Just assign the max length of 32767. It's only one iteration of a data _null_ step and though performance impact of a too long var will be minimal.

 

Stu_SAS
SAS Employee

Here is a macro function and FCMP function that will achieve this, modified from a utility function I use called cquote.

 

%macro squote(strlist);
    %unquote(%bquote(')%qsysfunc(tranwrd(%qsysfunc(compbl(%superq(strlist))),%bquote( ),%bquote(' ')))%bquote('))
%mend;

proc fcmp outlib=work.funcs.str;
    function squote(str$) $32767;
        return (cats("'", tranwrd(compbl(str),' ',"' '"), "'"));
    endfunc;
run;

Example:

options cmplib=work.funcs;

%put %squote(a b c);
%put %sysfunc(squote(a b c));
'a' 'b' 'c'
'a' 'b' 'c'

 

Tom
Super User Tom
Super User

Your math is off.

Since the length of the macro variable is longer than the character variable you created in the data step you are seeing truncation.

 98         %put %length(&allv_Y);
 3171

The maximum length of a character variable is 32K bytes. The maximum length of a macro variable is 64K bytes.

 

Note that the string will be longer once you add those extra characters.

 

If you expect to do this for lists that approach the limit of a character variable you might want to switch to a pure macro code solution.

 

If you expect to need to do this for a list that could exceed the length of macro variable you might want to switch to a solution that keeps the list as multiple observations in a dataset instead and then use a data step to write the generated code to a file.   One way around the macro variable limit is define an actual MACRO instead.

 

For example if you have a dataset names HAVE with a character variable named VAR with values like:

data have;
  input var :$32. @@ ;
cards;
LAKOACH AB_PA_IND_bad_ANYBAD AB_PA_MKR_TASHLUM AB_PA_AGE_VETEK_MASHK 
AB_PA_Y_TAS_SUMLLL_TYPE AB_PA_BITCHONOT  AB_NEWC_Y_NIZHOS 
AB_NEWC_Y_NIZMISGOSH_HARIGA AB_NEWC_AKM_HZR AB_NEWC_MASHKANTA 
AB_NEWC_INC_COMPONENT AB_NEWC_INC_TREND 
;

You could run a data step like this to create code that would define a macro name VARLIST.

filename code temp;
data _null_;
  set have end=eof;
  file code;
  if _n_=1 then put '%macro varlist;' ;
  put var @;
  if eof then put / '%mend;';
run;
%include code / source2;

That you could then call where you need that list of names to appear.

data new;
  length %varlist 8 ;
  call missing(of _all_);
run;

 

ballardw
Super User

Will you provide the reason that you want these variable names in single quotes?

 

I can see lots of potential problems with a long string and many single quotes for some types of use and perhaps it would be easier to approach the how this is to be used in the long run.

 

As an aside to basic SAS coding, when you have variables with common names that only vary by a sequence of digits such as your 

balance_MESHU_LLL_PIG_MTI_1_AMT 
balance_MESHU_LLL_PIG_MTI_6_AMT

you are often much better off providing the sequence number at the end of the variable as then you can use lists such as Common_part_:  to get all variables that start with a common name portion or Common_part_2 - Common_part_6 to process just the 2 through 6 named variables. Note that the : list builder immediately follows the common part of the name.

 

These lists can be used in keep/drop statements, array definitions using existing variables and many function calls that accept multiple variables using OF <list descriptor> such as Max(of Common_part_:

sas-innovate-2026-white.png



April 27 – 30 | Gaylord Texan | Grapevine, Texas

Registration is open

Walk in ready to learn. Walk out ready to deliver. This is the data and AI conference you can't afford to miss.
Register now and lock in 2025 pricing—just $495!

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
  • 291 views
  • 1 like
  • 6 in conversation