Presentation is loading. Please wait.

Presentation is loading. Please wait.

11 Chapter 4: Developing Reusable Macros 4.1 Introduction 4.2 Developing Macro Routines 4.3 Developing Macro Functions.

Similar presentations


Presentation on theme: "11 Chapter 4: Developing Reusable Macros 4.1 Introduction 4.2 Developing Macro Routines 4.3 Developing Macro Functions."— Presentation transcript:

1 11 Chapter 4: Developing Reusable Macros 4.1 Introduction 4.2 Developing Macro Routines 4.3 Developing Macro Functions

2 22 Chapter 4: Developing Reusable Macros 4.1 Introduction 4.2 Developing Macro Routines 4.3 Developing Macro Functions

3 3 Objectives 3 Describe the difference between a routine and a function. Modify the SASAUTOS= system option.

4 4 Creating Reusable Macros To adhere to Orion Star best practices, the programmers want to implement common tasks through reusable macro programs. A library of reusable macros aid in these tasks: simplifying macro definitions hiding complex code sharing and reusing code 4

5 5 Is It a Function or a Routine? Reusable macros can be divided into two categories, user-defined functions and user-defined routines. Each is created and implemented differently. 5 User-Defined FunctionsUser-Defined Routines are macros that contain only macro code. are macros that use DATA and PROC step code along with macro code. return a single value.can return multiple values. are called “in-line” within other statements such as %LET, %IF, or traditional SAS code. are not called “in-line” and can be treated as macro steps.

6 6 Steps for Creating Reusable Macros These steps are used to create reusable macros: 1.Thoroughly test and debug the macro. 2.Save the macro as an autocall macro. 3.Set the SASAUTOS= system option to specify the directory for the autocall library. 4.Call the utility macro in a subsequent macro. 6

7 7 Incorrectly Adding a Custom Autocall Library 7 Before you modify the SASAUTOS= option, it is important to review the current values to not overwrite current settings. The default action of the SASAUTOS= system option is to replace the current search list. This is the incorrect way to add an autocall library. proc options option=sasautos; run; options sasautos=('s:\workshop'); proc options option=sasautos; run;

8 8 Incorrectly Adding a Custom Autocall Library 8 Partial SAS Log The autocall macros supplied by SAS along with those in s:\orion_autocall are no longer available in the current session. 59 proc options option=sasautos; 60 run; SASAUTOS=('s:\orion_autocall', sasautos) Search list for autocall macros 61 options sasautos=('s:\workshop'); 62 proc options option=sasautos; 63 run; SASAUTOS=('s:\workshop') Search list for autocall macros

9 9 Adding a Custom Autocall Library 9 The correct way to add an autocall library is to append it to the current search list. Partial SAS Log 94 options sasautos=('s:\workshop' 's:\orion_autocall' sasautos); 95 96 proc options option=sasautos; 97 run; SASAUTOS=('s:\workshop' 's:\orion_autocall' sasautos) Search list for autocall macros

10 10 Chapter 4: Developing Reusable Macros 4.1 Introduction 4.2 Developing Macro Routines 4.3 Developing Macro Functions

11 11 Objectives 11 Create user-defined macro routines. Control when macro variables are created.

12 12 User-Defined Macro Routines After assessing their needs, the Orion Star programmers decided to create macro routines to perform the following tasks: delete global macro variables convert local macro variable values to uppercase create a list of character values create a list of data set names 12

13 13 Deleting Global Macro Variables 13 The DELVARS autocall macro will delete all global macro variables. delvars %macro delvars; data temp; set sashelp.vmacro; where scope='GLOBAL'; run; data _null_; set temp; call symdel(name); run; %mend delvars;

14 14 Uppercasing Local Macro Variable Values 14 The Orion Star programmers want to replace the multiple %LET statements with a macro routine to uppercase all local macro variable values. %macro printlst(country=AU,gender=F,type=CLUB); %let country=%upcase(&country); %let gender=%upcase(&gender); %let type=%upcase(&type); 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; %mend printlst; %printlst(country=ca,gender=m,type=med)

15 15 Uppercasing Local Macro Variable Values 15 Using available metadata, the UPVALUE autocall macro will uppercase all local macro variable values. %macro upvalue; data _null_; set sashelp.vmacro; where scope not in ('GLOBAL', 'AUTOMATIC'); call symputx(name,upcase(value)); run; %mend upvalue; upvalue

