Subscribe to DSC Newsletter

I have this macro that creates an external file and writes a line to it :

%macro createfile(directory,filename,extension);
    myFile=&directory || &filename || "." || &extension;
    putlog myFile; /* this display the C:\test.txt on the log*/
    file myFile;
    put "hello";
%mend createfile;
%createfile('C:\','test','txt');

 

Instead of creatting the file C:\test.txt, SAS creates a file named myFile. It seems that the variable myFile is not being resolved.

Any suggestions?

Views: 977

Replies to This Discussion

I hope this might work.

 

 

Failing that you could temporarily turn on some macro debugging options such as

 

options mprint;

options mlogic;

 

to aid in the debugging.

Bashshar: 

   You were close but you are missing the fact the file statement is compiled before the SAS variable myfile is created.  You can use the fact that SAS/Macro executes at compile time and thus macro variables will resolve as the data step compiles. 

Notes: 

  •    The %let statement creates a SAS macro variable instead of a SAS variable
  •    the double quotes allow the macro variables to resove.  Single quotes would prevent this.

 

 There is a lot more to say on this topic but I am a bit pressed for time so in short, here is the code:

 

%macro createfile(directory,filename,extension);
    %let myFile = "&directory&filename..&extension" ;
    %put &myFile; /* this display the C:\test.txt on the log*/


    file &myFile ;
    put "hello";
%mend createfile;
%createfile(C:\,test,txt) ;

 

Mike,

It there a macro version of the file statement, or a way around it? Your snipped of code is not working!

Thanks,

Bashshar, have you tried this slight amendment instead?

 

To use the file statement to create an external file, it must be used within a data step. So by surrounding the file and put statements by a data step should output the file.

 

%macro createfile(directory,filename,extension);
    %let myFile = "&directory&filename..&extension" ;
    %put &myFile; /* this display the C:\test.txt on the log*/

    data _null_;
    file &myfile;
    put "hello";
    run;
%mend createfile;
%createfile(C:\,test,txt) ;

 

David,

That piece by itself works if the name of the text file is literal text no a variable.

The csvFile.csv contains 3 columns. I want to create text files named as second_column+third_column.txt and contains the first_column as data :

column1          column2 column3

10000000000   c21        c31

20000000000   c22        c32

30000000000   c23        c33

40000000000   c24        c34

i.e.

c21c31.txt contains 10000000000

c22c32.txt contains 20000000000

....

%LET CSVFile_FullPath=C:\projects\csvFile.csv;
%LET Direct_FullPath=C:\projects\txtFilesFolde;

options xsync xmin noxwait nomprint nosymbolgen;
%sysexec del /f/q "&Direct_FullPath"; /* delete all text files in the directory*/
data _null_;
    infile "&CSVFile_FullPath" dsd dlm=',' firstobs=2 truncover missover;   
    input col1 :$11. col2 :$3. col3 :$5.;
    txtFile="&Direct_FullPath"||"\"||col2||col3||".txt";
    %WriteTo(txtFile,col1);
run;
%macro WriteTo(f,d);
    %let f="&f";
    data _null_;
    file &f mod;
    put &d;
    run;
%mend WriteTo;

 

The file that is being created is col2col3.txt, the variable names, not their values (c12c13.txt) !!!

I appreciate any help.

Hi Bashar,

It seems in your program you are calling a macro in a datastep and expecting the macro to take fresh value of "TXTFILE" variable at each iteration. But I think it's not feasible as SAS macro variable will not take the new value from a dataset variable (Unless CALL SYMPUT is used for value assignment). They takes the value from the macro call or macro definition. To make my self more clear here is sample code for your problem.

data a;
    infile "&CSVFile_FullPath" dsd dlm=',' firstobs=1 truncover missover;  
    input col1 :$11. col2 :$3. col3 :$5.;
    length txtfile $19.;
    txtFile="&Direct_FullPath"||"\"||strip(col2)||strip(col3)||".txt";
    call symput("t"||strip(put(_n_,2.0)),strip(txtfile));
run;
proc sql;
 select count(*) into: nobs from a;
quit;
%macro WriteTo(d=col1);
   %do i=1 %to &nobs;
    data _null_;
    set a ;
    file "&&t&i" mod;
    if _n_=&i;
    put &d;
    run;
    %end;
%mend WriteTo;
%WriteTo;

 

Though my code is pretty basic to comprend. Let me know if you have any questions. I hope this will help.

Example 5: Dynamically Changing the Current Output File
This DATA step uses the FILEVAR= option to dynamically change the currently opened output file to a new physical file.

Write a report. Create a long character variable. Use DATA _NULL_ to write a report rather than create a data set. The LENGTH statement creates a variable with length long enough to contain the name of an external file:

data _null_;
length name $ 200;
Read an in-stream data line and assign a value to the NAME variable:

input name $;
Close the current output file and open a new one when the NAME variable changes. The file-specification is just a place holder; it can be any valid SAS name:

file file-specification filevar=name mod;
date = date();
Append a log record to currently open output file:

put 'records updated ' date date.;

RSS

On Data Science Central

© 2019   AnalyticBridge.com is a subsidiary and dedicated channel of Data Science Central LLC   Powered by

Badges  |  Report an Issue  |  Privacy Policy  |  Terms of Service