11-09-2017 04:34 AM
I can not understand why cat does not take into account the zeros in this example.
The length of the macro variable x3 is 2 for months <10 after put (x2,Z2.). Another question, why the repeat function when the number of repetitions equal to 0
adds the 0 (which explains the use of the loop)
%macro remplir(); %DO LOOP=7 %to 12; %LET x1=%SYSFUNC(INTNX(month,%SYSFUNC(INTNX(day,%SYSFUNC(today()),%SYSFUNC(day(%SYSFUNC(today())))-1)),&LOOP.-19)); %LET x2=%SYSFUNC(MONTH(&x1.)); %LET x3=%SYSFUNC(PUTN(&x2., Z2.)); %let len=%length(&x3.); %let len1=%length(&x2.); %LET val1=&x1.; %LET val12=%SYSFUNC(CAT(%SYSFUNC(PUTN(&x1.,year2.)),M,&x3.)); %LET val13=%SYSFUNC(CAT(%SYSFUNC(PUTN(&x1.,year2.)),M,%sysfunc(repeat(0,%eval(2-%length(&x2.)))) ,&x2.)); %if &len1.=1 %then %do; %LET val14=%SYSFUNC(CAT(%SYSFUNC(PUTN(&x1.,year2.)),M,%sysfunc(repeat(0,%eval(2-%length(&x2.)))) ,&x2.)); %end; %else %do; %LET val14=%SYSFUNC(CAT(%SYSFUNC(PUTN(&x1.,year2.)),M,&x3.)); %end; %put &=x3/&=len./&=val12./&=val12./&=val13./&=val14.; %end; %mend remplir; %remplir;
11-09-2017 04:57 AM
Why, in $DEITY's name, are you doing that in a macro? The macro facility is a CODE GENERATOR, not a DATA PROCESSOR!!!. Use a data step!
That %sysfunc avalanche is a cancer-causing eyesore.
In the data step, use put's whenever you assign/create a variable, to see how your data is modified. The data step also notifies you of all automatical type conversions where formats might be lost.
11-09-2017 05:00 AM
Sorry, that code is nigh on impossible to read. Why not use a simple datastep to achieve your goal?
data _null_; do i=7 to 12; /* do some things here */ end; call symput('len',lengthn(...)); ... run;
Though I can't actually see why you would need all those macro variables in the first place. It would be far simpler if you put the calculation output in datasets and used merges - or are you planning on using this information in filenames/dataset names? If so consider doing all the programming using one dataset and split it out at the end - will simplfy coding quite a bit.
11-09-2017 05:36 AM
Thank you for your answers
I simplify the example.
Why cat does not take into account the 0?
%let x1=2010; %LET x2=01; %LET x3=%SYSFUNC(CAT(&x1.,M,&x2.)); %put &x3.;
11-09-2017 05:46 AM - edited 11-09-2017 05:49 AM
Oh, and to fix it just do:
%let x1=2010; %let x2=01; %let x3=&x1.M&x2.; %put &x3.;
You don't need cat() at all.
You will find this post helpful:
As always, the problem lies with doing data processing in macro language. Macro is for generating text, nothing more, and has limited functionality. In your case the cat() function is treating 01 as numeric, which is 1. You can use put in there as well, however best method is to use the tool appropriate to the task, and data processing is best done in Base SAS - in fact macro is just an addon.
11-09-2017 06:50 AM
cat DOES take leading zeroes into account:
data _null_; x1 = '2017'; x2 = '09'; x3 = cat(x1,'M',x2); put x3=; run;
But try this:
data _null_; x1 = 2017; x2 = 09; x3 = cat(x1,'M',x2); put x3=; run;
So you can see that your "problem" comes from your abuse of the macro facility.
11-09-2017 10:46 AM
Looks like an awful lot of work to simulate the use of the YYMMw. format with.
Generally you are better off leaving dates as date values until a human has to read them.
data _null_; x= '15Dec2016'd; put x yymm5.; run;
which is the value of your macro variables Val12 and Val14 on the second line of log output. (picked on December of personal reasons)