BookmarkSubscribeRSS Feed
jerrylshen
Obsidian | Level 7

Hi, I'm getting a " Literal Contains Unmatched Quote" with my array/list, I think:  

 

ERROR LOG:  

ERROR: Literal contains unmatched quote.
ERROR: The macro PREP_TABLE will stop executing.

The lists:

%let not_done_list = SALTND PEPPERND;
%let col_list =  SODIUM PEPPER;

%let query_list= 
'"Not Done" is marked, however, the result of Passing is provided, please correct.' 
'"Not Done" is marked, however, the result of Passing is provided, please correct.';

 

I'm passing this list to a macro that iterates through this list being called through %prep_table(...):  

%macro prep_table(notdone, col, query);
%local item;
%do item=1 %to %sysfunc(countw(&notdone));
	%let notdone=%scan(&not_done_list,&item);
   	%let col=%scan(&col_list,&item);
	%let query=%scan(&query_list,&item);

	%create_table(notdone=&notdone, col=&col, query=&query)
%end;
%mend prep_table;

%prep_table(notdone=&not_done_list, col=&col_list, query=&query_list);

 

The %create_table thing:

%macro create_table(notdone, col, query);

proc sql noprint;
CREATE TABLE t1 AS 
SELECT DISTINCT &query, Subject, &notdone, &col
FROM chem
GROUP BY Subject
HAVING ((col^="" or col="No") and col2^="") OR ((col="" or col="Yes") and col2="")
;
quit;

%mend create_table;

 