16 16 Uppercasing Local Macro Variable Values 16 The UPVALUE autocall macro is used by the PRINTLST macro to convert all parameter values to uppercase. %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; %mend printlst; %printlst(country=ca,gender=m,type=med) m204d01

17 17 Uppercasing Local Macro Variable Values 17 Partial SAS Log 83 %printlst(country=ca,gender=m,type=med) NOTE: There were 3 observations read from the data set SASHELP.VMACRO. WHERE scope not in ('AUTOMATIC', 'GLOBAL'); NOTE: DATA statement used (Total process time): real time 0.01 seconds cpu time 0.03 seconds NOTE: There were 3 observations read from the data set ORION.CUSTOMER_DIM. WHERE (Customer_Country='CA') and (Customer_Gender='M') and UPCASE(Customer_Type) contains 'MED'; m204d01

18 18 Generating a Dynamic List of Values 18 With data constantly changing, the Orion Star programmers find that they spend time maintaining a valid list of values for the IN operator. %macro baddata(dsn); %upvalue proc print data=&dsn; where Customer_Country not in ("AU" "CA" "DE" "IL" "TR" "US" "ZA"); title "Observations with Invalid Customer_Country Values"; run; title; %mend baddata;

19 19 Generating a Dynamic List of Values 19 The CHARLIST autocall macro was created to generate a macro variable whose value is a quoted, data-dependent list. charlist %macro charlist(lookupdsn, lookupvar); %local j; data _null_; set &lookupdsn end=final; call symputx(cats("&lookupvar",_n_), quote(&lookupvar),'L'); if final=1 then call symputx('n', _n_,'L'); run; %do j= 1 %to &n; %let clist=&clist &&&lookupvar&j; %end; %mend charlist;

20 20 Generating a Dynamic List of Values 20 charlist %macro charlist(lookupdsn, lookupvar); %local j; data _null_; set &lookupdsn end=final; call symputx(cats("&lookupvar",_n_), quote(&lookupvar),'L'); if final=1 then call symputx('n', _n_,'L'); run; %do j= 1 %to &n; %let clist=&clist &&&lookupvar&j; %end; %mend charlist; The DATA step generates the following macro variables: CUSTOMER_COUNTRY1 "AU" CUSTOMER_COUNTRY2 "CA" CUSTOMER_COUNTRY3 "DE" CUSTOMER_ COUNTRY4 "IL" CUSTOMER_ COUNTRY5 "TR" CUSTOMER_ COUNTRY6 "US" CUSTOMER_ COUNTRY7 "ZA" N 7

21 21 Generating a Dynamic List of Values 21 charlist %macro charlist(lookupdsn, lookupvar); %local j; data _null_; set &lookupdsn end=final; call symputx(cats("&lookupvar",_n_), quote(&lookupvar),'L'); if final=1 then call symputx('n', _n_,'L'); run; %do j= 1 %to &n; %let clist=&clist &&&lookupvar&j; %end; %mend charlist; The %DO loop generates the following macro variable: CLIST "AU" "CA" "DE" "IL" "TR" "US" "ZA"

22 22 Three ampersands are required when the value of one macro variable matches the entire name of a second macro variable. Partial Symbol Table 22 Triple Ampersand Resolution reference 1st scan &&&lookupvar&j &customer_country1 "AU" 2nd scan VariableValue J1 LOOKUPVARCustomer _Country CUSTOMER_COUNTRY1"AU" CUSTOMER_COUNTRY2"CA"

23 23

24 24 4.01 Quiz 1.Open the program m204a01. 2.Replace the question marks with a macro call to the CHARLIST autocall macro to create the macro variable CLIST. 24 m204a01 %macro baddata(dsn,lookupdsn,lookupvar); %local clist; ??????? %upvalue proc print data=&dsn; where &lookupvar not in(&clist); title "Observations with Invalid &lookupvar Values"; run; title; %mend baddata; %baddata(orion.invalid_customer_dim, orion.country_lookup, customer_country)

25 25 4.01 Quiz – Correct Answer 1.Open the program m204a01. 2.Replace the question marks with a macro call to the CHARLIST autocall macro to create the macro variable CLIST. 25 m204a01 %macro baddata(dsn,lookupdsn,lookupvar); %local clist; %charlist(&lookupdsn,&lookupvar) %upvalue proc print data=&dsn; where &lookupvar not in(&clist); title "Observations with Invalid &lookupvar Values"; run; title; %mend baddata; %baddata(orion.invalid_customer_dim, orion.country_lookup, customer_country)

