DATA Step, Macro, Functions and more

Fequently used code in a macro

Accepted Solution Solved
Reply
Contributor
Posts: 63
Accepted Solution

Fequently used code in a macro

I use following code in multiple programs. My problem is that if I change any code here then , I need to make same changes in multiple programs to keep it synchronized.

Is there a way to write a macro, insert the following code in that macro and call that macro in all programs? In that way I just if I need to make updates then I just need to makes changes to one macro and need not worry about keeping all programs synched up. 

Data A;

set B;

if prxmatch("m/XXX/oi",Partner1) > 0 then Principa =  'X';

if prxmatch("m/YYYY/oi",Partner1) > 0 then Principal_SDC= 'Y';

if prxmatch("m/ZZ/oi",Partner1) > 0 then Principal_SDC= 'Z';

if prxmatch.....

if prxmatch..

.

.

.

.

run;

Thanks,


Accepted Solutions
Solution
‎04-27-2015 10:56 AM
Super User
Posts: 5,498

Re: Fequently used code in a macro

Posted in reply to buckeyefisher

A few suggestions ...

First, the call to the macro should be simpler:

data want;

   set have;

   %prxmatch

run;

Since your macro contains the statements that should be part of the DATA step, there is no need to add CALL EXECUTE.  This won't solve your current problem, but it will solve the one that would have resulted if your program actually located the macro.

Second, when you say that your folder contains your macro, is it saved in a file named prxmatch.sas?

Third, just as a precaution, get rid of all capital letters.  This probably won't matter on a PC but could easily matter on other operating systems.  So the name of the file that holds the macro definition should be prxmatch.sas, and the %MACRO and %MEND statements should refer to prxmatch, and the call to the macro should read %prxmatch.

Good luck.


View solution in original post


All Replies
Trusted Advisor
Posts: 1,913

Re: Fequently used code in a macro

Posted in reply to buckeyefisher

Yes, you want a macro library, you can create a folde somewhere and then when you launch SAS, you use the SASAUTOS= option to point to this folder. Every SAS macro program in this folder is now available to you for use without you specifically including the macro code.

For example, if you have SASAUTOS=(sasautos "\\myserver\mydir\paiges_macros") then every SAS program in that folder is available to your programming. If you have a program in there called donothing.sas which contains %macro dothing; then in any program you write, %donothing is a recognized macro name.

So, then, if you update this one macro program, every program that calls it gets the updated macro. And of course, you can have as many macros in this folder as you want.

Contributor
Posts: 63

Re: Fequently used code in a macro

Posted in reply to PaigeMiller

PaigeMiller,

I followed the step and following is the code.

options sasautos=(sasautos "\\C:\Users\Macro"); * this has my macro  - PRXmatch

Data want;

set have;

call execute('%PRXmatch');

run;

this is the macro

%macro Prxmatch;

if prxmatch("m/XXX/oi",Partner1) > 0 then Principal= 'X';

..

%mend PRXmatch;

It gives me this error - Apparent invocation of macro PRXMATCH not resolved.

Super User
Super User
Posts: 7,942

Re: Fequently used code in a macro

Posted in reply to buckeyefisher

The macro is not being defined until after the datastep where it is used is called.  Put the %macro before the datastep.  However, you could just do away with the macro as that isn't adding anything.  Post some test data/required output if you want a more comprehensive answer. 

Contributor
Posts: 63

Re: Fequently used code in a macro

RW9,

My input file has strings on which I want to run PRXmatch command and there are more than 500 Proxmatch commands that I want to run. The 500+ commands are used in multiple programs hence I want to use a macro.

Required output - Extract the 500+ strings into the output file.

Hope this helps.

-----------------------

options sasautos=(sasautos "\\C:\Users\Macro"); * this has my macro  - PRXmatch

Data want;

set have;

call execute('%PRXmatch');

run;

this is the macro

%macro Prxmatch;

if prxmatch("m/XXX/oi",Partner1) > 0 then Principal= 'X';

..

%mend PRXmatch;

-----------------------

Super User
Super User
Posts: 7,942

Re: Fequently used code in a macro

Posted in reply to buckeyefisher

So, you have a file which is full of commands.  The question then is why do you need the macro approach.  At the start of your program just do:

data _null_;

     length cmd $2000;

     infile "xyz.txt" end=eof;

     input cmd $;

     if _n_=1 then call execute('data want; set have;');

     call execute(strip(cmd)||";");

     if eof then call execute('run;');

run;

To add a better example:

I have a file tmp.txt, with two rows: 1) if a=1 then b=1;, 2) if a=2 then b=2;

%macro Get(inds=,outds=);

  data _null_;

    length cmd $200.;

    infile "s:\temp\rob\tmp.txt" dlm="¬" end=eof;

    input cmd;

    if _n_=1 then call execute("data &outds.; set &inds.;");

    call execute(cmd);

    if eof then call execute("run;");

  run;

%mend Get;

data have;

  a=1;output;

  a=2;output;

  a=3;output;

run;

%get (inds=have,outds=want);

