Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chris Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

SCAN + list of variables in a macro 1

Status
Not open for further replies.

PerlIsGood

Programmer
Jan 24, 2002
154
US
Having some problems building a macro using a list of variables that is later used in a scan loop. Here is the following bits of code:
Code:
---in macro shell
%let globlistkeep=
		tot_bal1-tot_bal25
		tot_credit1-tot_credit25;

---in separate included sas program in a data step
	%let f = 1;
	do while (scan(&globlistkeep,&f,' ') ne );
		%let fvar = %scan(&globlistkeep,&f,' ');
			array fx {*} &fvar;

			do i=1 to &mnths;
				fx{i}=fx{i}*-1;
			end;

			if 
		%let f = eval(&f+1);
	end;

---log excerpt of error
MPRINT(BUILDHUB):   * ----- MERGE IN CREDITMIS AND GLOBESTAR DATA ----- ;
MPRINT(BUILDHUB):   * GLOBESTAR data;
MPRINT(BUILDHUB):   data globdata(keep=acct11 dtopened tdbamt1-tdbamt24);
MPRINT(BUILDHUB):   set
MPRINT(XUNC):   _c_1.italy_globestar
MPRINT(BUILDHUB):  ;
MPRINT(BUILDHUB):   array tenure {*} tenur1-tenur24;
MPRINT(BUILDHUB):   do x=1 to 24;
MPRINT(BUILDHUB):   if tenure{i} = 1 then tenurekeep=1;
MPRINT(BUILDHUB):   else tenurekeep=0;
MPRINT(BUILDHUB):   end;
2997      +	do while (scan(&globlistkeep,&f,' ') ne );

                                                    _
                                                    _
                                                    _
                                                    22
                                                    22
                                                    22
MPRINT(BUILDHUB):   do while (scan(tdbamt1-tdbamt24,1,' ') ne );
MPRINT(BUILDHUB):   array fx {*} tdbamt1-tdbamt24;
MPRINT(BUILDHUB):   do i=1 to 24;
MPRINT(BUILDHUB):   fx{i}=fx{i}*-1;
MPRINT(BUILDHUB):   end;
MPRINT(BUILDHUB):   if end;
MPRINT(BUILDHUB):   dto=put(dtopened,$8.);
WARNING: Variable dtopened has already been defined as numeric.
MPRINT(BUILDHUB):   year=substr(dto,1,4);
MPRINT(BUILDHUB):   if year in ('2005' '2006') and tenurekeep=1;
MPRINT(BUILDHUB):   run;

ERROR 22-322: Syntax error, expecting one of the following: a name, a quoted string, a numeric constant, a datetime constant, 
ERROR 22-322: Syntax error, expecting one of the following: a name, a quoted string, a numeric constant, a datetime constant, 
ERROR 22-322: Syntax error, expecting one of the following: a name, a quoted string, a numeric constant, a datetime constant, 
              a missing value, bitstring, INPUT, PUT.  
              a missing value, bitstring, INPUT, PUT.  
              a missing value, bitstring, INPUT, PUT.
