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

I tried to call macro using parameter which is variables, so I cannot write it directly in macro call.  I want pass the value of the variable memname...

 

 


154  options mprint;
155  %macro readdata(mname);
156  filename datafile "e:\Users\mhollifi\Desktop\Chotibhak\USA_FO_Active_2016-04\&mname..xml" ;
157  filename mapfile
157! "e:\Users\mhollifi\Desktop\Chotibhak\USA_FO_Active_2016-04\5-2016-04-30.map" ;
158
159  libname datafile xmlv2 xmlmap=mapfile automap=replace;
160
161  proc copy in=datafile out=work;
162  run;
163  %mend;
164
165  data _null_;
166  memname = compress (memname, ".xml");
167  call symput('mname',memname);
168  do i = 1 to &mcount;
169   %readdata(&&mname)
WARNING: Apparent symbolic reference MNAME not resolved.
ERROR: The text expression &MNAME contains a recursive reference to the macro variable MNAME.
       The macro variable will be assigned the null value.
MPRINT(READDATA):   filename datafile
"e:\Users\mhollifi\Desktop\Chotibhak\USA_FO_Active_2016-04\.xml" ;
MPRINT(READDATA):   filename mapfile
"e:\Users\mhollifi\Desktop\Chotibhak\USA_FO_Active_2016-04\5-2016-04-30.map" ;
MPRINT(READDATA):   libname datafile xmlv2 xmlmap=mapfile automap=replace;
ERROR: With the AUTOMAP= option, the specified XML document must exist.
ERROR: Error in the LIBNAME statement.

NOTE: Line generated by the invoked macro "READDATA".
1      filename datafile "e:\Users\mhollifi\Desktop\Chotibhak\USA_FO_Active_2016-04\&mname..xml"
1  !  ; filename mapfile
1  ! "e:\Users\mhollifi\Desktop\Chotibhak\USA_FO_Active_2016-04\5-2016-04-30.map" ;  libname
1  ! datafile xmlv2 xmlmap=mapfile automap=replace;  proc
                                                    -
                                                    117
ERROR 117-185: There was 1 unclosed DO block.

NOTE: Numeric values have been converted to character values at the places given by:
      (Line):(Column).
      166:21   167:21
NOTE: Character values have been converted to numeric values at the places given by:
      (Line):(Column).
      166:11
NOTE: The SAS System stopped processing this step because of errors.
NOTE: DATA statement used (Total process time):
      real time           0.01 seconds
      cpu time            0.00 seconds


MPRINT(READDATA):   proc copy in=datafile out=work;
MPRINT(READDATA):   run;
ERROR: Libref DATAFILE is not assigned.
NOTE: Statements not processed because of errors noted above.
NOTE: PROCEDURE COPY used (Total process time):
      real time           0.00 seconds
      cpu time            0.00 seconds

NOTE: The SAS System stopped processing this step because of errors.
170  end;
171  run;

1 ACCEPTED SOLUTION

Accepted Solutions
Astounding
PROC Star

That missing part of the program turns out to be important.  Try replacing this DATA step:

 

data _null_;
set contents;
call symput('mname',memname);
do i = 1 to &mcount;
 %readdata(&&mname)
end;
run;

 

Instead, use:

 

data _null_;
set contents;

call execute('%nrstr(%readdata(' || memname || '))' ) ;
run;

 

It's untested (obviously?), but I think I got the quotes in the proper place.

View solution in original post

9 REPLIES 9
PaigeMiller
Diamond | Level 26

The error message is very clear about what the problem is:

 

ERROR 117-185: There was 1 unclosed DO block.

--
Paige Miller
mhollifi
Obsidian | Level 7

thank you for your quick reply.

I cannot find unclosed do loop anywhere.

 

