BookmarkSubscribeRSS Feed
☑ This topic is solved. Need further help from the community? Please sign in and ask a new question.
_Manhattan
Quartz | Level 8

Hey guys,

I am trying to produce a report that generates several tables and stores information out of an excel file. So far my code did what I wanted: It produced three tables that contained all the information in just the right format. Unfortunately, after going from my little example data to the real data I realised that my code does not work if my created macro variable "&frage" contains not just single words but whole sentences. Now I am wondering if I have to find another solution for my report. The working code and excel looks like this (excel "test_skalen_items_v2" attached):

proc import
  datafile="yourpath\test_skalen_items_v2.xlsx"
  out=Skalen_Items
  dbms=xlsx
  replace;
run;

proc sql noprint;
  select distinct Frage into :fragen separated by " "
  from Skalen_Items;
quit;

%macro want;

%do i = 1 %to %sysfunc(countw(&fragen.));
%let frage = %scan(&fragen., &i.);

ods pdf file="yourpath\Table.pdf";
ods pdf startpage=now;


data &frage.(drop=Frage);
	set Skalen_Items(where=(Frage="&frage."));
run;

proc report data=&frage.;
	column Variable Antwortoption;
	define Antwortoption / "&frage.";
	compute Antwortoption;
		if Variable = "Kodierung" then call define(_col_ -1, "style", "style={font_weight=bold}");
	endcomp;
run; 

%end;
ods pdf close;
%mend want;
%want;

And if I use the excel "test_skalen_items_FAIL.xlsx" (also attached) the code does not work anymore. As you can see in the Excel, the column "Frage" does now contain not just the single words (e. g. Frage1) but whole sentences (e. g. Frage zwei jo).

 

To clarify again: Is it possible to create the tables as with my first excel but now with sentences (or: several words with spaces inbetween) or do I have to find a whole other solution for my report? I am thankful for any help!

 

Kind regards

1 ACCEPTED SOLUTION

Accepted Solutions
ballardw
Super User

If you separate values by space and allow Countw to look at that value then the spaces are delimiters. Same with Scan or %scan.

From the documentation of Countw:

If you use the COUNTW function with only two arguments, the default delimiters depend on whether your computer uses ASCII or EBCDIC characters.
  • If your computer uses ASCII characters, then the default delimiters are as follows:
    blank ! $ % & ( ) * + , - . / ; < ^ |
    In ASCII environments that do not contain the ^ character, the SCAN function uses the ~ character instead.
  • If your computer uses EBCDIC characters, then the default delimiters are as follows:
    blank ! $ % & ( ) * + , - . / ; < ¬ | ¢

So you pick a single character that does not appear in the values of your text. You pick. I'm not looking XLSX from unknown sources. Then modify the Countw and Scan to use that character and SEPARATE the values with that character.

proc sql noprint;
  select distinct Frage into :fragen separated by "*"
  from Skalen_Items;
quit;

%macro want;

%do i = 1 %to %sysfunc(countw(&fragen.,*));
%let frage = %scan(&fragen., &i.,*);

 

 

 

 

 

View solution in original post

4 REPLIES 4
ballardw
Super User

If you separate values by space and allow Countw to look at that value then the spaces are delimiters. Same with Scan or %scan.

From the documentation of Countw:

If you use the COUNTW function with only two arguments, the default delimiters depend on whether your computer uses ASCII or EBCDIC characters.
  • If your computer uses ASCII characters, then the default delimiters are as follows:
    blank ! $ % & ( ) * + , - . / ; < ^ |
    In ASCII environments that do not contain the ^ character, the SCAN function uses the ~ character instead.
  • If your computer uses EBCDIC characters, then the default delimiters are as follows:
    blank ! $ % & ( ) * + , - . / ; < ¬ | ¢

So you pick a single character that does not appear in the values of your text. You pick. I'm not looking XLSX from unknown sources. Then modify the Countw and Scan to use that character and SEPARATE the values with that character.

proc sql noprint;
  select distinct Frage into :fragen separated by "*"
  from Skalen_Items;
quit;

%macro want;

%do i = 1 %to %sysfunc(countw(&fragen.,*));
%let frage = %scan(&fragen., &i.,*);

 

 

 

 

 

Tom
Super User Tom
Super User

Also if you add quotes and use the Q option on COUNTW() and SCAN() then it does not matter if the delimiter is part of a value.

 

And if you use single quotes to do the quoting it has the added value of protecting any macro triggers, & or %, that are in the strings.

proc sql noprint;
select distinct quote(trim(Frage),"'") into :fragen separated by "*"
  from Skalen_Items
;
quit;

....


%do i = 1 %to %sysfunc(countw(&fragen.,*,q));
  %let frage = %scan(&fragen., &i.,*,q);
  ...
%end;

If you need to remove the quotes use the DEQUOTE() function.

  %let frage = %qsysfunc(dequote(%scan(&fragen., &i.,*,q)));
_Manhattan
Quartz | Level 8
Thank you! For future questions: what kind of format would be save to look at from unknown sources? CSV?

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
  • 4 replies
  • 1353 views
  • 4 likes
  • 3 in conversation