Chapter 5: Passing and Processing Macro Parameters

Slides:



Advertisements
Similar presentations
Chapter 9: Introducing Macro Variables 1 © Spring 2012 Imelda Go, John Grego, Jennifer Lasecki and the University of South Carolina.
Advertisements

Chapter 3: Editing and Debugging SAS Programs. Some useful tips of using Program Editor Add line number: In the Command Box, type num, enter. Save SAS.
Macro Processor.
Chapter 11: Creating and Using Macro Programs 1 STAT 541 ©Spring 2012 Imelda Go, John Grego, Jennifer Lasecki and the University of South Carolina.
Session 7, Chapter 6 From SAS 9.3 Macro Language Reference Macro Expressions P 71.
Introduction to C Programming
Chapter 3 Assignment and Interactive Input. 2 Objectives You should be able to describe: Assignment Operators Mathematical Library Functions Interactive.
 2008 Pearson Education, Inc. All rights reserved JavaScript: Introduction to Scripting.
 2007 Pearson Education, Inc. All rights reserved Introduction to C Programming.
Data types and variables
Chapter 2 Data Types, Declarations, and Displays
Introduction to C Programming
Introduction to Unix (CA263) Introduction to Shell Script Programming By Tariq Ibn Aziz.
Bash Shell Scripting 10 Second Guide Common environment variables PATH - Sets the search path for any executable command. Similar to the PATH variable.
“SAS macros are just text substitution!” “ARRRRGGHHH!!!”
1 Chapter 3: Macro Definitions 3.1 Defining and Calling a Macro 3.2 Macro Parameters 3.3 Macro Storage (Self-Study)
Computing for Research I Spring 2014 January 22, 2014.
Copyright © 2008, SAS Institute Inc. All rights reserved. SAS ® Macros: Top-Five Questions (and Answers!) Kim Wilson –Technical Support Analyst SAS Institute.
Objectives You should be able to describe: Data Types
SCSUG Avoiding Hand Cramps: Name2 macro and arrays for related variables November 9, am South Center SAS Users Group Austin, Texas.
Chapter 10:Processing Macro Variables at Execution Time 1 STAT 541 © Spring 2012 Imelda Go, John Grego, Jennifer Lasecki and the University of South Carolina.
JavaScript, Fifth Edition Chapter 1 Introduction to JavaScript.
1 Chapter 1: Introduction 1.1 Course Logistics 1.2 Purpose of the Macro Facility 1.3 Program Flow.
Copyright © 2012 Pearson Education, Inc. Publishing as Pearson Addison-Wesley C H A P T E R 2 Input, Processing, and Output.
11 Chapter 4: Developing Reusable Macros 4.1 Introduction 4.2 Developing Macro Routines 4.3 Developing Macro Functions.
SAS Macro: Some Tips for Debugging Stat St. Paul’s Hospital April 2, 2007.
INTRODUCTION TO SAS MACRO PROCESSING James R. Bence, Ph.D., Co-Director Quantitative Fisheries Center Professor Department of Fisheries and Wildlife March.
Input, Output, and Processing
5/30/2010 SAS Macro Language Group 6 Pradnya Nimkar, Li Lin, Linsong Zhang & Loc Tran.
Copyright © 2012 Pearson Education, Inc. Publishing as Pearson Addison-Wesley C H A P T E R 2 Input, Processing, and Output.
Data TypestMyn1 Data Types The type of a variable is not set by the programmer; rather, it is decided at runtime by PHP depending on the context in which.
Introduction to SAS Macros Center for Statistical Consulting Short Course April 15, 2004.
_______________________________________________________________________________________________________________ PHP Bible, 2 nd Edition1  Wiley and the.
 2008 Pearson Education, Inc. All rights reserved JavaScript: Introduction to Scripting.
