IBM Mainframe Forum Index
 
Log In
 
IBM Mainframe Forum Index Mainframe: Search IBM Mainframe Forum: FAQ Register
 

Calling and updating SAS Macro variables in same data step


IBM Mainframe Forums -> All Other Mainframe Topics
Post new topic   Reply to topic
View previous topic :: View next topic  
Author Message
Yogesh Jaiswal

New User


Joined: 31 May 2015
Posts: 12
Location: India

PostPosted: Thu Oct 11, 2018 12:37 pm
Reply with quote

Hi,

I have a requirement in which I need to call a macro using parms and then based on value received from that macro I need to update variable value in other macro/subprogram. All this needs to be done in same Data step as all the logic needs to be applied for all the records based on values received from Macro variables.
Back to top
View user's profile Send private message
vasanthz

Global Moderator


Joined: 28 Aug 2007
Posts: 1742
Location: Tirupur, India

PostPosted: Thu Oct 11, 2018 1:11 pm
Reply with quote

Show us your input data and expected output.
And then describe the requirement based on the data.
Back to top
View user's profile Send private message
expat

Global Moderator


Joined: 14 Mar 2007
Posts: 8797
Location: Welsh Wales

PostPosted: Mon Oct 15, 2018 11:46 am
Reply with quote

Using GLOBAL macro variables should do the job.
But more info is required.

Why the stated need to have everything done in a single data step ?
Sometimes this may not be possible;
Back to top
View user's profile Send private message
Yogesh Jaiswal

New User


Joined: 31 May 2015
Posts: 12
Location: India

PostPosted: Fri Oct 26, 2018 2:59 pm
Reply with quote

My requirement is like I have to produce report in which we have different Macros(like to fetch header first line, fetch region details, subtotal by region, class, fetch language, etc.). All these macro's need to be called for every record in my file which I prepared. That is the reason I need to do everything in a single data step or if I can call data step in loop that will also do.
Below are pseudo code which will help in my coding are:

Code:

/* MAIN SAS CODE */
OPTIONS MLOGIC MPRINT;             
%INC MACRO(MACCODE);               
                                   
DATA DEMO; 
  %LET MOV = 5;                 
  PUT "BEFORE CALL= " "&MOV"; 
  FORMAT FLAG 0;                       
  IF FLAG = 0 THEN DO;
    &LANGUAGE = LANG   /* LANG is coming from file */             
    call execute('%MACCODE(MOV)') ;     
    PUT "AFTER CALL= " "&MOV";
    PUT "FETCHED MOVCODE = " "&MOVCOD";
  END;                             
RUN;                               


Code:
/* MACRO CODE */
PAGE;                                           
%MACRO MACCODE(MOV);                                 
 /* READ THE INPUT MOVCODE FILE DEFINED IN JCL*/                 
DATA MOVCODE;                                   
  INFILE MOVCODE;                               
  INPUT @1  MCNO 3.                             
        @6  MCNAMEE $41.                       
        @48 MCNAMEF $41.;                       
                 
DATA MOVCDATA;                                 
  SET MOVCODE;                                 
  %PUT "IN MACRO = " &MOV;               
                                                                               
  IF &LANGUAGE = 'E' THEN   
    CALL SYMPUTX("MOVCOD",TRIM(MCNAMEE),"G");   
  ELSE
    CALL SYMPUTX("MOVCOD",TRIM(MCNAMEF),'G');
  %PUT "INSIDE AFTER UPDATE = " "&MOV";
RUN;                                         
%MEND MACCODE;                               
                                             
PAGE ;                                       


The above code is trying to pass MOV=5 and LANGUAGE to the macro MACCODE based on LANGUAGE the macro should return "MOVCOD" value in French or English which will be further used in Main SAS code to put in file or manipulate further.
The problem is when the SYMPUTX updates global variable it doesn't get updated in GST until it finds RUN statement i.e. completion of DATA step but we need that value in same data step where the macro is being called.

