BookmarkSubscribeRSS Feed
me888
Calcite | Level 5

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?

11 REPLIES 11
SASKiwi
PROC Star

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?

WarrenKuhfeld
Ammonite | Level 13

It is a macro statement label. Perhaps there is a %goto that goes to it.

me888
Calcite | Level 5

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

WarrenKuhfeld
Ammonite | Level 13

Then I would guess someone copied it in from somewhere else but never used it.

PaigeMiller
Diamond | Level 26

@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?

--
Paige Miller
me888
Calcite | Level 5

There isn't any GOTO

WarrenKuhfeld
Ammonite | Level 13

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. 

me888
Calcite | Level 5

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;

Quentin
Super User

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.

Tom
Super User Tom
Super User

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.  

WarrenKuhfeld
Ammonite | Level 13

@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.