ERROR: Expected close parenthesis after macro function invocation not found.

Reply
Occasional Contributor
Posts: 8

ERROR: Expected close parenthesis after macro function invocation not found.

[ Edited ]

I am using below code to seperate ady variable , but it gives me error ' Expected close parenthesis after macro function invocation not found.' i have tried using compress and tranwrd function. but it says the same thing.

 

options mlogic mprint symbolgen;
%MACRO VLIST(in= , col = ,typ= );


data vlist;
length col0001 $1000;
set &in.;


%if &typ. = DD %then %let n1 = %sysfunc(countw("&col.",'('));
%put &n1.;


array ddjoin(*) $ var1 - var&n1.;
%do i = 1 %to &n1.;


%if &i eq 1 %then ddjoin(&i.) = %sysfunc(scan(&col.,&i.,'('));

%if &i ne 1 %then ddjoin(&i.) = %sysfunc(scan( %sysfunc(scan(&col.,&i.,'(')), %eval(&i.-1),')'));

 

%end;


if cmiss(var1,var2) = 0 then col0001 = strip(var1) || '(' || strip(var2) || ')';

 

run;

 

%MEND VLIST;

%vlist(in=b, col = adt(ady), typ = DD );

Trusted Advisor
Posts: 1,785

Re: ERROR: Expected close parenthesis after macro function invocation not found.

Check this line - you miss ')' at end of it

%if &typ. = DD %then %let n1 = %sysfunc(countw("&col.",'('));

Occasional Contributor
Posts: 8

Re: ERROR: Expected close parenthesis after macro function invocation not found.

This line is fine. it has 2 open brackets and 2 close brackets.

 

%if &i ne 1 %then ddjoin(&i.) = %sysfunc(scan( %sysfunc(scan(&col.,&i.,'(')), %eval(&i.-1),')'));

 

This is the line,that is throwing the error.

it has same number of open and close brackets, i have also tried replacing brackets in input with some other symbol. but issue remains same.

Super User
Posts: 9,369

Re: ERROR: Expected close parenthesis after macro function invocation not found.

Why are you using brackets as separators in a string? Go back to the place where the string is created, and use a separator that makes sense.

Or replace the dumb brackets with something else in a data step before you invoke the macro.

---------------------------------------------------------------------------------------------
Maxims of Maximally Efficient SAS Programmers
How to convert datasets to data steps
How to post code
Highlighted
Occasional Contributor
Posts: 8

Re: ERROR: Expected close parenthesis after macro function invocation not found.

Posted in reply to KurtBremser

i have also tried replacing brackets in input with some other symbol. but issue remains same.

Super User
Posts: 9,369

Re: ERROR: Expected close parenthesis after macro function invocation not found.

The best separator for variable names is the blank, as blanks are not valid in SAS names anyway.

So see this example for how it works:

%let varstr=adt adg;

%macro teststring(col=);
%do i = 1 %to %sysfunc(countw(&col));
  %let var = %scan(&col,&i);
  %put var=&var;
%end;
%mend;
%teststring(col=&varstr);
---------------------------------------------------------------------------------------------
Maxims of Maximally Efficient SAS Programmers
How to convert datasets to data steps
How to post code
Super Contributor
Posts: 498

Re: ERROR: Expected close parenthesis after macro function invocation not found.

Seems to be usage of macro statements where normal data-step-statements are required. If you need the scan-function in the macro-world, use %scan and don't use quotes when passing strings to macros.

 


@sas_user wrote:

I am using below code to seperate ady variable , but it gives me error ' Expected close parenthesis after macro function invocation not found.' i have tried using compress and tranwrd function. but it says the same thing.

 

options mlogic mprint symbolgen;
%MACRO VLIST(in= , col = ,typ= );


data vlist;
length col0001 $1000;
set &in.;


%if &typ. = DD %then %let n1 = %sysfunc(countw("&col.",'('));
%put &n1.;


array ddjoin(*) $ var1 - var&n1.;
%do i = 1 %to &n1.;


%if &i eq 1 %then ddjoin(&i.) = %sysfunc(scan(&col.,&i.,'('));

%if &i ne 1 %then ddjoin(&i.) = %sysfunc(scan( %sysfunc(scan(&col.,&i.,'(')), %eval(&i.-1),')'));

 

%end;


if cmiss(var1,var2) = 0 then col0001 = strip(var1) || '(' || strip(var2) || ')';

 

run;

 

%MEND VLIST;

%vlist(in=b, col = adt(ady), typ = DD );


 

Occasional Contributor
Posts: 8

Re: ERROR: Expected close parenthesis after macro function invocation not found.

[ Edited ]
Posted in reply to andreas_lds

I tried using like this:

 

%if &i eq 1 %then ddjoin(&i.) = %scan(&col.,&i.,'(');
%if &i ne 1 %then ddjoin(&i.) = %scan(%scan(&col.,&i.,'('), 1, ')');

 

 

This is the log:

 

