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
Rhodochrosite | Level 12

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
Rhodochrosite | Level 12

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
Rhodochrosite | Level 12

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.

BASUG is hosting free webinars Next up: Don Henderson presenting on using hash functions (not hash tables!) to segment data on June 12. Register now at the Boston Area SAS Users Group event page: https://www.basug.org/events.
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
Rhodochrosite | Level 12

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

sas-innovate-2024.png

Available on demand!

Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.

 

Register now!

Mastering the WHERE Clause in PROC SQL

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.

Discussion stats
  • 11 replies
  • 1014 views
  • 6 likes
  • 6 in conversation