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

Hi SAS Users,

 

This morning while trying to debug, I found out a problem regarding comparing the macro character value with a character value. My macro is

%let geogn_ = %substr(&outf,1,%length(&outf)-6);

data &outfm.screen12348911;
   set &outfm.merge2;
   if TYPE_1 = "EQ" 
   /*SCREEN 1*/
   and INDC3 not in ('UTILS', 'BANKS', 'FINSV', 'RLEST', 'INSUR')
   /*SCREEN 2*/
   and MAJOR="Y" 
   /*SCREEN 3*/
   and GEOGN = &geogn_.
   /*SCREEN 4*/
   and CURWS= &cur.
   /*screen 7*/
   and 
   s3 ge 0
   /*SCREEN 8*/
   and
   (s21 ge 0 or s21 =.) and s22 ge 0
   /*SCREEN 9*/
   and
   s2 ge 0
   /*SCREEN 11*/
;
run;

The main focus there is

and GEOGN = &geogn_.
   /*SCREEN 4*/
   and CURWS= &cur.
   /*screen 7*/

Because when I exclude these two lines of code, the code work normally

&cur. is a dimension of the macro

%macro ImportAndTranspose(
      File=
	  , cur=
	  , outf=
      , StartSheet=
      , EndSheet=
   );

The log of OPTIONS MPRINT is as below

 

data ARGENTINA_screen12348911;
MPRINT(IMPORTANDTRANSPOSE):   set ARGENTINA_merge2;
MPRINT(IMPORTANDTRANSPOSE):   if TYPE_1 = "EQ" and INDC3 not in ('UTILS', 'BANKS', 'FINSV', 'RLEST', 'INSUR') and MAJOR="Y" and 
GEOGN = ARGENTINA and CURWS= ARS and s3 ge 0 and (s21 ge 0 or s21 =.) and s22 ge 0 and s2 ge 0 ;

And regarding why I put TYPE_1 = "EQ" and INDC3 not in ('UTILS', 'BANKS', 'FINSV', 'RLEST', 'INSUR') using the single quote and the double quote is to check the interchangeable of these quotes so it should not be the reason.

 