26 26 4.01 Quiz i – Log 26 594 %baddata(orion.invalid_customer_dim,orion.country_lookup, customer_country) NOTE: There were 7 observations read from the data set ORION.COUNTRY_LOOKUP. NOTE: There were 4 observations read from the data set SASHELP.VMACRO. WHERE scope not in ('AUTOMATIC', 'GLOBAL'); NOTE: There were 5 observations read from the data set ORION.INVALID_CUSTOMER_DIM. WHERE CUSTOMER_COUNTRY not in ('AU', 'CA', 'DE', 'IL', 'TR', 'US', 'ZA'); m204a01

27 27 4.01 Quiz i – Output 27 m204a01 Observations with Invalid CUSTOMER_COUNTRY Values Customer_ Customer_ Customer_ Customer_ Customer_ Customer_ Obs Customer_ID Country Gender Customer_Name FirstName LastName BirthDate Age_Group 4 10 UZ F Karen Ballinger Karen Ballinger 18OCT1984 15-30 years 7 13 DR M Markus Sepke Markus Sepke 21JUL1988 15-30 years 12 20 ZZ M Michael Dineley Michael Dineley 17APR1959 46-60 years 50 1033 TT M Selim Okay Selim Okay 14OCT1979 15-30 years 63 19444 II M Avinoam Zweig Avinoam Zweig 28SEP1959 46-60 years Customer_ Obs Customer_Type Customer_Group Age 4 Orion Club members high activity Orion Club members 23 7 Orion Club Gold members low activity Orion Club Gold members 19 12 Orion Club members medium activity Orion Club members 48 50 Orion Club members low activity Orion Club members 28 63 Orion Club members high activity Orion Club members 48

28 28 Testing the Existence of a Macro Variable 28 When macro applications need to share or reuse macro variables, it is best to create them once in the global symbol table instead of rebuilding them in every application. The %SYMEXIST function first searches any local symbol tables and then searches the global symbol table for the macro variable. General form of the %SYMEXIST function: The %SYMEXIST function returns a value of 1 if the macro variable is found or a 0 if it is not found. %SYMEXIST(macro-variable-name)

29 29 Generating Macro Variables when Needed This demonstration illustrates conditionally executing the DSNLIST autocall macro in the PRINTALL and BACKUP macros. 29 m204d02

30 30 Exercise This exercise reinforces the concepts discussed previously. 30

31 31 Chapter 4: Developing Reusable Macros 4.1 Introduction 4.2 Developing Macro Routines 4.3 Developing Macro Functions

32 32 Objectives 32 Implement DATA step function equivalents as macros. Implement operators not supported by the macro facility.

33 33 User-Defined Macro Functions To simplify coding, the Orion Star programmers want to define macros that will act as macro functions to perform the following tasks: return the current date check the existence of a data set validate whether a string is a valid SAS name extract a data set attribute calculate the age of a data set 33

34 34 User-Defined Macro Functions 1. Define a macro with the same name as the DATA step function, if possible. 2. Create macro parameters that mirror the function arguments. In addition, you can modify how the macro interprets its arguments to customize its behavior. 3. Invoke the DATA step function using %SYSFUNC. 4. Save the macro as an autocall macro. 5. Call the macro the same way as a macro function. 34 Use these five steps to create a macro equivalent for a DATA step function:

35 35 Macro Version of the TODAY Function Create a macro version of the TODAY function, and format the results with the DATE9. format. 35 today %macro today; %sysfunc(today(), date9.) %mend today; Notice the lack of a semicolon.

36 36 Macro Version of the TODAY Function The Orion Star programmers will use the TODAY autocall macro to append today’s date to the end of a data set name. 36 %macro bckdsn(dsn); %local memname rename; %let dsn=%upcase(&dsn); %let memname=%scan(&dsn,-1,.); %let rename=%sysfunc(rename(&dsn,&memname._%today)); proc import datafile= "s:\workshop\c4\&memname" out=&dsn dbms=excel replace; mixed=yes; run; proc sql; select libname, memname from dictionary.tables where libname="%scan(&dsn,1,.)" and memname like "&memname%"; quit; %mend bckdsn; m204d03

