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 2025: Save the Date

 SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!

Save the date!

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.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 6 replies
  • 2147 views
  • 2 likes
  • 4 in conversation