DATA Step, Macro, Functions and more

problems creating macro variables with call symput

Accepted Solution Solved
Reply
Contributor
Posts: 29
Accepted Solution

problems creating macro variables with call symput

Hi, I'm trying to import lots of text files and am having problems creating the macro variables which will allow me to do this.

I've been able to assign the file names to variables so when I run;

     %put _user_ ;

I get the following;

     filenm1     text_file_01326

     filenm2     text_file_14568

     filenm3     text_file_08554

     filenm4     text_file_99954

As these files have different schemas, I'm trying to create a second macro variable for each file identifying the schema.

The schema identifier is on the first line of the text file. I've isolated this record and am trying to use call symput to assign a value to a macro variable as such.

The macro loop works and the if then else block works but no macro variable gets assigned.

If I remove the strip function from the call symput, I get an error in the log stating;

     ERROR: Symbolic variable name Filetp           1 must contain only letters, digits, and underscores.

This indicates that the index function is correctly identifying the existance of the text in the var1 string and it's the call symput which is not functioning as I want.

I've read SUGI papers which suggest that the variables can in some instances be created locally but I don't think that this what's happening here.

I've also tried assigning numbers and SAS data set variables as macro values but this also hasn't worked.

Any help with this would be greatly appreciated.

Cheers,

Paul.


Accepted Solutions
Solution
‎02-28-2012 10:55 AM
PROC Star
Posts: 7,473

Re: problems creating macro variables with call symput

Posted in reply to Astounding

The following worked for me:

data ob_2_1;

  var1='xx DMMT ss';

run;

data ob_2_2;

  var1='xx DDDD ss';

run;

data ob_2_3;

  var1='xx DMLN ss';

run;

%macro ftmac ;

  %do i = 1 %to 3 ;

    data _null_ ;

      set  ob_2_&i ; /*this data set contains only the first record from the text file*/

      if index(var1,'DMMT') ge 1 then do;

        %global %sysfunc(cats(filetp,&i.));

        call symput('filetp'||strip(&i),'DM1') ;

      end;

      else if index(var1,'DMLN') ge 1 then do;

        %global %sysfunc(cats(filetp,&i.));

        call symput('filetp'||strip(&i),'DM2') ;

      end;

    run ;

    %put _user_ ;

  %end ;

%mend ftmac ;

%ftmac

%put &filetp1. ;

View solution in original post


All Replies
Super User
Posts: 5,504

Re: problems creating macro variables with call symput

Posted in reply to FatCaptain

Paul,

One problem lies in the first parameter to CALL SYMPUT.  Within the context of a DATA step, &i is a number where the software is looking for characters.  Change this:

strip(&i)

Instead, while this would be acceptable:

"&i"

It would be easier to just use a first parameter that looks like this (and use double quotes, not single):

"filetp&i"

This streamlines the situation, but doesn't really fix it.

Yes, it is true in your examples that the macro variables created by CALL SYMPUT will be %LOCAL, not %GLOBAL.  If you need to reference them once the macro has finished executing, add this statement as the first statement in the %DO loop:

%global filetp&i;

Good luck.

Contributor
Posts: 29

problems creating macro variables with call symput

Posted in reply to Astounding

Hi Astounding,

Thanks for this. I've altered the code as you suggest but still no luck.

My original code generated this note in the SAS log which no longer appears.

   

     NOTE: Numeric values have been converted to character values at the places given by:

     (Line)Smiley SadColumn).

     1:1 1:1 1:1

Super User
Posts: 5,504

Re: problems creating macro variables with call symput

Posted in reply to FatCaptain

I've edited my answer a couple of times.  Sorry about that.  Please use the latest suggestions, and re-post what your program now looks like.

PROC Star
Posts: 7,473

problems creating macro variables with call symput

Posted in reply to FatCaptain

According to the test code I just ran your macro variables ARE being created, but only locally.  If you need them to be global, why not just add  %global statements creating them as global before you create them?

data ob_2_1;

  var1='xx DMMT ss';

run;

data ob_2_2;

  var1='xx DDDD ss';

run;

data ob_2_3;

  var1='xx DMLN ss';

run;

%macro ftmac ;

  %do i = 1 %to 3 ;

    data _null_ ;

      set  ob_2_&i ; /*this data set contains only the first record from the text file*/

      if index(var1,'DMMT') ge 1 then

       call symput('filetp'||strip(&i),'DM1') ;

      else if index(var1,'DMLN') ge 1 then

       call symput('filetp'||strip(&i),'DM2') ;

    run ;

    %put _user_ ;

  %end ;

%mend ftmac ;

%ftmac

%put &filetp1. ;

Super User
Posts: 5,504

Re: problems creating macro variables with call symput

Art,

OK, here's a headscratcher for you.

As you noticed, the macro variables are %LOCAL if you run the program as is. 

However, try adding this statement before running the macro:

%global i;

You'll find that the macro variables are now all %GLOBAL, including those generated by CALL SYMPUT.  The rules are that CALL SYMPUT will not force the creation of a %LOCAL symbol table.  When &I already exists in the %GLOBAL table, there is no local table needed and CALL SYMPUT is forced to add to the %GLOBAL table.  It's a case where you can look at the macro in its entirety, but can't tell ahead of time whether CALL SYMPUT will use the %GLOBAL or %LOCAL table.

Solution
‎02-28-2012 10:55 AM
PROC Star
Posts: 7,473

Re: problems creating macro variables with call symput

Posted in reply to Astounding

The following worked for me:

data ob_2_1;

  var1='xx DMMT ss';

run;

data ob_2_2;

  var1='xx DDDD ss';

run;

data ob_2_3;

  var1='xx DMLN ss';

run;

%macro ftmac ;

  %do i = 1 %to 3 ;

    data _null_ ;

      set  ob_2_&i ; /*this data set contains only the first record from the text file*/

      if index(var1,'DMMT') ge 1 then do;

        %global %sysfunc(cats(filetp,&i.));

        call symput('filetp'||strip(&i),'DM1') ;

      end;

      else if index(var1,'DMLN') ge 1 then do;

        %global %sysfunc(cats(filetp,&i.));

        call symput('filetp'||strip(&i),'DM2') ;

      end;

    run ;

    %put _user_ ;

  %end ;

%mend ftmac ;

%ftmac

%put &filetp1. ;

Contributor
Posts: 29

problems creating macro variables with call symput

Thank you both for your help with this.

Cheers,

Paul.

Trusted Advisor
Posts: 1,301

problems creating macro variables with call symput

Instead of using %global and call symput you can do call symputx with the 'G' modifier.

Arthur Tabachneck wrote:

    data _null_ ;

      ...

        %global %sysfunc(cats(filetp,&i.));

        call symputx('filetp'||strip(&i),'DM1','G') ;

      ...

Valued Guide
Posts: 634

problems creating macro variables with call symput

The SYMPUTX routine will also eliminate the numeric to character conversion note as it does not expect the second argument to be character as does SYMPUT.

PROC Star
Posts: 7,473

problems creating macro variables with call symput

FriedEgg: Nice addition .. very much appreciated!

PROC Star
Posts: 7,473

Re: problems creating macro variables with call symput

Posted in reply to Astounding

Astounding: Agreed, unless you force the issue as I did in my previous post

🔒 This topic is solved and locked.

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

Discussion stats
  • 11 replies
  • 2777 views
  • 0 likes
  • 5 in conversation