I tried to run the following code but the ERROR ( A character operand was found in the %EVAL function or %IF condition where a numeric operand is required) comes out for the loop with &ano_ini. and &ano_fin. Can someone help me figure this out?
%let data_ini='01jan2008'd;
%let data_fin='31dec2016'd;
%let data_1=putn(&data_ini.,'mmddyyyy');
%let ano_i=(year(data_1));
%let mes_i=(month(data_1));
%let data_2=putn(&data_fin.,'mmddyyyy');
%let ano_f=(year(data_2));
%let mes_f=(month(data_2));
%macro tabla (ano_ini,mes_ini,ano_fin,mes_fin);
proc sql;
create table serie(data num, taxa num);
%do i=&ano_ini. %to &ano_fin.;
%do j=&mes_ini. %to &mes_fin.;
INSERT INTO SERIE
set data=mdy(&j.,25,&i.),taxa=0.01;
%end;
%end;
create table serie as
select data as data format date9., taxa as taxa
from serie;
quit;
%mend;
%tabla (ano_i,mes_i,ano_f,mes_f);
Thank you
This would be significantly easier in a data step loop. You're creating a set of dates in a data set from start to finish? If you explain what you're trying to do, I can show you the data step code.
You created macro variables but didn't use them in the call, is that what you intended?
%tabla (ano_i,mes_i,ano_f,mes_f);
Should that be:
%tabla (&ano_i, &mes_i, &ano_f, &mes_f);
@brunarejani wrote:
I tried to run the following code but the ERROR ( A character operand was found in the %EVAL function or %IF condition where a numeric operand is required) comes out for the loop with &ano_ini. and &ano_fin. Can someone help me figure this out?
%let data_ini='01jan2008'd; %let data_fin='31dec2016'd; %let data_1=putn(&data_ini.,'mmddyyyy'); %let ano_i=(year(data_1)); %let mes_i=(month(data_1)); %let data_2=putn(&data_fin.,'mmddyyyy'); %let ano_f=(year(data_2)); %let mes_f=(month(data_2)); %macro tabla (ano_ini,mes_ini,ano_fin,mes_fin); proc sql; create table serie(data num, taxa num); %do i=&ano_ini. %to &ano_fin.; %do j=&mes_ini. %to &mes_fin.; INSERT INTO SERIE set data=mdy(&j.,25,&i.),taxa=0.01; %end; %end; create table serie as select data as data format date9., taxa as taxa from serie; quit; %mend; %tabla (ano_i,mes_i,ano_f,mes_f);
Thank you
Even if he fixes the macro call, it still won't work. The macro processor won't know what to do with the values of &ano_i and &ano_f in the %do i=&ano_ini %to &ano_fin; statement.
The valued of ano_i and probably of all the other macro variables are just plain text, you need them to actually resolve to integers so that they make sense in the %do-loop, so using %let ano_i=%sysfunc(year(&data_ini)); and similar changes to all the other macro variable definitions is needed.
@PaigeMiller Yes, the errors initially mentioned are gone and s/he will have new ones.
I still think a data step is a better approach though.
Here the SASLOG including the OPTIONS MPRINT and the %put s for the variables.
1 The SAS System 11:20 Tuesday, June 5, 2018 1 ;*';*";*/;quit;run; 2 OPTIONS PAGENO=MIN; 3 %LET _CLIENTTASKLABEL='Program'; 4 %LET _CLIENTPROJECTPATH=[hiden]; 5 %LET _CLIENTPROJECTNAME='Project 2.egp'; 6 %LET _SASPROGRAMFILE=; 7 8 ODS _ALL_ CLOSE; 9 OPTIONS DEV=ACTIVEX; NOTE: Procedures may not support all options or statements for all devices. For details, see the documentation for each procedure. 10 GOPTIONS XPIXELS=0 YPIXELS=0; 11 FILENAME EGSR TEMP; 12 ODS tagsets.sasreport12(ID=EGSR) FILE=EGSR STYLE=Analysis 12 ! STYLESHEET=(URL="[hiden]") NOGTITLE NOGFOOTNOTE GPATH=&sasworklocation ENCODING=UTF8 options(rolap="on"); NOTE: Writing TAGSETS.SASREPORT12(EGSR) Body file: EGSR 13 14 GOPTIONS ACCESSIBLE; 15 OPTIONS MPRINT; 16 17 %let data_ini='01jan2008'd; 18 %let data_fin='31dec2016'd; 19 20 %let data_1=putn(&data_ini.,'mmddyyyy'); 21 %let ano_i=year(data_1); 22 %let mes_i=month(data_1); 23 %let data_2=putn(&data_fin.,'mmddyyyy'); 24 %let ano_f=year(data_2); 25 %let mes_f=month(data_2); 26 27 %put ano_i is: &ano_i; ano_i is: year(data_1) 28 %put mes_i is: &mes_i; mes_i is: month(data_1) 29 %put ano_f is: &ano_f; ano_f is: year(data_2) 30 %put mes_f is: &mes_f; mes_f is: month(data_2) 31 32 %macro tabla (ano_ini,mes_ini,ano_fin,mes_fin); 33 proc sql; 34 create table serie(data num, taxa num); 35 %do i=&ano_ini. %to &ano_fin.; 36 %do j=&mes_ini. %to &mes_fin.; 37 INSERT INTO SERIE 38 set data=mdy(&j.,25,&i.),taxa=0.01; 39 %end; 40 %end; 41 create table serie as 42 select data as data format date9., taxa as taxa 43 44 from serie; 2 The SAS System 11:20 Tuesday, June 5, 2018 45 quit; 46 %mend; 47 48 %tabla (ano_i,mes_i,ano_f,mes_f); MPRINT(TABLA): proc sql; MPRINT(TABLA): create table serie(data num, taxa num); NOTE: Table WORK.SERIE created, with 0 rows and 2 columns. ERROR: A character operand was found in the %EVAL function or %IF condition where a numeric operand is required. The condition was: &ano_ini. ERROR: The %FROM value of the %DO I loop is invalid. ERROR: A character operand was found in the %EVAL function or %IF condition where a numeric operand is required. The condition was: &ano_fin. ERROR: The %TO value of the %DO I loop is invalid. ERROR: The macro TABLA will stop executing. 49 50 51 52 53 GOPTIONS NOACCESSIBLE; 54 %LET _CLIENTTASKLABEL=; 55 %LET _CLIENTPROJECTPATH=; 56 %LET _CLIENTPROJECTNAME=; 57 %LET _SASPROGRAMFILE=; 58 59 ;*';*";*/;quit; NOTE: The SAS System stopped processing this step because of errors. NOTE: PROCEDURE SQL used (Total process time): real time 0.01 seconds cpu time 0.00 seconds 59 ! run; 60 ODS _ALL_ CLOSE; 61 62 63 QUIT; RUN; 64
Here's a data step approach. You can wrap it in a macro if desired. The code is commented for clarity.
%let data_ini='01jan2008'd;
%let data_fin='31dec2016'd;
data serie;
*calculate the number of months needed;
n_months = intck('month', &data_ini, &data_fin);
taxa=0.01; *set variable to value, will be constant;
*decrement date to start properly;
date = intnx('month', &data_ini, -1, 'b') + 24; *increment to 25th day;
*loop and output date;
do i=0 to n_months;
date = intnx('month', date, 1, 's'); *increment date each month;
output;
end;
format date date9.;
keep date taxa;
run;
You are creating macro variables with text that look like calls to SAS functions. You could do that if you used them in a place where SAS is able to evaluate functions.
Not sure why you would even want to try to do this with SQL. Much easier to create data using a data step where you can have DO loops.
So converting your %DO loops into DO loops you would get something like this.
%macro tabla (ano_ini,mes_ini,ano_fin,mes_fin);
data serie ;
length data taxa 8;
do year=&ano_ini. to &ano_fin.;
do month=&mes_ini. to &mes_fin.;
data=mdy(month,25,year) ;
taxa=0.01;
output;
end;
end;
format data date9. ;
drop month year;
run;
%mend;
But the logic looks really strange since if you called it with
%tabla(2015,5,2017,12);
It would generate records for only the months of may to december data for all of the years from 2015 to 2017.
Is that what you wanted?
Or did you want to generate data for all of the months from may-2015 to december-2017?
%macro tabla (start,stop);
data serie ;
length data taxa 8;
do i=0 to intck('month',start,stop);
data=intnx('month,start,i,'b') + 24 ;
taxa=0.01;
output;
end;
format data date9. ;
drop i;
run;
%mend;
%tabla("01MAY2015"d,"01DEC2017"d);
Build your skills. Make connections. Enjoy creative freedom. Maybe change the world. Registration is now open through August 30th. Visit the SAS Hackathon homepage.
Register today!What’s the difference between SAS Enterprise Guide and SAS Studio? How are they similar? Just ask SAS’ Danny Modlin.
Find more tutorials on the SAS Users YouTube channel.
Select SAS Training centers are offering in-person courses. View upcoming courses for: