BookmarkSubscribeRSS Feed
ani
Calcite | Level 5 ani
Calcite | Level 5

By excecuting the following code i am facing the error marked in red:

%Macro read;

%let fileinfo=codedir;

%DO I = 1 %TO &maxlib;

DATA test3;

  Pipe_command = "dir /s /b "||'"'||&&lib&I||'"';

  PUT PIPE_COMMAND=;

  CALL SYMPUT ('Pipe_command', Pipe_command);

RUN;

%PUT &Pipe_command;

%sysfunc (FILENAME (fileinfo,%str (&Pipe_Command)),pipe);

%END;

%Mend read;

%read;

All lines are working fine except

%sysfunc (FILENAME (fileinfo,%nrbquote (&Pipe_Command)),pipe);

The error is:

SYMBOLGEN:  Macro variable PIPE_COMMAND resolves to dir /s /b "C:\sametime"

ERROR: Format name PIPE not found or the width and/or decimal specified for the format used are out

       of range.

MPRINT(READ):   20017;

MLOGIC(READ):  %DO loop index variable I is now 2; loop will not iterate again.

MLOGIC(READ):  Ending execution.

NOTE: Line generated by the macro function "SYSFUNC".

1     20017

      -----

      180

ERROR 180-322: Statement is not valid or it is used out of proper order.

I need a outfile named as CODEDIR containg the output of line ,%str (&Pipe_Command).

Need your suggestions to resolve the issue. 

Thanks in advance.. Smiley Happy

8 REPLIES 8
andreas_lds
Jade | Level 19
%sysfunc (FILENAME (fileinfo,%str (&Pipe_Command)),pipe);

I think the there should be just one closing brace after &Pipe_Command.

%sysfunc (FILENAME (fileinfo,%str (&Pipe_Command) ,pipe));

Peter_C
Rhodochrosite | Level 12

is that NRBQUOTE or STR?

looks like NRBQUOTE has "eaten" one of those close-brackets.

Peter_C
Rhodochrosite | Level 12

Ani

the mixture of data step and macro environment may be getting in the way here.

The purpose seems to be to invoke filename functions, each establishing a pipe to list files in a folder and the subfolders under that.

One caution :- only one fileref is used, so either more processing is to be performed between the loops or a counter suffix is needed on the fileref that will be assigned.

I would suggest :-

1

use the data step to invoke the filename function - as it is function designed to be invoked in data step.

2

in the data step, loop i=1 to maxlib

3

As appending a suffix to the fileref codedir will limit the list of code libraries to 9, abbreviate that to "code" (the context indicates it is a "dir")

4

insert some code (call execute?) to do something with the fileref

Here is my interpretation of a possible solution:

%Macro codedir( folders   /* delimited list of folders */

              , delimiter= #      /* delimiter between folders */

              , out= folder_list  /* data set to hold list of folders and RC from filename function */

              , files= files_list /* data set to hold list of files found in folders */ 

               ) ;

proc delete data= &files ;

run ;

DATA &out (keep= rc fileref folder ) ; ;

retain Pipe_c   'dir /s /b '  ;

length folder  $1000 fileref $8 ;

maxlib = countw( "&folders", "&delimiter" ) ;

  do i=1 to maxlib ;

      folder = scan( "&folders" , i , "&delimiter" ) ;

      fileref= 'code' !! put(i,4.-L) ;

      rc= FILENAME( fileref

                  ,  quote( Pipe_c !! quote( trim( folder ) ) )

                  , 'pipe' ) ;

      output  ;

      * submit for execution later, code to collect list of files in code folders;

      call execute( 'data a ;'  ) ;

      call execute( ' infile code' !! put( i, 4.-L )  ) ;

      call execute( '; input line $char1000. ; run; ' ) ;

      call execute( 'proc append base=&files ; run ;' ) ;

  end ;

  stop ;

RUN;

%Mend codedir ;

option compress=yes ;

