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

Hi all,

 

The idea is I want to create a macro which, based on a selected row in the data set, will pick up the value of a specified column and assign this value to &LTierperc1.

 

e.g, in the code below, the macro ChargeTier is suppose to assign the value from the third row of Column6 (the column is set as a variable), say that value is 0.78, to LTierperc1.

After running the macro, I ran %put &LTierperc1, I got the error message " WARNING: Apparent symbolic reference LTIERPERC1 not resolved".

LTierperc1 doesn't exist :(.

 

Can someone help please, I can't understand why the macro doesn't work.

I should mention the code works outside of a macro. Strange thing is if I first run the code outside of a macro and then run the macro, the macro works. But then when I close SAS and after re-opening SAS and running the macro, the macro doesn't work, i.e. LTierperc1, is not created.

 

Here is the code:

 

%ChargeTier(column6);

 

%macro ChargeTier(Chargecol);
            data _null_;
           set tiering.Chargecode (where=(rownum=3));
           call symputx('LTierperc1',&Chargecol.);
           run;

%mend ChargeTier;

 

 

 

I would also like to expand the code to do the following

%CalcCost(Column6, 100);

 

%macro CalcCost(Chargecol, Amount);

           %ChargeTier(&Chargecol);     /*use to obtain the percentage to apply*/

           %Charges(&Amount);             /*macro charges invokes a code which will tier the £100 before a cost is calculated*/

            run;

%mend CalcCost;

 

Because Column6 is first assigned to &Chagecode (in CalcCost) then as &Chargecol (in ChargeTier), is it ok to to do this? Is there a better way to do this?

 

 

Thanks for your help.

 

Krish

1 ACCEPTED SOLUTION

Accepted Solutions
Reeza
Super User

Macro variables have a scope, global or local. Local means it exists only in the macro and global means it exists anywhere in your current SAS session. CALL SYMPUTX has a third parameter which controls the scope. Set it to global and try it outside of the macro again.

 


@krish_101 wrote:

Hi all,

 

The idea is I want to create a macro which, based on a selected row in the data set, will pick up the value of a specified column and assign this value to &LTierperc1.

 

e.g, in the code below, the macro ChargeTier is suppose to assign the value from the third row of Column6 (the column is set as a variable), say that value is 0.78, to LTierperc1.

After running the macro, I ran %put &LTierperc1, I got the error message " WARNING: Apparent symbolic reference LTIERPERC1 not resolved".

LTierperc1 doesn't exist :(.

 

Can someone help please, I can't understand why the macro doesn't work.

I should mention the code works outside of a macro. Strange thing is if I first run the code outside of a macro and then run the macro, the macro works. But then when I close SAS and after re-opening SAS and running the macro, the macro doesn't work, i.e. LTierperc1, is not created.

 

Here is the code:

 

%ChargeTier(column6);

 

%macro ChargeTier(Chargecol);
            data _null_;
           set tiering.Chargecode (where=(rownum=3));
           call symputx('LTierperc1',&Chargecol.);
           run;

%mend ChargeTier;

 

 

 

I would also like to expand the code to do the following

%CalcCost(Column6, 100);

 

%macro CalcCost(Chargecol, Amount);

           %ChargeTier(&Chargecol);     /*use to obtain the percentage to apply*/

           %Charges(&Amount);             /*macro charges invokes a code which will tier the £100 before a cost is calculated*/

            run;

%mend CalcCost;

 

Because Column6 is first assigned to &Chagecode (in CalcCost) then as &Chargecol (in ChargeTier), is it ok to to do this? Is there a better way to do this?

 

 

Thanks for your help.

 

Krish


 

View solution in original post

3 REPLIES 3
Reeza
Super User

Macro variables have a scope, global or local. Local means it exists only in the macro and global means it exists anywhere in your current SAS session. CALL SYMPUTX has a third parameter which controls the scope. Set it to global and try it outside of the macro again.

 


@krish_101 wrote:

Hi all,

 

The idea is I want to create a macro which, based on a selected row in the data set, will pick up the value of a specified column and assign this value to &LTierperc1.

 

e.g, in the code below, the macro ChargeTier is suppose to assign the value from the third row of Column6 (the column is set as a variable), say that value is 0.78, to LTierperc1.

After running the macro, I ran %put &LTierperc1, I got the error message " WARNING: Apparent symbolic reference LTIERPERC1 not resolved".

LTierperc1 doesn't exist :(.

 

Can someone help please, I can't understand why the macro doesn't work.

I should mention the code works outside of a macro. Strange thing is if I first run the code outside of a macro and then run the macro, the macro works. But then when I close SAS and after re-opening SAS and running the macro, the macro doesn't work, i.e. LTierperc1, is not created.

 

Here is the code:

 

%ChargeTier(column6);

 

%macro ChargeTier(Chargecol);
            data _null_;
           set tiering.Chargecode (where=(rownum=3));
           call symputx('LTierperc1',&Chargecol.);
           run;

%mend ChargeTier;

 

 

 

I would also like to expand the code to do the following

%CalcCost(Column6, 100);

 

%macro CalcCost(Chargecol, Amount);

           %ChargeTier(&Chargecol);     /*use to obtain the percentage to apply*/

           %Charges(&Amount);             /*macro charges invokes a code which will tier the £100 before a cost is calculated*/

            run;

%mend CalcCost;

 

Because Column6 is first assigned to &Chagecode (in CalcCost) then as &Chargecol (in ChargeTier), is it ok to to do this? Is there a better way to do this?

 

 

Thanks for your help.

 

Krish


 

krish_101
Fluorite | Level 6

Apologies there was a similar Query
https://communities.sas.com/t5/SAS-Procedures/macro-Warning-apparent-symbol-not-resolved/td-p/125698

 

I've inserted %global LTierperc1 as follows:

 

%macro ChargeTier(chargecol);
%global LTierperc1;

data _null_;

...

%mend ChargeTier;

 

Code works 🙂

Tom
Super User Tom
Super User

Macro variable scoping.

When you assign a value to a macro variable SAS will use any existing macro variable first.  If the macro variable does not already exist then it makes a new macro variable in the current (lowest) scope. 

 

So in your new session when you run the macro the macro variable does not exists and is created as local to the macro. When the macro ends the macro variable is gone.

 

But when you ran it outside the macro you created a global macro variable.  Then when you run the macro it sees and uses that global macro variable to store the results. So you can see the value after the macro ends and its scope is gone. 

 

You can use the third parameter to CALL SYMPUTX() to force the macro variable into the global scope.

You could define the macro variable before the first call to the macro.

You could add a %GLOBAL statement to the macro to make sure the macro is defined as global. Or better add a conditional global statement. 

%if not %symexist(LTierperc1) %then %global LTierperc1;

sas-innovate-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

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.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 3 replies
  • 672 views
  • 0 likes
  • 3 in conversation