Do not input private or sensitive data. View Qlik Privacy & Cookie Policy.
Skip to main content

Announcements
Join us in Bucharest on Sept 18th for Qlik's AI Reality Tour! Register Now
cancel
Showing results for 
Search instead for 
Did you mean: 
sofiene92
Contributor
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
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
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
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