Help using Base SAS procedures

Use array in macro

Reply
Contributor
Posts: 28

Use array in macro

[ Edited ]

How can you use an array in a macro?

I cannot define an array in a macro, so I decided to make the array in a datastep and reference to it:

data _null_;
	x1 = 1;
	x2 = 2;
	array bonds{2} x1-x2;
	call symput('blub', bonds);
run;
%macro test(input=);
	%let var = 1;
	%put 1;
	%put &var;
%mend test;
%test(input=&blub);

It fails at the symput:

ERROR: Illegal reference to the array bonds.

 

SAS Super FREQ
Posts: 8,866

Re: Use array in macro

Posted in reply to WouterKBC
Hi:
The array reference "bonds" is not something that you can use the way you envision. Let's start by saying that it doesn't matter what you want to do with the token or array reference "bonds" -- it is just reference, not a physical data structure.

A SAS array name is just one way to reference a group of variables that you want to have treated as though it was like an array. So anytime you use the reference BONDS, SAS will expect you to use a subscript or index, such as BONDS(1) (which points to X1) or BONDS(2) (which points to X2).

I guess I don't understand what you are doing in your %TEST macro program. Do you want to pass the values of X1 and X2 to the macro program or do you want to pass the variable names to the macro program?

What is the purpose of your %let var=1; are you thinking that var will be your index to the array?

cynthia
Contributor
Posts: 28

Re: Use array in macro

Posted in reply to Cynthia_sas

It's just some dummy code.

Let's assume:

%macro test(input=);
	%let var = input{1};
	%put &var;
%mend test;

 

Can I pass my bonds array to this macro?

Trusted Advisor
Posts: 1,568

Re: Use array in macro

Posted in reply to WouterKBC

Call Symput in data step is equivalent to %LET, that is assing value to a macro variable;

 

In your code "bonds" is a reference name of an array, not a variable value.

 

You can try a macro similar to that:

 

%macro test(array=1 2 3);  

      %let i = 1;

      %do %until(&x = );

             %let   x = %scan(input, &i);  

             %put  I = &i  x = &x;

             %let i = %eval(&i +1);

       %end;

%mend;

%test

      

Trusted Advisor
Posts: 1,568

Re: Use array in macro

I made a mismatch;
use array instead input un the macro
Trusted Advisor
Posts: 1,568

Re: Use array in macro

Here is the repaired code to test:

 

%macro test(array=1 2 3);  

      %let i = 1;

      %do %until(&x = );

             %let   x = %scan(&array, &i);  

             %put  I = &i  x = &x;

             %let i = %eval(&i +1);

       %end;

%mend;

%test;

Contributor
Posts: 28

Re: Use array in macro

Thanks for your reply.

 

I still have one problem. The array is defined outside the macro in a data step.

Whenever I try to 'call symput', I get the error 'Illegal reference to the array' so I cannot use it as a parameter.

 

Any suggestions?

Contributor
Posts: 28

Re: Use array in macro

Posted in reply to WouterKBC

Something suboptimal:

array=&var1-&var10

 

Where var... is defined outside the macro (with call symput).

 

In this case, the vars need to be filled with some dummy data which is not what I want.

Trusted Advisor
Posts: 1,568

Re: Use array in macro

Posted in reply to WouterKBC

Then you can do:

 

data _NULL_;

      x1 = 1; x2=2;

     array bonds{2} x1-x2;

 

      len = length(bonds);

      length array_string = $20;

      array_string = left(x1);

      do i=2 to len;

           array_straing = trim(array_string) || ' '||left(x(i));

      end;

      call symput ('my_array', trim(array));

run;

 

then use the macro test as: 

%test(array = &my_array);

        

Contributor
Posts: 28

Re: Use array in macro

177 len = length(bonds);
ERROR: Illegal reference to the array bonds.
Trusted Advisor
Posts: 1,568

Re: Use array in macro

Posted in reply to WouterKBC

sorry, next code runs without errors:

 

data _NULL_;
      x1 = 1; x2=2;
     array bonds{2} x1-x2;
      len = dim(bonds);
      length array_string $20;
      array_string = left(x1);
      do i=2 to len;
           array_straing = trim(array_string) || ' '||left(bonds(i));
      end;

      call symput ('my_array', trim(array_string));
run;

SAS Super FREQ
Posts: 708

Re: Use array in macro

Hi

To put all values of an array into one string, you can use the CAT... functions together with the OF keyword and an arrayname. See example below.

 

data _NULL_;
  x1 = 1;
  x2 = 2;
  x3 = 3;
  array bonds{*} x1-x3;
  length array_string $20;
  array_string = catx(" ", of bonds{*});
  call symputx('my_array', array_string);
run;
%put NOTE: &=my_array;

Bruno

 

Super User
Posts: 19,815

Re: Use array in macro

Posted in reply to WouterKBC

Based on your other question about importing multiple excel workbooks/sheets I can't help but suggest that this is the wrong path to be going down. 

 

You need to provide the file paths. SAS can extract them from a directory or you can provide the path or generate them in some manner, assuming some logic in naming, to pass to your proc import. An array will not help in any way with this process.

 

If you have the paths in a datastep you can  call the import procedure macro via a call execute statement. 

Ask a Question
Discussion stats
  • 12 replies
  • 2073 views
  • 1 like
  • 5 in conversation