BookmarkSubscribeRSS Feed
sas_user
Calcite | Level 5

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 );

12 REPLIES 12
Shmuel
Garnet | Level 18

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

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

sas_user
Calcite | Level 5

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.

Kurt_Bremser
Super User

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.

sas_user
Calcite | Level 5

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

Kurt_Bremser
Super User

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);
andreas_lds
Jade | Level 19

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 );


 

sas_user
Calcite | Level 5

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):(Column).
1:3 7:2 7:47
NOTE: Numeric values have been converted to character values at the places given by: (Line):(Column).
5:2
NOTE: The SAS System stopped processing this step because of errors.

RW9
Diamond | Level 26 RW9
Diamond | Level 26

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.  

sas_user
Calcite | Level 5

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.

 

Astounding
PROC Star

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.

sas_user
Calcite | Level 5

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.

RW9
Diamond | Level 26 RW9
Diamond | Level 26

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.

sas-innovate-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

Register now!

How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

Find more tutorials on the SAS Users YouTube channel.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 12 replies
  • 3006 views
  • 0 likes
  • 6 in conversation