It's erroring out on the 'do while(scan' piece. I need to loop through the list-of-lists given in the macro variable. Perhaps there's a better way to cycle through that macro variable?

Notorious P.I.G.
 
The problem is this:-
Code:
do while (scan(&globlistkeep,&f,' ') ne );
Do while the term is not equal to .... what? You've not told it what to check against.
Should probably be:-
Code:
do while (scan(&globlistkeep,&f,' ') ne ' ' );
 
The above example has worked in previous programs. Not that it's correct or anything, but it has worked in the past. :)

If I understand correctly, my method of doing it is akin to saying "as long as there's 'something' keep processing"... but I'll try adding your suggestion and see if that helps any.

Notorious P.I.G.
 
From my experience, that line would work in macro code, but not in datastep code...
 
Okay I'm lost. I've added the change you recommended and now I'm getting error that I can't seem to identify. In the first step below, I'm getting 0 obs due to errors, but it doesn't say what error. In the second step I have an unclosed DO loop that doesn't seem to exist...
Code:
data globdata(keep=&globstatickeep &globlistkeep);
set %xunc(glob.&fvar._globestar);
run;

data globdata1;
set globdata;
array tenure {*} tenur1-tenur&mnths;
do x=1 to &mnths;
	if tenure{i} = 1 then tenurekeep=1;
	else tenurekeep=0;
end;

	%let f = 1;
	do while (scan(&globlistkeep,&f,' ') ne ' ');
		%let fvar = %scan(&globlistkeep,&f,' ');
			array fx {*} &fvar;

			do i=1 to &mnths;
				fx{i}=fx{i}*-1;
			end;

			if 
		%let f = eval(&f+1);
	end;

	dto=put(dtopened,$8.);
	year=substr(dto,1,4);
	if year in (&globrange) and tenurekeep=1;
run;

* CreditMIS data;
data credmis(keep=&credstatickeep &credlistkeep);
set crmis.&market._creditmis;

length acct11 $11.;
acct11=substr(acct15,1,11);

	%let f = 1;
	do while (scan(&credlistkeep,&f,' ') ne ' ');
		%let fvar = %scan(&credlistkeep,&f,' ');
			array fx {*} &fvar;

			do i=1 to &mnths;
				fx{i}=fx{i}*-1;
			end;

		%let f = eval(&f+1);
	end;
run;
Code:
--- log
MPRINT(BUILDHUB):   * ----- MERGE IN CREDITMIS AND GLOBESTAR DATA ----- ;
MPRINT(BUILDHUB):   * GLOBESTAR data;
MPRINT(BUILDHUB):   data globdata(keep=acct11 dtopened tdbamt1-tdbamt24);
MPRINT(BUILDHUB):   set
MPRINT(XUNC):   _c_1.italy_globestar
MPRINT(BUILDHUB):  ;
MPRINT(BUILDHUB):   run;

NOTE: There were 272103 observations read from the data set _C_1.ITALY_GLOBESTAR.
NOTE: The data set WORK.GLOBDATA has 272103 observations and 26 variables.
NOTE: Compressing data set WORK.GLOBDATA decreased size by 50.01 percent. 
      Compressed is 1767 pages; un-compressed would require 3535 pages.
NOTE: DATA statement used:
      real time           2:17.76
      cpu time            1:19.36
      

MPRINT(BUILDHUB):   data globdata1;
MPRINT(BUILDHUB):   set globdata;
MPRINT(BUILDHUB):   array tenure {*} tenur1-tenur24;
MPRINT(BUILDHUB):   do x=1 to 24;
MPRINT(BUILDHUB):   if tenure{i} = 1 then tenurekeep=1;
MPRINT(BUILDHUB):   else tenurekeep=0;
MPRINT(BUILDHUB):   end;
MPRINT(BUILDHUB):   do while (scan(tdbamt1-tdbamt24,1,' ') ne ' ');
MPRINT(BUILDHUB):   array fx {*} tdbamt1-tdbamt24;
MPRINT(BUILDHUB):   do i=1 to 24;
MPRINT(BUILDHUB):   fx{i}=fx{i}*-1;
MPRINT(BUILDHUB):   end;
MPRINT(BUILDHUB):   if end;
MPRINT(BUILDHUB):   dto=put(dtopened,$8.);
WARNING: Variable dtopened has already been defined as numeric.
MPRINT(BUILDHUB):   year=substr(dto,1,4);
MPRINT(BUILDHUB):   if year in ('2005' '2006') and tenurekeep=1;
MPRINT(BUILDHUB):   run;

NOTE: Numeric values have been converted to character values at the places given by: (Line):(Column).
      3000:8   
NOTE: The SAS System stopped processing this step because of errors.
NOTE: SAS set option OBS=0 and will continue to check statements. This may cause NOTE: No observations in data set.
WARNING: The data set WORK.GLOBDATA1 may be incomplete.  When this step was stopped there were 0 observations and 56 variables.
NOTE: DATA statement used:
      real time           0.01 seconds
      cpu time            0.01 seconds
      


MPRINT(BUILDHUB):   * CreditMIS data;
3015      +    

              _
              _
              _
              117
              117
              117
MPRINT(BUILDHUB):   data credmis(keep=acct11 tot_bal1-tot_bal25 tot_credit1-tot_credit25);
MPRINT(BUILDHUB):   set crmis.italy_creditmis;
MPRINT(BUILDHUB):   length acct11 $11.;
MPRINT(BUILDHUB):   acct11=substr(acct15,1,11);
3025      +	do while (scan(&credlistkeep,&f,' ') ne ' ');

                      ____
                      ____
                      ____
                      72
                      72
                      72
NOTE: Line generated by the macro variable "CREDLISTKEEP".
3025       tot_bal1-tot_bal25    tot_credit1-tot_credit25
                                 ___________
                                 ___________
                                 ___________
                                 22
                                 22
                                 22
MPRINT(BUILDHUB):   do while (scan(tot_bal1-tot_bal25 tot_credit1-tot_credit25 ,1,' ') ne ' ');
MPRINT(BUILDHUB):   array fx {*} tot_bal1-tot_bal25;
MPRINT(BUILDHUB):   do i=1 to 24;
MPRINT(BUILDHUB):   fx{i}=fx{i}*-1;
MPRINT(BUILDHUB):   end;
MPRINT(BUILDHUB):   end;
MPRINT(BUILDHUB):   run;

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

ERROR 72-185: The SCAN function call has too many arguments.
ERROR 72-185: The SCAN function call has too many arguments.
ERROR 72-185: The SCAN function call has too many arguments.

ERROR 22-322: Syntax error, expecting one of the following: !, !!, &, (, *, **, +, ',', -, /, <, <=, <>, =, >, ><, >=, AND, EQ, 
ERROR 22-322: Syntax error, expecting one of the following: !, !!, &, (, *, **, +, ',', -, /, <, <=, <>, =, >, ><, >=, AND, EQ, 
ERROR 22-322: Syntax error, expecting one of the following: !, !!, &, (, *, **, +, ',', -, /, <, <=, <>, =, >, ><, >=, AND, EQ, 
              GE, GT, LE, LT, MAX, MIN, NE, NG, NL, OR, [, ^=, {, |, ||, ~=.  
              GE, GT, LE, LT, MAX, MIN, NE, NG, NL, OR, [, ^=, {, |, ||, ~=.  
              GE, GT, LE, LT, MAX, MIN, NE, NG, NL, OR, [, ^=, {, |, ||, ~=.  

NOTE: Numeric values have been converted to character values at the places given by: (Line):(Column).
      3025:9   3025:1   
NOTE: The SAS System stopped processing this step because of errors.
WARNING: The data set WORK.CREDMIS may be incomplete.  When this step was stopped there were 0 observations and 51 variables.
NOTE: DATA statement used:
      real time           0.06 seconds
      cpu time            0.04 seconds

Notorious P.I.G.
 
Man where's the edit key when you need one. I've solved all probelms now except for one: How to I pass multiple list arguments to SCAN without receiving the following error?
Code:
%let credlistkeep=
		tot_bal1-tot_bal25
		tot_credit1-tot_credit25;
data credmis(keep=&credstatickeep &credlistkeep);
set crmis.&market._creditmis;

length acct11 $11.;
acct11=substr(acct15,1,11);

	%let f = 1;
	do while (scan(&credlistkeep,&f,' ') ne ' ');
		%let xvar = %scan(&credlistkeep,&f,' ');
			array fx {*} &xvar;

			do i=1 to &mnths;
				fx{i}=fx{i}*-1;
			end;

		%let f = eval(&f+1);
	end;
run;

------ERROR--------
3828  data
3828! credmis(keep=&credstatickeep &credlistkeep);
SYMBOLGEN:  Macro variable CREDSTATICKEEP resolves to acct11
SYMBOLGEN:  Macro variable CREDLISTKEEP resolves to tot_bal1-tot_bal25                  tot_credit1-tot_credit25
3828!              keep=&credstatickeep &credlistkeep);
SYMBOLGEN:  Macro variable MARKET resolves to italy
3829  set crmis.&market._creditmis;
3831  length acct11 $11.;
3832  acct11=substr(acct15,1,11);
3834  	%let f = 1;
3835  	do while (scan(&credlistkeep,&f,' ') ne ' ');
SYMBOLGEN:  Macro variable CREDLISTKEEP resolves to tot_bal1-tot_bal25                  tot_credit1-tot_credit25
NOTE: Line generated by the macro variable "CREDLISTKEEP".
3835  tot_bal1-tot_bal25                  tot_credit1-tot_credit25
                                          -----------
                                          22
SYMBOLGEN:  Macro variable F resolves to 1
3835  	do while (scan(&credlistkeep,&f,' ') ne ' ');
                 ----
                 72
ERROR 22-322: Syntax error, expecting one of the following: !, !!, &, (, *, **, +, ',', -, /, <, <=, <>, =, >, ><, >=, AND,
              EQ, GE, GT, LE, LT, MAX, MIN, NE, NG, NL, OR, [, ^=, {, |, ||, ~=.

ERROR 72-185: The SCAN function call has too many arguments.

3836  		%let fvar = %scan(&credlistkeep,&f,' ');
SYMBOLGEN:  Macro variable CREDLISTKEEP resolves to tot_bal1-tot_bal25                  tot_credit1-tot_credit25
SYMBOLGEN:  Macro variable F resolves to 1
3837  			array fx {*} &fvar;
SYMBOLGEN:  Macro variable FVAR resolves to tot_bal1-tot_bal25
3839  			do i=1 to &mnths;
SYMBOLGEN:  Macro variable MNTHS resolves to 24
3840  				fx{i}=fx{i}*-1;
3841  			end;
3843  		%let f = eval(&f+1);
SYMBOLGEN:  Macro variable F resolves to 1
3844  	end;
3845  run;

Notorious P.I.G.
 
OK, need to take a step back here. What are you trying to achieve with this do while loop. I can see the problem, you're feeding in multiple variables to the scan function which it can't handle, it can only do one of these at a time.
So, what is it that you want to get out of this?

Try " quotes around the &credlistkeep like this:
Code:
do while (scan("&credlistkeep",&f,' ') ne ' ');
that might be what you're trying to achieve...
 
Basically each variable list in &credlistkeep needs to be processed through that loop. &credlistkeep is built in another macro shell, I inserted it here so you could see how it's being used. It will change regularly, but it will always contain at least one list of variables (var1-varN).

I'll try "" tomorrow. Thanks for the input.

Notorious P.I.G.
 
You were on the right track Chris. Here is what eventually solved my problem:
Code:
%do %while (%nrbquote(&xvar) ne %str());

Thanks for the help!

Notorious P.I.G.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top