Based on information I have found on other sites and a SUGI paper written by Paul Sherman it appears that ERROR messages like "NOTE: Invalid second argument to function SUBSTR at line nnnnn column nnn" are actually indicating macro BLOCK and COLUMN rather than open code LINE and COLUMN. My question is, if I turn on MACRO options like MPRINT or MGEN or MLOGIC how can I determine the block numbers in the output. Is there some undocumented automatic macro variable like &SYSMACBLOCK that I could %PUT to the log to identify more closely which of my generated statements is generating the note when I have lots of SUBSTR calls?
@eshupp wrote:
Easier said than done when your error is in block 58296. If SAS knows which block the error is in I should have some way to display block numbers in the debugging output other than paging through thousands of lines of SASLOG. With open code errors the line numbers are displayed but MPRINT does not provide the same information.
Yeah, it would be nice if you could do this, but you can't. It's one of the limitations of the the way the macro processor was designed that a macro doesn't have line breaks in it (which is why you can't use CARDS in a macro). So when the macro generates lines of code and sends them to SAS to be compiled and executed, my guess is it's all one line (in a sense). So the log can't tell you a useful line number for an error.
One workaround some folks use is to use MPRINT and MFILE to create a .sas file with no macro code, which can then be %included to generate a log with useful line numbers for errors. See e.g. https://support.sas.com/resources/papers/proceedings14/1302-2014.pdf
Just turn on MPRINT and check the log for your mistakes.
If you are really desperate then turn on SYMBOLGEN and/or MLOGIC and slog your way through the reams of log messages.
Or better still put in some PUT or %PUT statements to debug where the errors are.
With MPRINT on, the ERROR messages appear immediately below the actual error (just as they do when you are not running macro code), plus you can see the actual SAS code that you macro has created; and you don't need a line number of block number to find them.
... other than paging through thousands of lines of SASLOG ...
No need to do that. Using the search function in the LOG window (ctrl-F) will get you there quickly.
@eshupp wrote:
Easier said than done when your error is in block 58296. If SAS knows which block the error is in I should have some way to display block numbers in the debugging output other than paging through thousands of lines of SASLOG. With open code errors the line numbers are displayed but MPRINT does not provide the same information.
Yeah, it would be nice if you could do this, but you can't. It's one of the limitations of the the way the macro processor was designed that a macro doesn't have line breaks in it (which is why you can't use CARDS in a macro). So when the macro generates lines of code and sends them to SAS to be compiled and executed, my guess is it's all one line (in a sense). So the log can't tell you a useful line number for an error.
One workaround some folks use is to use MPRINT and MFILE to create a .sas file with no macro code, which can then be %included to generate a log with useful line numbers for errors. See e.g. https://support.sas.com/resources/papers/proceedings14/1302-2014.pdf
Registration is now open for SAS Innovate 2025 , our biggest and most exciting global event of the year! Join us in Orlando, FL, May 6-9.
Sign up by Dec. 31 to get the 2024 rate of just $495.
Register now!
Learn how use the CAT functions in SAS to join values from multiple variables into a single value.
Find more tutorials on the SAS Users YouTube channel.
Ready to level-up your skills? Choose your own adventure.