BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
Jinglin
Fluorite | Level 6

Please find my code below. I'm trying to split the variable SAEEVE to 200 length variables, and it prints out this error. Hoe do I deal with this error?

 

data supp;

SAEEVE="SAETRT= strip (catx('/ ', SAETTXT1, SAETTXT2, SAETTXT3, SAETTXT4, SAETTXT5)) SAETRT= strip (catx('/ ', SAETTXT1, SAETTXT2, SAETTXT3, SAETTXT4, SAETTXT5)) SAETRT= strip (catx('/ ', SAETTXT1, SAETTXT2, SAETTXT3, SAETTXT4, SAETTXT5)) SAETRT= strip (catx('/ ', SAETTXT1, SAETTXT2, SAETTXT3, SAETTXT4, SAETTXT5)) SAETRT= strip (catx('/ ', SAETTXT1, SAETTXT2, SAETTXT3, SAETTXT4, SAETTXT5)) SAETRT= strip (catx('/ ', SAETTXT1, SAETTXT2, SAETTXT3, SAETTXT4, SAETTXT5)) SAETRT= strip (catx('/ ', SAETTXT1, SAETTXT2, SAETTXT3, SAETTXT4, SAETTXT5)) SAETRT= strip (catx('/ ', SAETTXT1, SAETTXT2, SAETTXT3, SAETTXT4, SAETTXT5)) SAETRT= strip (catx('/ ', SAETTXT1, SAETTXT2, SAETTXT3, SAETTXT4, SAETTXT5)) SAETRT= strip (catx('/ ', SAETTXT1, SAETTXT2, SAETTXT3, SAETTXT4, SAETTXT5)) SAETRT= strip (catx('/ ', SAETTXT1, SAETTXT2, SAETTXT3, SAETTXT4, SAETTXT5)) SAETRT= strip (catx('/ ', SAETTXT1, SAETTXT2, SAETTXT3, SAETTXT4, SAETTXT5)) SAETRT= strip (catx('/ ', SAETTXT1, SAETTXT2, SAETTXT3, SAETTXT4, SAETTXT5)) SAETRT= strip (catx('/ ', SAETTXT1, SAETTXT2, SAETTXT3, SAETTXT4, SAETTXT5)) SAETRT= strip (catx('/ ', SAETTXT1, SAETTXT2, SAETTXT3, SAETTXT4, SAETTXT5)) SAETRT= strip (catx('/ ', SAETTXT1, SAETTXT2, SAETTXT3,

SAETTXT4, SAETTXT5)) SAETRT= strip (catx('/ ', SAETTXT1, SAETTXT2, SAETTXT3, SAETTXT4, SAETTXT5))SAETRT= strip (catx('/ ', SAETTXT1, SAETTXT2, SAETTXT3, SAETTXT4, SAETTXT5)) SAETRT= strip (catx('/ ', SAETTXT1, SAETTXT2, SAETTXT3, SAETTXT4, SAETTXT5)) SAETRT= strip (catx('/ ', SAETTXT1, SAETTXT2, SAETTXT3, SAETTXT4, SAETTXT5)) SAETRT= strip (catx('/ ', SAETTXT1, SAETTXT2, SAETTXT3, SAETTXT4, SAETTXT5)) SAETRT= strip (catx('/ ', SAETTXT1, SAETTXT2, SAETTXT3, SAETTXT4, SAETTXT5)) SAETRT= strip (catx('/ ', SAETTXT1, SAETTXT2, SAETTXT3, SAETTXT4, SAETTXT5)) SAETRT= strip (catx('/ ', SAETTXT1, SAETTXT2, SAETTXT3, SAETTXT4, SAETTXT5)) SAETRT= strip (catx('/ ', SAETTXT1, SAETTXT2, SAETTXT3, SAETTXT4, SAETTXT5)) SAETRT= strip (catx('/ ', SAETTXT1, SAETTXT2, SAETTXT3, SAETTXT4, SAETTXT5)) SAETRT= strip (catx('/ ', SAETTXT1, SAETTXT2, SAETTXT3, SAETTXT4, SAETTXT5)) SAETRT= strip (catx('/ ', SAETTXT1, SAETTXT2, SAETTXT3, SAETTXT4, SAETTXT5)) SAETRT= strip (catx('/ ', SAETTXT1, SAETTXT2, SAETTXT3, SAETTXT4, SAETTXT5))";

run;

 

 

%let chr_str=200;

data _null_;

set supp;

call symputx('num_str',int((length(SAEEVE)+&chr_str-1)/&chr_str));

run;

%put num=&num_str;

data supp1;

set supp;

array Var[*] $ &chr_str SAEEVE1-SAEEVE&num_str;

_i=1; _j=1;

do  until (scan(SAEEVE,_I,'') eq '');

_w=scan(SAEEVE,_i,' ');

if lengthc(var[_j])+lengthc(_w)> lengthc(var[_j]) then _j+1;