I tried the thing here (https://stackoverflow.com/questions/5944628/unmatched-quotation-mark-issue-in-sas) but still same error

%let query_list= %str(%"Not Done%" is marked, however, the result of Passing is provided, please correct.);

How do I have list in SAS where each item also has quotes?  
The structure of the code is based on the solution comment: https://communities.sas.com/t5/SAS-Enterprise-Guide/Macro-iteration-on-two-variables/td-p/393804

 

Thanks

 

EDIT: updated with more code

 

EDIT EDIT: Ok, thanks to the comments, I realized that my program has issues elsewhere as well. So, I'm currently sorting it out and seeing if I can fix. Thanks  

  

 

7 REPLIES 7
Quentin
Super User

Can you provide a (simplified) version of %prep_table  which illustrates the error?  

 

The answer will likely depend in part on how you are iterating through the list.  

The Boston Area SAS Users Group (BASUG) is hosting our in person SAS Blowout on Oct 18!
This full-day event in Cambridge, Mass features four presenters from SAS, presenting on a range of SAS 9 programming topics. Pre-registration by Oct 15 is required.
Full details and registration info at https://www.basug.org/events.
jerrylshen
Obsidian | Level 7

Hi, I updated the post with more code. The shown code is essentially the whole program, but a bit simplified.  

Thanks

ballardw
Super User

Run the code with Options Mprint=on;

Show use the log results from running the code.

You show none of the actual macro definition. So we really can't tell where the issue occurs. It may well be happening somewhere other than where you expect.

One thing, Commas inside values passed as macro parameters are often problematic and I am not sure that quotes help at all.

 

Note that with this example passing the string to the macro is not a problem.

%macro dummy( str);
%put &str;
%mend;

%let parm='"Not Done" is marked, however, the result of Passing is provided, please correct.' '"Not Done" is marked, however, the result of Passing is provided, please correct.';
%dummy(&parm);

Since you do not show the actual call for your macro then it may be that what ever you are passing for the other parameters is the issue.

Or something else in the body of the macro.

jerrylshen
Obsidian | Level 7

Hi, I updated the post with more code. The shown code is essentially the whole program, but a bit simplified

 

I added "Options Mprint=on;". but the log is the same. 

ERROR: Literal contains unmatched quote.
ERROR: The macro PREP_TABLE will stop executing.

 

Thanks

Quentin
Super User

I'm confused, because your query list looks like it should be a message list.

 

The general problem is that you are parsing that list by word.  But really, there are only two items in the list (each sentence is an item).

 

Can you add a pipe to delimit the items of the list?  

 

Below is an example.  I added a pipe to delimit message_list, and specified that pipe be used as a delimiter for COUNTW() and SCAN().

 

%let not_done_list = SALTND PEPPERND;
%let col_list =  SODIUM PEPPER;

%let message_list= 
 '"Not Done" is marked, however, the result of Passing is provided, please correct.' 
|'"Not Done" is marked, some other message.';

%macro prep_table(notdone_list, col_list, message_list);
%local item notdone col message;
%do item=1 %to %sysfunc(countw(&message_list,|));
  %let notdone=%scan(&notdone_list,&item);
  %let col=%scan(&col_list,&item);
  %let message=%scan(&message_list,&item,|);

  %put &=item &=notdone &=col &=message ;
	
%end;
%mend prep_table;

%prep_table
  (notdone_list=&not_done_list
  ,col_list=&col_list
  ,message_list=&message_list
   )
The Boston Area SAS Users Group (BASUG) is hosting our in person SAS Blowout on Oct 18!
This full-day event in Cambridge, Mass features four presenters from SAS, presenting on a range of SAS 9 programming topics. Pre-registration by Oct 15 is required.
Full details and registration info at https://www.basug.org/events.
ballardw
Super User
%macro prep_table(notdone, col, query);
%local item;
%do item=1 %to %sysfunc(countw(&message_list));
	%let notdone=%scan(&not_done_list,&item);
   	%let col=%scan(&col_list,&item);
	%let query=%scan(&query_list,&item);

	%create_table(notdone=&notdone, col=&col, query=&query)
%end;
%mend prep_table;

%prep_table(notdone=&not_done_list, col=&col_list, query=&query_list);

Still undefined/not example: &Message_list ; the macro createtable.

 

 

I think that you need to specify exactly what you want for the delimiter list and that your resulting values for &query are not what you think.

The issue after some testing is coming from the SPACE inside the "Not Done". Example:

%macro dummy(str);
%put &str.;
%let s1 = %scan(&str.,1);
%let s2 = %scan(&str.,2);

%put S1 is &s1.;
%put S2 is &s2.;

%mend;

%dummy('a' 'list' 'of' 'words');
%dummy('a"b"' 'list' );
%dummy('"b"' 'list' );
%dummy('"b space"' 'list' );

The first three calls to dummy are fine, it is the 4th that generates the error. I don't have a suggestion at this time because I don't write code that passes such parameters and then attempts to parse them with the macro language.

That much text I would be tempted to place in variables in a dataset and perhaps use Call Execute to create the calls.

 

 

While almost all have done it at one time or another, having a macro variable that just "appears" that is set outside of the macro and not provided as a parameter is a very problematic source of problems.

 

Posting the LOG with the MPRINT results may show the context of error message more precisely. I have a sneaking suspicion it is appearing from something you don't expect (because you only provided the things you though caused the error)

You may also need to set the option MPRINTNEST to capture everything from the inner called macro. If you are building more macro variables in that called macro you may need option SYMBOLGEN to see how those bits of code are working.

 

ChrisNZ
Tourmaline | Level 20

You extract bits of string with only one quote. So the quotes are not balanced.

This works (notice the pipe separator):

%let not_done_list = SALTND PEPPERND;
%let col_list      = SODIUM PEPPER;
%let query_list    = '"Not Done" is marked, however, the result of Passing is provided, please correct.'  
                   | '"Not Done" is marked, however, the result of Passing is provided, please correct.' ;

%macro prep_table(notdone, col, query);
  %local item;
  %do item=1 %to %sysfunc(countw(&notdone));
    %let notdone=%scan(&not_done_list, &item.);
    %let col    =%scan(&col_list     , &item.);
    %let query  =%scan(&query_list   , &item., |);
    %create_table(notdone=&notdone, col=&col, query=&query)
  %end;
%mend prep_table;

 

 

SAS Innovate 2025: Call for Content

Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!

Submit your idea!

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
  • 7 replies
  • 3768 views
  • 0 likes
  • 4 in conversation