- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
%macro change_date_format(&Date_1=);
%let Date_1=&date_process.;
format &Date_1._New date9.;
&Date_1._New=mdy(substr(&Date_1.,1,2),substr(&Date_1.,4,2),substr(&Date_1.,7,4));
Drop &Date_1.;
%mend;
DATA CMI_Repository_2;
SET pdata.CMI_Repository_1;
%change_date_format(BM_LaunchInitialDate2);
run;
showing error:
ERROR: More positional parameters found than defined.
how should i write this.
Accepted Solutions
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
First off you used a macro variable in the macro definition for the parameter and defined it as a KEYWORD parameter. Keyword parameters must be used with the = in the actual macro call:
%macro dummy(keyword=);
definition requires use as
%dummy(keyword= some value);
when you use
%dummy(somevalue); then the parameter is assumed to be positional, meaning the first encountered value is the value for the first parameter in the definition. You did not define any positional parameters so that is the cause of the error.
However without knowing the value &date_1 at the time you compiled the macro we do not even know the proper name of the macro variable to use.
Where does the value from &date_process come from?
If the purpose of this macro is to create a new variable as a SAS date value from a string variable that has a content like 03212018 then perhaps
%macro change_date_format(datestringvar); &datestringvar.new = input(&datestringvar,mmddyy8.); format &datestringvar.new date9.; %mend;
Then the call you used would be correct.
Note: automatically adding the same string to an existing variable name to an existing variable may have issues with the new variable name if you have some variable names that approach the 32 character limit. Example:
date_for_processing_sales_report is already 32 characters long. Adding "new" to the end would exceed the length of a valid variable.
An exercise for the interested reader is the test the result of &datestringvar.new as a valid variable name and making and adjustment if too long.
Also note the use of an INFORMAT specifically designed to read dates in mmddyy format like 03212018. This informat will also read "032118", "03 21 18" or "03/21/18" as March 21, 2018.
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
If you are going to write macros, you absolutely must understand these topics:
- What is a positional parameter
- What is a keyword parameter
- How do you call a macro that has been defined with positional parameters
- How do you call a macro that has been defined with keyword parameters
Those are things you need to find in the documentation, and study.
Secondarily, your code (once it is working) would apply SUBSTR to a variable named BM_LaunchInitialDate2. I would hope that this is a character variable, since SUBSTR works on character strings only.
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
You can't call macros like that from a data step.
What are you trying to build a macro to do, that seems complicated.
This is what your macro should try to do:
date_new = input(date_old, mmddyy10.);
format date_new date9.;
So maybe:
%macro change_date_format(Date_1=);
&Date_1._New=input(&date_1, mmddyy10.);
format &Date_1._New date9.;
Drop &Date_1.;
%mend;
And then:
data cmi_repository;
set ..;
%change_date_format(date_1=bm_launchInitalDate2);
run;
Untested...
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
Hello,
There are several problems in your code.
%macro change_date_format(Date_1);
format &Date_1._New date9.;
&Date_1._New=input(&Date_1.,mmddyy10.);
drop &Date_1.;
%mend;
Also, you don't really need a macro here.
DATA CMI_Repository_2;
SET pdata.CMI_Repository_1;
format date1_new date2_new ... date9.;
date_1_new=input(date_1,mmddyy10.);
date2_new=...;
...
drop date1 date2 ...;
run;
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
I want to use this macro whenever I find similar situations. and my date is text hence I need to do this.
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
Since the creation of the new variable is just one line of code, there is no nessity to create a macro as it obfuscates the code by requiring the maintener to find the macro code to see exactly what is done.
Both other instruction for format definition and dropping can be factored over all variables you want to recode.
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
First off you used a macro variable in the macro definition for the parameter and defined it as a KEYWORD parameter. Keyword parameters must be used with the = in the actual macro call:
%macro dummy(keyword=);
definition requires use as
%dummy(keyword= some value);
when you use
%dummy(somevalue); then the parameter is assumed to be positional, meaning the first encountered value is the value for the first parameter in the definition. You did not define any positional parameters so that is the cause of the error.
However without knowing the value &date_1 at the time you compiled the macro we do not even know the proper name of the macro variable to use.
Where does the value from &date_process come from?
If the purpose of this macro is to create a new variable as a SAS date value from a string variable that has a content like 03212018 then perhaps
%macro change_date_format(datestringvar); &datestringvar.new = input(&datestringvar,mmddyy8.); format &datestringvar.new date9.; %mend;
Then the call you used would be correct.
Note: automatically adding the same string to an existing variable name to an existing variable may have issues with the new variable name if you have some variable names that approach the 32 character limit. Example:
date_for_processing_sales_report is already 32 characters long. Adding "new" to the end would exceed the length of a valid variable.
An exercise for the interested reader is the test the result of &datestringvar.new as a valid variable name and making and adjustment if too long.
Also note the use of an INFORMAT specifically designed to read dates in mmddyy format like 03212018. This informat will also read "032118", "03 21 18" or "03/21/18" as March 21, 2018.