Let me know if its still not clear.
Back to top
View user's profile Send private message
Yogesh Jaiswal

New User


Joined: 31 May 2015
Posts: 12
Location: India

PostPosted: Fri Oct 26, 2018 6:41 pm
Reply with quote

vasanthz wrote:
Show us your input data and expected output.
And then describe the requirement based on the data.

Apology for the late reply. I have tried to explain my query with demo code. There may be syntax errors but I want to know whether we can have the solution in SAS using single DATA step.

Thanks in advance.
Back to top
View user's profile Send private message
Robert Sample

Global Moderator


Joined: 06 Jun 2008
Posts: 8696
Location: Dubuque, Iowa, USA

PostPosted: Fri Oct 26, 2018 6:50 pm
Reply with quote

I think you're going to find that what you want to do is simply not possible. From the SAS 9.1 Macro Language Reference manual at support.sas.com/documentation/onlinedoc/91pdf/sasdoc_91/base_macro_6997.pdf :
Quote:
The text substitution produced by the macro processor is completed before the
program text is compiled and executed. The macro facility uses statements and
functions that resemble those that you use in the DATA step. An important difference,
however, is that macro language elements can only trigger text substitution and are not
present during program or command execution.
From your description you want to read data from an external source (which requires the program text to be compiled and executed) and perform some macro expansion based upon that data (which is required to be done BEFORE the program text is compiled and executed). You might be able to do something in multiple DATA steps, but in a single DATA step it cannot be done.
Back to top
View user's profile Send private message
expat

Global Moderator


Joined: 14 Mar 2007
Posts: 8797
Location: Welsh Wales

PostPosted: Mon Oct 29, 2018 1:05 pm
Reply with quote

Depending on the number of variables in the dataset you could take a look at CALL SET, which I have only ever used the once. It does have its problems though.

But if you have data or value dependent situations, then the code is still relatively easy to do, letting you call the right macro for the right job.
NOTE: Make sure that the conditional tests and associated macro calls are enclosed within a DO / END loop, else they don't work too well.

You can also use plain SAS code as a macro too, so you do have options.

Code:

%macro tester1(InVar,OutVar);
      &OutVar = &InVar * 2;
%mend;
%macro tester2(InVar,OutVar);
      &OutVar = &InVar * 4;
%mend;
%macro tester3(OutVar);
   If Lang = "Eng"
      Then &Outvar = "roast beef";
      Else &Outvar = "grenouille";
%mend;

Data Inbits;
   a = 1; lang = "Eng"; output;
   a = 2; lang = "Fre"; output;
   run;

Data Outbits;
   Set Inbits;
   If A GE 2 Then do;
      %Tester1(A,B);
   End;
   Else do;
      %Tester2(A,C);
   End;
   %tester3(Tran_out);
   Array change _numeric_;
   Do over change;
      if change = . then change = 0;
   End;
   run;
Back to top
View user's profile Send private message
Yogesh Jaiswal

New User


Joined: 31 May 2015
Posts: 12
Location: India

PostPosted: Thu Nov 01, 2018 12:22 pm
Reply with quote

Thank you all for your reply. I did things with some other way i.e. included macro code in main SAS itself and resolved the variables there itself. This way the variable communication is not required.
Back to top
View user's profile Send private message
View previous topic :: :: View next topic  
Post new topic   Reply to topic View Bookmarks
All times are GMT + 6 Hours
Forum Index -> All Other Mainframe Topics

 


Similar Topics
Topic Forum Replies
No new posts Store the data for fixed length COBOL Programming 1
No new posts Data set Rec-Cnt and Byte-Cnt Testing & Performance 2
No new posts Calling DFSORT from Cobol, using OUTF... DFSORT/ICETOOL 5
No new posts SCOPE PENDING option -check data DB2 2
No new posts Calling Java method from batch COBOL ... COBOL Programming 5
Search our Forums:

Back to Top