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

Hello.

 

I am a newbie in SAS-programming, but have coded in many mainframe language.

 

I have made a SAS-program, running under z/OS, that takes a list of files and runs them through a set of macros, to retrieve membernames and data about each member from the file, one file at the time. (PDS-files).

 

Inside the innermost macro, a data-element test is created, that contains all the information about the members found in a single dataset. I can print the dataset from each file, to see what it contains.

 

My challenge is to sum the test datasets from the innermost macro, and keep them in a data element, after all files have been processed, so that I can continue working on the complete member-list outside the outermost macro. In the original example the data element created a print-file for each element in the filelist, but I need a file containing ALL members from ALL the files. 

 

Can anyone advise me of how to obtain my goal ? 

 

Most of the core of the code below has been retrieved from "SAS 9.4 Companion for z/OS, Sixth edition, SOURCE Procedure: z/OS, example 3: Producing Directory ...

Regards Henrik.

  *****************************;                                          
  * filenames to be processed *;                                         
  *****************************;                                          
  data filenames;                                                       
    format level $2.;                                                   
    format file_type $8.;                                                    
    format name_of_file $35.;                                                
    INPUT                                                               
          level   $                                                     
          name_of_file $                                                     
          file_type    $;                                                    
 datalines;                                                             
 1 user.test.pli PLI                                               
 2 common.prod.pli PLI                                                
 1 user.test.cobol cobol                                               
 2 common.prod.cobol cobol
 ;                                                                      
 
*-------------------------------------------------------------------*;  
 proc sort data=filenames;                                              
   by file_type level name_of_file;                                               
 run;                                                                   
*-------------------------------------------------------------------*;  
 proc print data=filenames;                                             
 run;                                                                   
*-------------------------------------------------------------------*;  
%MACRO OBSN(ds,nobsp);                                                  
  %global dset nobs;                                                    
  %let dset=&ds;                                                        
  %let dsid = %sysfunc(open(&dset));                                    
  %if &dsid %then                                                       
  %do;                                                                  
    %let nobs =%sysfunc(attrn(&dsid,NOBS));                             
    %let rc = %sysfunc(close(&dsid));                                   
  %end;                                                                 
  %else                                                                 
    %put Open for data set &dset failed - %sysfunc(sysmsg());           
%MEND OBSN;                                                             
*-------------------------------------------------------------------*;  
%macro find_members(f_level,f_name_of_file,f_file_type);                          
  %let i_level = &f_level;                                              
  %let i_name_of_file = &f_name_of_file;                                          
  %let i_file_type = &f_file_type;                                                
 
  FILENAME COBUSER  "&i_name_of_file" DISP=SHR;                              
  *--------------------------------------*;                             
  filename dirent '&temp';                                              
                                                                        
  proc source indd=cobuser nodata noprint dirdd=dirent;                 
                                                                        
  data   test;                                                          
                                                                        
  infile dirent eof=EXIT;                                               
*  file print header=HDR*;                                              
  retain TotEntries 0;                                                  
                                                                        
  input  member $8. ttr pib3.  ind pib1. @;                             
  TotEntries = ( TotEntries + 1);                                       
  halfwords = mod(ind,32);                                              
                                                                        
  if (halfwords = 15) or (halfwords = 20)                               
  then do;                                                              
    input ver      pib1.    /*  1    Version               */           
          mod      pib1.    /*  2    Modification          */           
          flags    pib1.    /*  3    Flags                 */           
          modifids pib1.    /*  4    Seconds last modified */           
          ccreate  pib1.    /*  5    Creation Date         */           
          create   pd3.     /*  6-8  "           "         */           
          cchanged pib1.    /*  9-9  Last Modified Date    */           
          changed  pd3.     /* 10-12 "           "         */           
          hh       pk1.     /* 13    Hour                  */           
          mm       pk1.     /* 14    Minute                */           
          ccurrent pib2.    /* 15-16 Current Lines         */           
          cinitial pib2.    /* 17-18 Initial Lines         */           
          cmodifid pib2.    /* 19 20 Modified Lines        */           
          userid   $char7.  /* 21-27 Userid                */           
          depends  $char1.  /* 28    If bit 3/byte 3 = ON  */           
          Ecurrent pib4.    /* 29-32 ON:  Current Lines    */           
          Einitial pib4.    /* 33-36 ON:  Initial Lines    */           
          Emodifid pib4. ;  /* 37-40 ON:  Modified Lines   */           
                                                                        
    yyyydddc = (ccreate * 100000)  + 1900000 + create;                  
    jcreate  = datejul(yyyydddc);                                       
    yyyydddx = (cchanged * 100000) + 1900000 + changed;;                
    jchange  = datejul(yyyydddx);                                       
                                                                        
    s_lvl = symget("i_level");                                          
    s_sprog =  symget("i_file_type");                                   
    s_path =  symget("i_name_of_file");                                 
                                                                        
  end;                                                                  
                                                                        
  return;                                                               
                                                                        
  EXIT:                                                                 
    put "Directory Entries Processed: " TotEntries;                     
                                                                        
  title "Print of TEST after &i_name_of_file";                          
  proc print data=test;                                                 
  run;                                                                  
  title "";                                                             
                                                                        
