What is %NoData: for? I usually found it towards the end of the program. Is that a built-in macro? What is it ended with colon instead of semi-colon?
I've never heard of it before, and the colon could be just a mistype given it is on the same key as the semicolon. What happens when you run it?
It is a macro statement label. Perhaps there is a %goto that goes to it.
It's located above the %mend, i think it's a built in code for handling no data, but i can't find a reference
Then I would guess someone copied it in from somewhere else but never used it.
@me888 wrote:
It's located above the %mend, i think it's a built in code for handling no data, but i can't find a reference
There is no %GOTO anywhere in the code?
There isn't any GOTO
So it is an unused macro statement label.
I wrote a lot of long complicated macros in my day.
Each step was followed by a
%if disaster %then %goto abort;
followed by an %abort: macro statement label at the end that then tried to print some sensible message. In the psuedo code above, "disaster" might be operationalized as "&syserr > 4" or in a bunch of other ways.
Here is one example of %NoData: being used ... This is not my code, I came across it while researching it online
%MACRO summary(__dset = ,
__var1 = ,
__var2 = ,
__ref = ,
__basevs = ,
__out = );
%LET __var1 = %UPCASE(&__var1);
%LET __var2 = %UPCASE(&__var2);
%IF %validate(__dset = &__dset ,
__var1 = &__var1 ,
__var2 = &__var2 ,
__ref = &__ref ,
__vars = &__basevs,
__out = &__out ) = 1 /*error found*/
%THEN %RETURN;
%split(__vars=&__basevs)
%makeset(__dset = &__dset ,
__var1 = &__var1 ,
__var2 = &__var2 ,
__class_vars = &__class_vars,
__continuous_vars = &__continuous_vars )
%ctab(__dset = __analysis_set,
__col_var = &__var1 ,
__row_var = &__var2 )
%logit(__test = Crude,
__dset = __analysis_set,
__response = &__var1,
__independent = &__var2,
__ref = &__ref )
%logit(__test = Adjusted,
__dset = __analysis_set,
__response = &__var1,
__independent = &__var2,
__ref = &__ref,
__class_vars = &__class_vars,
__continuous_vars = &__continuous_vars )
%summaryset(__base = &__out)
%nodata:
%MEND summary;
Trust @WarrenKuhfeld . It's a %label statement.
The code was probably originally:
%IF %validate(__dset = &__dset , __var1 = &__var1 , __var2 = &__var2 , __ref = &__ref , __vars = &__basevs, __out = &__out ) = 1 /*error found*/ %THEN %GOTO NODATA;
And then someone changed to:
%IF %validate(__dset = &__dset , __var1 = &__var1 , __var2 = &__var2 , __ref = &__ref , __vars = &__basevs, __out = &__out ) = 1 /*error found*/ %THEN %RETURN;
And they didn't bother to get rid of the %label.
You can get rid of it if you want. Some people have the habit of always leaving it in the end of a macro definition, as an easy way to skip out of out the macro. This was probably common practice before there was a %RETURN statement, and old habits die hard.
They probably replaced the %GOTO statement with the %RETURN statement.
So someone converted a nice STRUCTURED program that had its entry at the TOP and exit at the BOTTOM into a mangled mess that has two exits, one near the top and a second one at the bottom.
@Tom : Well said. It has long been fashionable to bad mouth gotos, but I would much rather have a program that has an entry at the top and ONE entry at the end, implemented with gotos. I never use gotos to otherwise jump around--well, almost never--but if disaster go to abort can be really handy.
Join us for SAS Innovate 2025, our biggest and most exciting global event of the year, in Orlando, FL, from May 6-9. Sign up by March 14 for just $795.
SAS' Charu Shankar shares her PROC SQL expertise by showing you how to master the WHERE clause using real winter weather data.
Find more tutorials on the SAS Users YouTube channel.