%codedir( savian#ArtC.book1)

(tested OK)

"Savian" and "ArtC.book1" are folders under the "current folder" of my SAS session

peterC

ani
Calcite | Level 5 ani
Calcite | Level 5

Hi Peter,

Thanks for your inputs!

But I have no scope to pass parameters in the code. Actually I just need to produce a output file named as codedir which will contain the result of dir /s /b "C:\Smaetime"

C:\Smaetime: is the local path of my system.

DATA test3

Pipe_command = "'dir /s /b "||'"'||&&lib&I||'"'||"'";

PUT PIPE_COMMAND=;

CALL SYMPUT ('Pipe_command', Pipe_command);

RUN;

%PUT &Pipe_command;

FILENAME codedir pipe &Pipe_Command;

When I use  FILENAME codedir pipe &Pipe_Command; 

Its not working. This is why I tried the following way:

%Macro read;

%let fileinfo=codedir;

%DO I = 1 %TO &maxlib;

DATA test3;

  Pipe_command = "dir /s /b "||'"'||&&lib&I||'"';

  PUT PIPE_COMMAND=;

  CALL SYMPUT ('Pipe_command', Pipe_command);

RUN;

%PUT &Pipe_command;

%sysfunc (FILENAME (fileinfo,%str (&Pipe_Command)),pipe);

%END;

%Mend read;

%read;

And here I face the error:

SYMBOLGEN:  Macro variable PIPE_COMMAND resolves to dir /s /b "C:\sametime"

ERROR: Format name PIPE not found or the width and/or decimal specified for the format used are out

       of range.

MPRINT(READ):   20017;

MLOGIC(READ):  %DO loop index variable I is now 2; loop will not iterate again.

MLOGIC(READ):  Ending execution.

NOTE: Line generated by the macro function "SYSFUNC".

1     20017

      -----

      180

ERROR 180-322: Statement is not valid or it is used out of proper order.

My concern is not in the maxlib count or anyother count. I just need the output of the dir /s /b "C:\Smaetime" in a file and then i'll use this a file as a input.

Thanks in advance Smiley Happy

Peter_C
Rhodochrosite | Level 12

then it becomes simpler

just the data step to create and run a step to use the fileref creating sas table "work.filelist"

replace  C:\temp  with your folder

DATA _null_ ;

length  fileref $8 ;

retain Pipe_c   'dir /s /b "C:\temp" ' fileref 'codedir' ;

   rc= FILENAME( fileref

               ,  quote( Pipe_c  )

               , 'pipe' ) ;

   * submit for execution later, code to collect list of files in code folders;

   call execute( 'data filelist( compress=yes );'  ) ;

   call execute( ' infile codedir lrecl=1000 ;'    ) ;

   call execute( '; input line $char1000. ; run; ' ) ;

   call execute( 'FILENAME CODEDIR ;' ); * to release the fileref ;

stop ;

RUN;

ani
Calcite | Level 5 ani
Calcite | Level 5

Hi Peter,,

Thanks again for your help and it really good. But when I move to the next step :

DATA Search_Obj_Names (KEEP=Srch_File Program_Nam Path);

  EOFC = 0;

  INFILE codedir MISSOVER TRUNCOVER END=EOFC ;

  RETAIN cnt   0;

  INPUT @ 1 Srch_File  $256.

        ;

  cnt + 1;

  Backward = REVERSE(TRIM(srch_file));

  last_slash = INDEX(Backward, '\');

  IF  last_slash = 0 THEN

      last_slash = INDEX(Backward, '/');

  IF  Last_slash = 0 THEN

    DO;

      Program = Srch_file;

      Path    = Srch_file;

    END;

  ELSE

    DO;

      Program_Nam = REVERSE(SUBSTR(Backward, 1, Last_slash - 1));

      Path = STRIP(REVERSE(SUBSTR(backward, Last_slash)));

    END;

  S7 = INDEX (Program_Nam, 'sas7bdat');

  IF  S7 THEN;

  ELSE

      OUTPUT;

RUN;


It throws an error :

ERROR: No logical assign for filename CODEDIR.

Please look into this and put your inputs plz.

Thanks in advance  Smiley Happy

Peter_C
Rhodochrosite | Level 12

I had half anticipated what you wanted, and loaded the physical names - then released CODEDIR

Either you you remove the last call execute() statement

     call execute( 'FILENAME CODEDIR ;' ); * to release the fileref ;

or adapt your data step.

CODEDIR returns the bare path and filename.

The following code works onn WIN and UNIX platforms, but not on zOS and probably not on VMS

I would suggest you adapt your process.

Parsing the lines returned by CODEDIR  might be easier with the scan() function

filename = scan( line, -1, '/\' ) ; * neither / not \ will appear in filenames you are concerned about;

filetype = scan( filename, -1, '.' ) ;

if filetype = 'sas7bdat' then SAS_ds_name = upcase( scan( filename, 1, '.' )) ;

else

if lowcase(filetype) = 'sas' then prog_name = filename ;

 

not sure why you identify sas7bdat and then ignore them..

data ds_and_progs ;

set filelist ;

   length filename $100 filetype $8 prog_name $40 sas_ds_name $32 filepath $1000;

   filename = scan( line, -1, '/\' ) ;

            * neither / not \ will appear in filenames you are concerned about;

   filetype = scan( filename, -1, '.' ) ;

   if filetype = 'sas7bdat' then

         SAS_ds_name = upcase( scan( filename, 1, '.' )) ;

   else

   if lowcase(filetype) = 'sas' then

         prog_name   = filename  ;

   else delete ;

   filepath = substr( line, 1, length(line) - length( filename) -1 ) ;

run ;

.

pick the results you want

dhana
Fluorite | Level 6

Please try this

FILENAME CODEDIR PIPE "dir /s /d c:\sametime";

DATA DSN;

     INFILE CODEDIR TRUNCOVER;

     INPUT VAR1 $ 50.;

     .....

     SAS STATEMENTS

     .....

RUN;

you can use this CODEDIR anywhere in your program.

Hope this helps

Thanks

Dhanasekaran R

sas-innovate-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

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.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 8 replies
  • 1113 views
  • 6 likes
  • 4 in conversation