Solution
‎04-27-2015 10:56 AM
Super User
Posts: 5,498

Re: Fequently used code in a macro

Posted in reply to buckeyefisher

A few suggestions ...

First, the call to the macro should be simpler:

data want;

   set have;

   %prxmatch

run;

Since your macro contains the statements that should be part of the DATA step, there is no need to add CALL EXECUTE.  This won't solve your current problem, but it will solve the one that would have resulted if your program actually located the macro.

Second, when you say that your folder contains your macro, is it saved in a file named prxmatch.sas?

Third, just as a precaution, get rid of all capital letters.  This probably won't matter on a PC but could easily matter on other operating systems.  So the name of the file that holds the macro definition should be prxmatch.sas, and the %MACRO and %MEND statements should refer to prxmatch, and the call to the macro should read %prxmatch.

Good luck.


Super User
Super User
Posts: 7,942

Re: Fequently used code in a macro

Posted in reply to Astounding

Yes, I see what your getting at.  Setup the text file so it can just be included, i.e. have the text file:

if a=1 then b=1;

if a=2 then b=2;

Then in the code just do:

data have;

  a=1;output;

  a=2;output;

  a=3;output;

run;

data want;

  set have;

  %include "s:\temp\rob\tmp.txt";

run;

Good shout that, didn't think of the include in the code itself.

Trusted Advisor
Posts: 1,913

Re: Fequently used code in a macro

While %include will work in some situations, it isn't as flexible or powerful as using SASAUTOS and it has drawbacks. So perhaps in this limited example, %include works as well as SASAUTOS, but I would like to point out some situations where it does not work as well.

For example, if you have a macro with different arguments

%macro mymacro(arg1=0,arg2=100);

and today you want to call it with arg1=0 and arg2=98, and tomorrow you want to call it with arg1=1 and arg2=14, then the %include approach requires you to edit the file to place these arguments into the code somewhere, and the next time you call it, you can (mistakenly) get these arguments again, unless you remember to edit the macro and change the arguments to the new values that they should take on. And I'm thinking that once you have developed a working macro, you don't want to be constantly editing solely for the purpose of changing the arguments.

The other drawback to %include is that you have to constantly type the entire line of text including the exact location of the file (which means you have to remember the exact folder location, and type it without typographical errors) as

%include "s:\temp\rob\mymacro.sas";

instead of just typing the macro name with a % sign in front of it such as (if said macro was defined with no arguments)

%mymacro

or with arguments

%mymacro(arg1=0,arg2=98)

Note: in either case, you don't have to remember the location of the macro, and there is no risk of mistyping the location of the macro.

Trusted Advisor
Posts: 1,913

Re: Fequently used code in a macro

Posted in reply to buckeyefisher

options sasautos=(sasautos "\\C:\Users\Macro");

I think it should be

options sasautos=(sasautos "C:\Users\Macro");

Trusted Advisor
Posts: 3,212

Re: Fequently used code in a macro

Posted in reply to buckeyefisher

500+ strings as a source. That sounds like the strings are coming from some system and are being stored somewhere.
You do not like to copy/paste that. But you can make a program that read that all and transform those in usable code parts.
The idea of creating source-members (RW9) that are included in the other programs could be the fat and most simple approach for that.

Creating source member is putting them writing them as external files like data and including them later as source. Not too difficult to do.

It is using the behavior of SAS as interpreter language and not using the compilation segregation as with many other languages.   

---->-- ja karman --<-----
Contributor
Posts: 63

Re: Fequently used code in a macro

Two solutions worked perfectly. One with including a text file and other with calling a macro (and yes making all small caps and saving it as .SAS file).

data want;

  set have;

  %include "s:\temp\rob\tmp.txt";

run;

data want;

   set have;

   %prxmatch

run;

Thanks you very much !!!

Regular Contributor
Posts: 227

Re: Fequently used code in a macro

Posted in reply to buckeyefisher

There are just a few reasons to use macros

* conditionals: %if

* loops: %do

* %sysfunc, %sysevalf

* write a function to return a value.

In the example you have posted, I see none of the above.

Others have pointed out the %include statement,

which is what I, too, recommend.

The differences, in your situation, where the code is only repetition and has not need of macro statements

* code in the %included program is always compiled in that step.

* a macro call generates a search of the sasautos library (set of folders)

and an %include of the file containing the macro

the code is compiled before being used in the step.

From the way I read your post, you are using this set of prx* statements in multiple programs,

but not more than once in any one program.

If that is true then there is no benefit to using a macro for this suite of statements.

Since I run all my programs in batch,

you may reply that you run several different programs in a session,

in which case the savings gained by the macro being compiled are worthy of consideration.

Caveat: just do not change the macro and expect the changes to show up in your next call of the macro.

you are using the compiled version of the macro

you have to recompile the macro, for which there are two ways to get it updated:

1. options mrecall;

2. %include 'my-macro';

Ron Fehd  macro maven

🔒 This topic is solved and locked.

Need further help from the community? Please ask a new question.

Discussion stats
  • 12 replies
  • 401 views
  • 6 likes
  • 6 in conversation