Part:2.  Keywords are words with special meaning in JavaScript  Keyword var ◦ Used to declare the names of variables ◦ A variable is a location in the.
CHAPTER 2 PROBLEM SOLVING USING C++ 1 C++ Programming PEG200/Saidatul Rahah.
Internet & World Wide Web How to Program, 5/e © by Pearson Education, Inc. All Rights Reserved.
4 - Conditional Control Structures CHAPTER 4. Introduction A Program is usually not limited to a linear sequence of instructions. In real life, a programme.
SAS ® 101 Based on Learning SAS by Example: A Programmer’s Guide Chapter 25 By Tasha Chapman, Oregon Health Authority.
Definition of the Programming Language CPRL
Retrieving Data Using the SQL SELECT Statement
Topics Designing a Program Input, Processing, and Output
Chapter 6 JavaScript: Introduction to Scripting
ME 142 Engineering Computation I
CSC201: Computer Programming
Chapter 6: Set Operators
Chapter 3 Assignment and Interactive Input.
A First Book of ANSI C Fourth Edition
Two “identical” programs
Intro to PHP & Variables
Creating Macro Variables in SQL (Review)
Conditional Processing
Chapter 7: Macros in SAS Macros provide for more flexible programming in SAS Macros make SAS more “object-oriented”, like R Not a strong suit of text ©
Conditions and Ifs BIS1523 – Lecture 8.
Chapter 3 The DATA DIVISION.
Introduction to C++ Programming
Creating Macro Variables and Assigning Value
WEB PROGRAMMING JavaScript.
Indirect References to Macro Variables
Creating Macro Variables in the DATA Step
Macro Variable’s scope
Defining and Calling a Macro
Global and Local Symbol Tables
Retrieving Macro Variables in the DATA Step
3 Iterative Processing.
3 Parameter Validation.
Boolean Expressions to Make Comparisons
How Best to Use Macro Quoting Functions?
Topics Designing a Program Input, Processing, and Output
Topics Designing a Program Input, Processing, and Output
Presentation transcript:

Chapter 5: Passing and Processing Macro Parameters 3 Chapter 5: Passing and Processing Macro Parameters 5.1 Validating Parameter Values 5.2 Data-Driven Macro Calls 5.3 Working with Special Characters

Chapter 5: Passing and Processing Macro Parameters 3 Chapter 5: Passing and Processing Macro Parameters 5.1 Validating Parameter Values 5.2 Data-Driven Macro Calls 5.3 Working with Special Characters

Objectives Validate macro parameters.

Parameter Validation Up to this point, many of Orion Star’s applications have minimal parameter validation. The developers want to increase the amount of validation to reduce difficulties caused by user input. All macro applications should perform the following actions: establish rules for valid values Are null values valid? What are valid values? validate parameter values against valid values generate error or warning message when invalid values are encountered and possibly terminate the macro

Without Parameter Validation (Review) The PRINTLST macro prints a subset of data based on the variables Country, Gender, and Type from orion.customer_dim. Without parameter validation, what potential problems might a user of this macro encounter? %macro printlst(country=AU,gender=F,type=CLUB); %upvalue proc print data=orion.customer_dim; var Customer_Name Customer_ID Customer_Age_Group Customer_Type; where Customer_Country = "&country" and Customer_Gender = "&gender" and upcase(Customer_Type) contains "&type"; title "Listing of Customer Names Subsetted By:"; title2 "Country=&country Gender=&gender Customer Type=&type"; run; title; %mend printlst; m205d01

Without Parameter Validation (Review) Country A null value or an invalid value will return zero rows. GENDER TYPE * A null value might result in an incorrect subset of data or zero rows. An invalid value might result in an incorrect subset of data or zero rows. * The CONTAINS operator selects observations that include the specified substring. The substring AL, null values, and blank values are found in the variable Customer_Type.

Validation Against a Known List of Values When a list of valid values is known, the macro applications should use one of these to validate parameter values: the OR operator for equals conditions the AND operator for not-equals conditions the user-defined FIND macro the IN operator  The IN operator is new in SAS 9.2.

Validation Using the OR and AND Operators %macro grplist(type); %let type=%upcase(&type); %if &type= or (&type ne GOLD and &type ne INTERNET and &type ne CATALOG) %then %do; %if &type = %then %put ERROR: A null value for TYPE is not valid.; %else %put ERROR: Value of TYPE: &type is not valid.; %put ERROR- Valid values are CATALOG, INTERNET or GOLD; %put ERROR- The macro will terminate now.; %return; %end; proc print data=orion.customer_dim; var Customer_Group Customer_Name Customer_Gender Customer_Age; where upcase(Customer_Group) contains "&type"; title "&type Customers"; run; title; %mend grplist; m205d02a

