BookmarkSubscribeRSS Feed
deleted_user
Not applicable
I have the following macro MD –

-----------------------------------------------------------------------------------------------------

%macro MD(DIR);

%LET COUNT=0;

%LET DLM=\;

%IF %SUBSTR(&DIR,%LENGTH(&DIR),1) NE &DLM %THEN %DO;

%LET DIR=&DIR&DLM;

%END;

%DO J=1 %TO %LENGTH(&DIR);

%IF %SUBSTR(&DIR,&J,1)=&DLM %THEN %DO;

%LET COUNT=%EVAL(&COUNT+1);

%END; %END;

%LET DRIVE=%SUBSTR(&DIR,1,3);

%LET LEVEL=&DRIVE;

%DO I=2 %TO &COUNT;

%LET WORD=%SCAN(&DIR,&I,&DLM);

%LET LNEW=&LEVEL&WORD&DLM;

data _null_;

*rc=filename('newdir',"&lnew");

*c=dopen('newdir');

*if c=0 then new=dcreate("&word","&level");

%PUT "mkdir "&lnew"";

%PUT "cd "&lnew"";

run;

%LET LEVEL=&LNEW;

%END;

%mend;


When I invoke it with %MD("C:\test1\test2");

I am getting the following error in the log

MLOGIC(MD): Beginning execution.

MLOGIC(MD): Parameter DIR has value "C:\test1\test2"

MLOGIC(MD): %LET (variable name is COUNT)

MLOGIC(MD): %LET (variable name is DLM)

SYMBOLGEN: Macro variable DIR resolves to "C:\test1\test2"

SYMBOLGEN: Macro variable DIR resolves to "C:\test1\test2"

SYMBOLGEN: Macro variable DLM resolves to \

ERROR: A character operand was found in the %EVAL function or %IF condition where a numeric operand is required.

The condition was: %SUBSTR(&DIR,%LENGTH(&DIR),1) NE &DLM

ERROR: The macro MD will stop executing.

Appreciate any quick help
9 REPLIES 9
sbb
Lapis Lazuli | Level 10 sbb
Lapis Lazuli | Level 10
You have some macro variable matching resolution issue with the &DIR value - particularly where there is special-handling considerations with the back-slash character.

Suggest you search the SAS support http://support.sas.com/ website and consider the Google advanced search argument below for useful reference links:

macro variable resolution back slash site:sas.com



Scott Barry
SBBWorks, Inc.
Patrick
Opal | Level 21
If I understand right what you try to achieve: Wouldn't this be a shorter way to do it?

%macro MakeDir(DIR);
options noxwait;
x mkdir "&DIR";
%mend;
%MakeDir(c:\test1\test2\test3);
DanielSantos
Barite | Level 11
Hello,

loose the double quotes at macro call (as, %MD(C:\test1\test2) ), and it will work just fine.

Cheers from Portugal.

Daniel Santos @ www.cgd.pt
deleted_user
Not applicable
Thanks All for your suggestions. It worked when I used qSUBSTR instead of SUBSTR.

I have a problem now writing the commands(ftp) generated by macro to the file

Following is my macro code

/* Setup libref to execute the ftp command */
filename ftpcmds "&ftpcmds";

%macro MD(DIR);
%LET COUNT=0;
%LET DLM=\;

%DO J=1 %TO %LENGTH(&DIR);
%IF %qSUBSTR(&DIR,&J,1)=&DLM %THEN %DO;
%LET COUNT=%EVAL(&COUNT+1);
%END; %END;

%LET STARTINDEX = 1;
%DO I=1 %TO &COUNT;

%LET SLASHINDEX = %INDEX(&DIR,&DLM);
%LET WORD = %SUBSTR(&DIR,&STARTINDEX,&SLASHINDEX-1);
%LET DIR = %SUBSTR(&DIR,&SLASHINDEX+1);
%LET STARTINDEX = &SLASHINDEX + 1;

%LET LNEW=&WORD;

%PUT "mkdir "&lnew"";
%PUT "cd "&lnew"";
%END;

%LET WORD = &DIR;
%LET LNEW=&WORD;
%PUT "mkdir "&lnew"";
%PUT "cd "&lnew"";
%mend;

The PUT statements don't seem to be writing to file pointed to by ftpcmds

The file statement is in the data segment from where the macro is invoked


data _null_;

OPTIONS MPRINT;
OPTIONS SYMBOLGEN;
OPTIONS MLOGIC;
file ftpcmds pad lrecl=80;

....
....

%MD(&destdir); /* destDir is set to test1/test2 */

...
....

run;


Any idea why the put statements don't write to the file pointed to by ftpcmds?

Thanks & Regards,
Neel
sbb
Lapis Lazuli | Level 10 sbb
Lapis Lazuli | Level 10
The %PUT and PUT statements are very different. You need to use PUT statements to write to a sequential file. You may need to look at using FPUT as well.

Scott Barry
SBBWorks, Inc.
deleted_user
Not applicable
Thanks Scott!