17   options mprint;
18   %macro readdata(mname);
19   filename datafile "e:\Users\mhollifi\Desktop\Chotibhak\USA_FO_Active_2016-04\&mname..xml" ;
20   filename mapfile
20 ! "e:\Users\mhollifi\Desktop\Chotibhak\USA_FO_Active_2016-04\5-2016-04-30.map" ;
21
22   libname datafile xmlv2 xmlmap=mapfile automap=replace;
23
24   proc copy in=datafile out=work;
25   run;
26   %mend;

27   data _null_;
28   set contents;
29   memname = compress (memname, ".xml");
30   call symput('mname',memname);
31   do i = 1 to &mcount;
32    %readdata(&&mname)
WARNING: Apparent symbolic reference MNAME not resolved.
ERROR: The text expression &MNAME contains a recursive reference to the macro variable MNAME.
       The macro variable will be assigned the null value.
MPRINT(READDATA):   filename datafile
"e:\Users\mhollifi\Desktop\Chotibhak\USA_FO_Active_2016-04\.xml" ;
MPRINT(READDATA):   filename mapfile
"e:\Users\mhollifi\Desktop\Chotibhak\USA_FO_Active_2016-04\5-2016-04-30.map" ;
MPRINT(READDATA):   libname datafile xmlv2 xmlmap=mapfile automap=replace;
ERROR: With the AUTOMAP= option, the specified XML document must exist.
ERROR: Error in the LIBNAME statement.

NOTE: Line generated by the invoked macro "READDATA".
1      filename datafile "e:\Users\mhollifi\Desktop\Chotibhak\USA_FO_Active_2016-04\&mname..xml"
1  !  ; filename mapfile
1  ! "e:\Users\mhollifi\Desktop\Chotibhak\USA_FO_Active_2016-04\5-2016-04-30.map" ;  libname
1  ! datafile xmlv2 xmlmap=mapfile automap=replace;  proc
                                                    -
                                                    117
ERROR 117-185: There was 1 unclosed DO block.

NOTE: The SAS System stopped processing this step because of errors.
NOTE: DATA statement used (Total process time):
      real time           0.12 seconds
      cpu time            0.06 seconds


NOTE: Writing HTML Body file: sashtml.htm
MPRINT(READDATA):   proc copy in=datafile out=work;
MPRINT(READDATA):   run;
ERROR: Libref DATAFILE is not assigned.
NOTE: Statements not processed because of errors noted above.
NOTE: PROCEDURE COPY used (Total process time):
      real time           0.30 seconds
      cpu time            0.18 seconds

NOTE: The SAS System stopped processing this step because of errors.
33   end;
34   run;

Reeza
Super User

Post your code as well. Reading it with the line numbers is problematic.

 

 

Astounding
PROC Star

At a minimum, you have two issues to fix.

 

Where does &MCOUNT come from? 

 

The DATA step that uses CALL SYMPUT to create &MNAME ... it has to execute CALL SYMPUT in order to create &MNAME.  But the DATA step has not yet executed by the time &MNAME is needed.  This actually requires some in-depth knowledge about the timing of actions in the DATA step vs. macro language.

 

The other issue is that COMPRESS does not work the way you hope.  It does not look for the word ".xml" and remove it.  It looks for all instances of "." and all instances of "x" and all instances of "m" and all instances of "l" and removes any and all of them.  You need a better way to remove ".xml" from the end of your file names, assuming that is your intention.

mhollifi
Obsidian | Level 7

thank you for your reply.

the first step of the program is like this and the memname and memcount has been created in this step.

1    filename inzip ZIP "e:\Users\mhollifi\Desktop\Jotikasthira\USA_FO_Active_2016-04.zip";
2    data contents;
3     length memname $200;
4     fid=dopen("inzip");
5     PUT 'fid: ' fid=;
6     if fid=0 then
7      stop;
8     memcount=dnum(fid);
9     PUT 'Memcount: ' memcount=;
10    do i=1 to memcount;
11     memname=dread(fid,i);
12     output;
13    end;
14    rc=dclose(fid);
15    call symput('mcount',memcount);
16   run;