Apart from that , I also tried to put the quote on "&geogn_." and "&cur." but when checking the options mprint, they are wrong (just show  "&geogn_." directly rather than "ARGENTINA" as I expected.

 

And a further question, I know the name of a dataset is limited by 32 characters, I am not sure if the name of output also being limited by 32 characters?

Can you please have a look and help me to sort it out?

Many thanks and warm regards.

Thank you for your help, have a fabulous and productive day! I am a novice today, but someday when I accumulate enough knowledge, I can help others in my capacity.
1 ACCEPTED SOLUTION

Accepted Solutions
ballardw
Super User

There is not way for us to tell what is resolving when you do not show starting values for the macro variable like &outf.

 

And where is &outfm defined? In other code you have shown

 outfm = %substr(&outf,1,4)

Which is suspect with this code because you apparently are getting ARGENTINA, which is way longer than 4 characters. So perhaps you have a timing issue of which variable you want to use when. Does your log show any messages such as:

WARNING: Argument 3 to macro function %SUBSTR is out of range.

 

Reusing macro variable names without consideration is one of the ways to madness.

 

WHOLE datesteps, whole procedures or whole macros including the invoking statement.

If your macro is too "long" to deal with for debugging then perhaps break it apart into smaller segments that get called.

For example just the name of your macro: importandtranspose tells me that you could have an import macro, a transpose, and the data step you show looks like yet another step in a larger process. Then you can debug each smaller piece.

 

What "output" other than a data set are you discussing about the 32 character length limit? If you mean a FILE then you are limited by the operating system name rules.

View solution in original post

13 REPLIES 13
PaigeMiller
Diamond | Level 26

Is your question

 

  1. Why does the MPRINT show GEOGN = ARGENTINA ?? Or
  2. Why doesn't GEOGN = ARGENTINA work ??
--
Paige Miller
Phil_NZ
Barite | Level 11

Hi @PaigeMiller 

Mine is the second question. Thank you, Sorry for confusing you!

Why doesn't GEOGN = ARGENTINA work ??

Thank you for your help, have a fabulous and productive day! I am a novice today, but someday when I accumulate enough knowledge, I can help others in my capacity.
PaigeMiller
Diamond | Level 26

I don't see where you have explained why you think it is not working. I don't see where you state what the expected output is.

 

GEOGN = ARGENTINA

 

compares two data set variables, one named GEOGN and one named ARGENTINA, to see if they have the exact same value on a given observation. Is that what you want?

--
Paige Miller
Phil_NZ
Barite | Level 11

Hi @PaigeMiller 

I run the code and when I added this condition, the code no longer works, but when I hide this condition, the code work normally, so I can hazard a guess it should be the problem

 

The GEOGN is a variable in my dataset

My97_0-1611870042243.png

 

And how I got the macro variable &geogn_

%let geogn_ = %substr(&outf,1,%length(&outf)-6);

where out_f is ARGENTINA_sheet

My point is, I am not sure if I compare the character variable (geogn_) and the character value of a variable of dataset (GEOGN) like this is properly. Why ?

 

Looking back to the log

 

data ARGENTINA_screen12348911;
MPRINT(IMPORTANDTRANSPOSE):   set ARGENTINA_merge2;
MPRINT(IMPORTANDTRANSPOSE):   if TYPE_1 = "EQ" and INDC3 not in ('UTILS', 'BANKS', 'FINSV', 'RLEST', 'INSUR') and MAJOR="Y" and 
GEOGN = ARGENTINA and CURWS= ARS and s3 ge 0 and (s21 ge 0 or s21 =.) and s22 ge 0 and s2 ge 0 ;

We can see the character value to compare normally inside the quotation like 'UTILS', 'BANKS', 'FINSV', 'RLEST', 'INSUR' or "Y" or "EQ" but GEOGN = ARGENTINA and CURWS= ARS are not in quotation, I think it is the main reason causing the problem.

Please let me know if I did not catch your point properly.

Thank you for your help, have a fabulous and productive day! I am a novice today, but someday when I accumulate enough knowledge, I can help others in my capacity.
PaigeMiller
Diamond | Level 26

@Phil_NZ wrote:

 

The GEOGN is a variable in my dataset

My97_0-1611870042243.png

This implies that you want to compare the value of the variable named GEOGN to the text string ARGENTINA; but the way you have written the code you are comparing the value of variable named GEOGN to the value of the variable named ARGENTINA. These are not the same.

 

I believe you want

 

GEOGN = "&geogn_."

to compare GEOGN to a text string.

 

--
Paige Miller
Phil_NZ
Barite | Level 11

Hi @PaigeMiller 

 

Thank you!

But when I put the quotation around &geogn. like that

GEOGN = "&geogn_."

It will show that I compare GEOGN = "&geogn_."  directly rather than compare GEOGN  with "ARGENTINA"

Apart from that , I also tried to put the quote on "&geogn_." and "&cur." but when checking the options mprint, they are wrong (just show  "&geogn_." directly rather than "ARGENTINA" as I expected.

I am looking for an approach to compare GEOGN = "ARGENTINA" while &geogn_=ARGENTINA

Thank you for your help, have a fabulous and productive day! I am a novice today, but someday when I accumulate enough knowledge, I can help others in my capacity.
PaigeMiller
Diamond | Level 26

With MPRINT on, please show me the LOG of this DATA step (the entire log for this DATA step, from start of the data step to end of the data step, with nothing chopped out).

--
Paige Miller
ballardw
Super User

@Phil_NZ wrote:

Hi @PaigeMiller 

 

Thank you!

But when I put the quotation around &geogn. like that

GEOGN = "&geogn_."

It will show that I compare GEOGN = "&geogn_."  directly rather than compare GEOGN  with "ARGENTINA"

Apart from that , I also tried to put the quote on "&geogn_." and "&cur." but when checking the options mprint, they are wrong (just show  "&geogn_." directly rather than "ARGENTINA" as I expected.

I am looking for an approach to compare GEOGN = "ARGENTINA" while &geogn_=ARGENTINA


Make sure that your code isn't acquiring "smart" or curly quotes. And

Phil_NZ
Barite | Level 11

Hi @PaigeMiller

 

I just check and run again and found out the reason. It is because of the single quote and double quote. 

In particular, if I code 

and GEOGN = '&geogn_.'

   and CURWS= '&cur.'

The log would be

 and GEOGN = '&geogn_.'        and CURWS= '&cur.'   

But if I use double quotes

  and GEOGN = "&geogn_."
   /*SCREEN 4*/
   and CURWS= "&cur."

the log is

GEOGN = "ARGENTINA"        and CURWS= "ARS"

and my problem is solved. so interesting  because previously I always assume the interchangeability between single and double quote. And it aligned with the comment of @Tom in this topic https://communities.sas.com/t5/General-SAS-Programming/Working-with-single-quotes-and-double-quotes/....

The lesson I learnt is that the main exception to interchangeability within SAS is that macro expressions (not just macro variables) inside single quotations are not evaluated while those in double quotes are.

 

Do you agree with my thought?

 

Thank you for your help, have a fabulous and productive day! I am a novice today, but someday when I accumulate enough knowledge, I can help others in my capacity.
PaigeMiller
Diamond | Level 26

@Phil_NZ wrote:

Hi @PaigeMiller

 

I just check and run again and found out the reason. It is because of the single quote and double quote. 

In particular, if I code 

and GEOGN = '&geogn_.'

   and CURWS= '&cur.'

The log would be

 and GEOGN = '&geogn_.'        and CURWS= '&cur.'   

But if I use double quotes

  and GEOGN = "&geogn_."
   /*SCREEN 4*/
   and CURWS= "&cur."

the log is

GEOGN = "ARGENTINA"        and CURWS= "ARS"

and my problem is solved. so interesting  because previously I always assume the interchangeability between single and double quote. And it aligned with the comment of @Tom in this topic https://communities.sas.com/t5/General-SAS-Programming/Working-with-single-quotes-and-double-quotes/....

The lesson I learnt is that the main exception to interchangeability within SAS is that macro expressions (not just macro variables) inside single quotations are not evaluated while those in double quotes are.

 

Do you agree with my thought?

 


Yes, macro variables will resolve properly inside double-quotes. They do not resolve inside single quotes. (Everywhere else in SAS, double and single quotes are interchangeable, as long they are used in pairs, but macro variables are different)

--
Paige Miller
ballardw
Super User

There is not way for us to tell what is resolving when you do not show starting values for the macro variable like &outf.

 

And where is &outfm defined? In other code you have shown

 outfm = %substr(&outf,1,4)

Which is suspect with this code because you apparently are getting ARGENTINA, which is way longer than 4 characters. So perhaps you have a timing issue of which variable you want to use when. Does your log show any messages such as:

WARNING: Argument 3 to macro function %SUBSTR is out of range.

 

Reusing macro variable names without consideration is one of the ways to madness.

 

WHOLE datesteps, whole procedures or whole macros including the invoking statement.

If your macro is too "long" to deal with for debugging then perhaps break it apart into smaller segments that get called.

For example just the name of your macro: importandtranspose tells me that you could have an import macro, a transpose, and the data step you show looks like yet another step in a larger process. Then you can debug each smaller piece.

 

What "output" other than a data set are you discussing about the 32 character length limit? If you mean a FILE then you are limited by the operating system name rules.

Phil_NZ
Barite | Level 11

Hi @ballardw 

 

First off, thank you for your dedicated lesson, actually I also slightly adjusted my code to suit the new way of dealing with data.

 

filename mydir 'C:\Users\pnguyen\Desktop\New folder';
data _null_;
did = dopen('mydir');
do i = 1 to dnum(did);
  fname = scan(dread(did,i),1,'.');
  /*fname: ARGENTINAARG*/
  length short_fn $29 currency $3 ;
  short_fn= cats(substr(fname, 1,length(fname)-3),'_');
  currency=substr(fname,length(fname)-2);
  cmd=cats('%ImportAndTranspose(File=C:\Users\pnguyen\Desktop\New folder\',
      strip(fname),
      ',cur=',currency,
      ',outf=',short_fn,'sheet,startsheet=1,endsheet=45);');
  call execute(cmd);
end;
keep fname;
run;

Then inside the macro, I assign outfm

%let outfm = %substr(&outf,1,%length(&outf)-5);

 

I did not post the new code here because I do not want you to be confused by my long code. Because I also went through some topics and people say that we should focus on the main point rather than post the whole thing. 

 

Apart from that "ARGENTINA" is retrieved from outf, not outfm. I am sorry because the way I name the variable confused you.

I will try to balance in the upcoming posts. 

 

Many thanks for your help so far @ballardw,

I really and truly appreciate it.

 

Thank you for your help, have a fabulous and productive day! I am a novice today, but someday when I accumulate enough knowledge, I can help others in my capacity.
ballardw
Super User

The point to the question about the variables comes from the beginning of your post:

%let geogn_ = %substr(&outf,1,%length(&outf)-6);

data &outfm.screen12348911;
   set &outfm.merge2;
   if TYPE_1 = "EQ" 

You are asking about resolved values for &geogn_. But not providing any way to actually know what that might be as no value for &outf is provided in the question.

HOWEVER the suspiciously similar variable &outfm, without explicit values either is mentioned.

I cannot tell how many times in this forum a problem relates to misspelling or using the wrong variable/value/character or what not. So clarification about the specific values is  a good idea.

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
  • 13 replies
  • 2775 views
  • 5 likes
  • 3 in conversation