I changed the code to use PUT statement instead. But I'm getting some error in the log file indicating the PUT used in the macro is not used in the right context.

Below is my code fragment containing the macro and the macro invocation block...

------------------------------------------------------------------------------------------------
/* Setup libref to execute the ftp command */
filename ftpcmds "&ftpcmds";

%macro MD(DIR);
%LET COUNT=0;
%LET DLM=\;

%DO J=1 %TO %LENGTH(&DIR);
%IF %qSUBSTR(&DIR,&J,1)=&DLM %THEN %DO;
%LET COUNT=%EVAL(&COUNT+1);
%END; %END;

%LET STARTINDEX = 1;
%DO I=1 %TO &COUNT;

%LET SLASHINDEX = %INDEX(&DIR,&DLM);
%LET WORD = %SUBSTR(&DIR,&STARTINDEX,&SLASHINDEX-1);
%LET DIR = %SUBSTR(&DIR,&SLASHINDEX+1);
%LET STARTINDEX = &SLASHINDEX + 1;

%LET LNEW=&WORD;

PUT "mkdir "&lnew"";
PUT "cd "&lnew"";
%END;

%LET WORD = &DIR;
%LET LNEW=&WORD;
PUT "mkdir "&lnew"";
PUT "cd "&lnew"";
%mend;




data _null_;

OPTIONS MPRINT;
OPTIONS SYMBOLGEN;
OPTIONS MLOGIC;
file ftpcmds pad lrecl=80;
put "user "&userid" "&ftppwd"";
put "verbose";
put "trace";
put "&xfermode";
put "cd "&homedir"";
put "lcd "&localdir"";
call execute('%MD('||&destdir||');');

/* uncomment the appropriate line below */
put "prompt"; /* used for MPUT and MGET commands */
put "mput SASFTP1.txt SASFTP2.txt";

put "quit";
run;

/* We built the control file for ftp, now run it */

filename doftp pipe %unquote(%str(%')ftp -n -s:"&ftpcmds" &host%str(%'));
data _null_;
infile doftp;
input;
put _infile_;
run;

----------------------------------------------------------------------------------------------------


Snippet from my log file is


---------------------------------------------------------------------------------------------------

MPRINT(MD): PUT "mkdir "test1"";
SYMBOLGEN: Macro variable LNEW resolves to test1
MPRINT(MD): PUT "cd "test1"";
MLOGIC(MD): %DO loop index variable I is now 2; loop will not iterate again.
MLOGIC(MD): %LET (variable name is WORD)
SYMBOLGEN: Macro variable DIR resolves to test2
MLOGIC(MD): %LET (variable name is LNEW)
SYMBOLGEN: Macro variable WORD resolves to test2
SYMBOLGEN: Macro variable LNEW resolves to test2
MPRINT(MD): PUT "mkdir "test2"";
SYMBOLGEN: Macro variable LNEW resolves to test2
MPRINT(MD): PUT "cd "test2"";
MLOGIC(MD): Ending execution.
NOTE: 9 records were written to the file FTPCMDS.
The minimum record length was 80.
The maximum record length was 80.

NOTE: CALL EXECUTE generated line.
NOTE: Line generated by the CALL EXECUTE routine.
1 + PUT "mkdir "test1"";
___
180

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

NOTE: Line generated by the CALL EXECUTE routine.
1 + PUT "cd "test1"";
___
180

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

NOTE: Line generated by the CALL EXECUTE routine.
1 + PUT "mkdir "test2"";
___
180

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

NOTE: Line generated by the CALL EXECUTE routine.
1 + PUT "cd "test2"";
___
180
5 The SAS System 09:28 Tuesday, September 15, 2009


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


---------------------------------------------------------------------------------------------------

Any ideas what the issue is?

Appreciate any quick help on this.


Thanks & Regards,
Neel
sbb
Lapis Lazuli | Level 10 sbb
Lapis Lazuli | Level 10
The diagnostic is correct - your PUT code is outside the DATA step.

Scott Barry
SBBWorks, Inc.
deleted_user
Not applicable
Thanks Scott!

Any idea how to achieve what I'm doing without this issue? I want to write to the file from data segment as well as from inside the macro.


Thanks & Regards,
Neel
sbb
Lapis Lazuli | Level 10 sbb
Lapis Lazuli | Level 10
Not really - [here's one person's opinion] you need to work through the development (and eventually support) of the code yourself - how long has this thread been going, since you needed a "quick reply"? You need to figure out what it is you want to accomplish, state it clearly, and take the pieces of your various program code you have shared and come up with a working solution, ideally one that you can own and support going forward.

Scott Barry
SBBWorks, Inc.

SAS Innovate 2025: Call for Content

Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!

Submit your idea!

What is Bayesian Analysis?

Learn the difference between classical and Bayesian statistical approaches and see a few PROC examples to perform Bayesian analysis in this video.

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
  • 9 replies
  • 1521 views
  • 0 likes
  • 4 in conversation