var[_j]=strip(var[_j])||''||_w;

_i+1;

end;

run;

 

1 ACCEPTED SOLUTION

Accepted Solutions
Kurt_Bremser
Super User

You really should start following Maxim 1 and read the SAS documentation

(http://documentation.sas.com/?cdcId=pgmsascdc&cdcVersion=9.4_3.3&docsetId=lefunctionsref&docsetTarge...😞

Returns the length of a character string, including trailing blanks.

 

Your _j is incremented every time a "word" is read, and you don't even assign any value to SAEEVE1 (you start with SAEEVE2).

 

Use the length() function instead of lengthc() where appropriate:

data supp1;
set supp;
array Var[*] $ &chr_str SAEEVE1-SAEEVE&num_str;
_i = 1;
_j = 1;
do until (scan(SAEEVE,_i,'') eq '');
  _w = scan(SAEEVE,_i,' ');
  if length(var[_j]) + length(_w) > lengthc(var[_j]) then _j + 1;
  var[_j] = strip(var[_j]) || '' || _w;
  _i + 1;
end;
run;

Just like you used %put to reveal the values of macro variables, use put in a data step to show how values develop during data step execution. This will lead you to an understanding where your code does not perform as you want.

View solution in original post

6 REPLIES 6
RW9
Diamond | Level 26 RW9
Diamond | Level 26

Sorry, you have SAS code in a text variable, and you are then writing macro code to parse it out?  Why?  This route lies madness.

 

For splitting to 200 characters, a simple way is to read the characters one by one, then add the word on, and if longer than 200 write out, something like:

data want;
  set supp;
  length word line $200;
  do i=1 to lengthn(saeeve);
    if char(saeeve,i) in (" ",",","(",")") then do;
      if lengthn(catx(" ",line,word)) >= 200 then output;
      line=word;
    end;
    word=cats(word,char(saeeve,i));
  end;
run;

Note note tested, but it will give you a start. However I really advise you consider what you are doing as firstly character strings have limitations, and secondly code can have any number of delimiters, special characters and nuances that your not going to pick up.

Jinglin
Fluorite | Level 6
Sorry for making confuse. The text value of SAEEVE was dummied, and please ignore it. This SAEEVE is just refer to one variable which length is over 2000. And I want to split to 200 length limit variables like SAEEVE1 SAEEVE2..etc.
Actually this error still exist when I remove those special characters, and I really want to know why the error come out.
Thanks for your reply, and I will try with your method one more time.
Kurt_Bremser
Super User

You really should start following Maxim 1 and read the SAS documentation

(http://documentation.sas.com/?cdcId=pgmsascdc&cdcVersion=9.4_3.3&docsetId=lefunctionsref&docsetTarge...😞

Returns the length of a character string, including trailing blanks.

 

Your _j is incremented every time a "word" is read, and you don't even assign any value to SAEEVE1 (you start with SAEEVE2).

 

Use the length() function instead of lengthc() where appropriate:

data supp1;
set supp;
array Var[*] $ &chr_str SAEEVE1-SAEEVE&num_str;
_i = 1;
_j = 1;
do until (scan(SAEEVE,_i,'') eq '');
  _w = scan(SAEEVE,_i,' ');
  if length(var[_j]) + length(_w) > lengthc(var[_j]) then _j + 1;
  var[_j] = strip(var[_j]) || '' || _w;
  _i + 1;
end;
run;

Just like you used %put to reveal the values of macro variables, use put in a data step to show how values develop during data step execution. This will lead you to an understanding where your code does not perform as you want.

Jinglin
Fluorite | Level 6
Yes, you are right. thank you very much.
Astounding
PROC Star

The calculation of how many variables are needed depends only on the length == how many 200-character chunks are needed.  But the assignment of values to those variables depends on where blanks are found.  That can require an extra variable.  To take a simple (perhaps unrealistic example), suppose your original string is 407 characters long:  101 characters then a blank, 101 more characters then a blank, etc.  You woud calculate that you need 3 variables.  But you actually need 4 variables.

 

There's no harm in creating an extra variable that might not be needed.  Just add 1 to the formula for &NUM_STR.

 

Jinglin
Fluorite | Level 6
Thanks for your example, and it's really useful. You are right.

sas-innovate-2024.png

Don't miss out on SAS Innovate - Register now for the FREE Livestream!

Can't make it to Vegas? No problem! Watch our general sessions LIVE or on-demand starting April 17th. Hear from SAS execs, best-selling author Adam Grant, Hot Ones host Sean Evans, top tech journalist Kara Swisher, AI expert Cassie Kozyrkov, and the mind-blowing dance crew iLuminate! Plus, get access to over 20 breakout sessions.

 

Register now!

SAS Enterprise Guide vs. SAS Studio

What’s the difference between SAS Enterprise Guide and SAS Studio? How are they similar? Just ask SAS’ Danny Modlin.

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
  • 6 replies
  • 1763 views
  • 2 likes
  • 4 in conversation