×
INTELLIGENT WORK FORUMS
FOR COMPUTER PROFESSIONALS

Contact US

Log In

Come Join Us!

Are you a
Computer / IT professional?
Join Tek-Tips Forums!
  • Talk With Other Members
  • Be Notified Of Responses
    To Your Posts
  • Keyword Search
  • One-Click Access To Your
    Favorite Forums
  • Automated Signatures
    On Your Posts
  • Best Of All, It's Free!

*Tek-Tips's functionality depends on members receiving e-mail. By joining you are opting in to receive e-mail.

Posting Guidelines

Promoting, selling, recruiting, coursework and thesis posting is forbidden.

Students Click Here

SAS MACRO not resolving macro variables

SAS MACRO not resolving macro variables

SAS MACRO not resolving macro variables

(OP)
Basically, I want to read two columns from a csv file and create a text file for each record. The text file name is the first column and I want to write the second column to this text file.
CSV file records sample:
column1 column2
txtfile1 file1data
txtfile2 file2data
txtfile3 file3data
txtfile4 file4data

<**** start code ****>
%LET CSVFile_FullPath=C:\projects\csvFile.csv;
%LET Directory_FullPath=C:\projects\txtFilesFolders;

data _null_;
infile "&CSVFile_FullPath" dsd dlm=',' firstobs=2 truncover missover;
input col1 :$8. col2 :$9.;
/*build the text file name*/
txtFile="&Directory_FullPath"||"\"||col1||".txt";
/* pass txt file name and data to a macro*/
%WriteTo(txtFile,col2);
run;
/*parms: file name and data*/
%macro WriteTo(fle,dta);
%let f="&fle";
data _null_;
file &f mod;
put &dta;
run;
%mend WriteTo;
<**** end code ****>

The file that is being created is txtFile.txt, instead of txtfile1.txt, txtfile2.txt, txtfile3.txt, txtfile4.txt. It seems that the macro is not resolving the macro variable for some reason.
I appreciate any help.

RE: SAS MACRO not resolving macro variables

You are mixing the execution times of macro and the datastep in your coding. Before any datastep or other code is executed, macros are resolved and executed - regard it as a "pre-compiler".

Your macro contains a datastep, and it is positioned within a datastep, so the first DS executes up to the macro call and SAS "gently" assumes an invisible "run;" before the one (!) datastep created by the macro call. That datastep gets executed, then you have a final hanging "run;" which you planned for the first datastep.

Why the filename and content is wrong? The macro parameter FLE gets assigned the string "txtFile", the DTA parameter gets "col2" - the macro call does not know the variables from the table or their content, it consumes string and macro variable content as parameter values. As a side note, the macro definition must be placed before the use, so unless you have an AUTOCALL library, you need to submit the macro code before any use of it.

Also careful with not setting length for variable txtFile - it will be defined by the first assignment then, so in case your first col1 isn't the longest of the whole set, you will have corrupted file names.

Off for a solution now. This works if you do not have too many files and content is limited; all is read into memory, a macro variable can hold a string of up to 64KB. Each filename and the content is read into a macro variable in memory, the two are indexed via a counter as part of the macro variable name. The number of files to write is in &NUMFILES. A macro loops over these variables and executes a datastep per file to write content to it. If content is larger or too many files are to created (limited RAM), you could either go via SCL statements or by creating the code in a single SAS file and including the file (%include) - but that is a different story:

%let numFiles=0;

data _null_;
  infile "&CSVFile_FullPath" dsd dlm=',' firstobs=2 truncover missover;
  input col1 :$8. col2 :$9.;  
  /*--  changed as of here...  */
  length idx $5;
  idx = strip (put (_n_, BEST32.));
  call symput ('_file' !! idx, strip(col1));
  /* this not allows leading/trailing spaces in content */
  call symput ('_content' !! idx, strip(col2));
  call symput ('numFiles', idx);
run;

%macro writeAll;
  %do idx=1 %to &NUMFILES.;
    data _null_;
      file "&DIRECTORY_FULLPATH.\&&_FILE&idx.." mod;
      put "&&_CONTENT&idx..";
    run;
  %end;
%mend;
%writeAll;


Cheers,
Matthias

Red Flag This Post

Please let us know here why this post is inappropriate. Reasons such as off-topic, duplicates, flames, illegal, vulgar, or students posting their homework.

Red Flag Submitted

Thank you for helping keep Tek-Tips Forums free from inappropriate posts.
The Tek-Tips staff will check this out and take appropriate action.

Reply To This Thread

Posting in the Tek-Tips forums is a member-only feature.

Click Here to join Tek-Tips and talk with other members! Already a Member? Login

Close Box

Join Tek-Tips® Today!

Join your peers on the Internet's largest technical computer professional community.
It's easy to join and it's free.

Here's Why Members Love Tek-Tips Forums:

Register now while it's still free!

Already a member? Close this window and log in.

Join Us             Close