Skip to main content
Announcements
A fresh, new look for the Data Integration & Quality forums and navigation! Read more about what's changed.
cancel
Showing results for 
Search instead for 
Did you mean: 
sofiene92
Contributor

[resolved] Error substring : index out of range

Hello,
I have a problem concerning substring function.
My project is a Java project, i use TOS 2.3.1 and I have a field (rha.ACTES) in which there is very long string (about 50 characters max, and this field can be nullable), and I want to extract the first eight characters in an other field (ACTE01) thanks to substring.
But I have a problem when I export in an Excel file, I have an error when I run my job...
I think this error comes from tMap.
Thanks for your answers.

Sofiene92
0683p000009MC0Z.png 0683p000009MBhQ.png
Labels (3)
1 Solution

Accepted Solutions
Anonymous
Not applicable

Hello again,
this is a little bit tricky. Add the following two code routines to your project:
    /**
* decomposeByFixLength: decompose a String in parts depending on a list of positions
*
*
* {talendTypes} String
*
* {Category} User Defined
*
* {param} string("") text: The string which should be cut in parts
*
* {param} int("") length: The length of each part
*
* {example} decomposeByFixLength("this is a string", new int[]{3,3,1}) # "thi", "s i", "s".
*/
public static String[] decomposeByFixLength(String text, int[] length) {
if(text == null) return null;
String[] extractedParts= new String;
int actualPart= 0;
for (int len: length) {
extractedParts= text.substring(0, java.lang.Math.min(text.length(), len));
text= text.substring(java.lang.Math.min(text.length(), len));
}
return extractedParts;
}


/**
* join: joins strings together with a given separator
*
*
* {talendTypes} String
*
* {Category} User Defined
*
* {param} String("") parts: Array of Strings to join
*
* {param} String("") separator: Separator for the concatenated string parts
*
* {example} join(new String[]{"this","is","a","test"}, ",") # "this,is,a,test".
*/
public static String join(String[] parts, String separator) {
if(parts.length == 0) return "";
StringBuffer buf = new StringBuffer();
buf.append(parts);
for(int i=1,n=parts.length; i<n; i++)
buf.append(separator).append(parts);
return buf.toString();
}

The documentation does not work. But the functions should do it right.
In your tMap add the following code (I use decomposeString as name for the above routine class):
decomposeString.join(decomposeString.decomposeByFixLength(rha.ACTES, new int  {8,8,8} ),",")

@Talend-Team: It may be a good idea to add this (or some optimized functions) to TOS itself. Is there a easy qay to share them (e.g. in the Ecosystem)
Bye
Volker

View solution in original post

14 Replies
Anonymous
Not applicable

You try to take the first 8 characters of a string, which have less than 8 char's.
Change your code to the following if you are not sure that your string has at minimum a length of 8 char's:
rha.ACTES.substring(0, java.lang.Math.min(rha.ACTES.length(),8))

Bye
Volker
sofiene92
Contributor
Author

Hello,
thank you very much Volker, it works for ACTE01!
But I have an other problem : I want to extract from ACTES 8 characters by 8 characters as we can see on the following sample :
Do you have an idea?
In fact, I want to put a comma 8 caracters by 8 caracters in ACTES, like that :
ACTES ACTES2
LFQK0020NAQK0150NEQK0100YYYY0300 ==> LFQK0020,NAQK0150,NEQK0100,YYYY0300
Thank you for your answers!

Sofiene92
0683p000009MBmF.png
Anonymous
Not applicable

Hello again,
this is a little bit tricky. Add the following two code routines to your project:
    /**
* decomposeByFixLength: decompose a String in parts depending on a list of positions
*
*
* {talendTypes} String
*
* {Category} User Defined
*
* {param} string("") text: The string which should be cut in parts
*
* {param} int("") length: The length of each part
*
* {example} decomposeByFixLength("this is a string", new int[]{3,3,1}) # "thi", "s i", "s".
*/
public static String[] decomposeByFixLength(String text, int[] length) {
if(text == null) return null;
String[] extractedParts= new String;
int actualPart= 0;
for (int len: length) {
extractedParts= text.substring(0, java.lang.Math.min(text.length(), len));
text= text.substring(java.lang.Math.min(text.length(), len));
}
return extractedParts;
}


/**
* join: joins strings together with a given separator
*
*
* {talendTypes} String
*
* {Category} User Defined
*
* {param} String("") parts: Array of Strings to join
*
* {param} String("") separator: Separator for the concatenated string parts
*
* {example} join(new String[]{"this","is","a","test"}, ",") # "this,is,a,test".
*/
public static String join(String[] parts, String separator) {
if(parts.length == 0) return "";
StringBuffer buf = new StringBuffer();
buf.append(parts);
for(int i=1,n=parts.length; i<n; i++)
buf.append(separator).append(parts);
return buf.toString();
}

The documentation does not work. But the functions should do it right.
In your tMap add the following code (I use decomposeString as name for the above routine class):
decomposeString.join(decomposeString.decomposeByFixLength(rha.ACTES, new int  {8,8,8} ),",")

@Talend-Team: It may be a good idea to add this (or some optimized functions) to TOS itself. Is there a easy qay to share them (e.g. in the Ecosystem)
Bye
Volker
sofiene92
Contributor
Author

Hello!
Thank you very much, it works perfectly, I have just changed {8,8,8} by {8,8,8,8,8,8,8,8,8,8} because the field "rha.ACTES" can have a length of 80 max.
Finally, I want to put comma 8 by 8 because I will normalize after.
And thanks to you, I can continue my work, I was blocked since two days!
Danke schön!
Best regards...

Sofiene92
Anonymous
Not applicable

Hi,
you are welcome! And sorry for my late answer's I managed it only at the night to spend some minutes for TOS... 🙂
Bye
Volker
Anonymous
Not applicable

Hi all,
I'm having a similar situation occur to me...
I have a STRING field that can be nullable at times, in which I want to read the first 3 numbers (if there is any data in the field) and use it as the AREACODE.

For example:
I have a STRING field right now in a file called BusinessPhoneNumber...
This field can be blank (if a client does not have a worknumber) or it can be a phone number, such as 123456789...
If the field is not null then I need to read 123 and spit it out as the AreaCode as an INTEGER....


I tried creating a VARIABLE named workArea as so:
StringHandling.LEFT(row1.workPhoneNum,3)
and then convert it to int by using:
Integer.parseInt(var.workArea)
Only problem with this is if the workPhoneNum field I'm using in the StringHandling.LEFT method is blank, I receive the following error:
java.lang.NumberFormatException: For input string: "" (because currently in the file workPhone is blank, but in other files it may not be)


Any help would be greatly appreciated!
Thanks,
Chris
Anonymous
Not applicable

Hello
java.lang.NumberFormatException: For input string: "" (because currently in the file workPhone is blank, but in other files it may not be

You should handle the empty string first, if it is a empty, define a default value, like just set it as 0. eg:
VARIABLE :
row1.workPhoneNum.equals("")?"" 0683p000009M9p6.pngtringHandling.LEFT(row1.workPhoneNum,3)
AreaCode :
var.workArea.equals("")?0:Integer.parseInt(var.workArea)
Best regards
shong
Anonymous
Not applicable

Thanks, Shong!
This worked perfectly!
_AnonymousUser
Specialist III

hi
I can find length of number using below function , where row1.id is integer data type
String.valueOf(row1.id).length() based on this value
i want to do following :
String.valueOf(row1.id).length()<7?row1.id:987+row1.id
i want to append 987 to all numbers whose length is less than 6