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

I'm trying to create a user-define function that will work on character strings, so first I decided to learn the "plumbing" before developing the function.

 

I've created two user defined functions: DAVECASE(simply returns the length of a character string) and DAVESUM(returns the sum of the two integers passed in).

 

proc fcmp outlib=macros.userddefinedfunctions.davecase;  ** path/name for user-defined function **;

function davecase(instring);
 
      propstr = LENGTH(instring);

      return(propstr);

endsub;

function davesum(part1,part2);

      newsum = part1 + part2;

     return(newsum);

endsub;

 

Here is the code from which these two user-define functions are called:

data x;
 
     stringx = 'this is the untouched string';

	 daveway = DAVECASE(stringx);   ** gets tripped up, seems to expect integer **;

	 oldway = PROPCASE(stringx);     ** works fine **;

	 total = DAVESUM(2,3);       ** works fine;

	 run;

 

DAVESUM works perfectly, returning 5.

 

DAVECASE seems to get tripped up because somewhere along the line an integer is expected instead of a character string.

 

27         data x;
28         
29              stringx = 'this is the untouched string';
30         
31         	 daveway = DAVECASE(stringx);   ** gets tripped up, seems to expect integer **;
32         
33         	 oldway = PROPCASE(stringx);     ** works fine **;
34         
35         	 total = DAVESUM(2,3);       ** works fine;
36         
37         	 run;

NOTE: Character values have been converted to numeric values at the places given by: (Line):(Column).
      31:22   
NOTE: Invalid numeric data, stringx='this is the untouched string' , at line 31 column 22.
stringx=this is the untouched string daveway=1 oldway=This Is The Untouched String total=5 _ERROR_=1 _N_=1
NOTE: The data set WORK.X has 1 observations and 4 variables.
NOTE: DATA statement used (Total process time):

 

Is there something I need to do to indicate that the value being passed to DAVECASE is character?

 

Thanks,

 

...dave

 

 

1 ACCEPTED SOLUTION

Accepted Solutions
ed_sas_member
Meteorite | Level 14

Hi @daveconifer1 

 

You need to specify that the argument is a character one by adding a '$' as follows in the function definition:

function davecase(instring $);

NB: for the second function, contrary to the SUM() function, the "+" operator does not handle missing values

 

Best,

View solution in original post

5 REPLIES 5
ed_sas_member
Meteorite | Level 14

Hi @daveconifer1 

 

You need to specify that the argument is a character one by adding a '$' as follows in the function definition:

function davecase(instring $);

NB: for the second function, contrary to the SUM() function, the "+" operator does not handle missing values

 

Best,

daveconifer1
Fluorite | Level 6

Thanks, Ed!  I was all over the documentation, or so I thought, but I didn't see that.

 

I got past that, and now my function has a new issue, so that's progress.  This isn't as straightforward as i thought.  I simplified DAVECASE to just return a copy of the argument:

function davecase(instring $);
 
      length propstr $ 80 ;

      propstr = instring;

      return(propstr);

endsub;

 

But I still get this:

149        data x;
150        
151             stringx = 'this is the untouched string';
152        
153        	 daveway = DAVECASE(stringx);   ** gets tripped up, seems to expect integer **;
154        
The SAS System

155        	 oldway = PROPCASE(stringx);     ** works fine **;
156        
157        	 total = DAVESUM(2,3);       ** works fine;
158        
159        	 run;

ERROR: Unable to convert a character value to a numeric value in function 'davecase' in statement number 3 at line 7 column 8.
       The statement was:
    0     (7:8)      _davecase_ = Move N<=C(propstr="this is the untouched string                                                    
")
ERROR: Exception occurred during subroutine call.
stringx=this is the untouched string daveway= oldway=This Is The Untouched String total=5 _ERROR_=1 _N_=1
NOTE: The data set WORK.X has 1 observations and 4 variables.

 

I'll look for more documentation and examples.

 

Thanks again,

 

...dave

ed_sas_member
Meteorite | Level 14

Hi @daveconifer1 

 

You can try to remove the LENGTH statement and adapt the FUNCTION definition as follows:

function davecase(instring $) $ 80;

-> in the parenthesis, you specify the input variable type ($)

-> after the parenthesis, you specify the output type and set the proper length (default = 8).

Best,

daveconifer1
Fluorite | Level 6

Thanks so much again, Ed!  That worked perfectly, and makes perfect sense to me as well.  I didn't like that LENGTH statement for the return argument, I was just trying stuff.

 

I appreciate your help.  Now I can work on the function, since the plumbing is working.

 

...dave

 

ed_sas_member
Meteorite | Level 14
Awesome!
Thank you @daveconifer1 😊

hackathon24-white-horiz.png

2025 SAS Hackathon: There is still time!

Good news: We've extended SAS Hackathon registration until Sept. 12, so you still have time to be part of our biggest event yet – our five-year anniversary!

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.

SAS Training: Just a Click Away

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

Browse our catalog!

Discussion stats
  • 5 replies
  • 1826 views
  • 3 likes
  • 2 in conversation