Based on your desired objectives for your macro, you will definitely significantly lessen the syntax difficulties using the automatic variable &SQLOBS for your countsas well as the range-macro variables as Tom pointed out. As an attempt to provide a clearer explanation why the unquote/nrstr combination solves the very issue that you had, I will suggest a few things. 1. Whenever errors or warnings are issued for "macro variable blah resolves or cannot be resolved", use option symbolgen; and read the details of the segment around your warnings/errors. It basically provides each step that the macro processor does to execute the macro elements of any given line (at compilation phase). 2. Always keep in mind that the core concept behind the macro processor is that of a text parser. It basically allows you to parse a bunch of SAS code that you would just not want to hard type. The difficulty underlying with this, is that anytime you need to extract data (through data step or proc sql in general) via execution phase statements to store it in macro variables for use within the same macro. It can create a giant turmoil of timeliness (the macro variables you thought had been created will only be "later" when the code segment gets executed so when you attempt to dereference them, they don't exist) 3. Macro variables dereferencing happens naturally before macro functions (This is the main issue that caused your error). Thus, if you ought to do tricky task where information about a macro variable that you wish to deref is derived after applying an inline %function, you will need to manipulate the macro processor to delay the outer ampersands until after the %functions are resolved. Let's go back to the example by Jakkas %Let colCount = &&countCol%Trim(%Left(&count)); In this scenario, since ampersands are resolved before the %functions, the macro processor does this (which can be validated with options symbolgen): 1st pass && resolves to &, &count resolves to 5 2nd pass &countCol cannot be resolved, issueing the error 3rd pass (inner functions first) %left( 5) is resolved to 5 (symbolgen will use TEXT automatic macro var for most text-oriented in-line macro functions) 4th pass (outer function) %trim(5) is resolved to 5 However, %nrstr() prevents any macro elements inside the paranthesis to be resolved by the macro processor unless controlled otherwise. Thus %Let colCount = %unquote(%nrstr(&countCol)%Trim(%Left(&count.))); is resolved as follow first pass skip over &countCol because it is %nrstr(), resolve &count as 5 2nd pass (resolving %inline function from inside to outside) %left( 5) resolves as 5 3rd pass %trim(5) resolves as 5 4th pass %unquote(%nrstr(&countCol)5) resolves as &countCol5 5th pass &countCol5 resolves as 10000 in practice %nrstr(&countCol) actually does get resolved and if you read the documentation, SAS simply changes the & representation to it's unicode?(maybe it's ascii or hex or even binary representation - regardless, not one that is read as an & by the macro processor). For simplicity, simply consider that it only gets resolved once it is unquoted by %unquote. Hope this explanation helps you a little. P.S. %STR, %NRSTR, %QUOTE, %NRQUOTE and %UNQUOTE eventually are necessary but very, very often. The code can be simplified elsewhere to avoid having to twist your bring to figure out when what should be resolved and have a better code flow/readability. Hence, the tips pointed above, namely the generic one to remove leading blanks and the various proc sql interractions with the macro facility pointed out by Tom are much better alternatives.
... View more