Validation Using the OR and AND Operators Partial SAS Log 1922 %grplist() ERROR: A null value for TYPE is not valid. Valid values are CATALOG, INTERNET or GOLD The macro will terminate now. 1923 %grplist(silver) ERROR: Value of TYPE: SILVER is not valid. 1924 %grplist(catalog) NOTE: There were 8 observations read from the data set ORION.CUSTOMER_DIM. WHERE UPCASE(Customer_Group) contains 'CATALOG'; NOTE: PROCEDURE PRINT used (Total process time): real time 0.00 seconds cpu time 0.00 seconds

Validation Using the FIND Macro The FIND macro simplifies the %IF statement logic. %macro grplist(type); %let type=%upcase(&type); %if &type= or %find(GOLD INTERNET CATALOG ,&type)=0 %then %do; %if &type = %then %put ERROR: A null value for TYPE is not valid.; %else %put ERROR: Value of TYPE: &type is not valid.; %put ERROR- Valid values are CATALOG, INTERNET or GOLD; %put ERROR- The macro will terminate now.; %return; %end; proc print data=orion.customer_dim; var Customer_Group Customer_Name Customer_Gender Customer_Age; where upcase(Customer_Group) contains "&type"; title "&type Customers"; run; title; %mend grplist; m205d02b

Using the IN Operator Although similar in functionality to the DATA step IN operator, the macro IN operator is syntactically different. Macro DATA Step The # can be used in place of the keyword IN. Yes No The operator requires parentheses around the list of values. The operator requires the MINOPERATOR option or system option. Placement of the NOT operator is a consideration. Before the IN expression Before the IN operator The operator allows for null values.

Incorrect Validation of Null Using the IN Operator %macro grplist(type)/minoperator; %let type=%upcase(&type); %if &type= or not(&type in GOLD INTERNET CATALOG) %then %do; %if &type = %then %put ERROR: A null value for TYPE is not valid.; %else %put ERROR: Value of TYPE: &type is not valid.; %put ERROR- Valid values are CATALOG, INTERNET or GOLD; %put ERROR- The macro will terminate now.; %return; %end; proc print data=orion.customer_dim; var Customer_Group Customer_Name Customer_Gender Customer_Age; where upcase(Customer_Group) contains "&type"; title "&type Customers"; run; title; %mend grplist; m205d02c

Incorrect Validation of Null Using the IN Operator If the macro variables in the IN expression resolve to a null value, the macro processor generates the following errors: The IN operator does not recognize a null value as a valid value. If TYPE resolves to null, the %IF statement resolves to this statement: 2145 %grplist() SYMBOLGEN: Macro variable TYPE resolves to ERROR: Operand missing for IN operator in argument to %EVAL function. ERROR: The macro GRPLIST will stop executing. %if = or not( in GOLD INTERNET CATALOG) %then %do;

Validation of Null Using the IN Operator Testing for a null value must be done separately and prior to the %IF statement containing the IN operator. %if &type= %then %do; %put ERROR: A null value for TYPE is not valid.; %put ERROR- Valid values are CATALOG, INTERNET or GOLD; %put ERROR- The macro will terminate now.; %return; %end; %if not(&type in GOLD INTERNET CATALOG) %then %put ERROR: Value of TYPE: &type is not valid.; m205d03

Validating Null Using the IN Operator This demonstration illustrates using the IN operator to test against a list of values. m205d03

Validation Using a Dynamic List of Values To reduce maintenance associated with parameter validation, the Orion Star programmers want to generate a data-driven list to replace the hardcoded values. The SQL procedure can be used to create the list of valid values dynamically and to save the result into a macro variable. %if not(&country in AU CA DE IL TR US ZA) %then %do;

The SQL Procedure INTO Clause (Review) Partial SAS Log proc sql noprint; select distinct country into :countrylist separated by ' ' from orion.customer; quit; 2241 %put Customer Countries: &countrylist; Customer Countries: AU CA DE IL TR US ZA m205d04

The SQL Procedure INTO Clause (Review) The INTO clause can store the unique values of a specified column in a single macro variable. General form of the INTO clause to create a list of unique values in one macro variable: SELECT DISTINCT col1, . . . INTO :mvar SEPARATED BY 'delimiter', . . . FROM table-expression WHERE where-expression other clauses;

Validating Using a Dynamic List of Values This demonstration illustrates using the SQL procedure to generate a data-driven list. m205d04

Exercise This exercise reinforces the concepts discussed previously.