37 37 Macro Version of the TODAY Function Partial SAS Log PROC SQL Output 37 Library Name Member Name ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ ORION DAILY_SALES ORION DAILY_SALES_02NOV2008 1261 %bckdsn(orion.daily_sales) MLOGIC(BCKDSN): Beginning execution. MLOGIC(BCKDSN): Parameter DSN has value orion.daily_sales MLOGIC(BCKDSN): %LOCAL MEMNAME RENAME MLOGIC(BCKDSN): %LET (variable name is DSN) MLOGIC(BCKDSN): %LET (variable name is MEMNAME) MLOGIC(BCKDSN): %LET (variable name is RENAME) MLOGIC(TODAY): Beginning execution. MLOGIC(TODAY): Ending execution. m204d03

38 38 Determining Data Set Existence Whenever a data set name is passed as a parameter value, the Orion Star programmers want to test for the existence of the data set before progressing further in a macro program. They created a macro version of the EXIST function to simplify the macro program. 38 %macro exist(dsn); %sysfunc(exist(&dsn)) %mend exist; exist

39 39 Using the EXIST Autocall Macro This demonstration illustrates using the EXIST autocall macro to determine whether a data set exists. 39 m204d04

40 40 Validating SAS Names Many of Orion Star’s applications import data from an external file and use the filename as the data set name. The programmers found that the filename is not always a valid SAS name. The macro version of the NVALID function determines if the value of PARAM is a valid SAS name. The NVALID function returns a value of 1 if the string is a valid SAS name or 0 if it is not a valid name. 40 nvalid %macro nvalid(param); %sysfunc(nvalid(&param)) %mend nvalid;

41 41 Validating SAS Names The IMPRTXLS macro uses the NVALID autocall macro to determine if an Excel spreadsheet name is a valid data set name. 41 m204d05 %macro imprtxls(file); %local dsn; %let dsn=%scan(&file,-2,.\); %if not %nvalid(&dsn) %then %do; %put WARNING: Excel file name is not a valid SAS name.; %put WARNING- A default data set name of XLSFILE will be created.; %let dsn=xlsfile; %end; proc import datafile="&file" out=&dsn dbms=excel replace; mixed=yes; run; %mend imprtxls;

42 42 Validating SAS Names Partial SAS Log 42 766 %imprtxls(s:\workshop\c4\order fact.xls) WARNING: Excel file name is not a valid SAS name. A default data set name of XLSFILE will be created. NOTE: Data source is connected in READ ONLY mode. NOTE: WORK.XLSFILE data set was successfully created. NOTE: PROCEDURE IMPORT used (Total process time): real time 0.20 seconds cpu time 0.12 seconds 767 %imprtxls(s:\workshop\c4\daily_sales.xls) NOTE: Data source is connected in READ ONLY mode. NOTE: WORK.DAILY_SALES data set was successfully created. NOTE: PROCEDURE IMPORT used (Total process time): real time 0.17 seconds cpu time 0.12 seconds m204d05

43 43 Simplifying the Use of SAS File I/O Functions The Orion Star programmers see an increased use of the SAS File I/O functions to extract data set attributes. 43 %let dsid=%sysfunc(open(orion.daily_sales)); %let nobs=%sysfunc(attrn(&dsid,nlobs)); %let dsidc=%sysfunc(close(&dsid)); options nodate nonumber; proc print data=orion.daily_sales; title "ORION.DAILY_SALES contains "; title2 "&nobs observations"; run;

44 44 Macro Version of the ATTRC Function To simplify programs extracting data set attributes, the Orion Star programmers created a macro version of the ATTRC and ATTRN functions. Both autocall macros will return an attribute’s value. 44 attrc %macro attrc(dsn,attr); %local dsid attrc dsidc; %let dsid=%sysfunc(open(&dsn)); %let attrc=%sysfunc(attrc(&dsid,&attr)); %let dsidc=%sysfunc(close(&dsid)); &attrc %mend attrc;

45 45 Macro Version of the ATTRN Function 45 attrn %macro attrn(dsn,attr); %local dsid attrn dsidc; %let dsid=%sysfunc(open(&dsn)); %let attrn=%sysfunc(attrn(&dsid,&attr)); %let dsidc=%sysfunc(close(&dsid)); &attrn %mend attrn;

46 46

47 47 4.02 Quiz 1.Open the program m204a02. 2.Replace the question marks with the ATTRN autocall macro to extract the logical number of observations in a data set. 47 m204a02 options nodate nonumber; proc print data=orion.daily_sales; title "ORION.DAILY_SALES contains "; title2 "?????????? observations"; run;