NOTE: Numeric values have been converted to character values at the places given by:
      (Line):(Column).
      15:23
fid: fid=1
Memcount: memcount=4172

mhollifi
Obsidian | Level 7

my code is

 

filename inzip ZIP "e:\Users\mhollifi\Desktop\Jotikasthira\USA_FO_Active_2016-04.zip";
data contents;
 length memname $200;
 fid=dopen("inzip");
 PUT 'fid: ' fid=;
 if fid=0 then
  stop;
 memcount=dnum(fid);
 PUT 'Memcount: ' memcount=;
 do i=1 to memcount;
  memname=dread(fid,i);
  output;
 end;
 rc=dclose(fid);
 call symput('mcount',memcount);
run;
options mprint;
%macro readdata(mname);
filename datafile "e:\Users\mhollifi\Desktop\Chotibhak\USA_FO_Active_2016-04\&mname" ;
filename mapfile  "e:\Users\mhollifi\Desktop\Chotibhak\USA_FO_Active_2016-04\5-2016-04-30.map" ;

libname datafile xmlv2 xmlmap=mapfile automap=replace;

proc copy in=datafile out=work;
run;
%mend;

data _null_;
set contents;
call symput('mname',memname);
do i = 1 to &mcount;
 %readdata(&&mname)
end;
run;

mhollifi
Obsidian | Level 7

thank you all for your help.

When I put run after call symput statement, it reads only the last observation.  I want go through variables after variables.

So the solution with symput doesn't work...How to use variable name as macro parameter?

 

126  options mprint;
127  %macro readdata(mname);
128  filename datafile "e:\Users\mhollifi\Desktop\Chotibhak\USA_FO_Active_2016-04\&mname" ;
129  filename mapfile
129! "e:\Users\mhollifi\Desktop\Chotibhak\USA_FO_Active_2016-04\5-2016-04-30.map" ;
130
131  libname datafile xmlv2 xmlmap=mapfile automap=replace;
132
133  proc copy in=datafile out=work;
134  run;
135  %mend;
136
137  data _null_;
138  set contents;
139  call symput('mname',memname); run;

NOTE: There were 4172 observations read from the data set WORK.CONTENTS.
NOTE: DATA statement used (Total process time):
      real time           0.01 seconds
      cpu time            0.01 seconds


ERROR: The %DO statement is not valid in open code.
140  %do i = 1 %to &mcount;
141   %readdata(&&mname)
MPRINT(READDATA):   filename datafile
"e:\Users\mhollifi\Desktop\Chotibhak\USA_FO_Active_2016-04\999845-2016-04-30.xml" ;
MPRINT(READDATA):   filename mapfile
"e:\Users\mhollifi\Desktop\Chotibhak\USA_FO_Active_2016-04\5-2016-04-30.map" ;
MPRINT(READDATA):   libname datafile xmlv2 xmlmap=mapfile automap=replace;
ERROR: With the AUTOMAP= option, the specified XML document must exist.
ERROR: Error in the LIBNAME statement.
MPRINT(READDATA):   proc copy in=datafile out=work;
MPRINT(READDATA):   run;
ERROR: Libref DATAFILE is not assigned.
NOTE: Statements not processed because of errors noted above.
NOTE: PROCEDURE COPY used (Total process time):
      real time           0.01 seconds
      cpu time            0.01 seconds

NOTE: The SAS System stopped processing this step because of errors.
ERROR: The %END statement is not valid in open code.
142  %end;
143  run;

 

Astounding
PROC Star

That missing part of the program turns out to be important.  Try replacing this DATA step:

 

data _null_;
set contents;
call symput('mname',memname);
do i = 1 to &mcount;
 %readdata(&&mname)
end;
run;

 

Instead, use:

 

data _null_;
set contents;

call execute('%nrstr(%readdata(' || memname || '))' ) ;
run;

 

It's untested (obviously?), but I think I got the quotes in the proper place.

mhollifi
Obsidian | Level 7
thank you. it worked.

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