NOTE: Line generated by the invoked macro "VLIST".
7 ddjoin(&i.) = %scan(%scan(&col.,&i.,'('), 1, ')')
------
22
SYMBOLGEN: Macro variable COL resolves to aphase(aperstdy)
SYMBOLGEN: Macro variable I resolves to 2
ERROR: Macro function %SCAN has too few arguments.
NOTE: Line generated by the invoked macro "VLIST".
7 ddjoin(&i.) = %scan(%scan(&col.,&i.,'('), 1, ')')
-
390
ERROR 22-322: Syntax error, expecting one of the following: !, !!, &, (, *, **, +, -, /, ;, <, <=, <>, =, >, ><, >=, AND, EQ, GE, GT, LE,
LT, MAX, MIN, NE, NG, NL, OR, [, ^=, {, |, ||, ~=.

ERROR 390-185: Expecting an relational or arithmetic operator.

MLOGIC(VLIST): %DO loop index variable I is now 3; loop will not iterate again.
NOTE: Line generated by the invoked macro "VLIST".
7 ddjoin(&i.) = %scan(%scan(&col.,&i.,'('), 1, ')')
-
200
ERROR 200-322: The symbol is not recognized and will be ignored.

MPRINT(VLIST): ddjoin(1) = aphase ddjoin(2 ) = , 1, ')') ;
MPRINT(VLIST): run;

NOTE: Character values have been converted to numeric values at the places given by: (Line)Smiley SadColumn).
1:3 7:2 7:47
NOTE: Numeric values have been converted to character values at the places given by: (Line)Smiley SadColumn).
5:2
NOTE: The SAS System stopped processing this step because of errors.

Super User
Super User
Posts: 9,024

Re: ERROR: Expected close parenthesis after macro function invocation not found.

What is it your actually trying to do here?  It looks to me like you have created a very complicated way of doing something very simple.  Provide some test data and show what you want out, and will give a simple datastep example of how to do it.  

Occasional Contributor
Posts: 8

Re: ERROR: Expected close parenthesis after macro function invocation not found.

I am trying to create a macro here, that will create a listing dataset. in my data i have a column to present date and day in date(day) format.

I want my user to just give variable names in the format he wants in the output. so that he do not have to pass so many parameters to tell macro what kind of join it wants, but the macro finds it out itself.

so if my user is passing col = adt(ady), i want my macro to separate both variables and join them in adt(ady) format.

I hope it helps.

 

Super User
Posts: 6,413

Re: ERROR: Expected close parenthesis after macro function invocation not found.

I agree with @RW9 that you are making this an extremely difficult problem and there has to be an easy way.  Look at these lines from your code:


%if &i eq 1 %then ddjoin(&i.) = %sysfunc(scan(&col.,&i.,'('));

%if &i ne 1 %then ddjoin(&i.) = %sysfunc(scan( %sysfunc(scan(&col.,&i.,'(')), %eval(&i.-1),')'));

 

Without any errors, these would generate:

 

ddjoin(1) = adt

ddjoin(2) = ady

 

Surely these are not the statements you want to appear in your DATA step.  At a minimum you would want a semicolon ending those statements, and you might want quotes around the values being assigned.

 

Give an example of what the desired output would look like.  There is almost certainly an easy way to get there.

Occasional Contributor
Posts: 8

Re: ERROR: Expected close parenthesis after macro function invocation not found.

[ Edited ]
Posted in reply to Astounding

I am trying to create a macro here, that will create a listing dataset. in my data i have a column to present date and day in date(day) format.

I want my user to just give variable names in the format he wants in the output. so that he do not have to pass so many parameters to tell macro what kind of join it wants, but the macro finds it out itself.

so if my user is passing col = adt(ady), i want my macro to separate both variables and join them in adt(ady) format.

 

 

ddjoin(1) = adt

ddjoin(2) = ady

 

this is exactly what i want. but it is throwing errors for ddjoin(2).

so once both are seperated, it can be joined as:

if cmiss(var1,var2) = 0 then col0001 = strip(var1) || '(' || strip(var2) || ')';

 

I hope it helps.

Super User
Super User
Posts: 9,024

Re: ERROR: Expected close parenthesis after macro function invocation not found.

Nope you lost me.  You keep talking about a join, are you merging data?  Or is it to create a concatenated variable from two variables?  If its this, I don't how this macro will actually benefit you.  A simple cats() will take strings, or convert numbers implicitly, again making checking types irrelevant.  It is one of the big failings with macro language as used in that it adds extra layers of complexity, reduces functionality, and is mainly undocumented appropriately.  You creating code to do something very specific, which doesn't actually need to be done , you have posted the code you should yourself, with a minor change:

if cmiss(var1,var2)=0 then col0001=cats(var1,'(',var2,')');

Generating loads of macro around that will not add anything to that code, and will cost you many hours in build, test, documentation, and support to implement.

Ask a Question
Discussion stats
  • 12 replies
  • 164 views
  • 0 likes
  • 6 in conversation