%mend find_members;                                                     
*-------------------------------------------------------------------*;  
%MACRO get_data(Navn,Nr);                                              
  put ### get_data : Processing &navn &nr;                          
  %GLOBAL HJ_level;                                                 
  %GLOBAL HJ_name_of_file;                                          
  %GLOBAL HJ_file_type;                                             
  data _null_;                                                      
    set &navn;                                                      
    if _n_ = &nr                                                    
    then do;                                                        
      call symput("hj_level",level);                                
      call symput("hj_name_of_file",name_of_file);                  
      call symput("hj_file_type",file_type);                        
    end;                                                            
  run;                                                              
  %put ### get_data : End of processing;                                      
%MEND get_data;                                                     
*-------------------------------------------------------------------*;  
%macro start(idata);                                                    
  %put ### START 001;                                                   
  %obsn(&idata,NOBS);                                                   
  %let ant = &NOBS;                                                     
  %PUT Antal = &ant;                                                    
  %do i = 1 %to &ant;                                                   
    %get_data(&idata,&i);                                              
    %let x_level   = &hj_level;                                         
    %let x_name_of_file = &hj_name_of_file;                             
    %let x_file_type    = &hj_file_type;                                
    %find_members(&hj_level, &hj_name_of_file, &hj_file_type);          
  %end; 
  %put ### START 999;                                                   
%mend;                                                                  
*-------------------------------------------------------------------*;  
data _null_;                                                            
  set filenames;                                                        
  options mprint;                                                       
  %start(filenames);                                                    
run;                                                                    
 
1 ACCEPTED SOLUTION

Accepted Solutions
Astounding
PROC Star

It's easiest to accumulate them at this point:

 

proc print data=test;                                                 
  run;                                                                  
  title "";   

Just add to the program:

 

proc append data=test base=all_tests;
run;

The first time through, when ALL_TESTS doesn't yet exist, this creates ALL_TESTS by copying TEST.  All the subsequent times through, it appends TEST to the end of ALL_TESTS.

View solution in original post

2 REPLIES 2
Astounding
PROC Star

It's easiest to accumulate them at this point:

 

proc print data=test;                                                 
  run;                                                                  
  title "";   

Just add to the program:

 

proc append data=test base=all_tests;
run;

The first time through, when ALL_TESTS doesn't yet exist, this creates ALL_TESTS by copying TEST.  All the subsequent times through, it appends TEST to the end of ALL_TESTS.

Tom
Super User Tom
Super User

You seem to have made using data to drive calling a macro much too complicated.

data _null_;                                                      
    set &navn;                                                      
    call execute(cats(
      '%nrstr(%find_members)(',level,',',name_of_file,',',file_type,')'
    ));          
run;

hackathon24-white-horiz.png

2025 SAS Hackathon: There is still time!

Good news: We've extended SAS Hackathon registration until Sept. 12, so you still have time to be part of our biggest event yet – our five-year anniversary!

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.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 2 replies
  • 794 views
  • 0 likes
  • 3 in conversation