48 48 4.02 Quiz – Correct Answer 1.Open the program m204a02. 2.Replace the question marks with the ATTRN autocall macro to extract the logical number of observations in a data set. 48 m204a02 options nodate nonumber; proc print data=orion.daily_sales; title "ORION.DAILY_SALES contains "; title2 "%attrn(orion.daily_sales, nlobs) observations"; run; 1.Open the program m204a02. 2.Replace the question marks with the ATTRN autocall macro to extract the logical number of observations in a data set.

49 49 4.02 Quiz i – Output 49 ORION.DAILY_SALES contains 58 observations Obs Product_ID Product_Name Total_Retail_Price 1 220200200024 Pro Fit Gel Gt 2030 Women's Running Shoes $178.50 2 220200100092 Big Guy Men's Air Terra Sebec Shoes $83.00 3 240200100043 Bretagne Performance Tg Men's Golf Shoes L. $282.40 4 220100700024 Armadillo Road Dmx Women's Running Shoes $99.70 5 220200300157 Hardcore Men's Street Shoes Large $220.20 6 240200100051 Bretagne Stabilites 2000 Goretex Shoes $420.90 7 220200100035 Big Guy Men's Air Deschutz Viii Shoes $125.20 8 220200100090 Big Guy Men's Air Terra Reach Shoes $177.20 9 220200200018 Lulu Men's Street Shoes $132.80 10 240200100052 Bretagne Stabilities Tg Men's Golf Shoes $99.70 11 220100700052 Trooper Ii Dmx-2x Men's Walking Shoes $106.10 12 220200300116 South Peak Men's Running Shoes $84.20 13 240100100433 Shoelace White 150 Cm $3.00 14 220200300079 Hilly Women's Crosstrainer Shoes $128.60 15 240200100052 Bretagne Stabilities Tg Men's Golf Shoes $199.40 16 240200100226 Rubby Men's Golf Shoes w/Goretex Plain Toe $183.90 17 220200200071 Twain Men's Exit Low 2000 Street Shoes $200.20 18 220100700042 Power Women's Dmx Wide, Walking Shoes $171.20 19 210200400020 Kids Baby Edge Max Shoes $38.00 20 210200400070 Tony's Children's Deschutz (Bg) Shoes $41.60

50 50 Determining the Age of a SAS Data Set Many of Orion Star’s applications require determining the age of a data set. The programmers want to replace complex code with a single macro call. 50 age %macro age(dsn); %local dsid crdate dsidc days; %let dsid=%sysfunc(open(&dsn)); %let crdate=%sysfunc(attrn(&dsid,crdte)); %let dsidc=%sysfunc(close(&dsid)); %let days=%sysevalf("%today"d -%sysfunc(datepart(&crdate))); &days %mend age;

51 51 Using the AGE Macro This demonstration illustrates using the AGE autocall macro to determine whether a data set needs to be refreshed. 51 m204d06

52 52 User-Defined Macro Operators Operators in macro expressions are a subset of those in the DATA step. The macro facility does not recognize the IN operator in releases prior to SAS 9.2 the BETWEEN operator the colon (:) modifier. Macros can be written to simulate the functionality of these operators, producing a Boolean result. 52

53 53 The User-Defined FIND Operator Orion Star is still running SAS 9.1 on some servers and created the FIND macro as an alternative to the IN operator to simplify %IF logic. 53 m204d07 %macro grplist(type); %if %find(GOLD INTERNET,&type)=0 %then %do; %put ERROR: Value of TYPE: &type is not valid.; %put ERROR- Valid values are INTERNET or GOLD; %return; %end; %let type=%upcase(&type); 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; %mend grplist;

54 54 The User-Defined FIND Operator The FIND macro uses the INDEXW function to search a character expression for a string that is specified as a word. Although the INDEXW function returns the position of the first character in the word, the FIND macro returns a 1 if the value is found or a 0 if it is not. 54 find %macro find(source,string); %let source=%upcase(&source); %let string=%upcase(&string); %if %sysfunc(indexw(&source,&string))>0 %then 1; %else 0; %mend find;