Chapter 5: Passing and Processing Macro Parameters 3 Chapter 5: Passing and Processing Macro Parameters 5.1 Validating Parameter Values 5.2 Data-Driven Macro Calls 5.3 Working with Special Characters

Objectives Generate repetitive macro calls using the following: %DO loop CALL EXECUTE routine SQL procedure

Data-Dependent Macro Calls The Orion Star programmers need to call the MEMLIST macro for each value of Customer_Type. Because the value of Customer_Type can change, they want to generate data-dependent macro calls as illustrated below: %memlist(Orion Club members inactive) %memlist(Orion Club members low activity) %memlist(Orion Club members medium activity) %memlist(Orion Club members high activity) %memlist(Orion Club Gold members low activity) %memlist(Orion Club Gold members medium activity) %memlist(Orion Club Gold members high activity) %memlist(Internet/Catalog Customers)

Data-Dependent Macro Calls Three different methods can be used to generate data-dependent macro calls. %DO loop CALL EXECUTE routine SQL procedure

Method 1: %DO Loop Generally used to generate SAS code, the %DO loop can be used to generate data-dependent macro calls. %macro gencall; data _null_; set orion.customer_type end=final; call symputx(cats('type', _n_, Customer_Type,'L'); if final then call symputx('n',_n_,'L'); run; %do num=1 %to &n; %memlist(&&type&num) %end; %mend gencall; %gencall m205d05

Method 1: %DO Loop Partial Symbol Table Generate Macro Calls %memlist(&&type&num) %memlist(&type1) %memlist(Orion Club members inactive) Variable Value NUM 1 TYPE1 Orion Club members inactive TYPE2 Orion Club members low activity TYPE3 Orion Club members medium activity

Method 1: %DO Loop Partial SAS Log MPRINT(MEMLIST): proc print data=Orion.Customer_dim; MPRINT(MEMLIST): var Customer_Name Customer_ID Customer_Age_Group; MPRINT(MEMLIST): where Customer_Type="Orion Club members low activity"; MPRINT(MEMLIST): title "A List of Orion Club members low activity"; MPRINT(MEMLIST): run; MPRINT(MEMLIST): title; MPRINT(MEMLIST): where Customer_Type="Orion Club members medium activity"; MPRINT(MEMLIST): title "A List of Orion Club members medium activity"; MPRINT(MEMLIST): where Customer_Type="Orion Club members high activity"; MPRINT(MEMLIST): title "A List of Orion Club members high activity";

Generating Code with the DATA Step The EXECUTE routine processes a text string during DATA step execution and can be used to generate data-driven macro calls. General form of the CALL EXECUTE statement: The value of argument can be one of the following: a text expression, enclosed in quotation marks the name of a character variable a character expression that is resolved by the DATA step to a macro text expression CALL EXECUTE (argument);

Generating Code with the DATA Step If argument is a text expression, it is inserted into the input stack as additional program code that will execute after the current DATA step. Partial SAS Log 334 data new; 335 Dog='Paisley'; 336 call execute('proc print; run;') ; 337 run; NOTE: The data set WORK.NEW has 1 observations and 1 variables. NOTE: DATA statement used (Total process time): real time 0.01 seconds cpu time 0.01 seconds NOTE: CALL EXECUTE generated line. 1 + proc print; run; NOTE: There were 1 observations read from the data set WORK.NEW. NOTE: PROCEDURE PRINT used (Total process time): real time 0.00 seconds cpu time 0.00 seconds

Executing Macro Code from a DATA Step If the argument to the CALL EXECUTE routine resolves to a macro call, the macro executes immediately and DATA step execution pauses while the macro executes. Macro language statements within the macro definition are executed. All other SAS code generated by the macro is inserted into the input stack to execute after the current DATA step.

Method 2: CALL EXECUTE Routine Use the CALL EXECUTE routine to generate a macro call for each value of Customer_Type.  The orion.customer_type data set contains one observation for each unique value of Customer_Type. data _null_; set orion.customer_type(keep=Customer_Type) end=final; macrocall=catt('%memlist(', Customer_Type, ')'); call execute(macrocall) ; run; m205d06

Method 2: CALL EXECUTE Routine Partial SAS Log 858 data _null_; 859 set orion.customer_type(keep=Customer_Type) end=final; 860 macrocall=catt('%memlist(', Customer_Type, ')'); 861 call execute(macrocall) ; 862 run; MPRINT(MEMLIST): proc print data=Orion.Customer_dim; MPRINT(MEMLIST): var Customer_Name Customer_ID Customer_Age_Group; MPRINT(MEMLIST): where Customer_Type="Orion Club members inactive"; MPRINT(MEMLIST): title "A List of Orion Club members inactive"; MPRINT(MEMLIST): run; MPRINT(MEMLIST): title; MPRINT(MEMLIST): where Customer_Type="Orion Club members low activity"; MPRINT(MEMLIST): title "A List of Orion Club members low activity"; MPRINT(MEMLIST): where Customer_Type="Orion Club members medium activity"; MPRINT(MEMLIST): title "A List of Orion Club members medium activity";

Method 3: The SQL Procedure Use the INTO clause of PROC SQL to create a macro variable that contains a macro call for each value. proc sql noprint; select distinct catt('%memlist(', customer_type, ')') into :mcalls separated by ' ' from orion.customer_type; quit; &mcalls *Resolution results in macro calls; m205d07

Exercise This exercise reinforces the concepts discussed previously.

Chapter 5: Passing and Processing Macro Parameters 3 Chapter 5: Passing and Processing Macro Parameters 5.1 Validating Parameter Values 5.2 Data-Driven Macro Calls 5.3 Working with Special Characters

Objectives List and describe special characters. Pass special characters. Use special characters in functions. Protect special characters in resolved values.

Special Characters The macro language is a character-based language. Special characters can be misinterpreted by the macro processor when they appear in text strings, including these operators. blank , ; “ ‘ ( ) | + - * / < > = ¬ ^ ~ % & # The following mnemonics might also be misinterpreted: AND OR NOT EQ NE LE LT GE GT IN

Comma: Argument Separator or Part of Text? Commas are used as separators between parameter values in macro calls and as arguments in functions. %macro name(fullname); %let first=%scan(&fullname,2); %let last=%scan(&fullname,1); %let newname=&first &last; %put &newname; %mend name; %name(Taylor, Jenna) The comma will be misinterpreted as a separator instead of as part of the value.

Quotation Mark: Literal Delimiter or Part of Text? An apostrophe or unmatched quotation mark is treated as the beginning of a quoted string, causing the windowing environment to stop responding. %macro unmatched(fullname); %let first=%scan(&fullname,2); %let last=%scan(&fullname,1); %let newname=&first &last; %put &newname; %mend unmatched; %unmatched(O'Malley, George) The apostrophe is treated as the beginning of a quoted string.

OR: Logical Operator or a Text Abbreviation? The literal OR is interpreted as a logical operator that requires an expression on each side of the OR operator. %macro operator(state); %if &state = OR %then %put State is Oregon; %else %put State is &state; %mend operator; %operator(PA) The %IF statement resolves to %if PA= OR %then, which is not allowed.

Ampersand: Macro Trigger or Part of Text? Macro triggers found in a macro call are resolved before the macro executes. %macro ampersand(company); %put &company; %mend ampersand; %ampersand(AT&T) The ampersand will be misinterpreted as a macro trigger.

Quoting Functions Macro quoting functions resolve ambiguities by masking the significance of special characters and mnemonics so that the macro processor does not misinterpret them to be part of the syntax of a macro statement or expression. The following are the most commonly used quoting functions: %STR and %NRSTR %SUPERQ %BQUOTE

Masking Special Characters Word Scanner Macro Processor The value of the macro variable should contain an ampersand and a percent sign as text. Input Stack %let xyz=%nrstr(&A+%B); ...

Masking Special Characters Word Scanner Macro Processor % let xyz = nrstr ( & A + B ) ; The word scanner identifies individual tokens. ...

Masking Special Characters Word Scanner Macro Processor %let xyz = % nrstr ( & A + B ) ; The macro trigger %let redirects tokens to the macro processor. ...

Masking Special Characters Word Scanner Macro Processor & A + % B ) ; %let xyz=%nrstr( When %NRSTR is encountered, the macro processor masks special tokens that appear within the FUNCTION argument. ...

Masking Special Characters Word Scanner Macro Processor ) ; %let xyz=%nrstr(&A+%B In effect, each individual character within a special token is treated as plain text. In reality, those tokens are stored as otherwise unused hexadecimal characters. ...

Masking Special Characters Word Scanner Macro Processor ; %let xyz=%nrstr(&A+%B) Normal tokenization resumes after the %NRSTR is terminated with a right parenthesis. ...

Masking Special Characters Word Scanner Macro Processor ; %let xyz=%nrstr(&A+%B) The macro processor will interpret this semicolon as the end of the %LET statement.

Masking Special Characters The quoting functions mask special characters by converting them to hexadecimal values called delta characters. Becomes: 01 0F 41 15 10 42 02 %let xyz=%nrstr(&A+%B);

Viewing Masked Characters The SYMBOLGEN option generates additional messages to the SAS log when a value is masked. The %PUT statement with the _USER_ argument displays the unprintable characters stored as a result of macro quoting. 109 options symbolgen; 110 %let xyz=%nrstr(&A+%B); 111 %put &xyz; SYMBOLGEN: Macro variable XYZ resolves to &A+%B SYMBOLGEN: Some characters in the above value which were subject to macro quoting have been unquoted for printing. &A+%B

Compile Time versus Execution Time The compilation functions (%STR and %NRSTR) treat special characters as text in a macro program statement in open code or while compiling a macro. The execution functions (%SUPERQ and %BQUOTE) mask special characters during macro execution. The macro processor resolves the expression or value and masks the result.

Compile Time versus Execution Time To help distinguish between compile-time quoting functions and execution-time quoting functions, the Orion Star programmers developed this “golden rule”: If you can see the special character, meaning you typed the special character, then it is a compile-time issue. If you cannot see the special character, meaning the macro facility typed the special character, then it is an execution-time issue.

Passing Special Characters: Compile Time Compile-time masking is necessary when a user types special characters in one of the following: macro statements valid in open code, such as %LET and %PUT statements macro programming logic, such as an %IF statement parameter values on a macro call macro function arguments  Orion Star's golden rule: If the special character can be seen, a compile-time function is needed.

Masking Tokens at Compile Time The %STR function masks special characters and mnemonics typed by a user. General form of the %STR function: character-string can be any combination of text and macro triggers. %STR(character-string)

Tokens Masked by the %STR Function The %STR function performs the following actions: forces the macro processor to interpret special characters and mnemonics as plain text during compilation by masking their usual meanings masks these special characters and mnemonics: blank , ; + - * / < > = ¬ ^ ~ # | AND OR NOT EQ NE LE LT GE GT IN masks single quotation marks, double quotation marks, and parentheses when they appear in pairs attempts to resolve the ampersand (&) and the percent (%) sign

Passing a Comma as Text The %STR function causes the comma to be interpreted as text, not as a separator. %macro comma(fullname); %let first=%scan(&fullname,2); %let last=%scan(&fullname,1); %let newname=&first &last; %put &newname; %mend comma; %comma(%str(Taylor, Jenna)) Partial SAS Log 64 %comma(%str(Taylor, Jenna)) Jenna Taylor

Passing an Unmatched Quotation Mark as Text The %STR function requires unmatched quotation marks and parentheses to be preceded by a percent sign (%). %macro unmatched(fullname); %let first=%scan(&fullname,2); %let last=%scan(&fullname,1); %let newname=&first &last; %put &newname; %mend unmatched; %unmatched(%str(O%'Malley, George))

Using OR as a Text Abbreviation The %STR function causes special characters in macro programming logic to be interpreted as a text string on the right side of the equal sign. %macro operator(state); %if &state = %str(OR) %then %put State is Oregon; %else %put State is &state; %mend operator; %operator(PA) Partial SAS Log 77 %operator(PA) State is PA

Special Characters as Function Arguments The comma is used as a separator between function arguments. To specify a comma as a delimiter, use the %STR function. %macro comma(fullname); %let first=%scan(&fullname,2,%str(,)); %let last=%scan(&fullname,1,%str(,)); %let newname=&first &last; %put &newname; %mend comma; %comma(%str(Taylor, Jenna))

Masking & and % at Compile Time In addition to masking the same characters as the %STR function, the %NRSTR function masks the ampersand (&) and percent (%) sign. General form of the %NRSTR function: character-string can be any combination of text and macro triggers. %NRSTR(character-string)

Passing an Ampersand as Text The %NRSTR function prevents the macro processor from recognizing &T as a macro variable reference. %macro ampersand(company); %put &company; %mend ampersand; %ampersand(%nrstr(AT&T)) Partial SAS Log 99 %ampersand(%nrstr(AT&T)) AT&T

Passing Special Characters This demonstration illustrates using the %NRSTR function to pass special characters in a macro call. m205d08

Passing an Unbalanced Quotation Mark as Text SAS Log If the value of FULLNAME is masked, why does the macro generate errors? 1 %macro unmatched(fullname); 2 %let first=%scan(&fullname,2); 3 %let last=%scan(&fullname,1); 4 %let newname=&first &last; 5 %put &newname; 6 %mend unmatched; 7 8 9 %unmatched(%str(O%'Malley, George)) ERROR: Literal contains unmatched quote. ERROR: The macro UNMATCHED will stop executing.

What Went Wrong? Word Scanner Macro Processor Macro Symbol Table FULLNAME O'Malley, George The macro variable FULLNAME contains a masked apostrophe and comma. Input Stack %let last=%scan(&fullname,1); ...

What Went Wrong? Word Scanner % scan ( & fullname , 1 ) ; Macro Processor Function %let last= The macro variable reference will be resolved as the %SCAN function call is constructed. The result of the %SCAN function will be placed after the = sign in the %LET statement. Macro Symbol Table FULLNAME O'Malley, George Input Stack %let last=%scan(&fullname,1); ...

What Went Wrong? Word Scanner ; Macro Processor %let last=O'Malley The masking applied to the apostrophe is removed when the macro variable is resolved in the %SCAN function. Macro Symbol Table FULLNAME O'Malley, George Input Stack %let last=%scan(&fullname,1); ...

What Went Wrong? Word Scanner Macro Processor %let last=O'Malley; The semicolon that should end the %LET statement is interpreted as part of the literal. The literal was not terminated. Macro Symbol Table FULLNAME O'Malley, George Input Stack %let last=%scan(&fullname,1);

Unmasking of Special Characters When a special character is masked with a macro quoting function, it is unmasked under these conditions: It leaves the word scanner and is passed to the DATA step compiler, SAS procedures, SAS macro facility, or other parts of SAS. It is resolved in the %SCAN, %SUBSTR, or %UPCASE function. It is explicitly unmasked by the %UNQUOTE function.

Passing Special Characters: Execution Time Execution-time masking is necessary when a macro variable that contains special characters resolves in one of the following: macro programming logic macro invocation macro function  Orion Star's golden rule: If you cannot see the special character, an execution-time quoting function is needed.

Masking All Tokens at Execution Time The %SUPERQ function masks all special characters and mnemonics during execution. General form of the %SUPERQ function: argument can be a macro variable name or an expression that resolves to a macro variable name. Do not precede the argument with an ampersand (&). %SUPERQ(argument)

Resolving OR as a Text Abbreviation Masking the resolved value of state with the %SUPERQ function prevents the macro processor from misinterpreting the resolved value OR as a mnemonic. SAS Log %macro operator(state); %if %superq(state)=%str(OR) %then %put State is Oregon; %else %put State is &state; %mend operator; 55 %operator(OR) State is Oregon

Resolving a Comma as Text If the resolved value of a function argument contains commas, additional execution-time macro quoting is required. The resolution of &NAME creates a %SUBSTR function call that appears to have four arguments. 1 2 3 4 %let name=Taylor, Jenna; %let initial=%substr(&name,1,1); %substr(Taylor, Jenna,1,1)

Masking Function Arguments Masking the resolved value of name with the %SUPERQ function prevents the macro processor from misinterpreting the comma in the resolved value as a separator. SAS Log %let name=Taylor, Jenna; %let initial=%substr(%superq(name),1,1); 97 %put Last name begins with &initial.; Last name begins with T

Masking Function Results Occasionally, the result of a macro function can contain special characters that are misinterpreted because they are unmasked by a function. When the UNMATCHED macro executes, the second %LET statement using the %SCAN function contains an unmatched single quotation mark. %macro unmatched(fullname); %let first=%scan(&fullname,2); %let last=%scan(&fullname,1); %let newname=&first &last; %put &newname; %mend unmatched; %unmatched(%str(O%'Malley, George)) %let last=O'Malley;

Masking Function Results The %QSCAN function masks the result, loading the unmatched single quotation mark into the macro variable as a masked character. SAS Log %macro unmatched(fullname); %let first=%qscan(&fullname,2); %let last=%qscan(&fullname,1); %let newname=&first &last; %put &newname; %mend unmatched; 132 %unmatched(%str(O%'Malley, George)) George O'Malley

Masking Function Results Many macro functions and autocall macros have “Q” equivalents that return masked results. %CMPRES %QCMPRES %LEFT %QLEFT %LOWCASE %QLOWCASE %SCAN %QSCAN %SUBSTR %QSUBSTR %SYSFUNC %QSYSFUNC %TRIM %QTRIM %UPCASE %QUPCASE

Resolving Special Characters This demonstration illustrates using the %QSCAN and %QSYSFUNC functions to mask special characters in resolved values. m205d09

& and % in Resolved Values Depending on the circumstance, you might or might not want the ampersand or the percent sign to be recognized as macro triggers. Using this function Treats & or % as %SUPERQ text %BQUOTE macro triggers

& and % as Text in Resolved Values The %SUPERQ function treats all special characters, including the ampersand (&) and percent (%) sign, as text.  No attempt was made to resolve &T. 184 %macro resolves(name); 185 %let t=INC.; 186 data _null_; 187 call symputx('company', 'AT&T'); 188 run; 189 %if &name=%superq(company) %then %put Values Are The Same; 190 %else %put Company=%bquote(&company) Name=&name; 191 %mend resolves; 192 %resolves(%nrstr(AT&T)) NOTE: DATA statement used (Total process time): real time 0.01 seconds cpu time 0.03 seconds SYMBOLGEN: Macro variable NAME resolves to AT&T SYMBOLGEN: Some characters in the above value which were subject to macro quoting have been unquoted for printing. Values Are The Same

& and % as Macro Triggers in Resolved Values To attempt resolution of embedded macro triggers in resolved values, use the %BQUOTE function. General form of the %BQUOTE function: The %BQUOTE function masks the same special characters and mnemonics as the %SUPERQ function during macro execution. %BQUOTE(character-string | text-expression)

& and % as Macro Triggers in Resolved Values 193 %macro resolveb(name); 194 %let t=INC.; 195 data _null_; 196 call symputx('company', 'AT&T'); 197 run; 198 %if &name=%bquote(&company) %then %put Values Are The Same; 199 %else %put Company=%bquote(&company) Name=&name; 200 %mend resolveb; 201 %resolveb(%nrstr(AT&T)) NOTE: DATA statement used (Total process time): real time 0.00 seconds cpu time 0.00 seconds SYMBOLGEN: Macro variable NAME resolves to AT&T SYMBOLGEN: Some characters in the above value which were subject to macro quoting have been unquoted for printing. SYMBOLGEN: Macro variable COMPANY resolves to AT&T SYMBOLGEN: Macro variable T resolves to INC. Company=ATINC. Name=AT&T The %BQUOTE function recognizes the &T in AT&T as a macro trigger.

%SUPERQ versus %BQUOTE The %SUPERQ function is the recommended macro quoting function when you perform direct macro variable substitution and all characters are to be treated as text. Use the %BQUOTE function in situations where the resolution of a macro trigger is desired or the argument is an expression rather than a single macro variable reference. %SUPERQ %BQUOTE Accepts a single macro name X Accepts an expression that yields a macro variable name Does not treat % and & as macro triggers

Masking an Ampersand in Resolved Values This demonstration illustrates using the %SUPERQ function to mask the ampersand in resolved values. m205d10

Unmasking Characters Occasionally, the process of masking characters using macro quoting functions produces unexpected results when the resulting string is resolved. The %UNQUOTE function reverses the effects of macro quoting and restores the normal syntax interpretation. General form of the %UNQUOTE function: %UNQUOTE(character-string | text-expression)

Masked Characters Disrupt Compilation This demonstration illustrates how a masked character will disrupt compilation. m205d011

Unmasking Characters with the %UNQUOTE Function This demonstration illustrates how the %UNQUOTE function unmasks special characters to enable normal compilation. m205d012

When to Use the %UNQUOTE Function The following conditions require the %UNQUOTE function: When a value was previously masked by a quoting function and you want to use the unmasked value later in the same macro. When masking text with a macro quoting function changes the way that the word scanner tokenizes it. The generated SAS statements appear to be correct, but the SAS compiler does not recognize them as valid syntax.

Exercise This exercise reinforces the concepts discussed previously.