55 55 The User-Defined FIND Operator The GRPLIST macro uses the FIND autocall macro to check the value of the parameter TYPE. 55 m204d07 %macro grplist(type); %if %find(GOLD INTERNET,&type)=0 %then %do; %put ERROR: Value of TYPE: &type is not valid.; %put ERROR- Valid values are INTERNET or GOLD; %return; %end; %let type=%upcase(&type); 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; %mend grplist;

56 56 The User-Defined FIND Operator Partial SAS Log 56 151 %grplist(silver) MPRINT(GRPLIST): options nomlogic; ERROR: Value of TYPE: silver is not valid. Valid values are INTERNET or GOLD 152 %grplist(Internet) MPRINT(GRPLIST): proc print data=orion.customer_dim; MPRINT(GRPLIST): var Customer_Group Customer_Name Customer_Gender Customer_Age; MPRINT(GRPLIST): where upcase(Customer_Group) contains "INTERNET"; MPRINT(GRPLIST): title "INTERNET Customers"; MPRINT(GRPLIST): run; NOTE: There were 8 observations read from the data set ORION.CUSTOMER_DIM. WHERE UPCASE(Customer_Group) contains 'INTERNET'; NOTE: PROCEDURE PRINT used (Total process time): real time 0.01 seconds cpu time 0.03 seconds m204d07

57 57 Creating a Macro Version of the BETWEEN Operator To simplify %IF statement logic, the Orion Star programmers created a macro version of the BETWEEN operator to check a range of values. 57 %macro between(var,low,high); %sysevalf(&var >= &low and &var <= &high) %mend between; between

58 58 Creating a Macro Version of the BETWEEN Operator The BETWEEN autocall macro made parameter validation easier to maintain for the Orion Star programmers. 58 %macro monorder(month, year); %if not(%between(&month,1,12)) or not(%between(&year,2003,2007)) %then %do; %put ERROR: Month is not between 1 and 12 or; %put ERROR- Year is not between 2003 and 2007.; %put ERROR- The macro will stop executing.; %return; %end; data monthorders; set orion.order_fact; where month(Order_Date)=&month and year(Order_Date)=&year; DaysToShip=Delivery_Date-Order_Date; run; proc print data=monthorders; var Order_ID Order_Date Delivery_Date DaysToShip; title "Orders for &month/&year"; run; title; %mend monorder; m204d08

59 59 Creating a Macro Version of the BETWEEN Operator Partial SAS Log 59 693 %monorder(1,2007) NOTE: There were 13 observations read from the data set ORION.ORDER_FACT. WHERE (MONTH(Order_Date)=1) and (YEAR(Order_Date)=2007); NOTE: The data set WORK.MONTHORDERS has 13 observations and 13 variables. NOTE: DATA statement used (Total process time): real time 0.00 seconds cpu time 0.00 seconds NOTE: There were 13 observations read from the data set WORK.MONTHORDERS. NOTE: PROCEDURE PRINT used (Total process time): real time 0.00 seconds cpu time 0.00 seconds 694 %monorder(13,2007) ERROR: Month is not between 1 and 12 or Year is not between 2003 and 2007. The macro will stop executing. m204d08

60 60 Creating a Macro Version of the =: Operator (Self-Study) The =: operator allows for comparison on a specified prefix of a character string. 60 %macro starts(string,search,case); %if %upcase(&case)=N or &case= %then %do; %let string=%upcase(&string); %let search=%upcase(&search); %end; %if %substr(&string,1,%length(&search))= &search %then 1; %else 0; %mend starts; starts

61 61 Creating a Macro Version of the =: Operator (Self-Study) Partial SAS Log 61 %macro saleslst(jobtitle); 402 %if %starts(&jobtitle,SALES,N) %then %do; 403 proc print data=orion.sales; 404 where Job_Title="&jobtitle"; 405 format Birth_Date Hire_Date mmddyy10.; 406 run; 407 %end; 408 %else 409 %put ERROR: Job Title must start with SALES.; 410 %mend saleslst; 411 %saleslst(Sales Rep. I) NOTE: There were 63 observations read from the data set ORION.SALES. WHERE Job_Title='Sales Rep. I'; NOTE: PROCEDURE PRINT used (Total process time): 412 %saleslst(Manager) ERROR: Job Title must start with SALES. m204d09

62 62 Exercise This exercise reinforces the concepts discussed previously. 62


Download ppt "11 Chapter 4: Developing Reusable Macros 4.1 Introduction 4.2 Developing Macro Routines 4.3 Developing Macro Functions."

Similar presentations


Ads by Google