1

I am trying to search account numbers on an excel file, which in return, i will get a 'total amount due' if the account number exists in the sheet. I can scan using this code, however, I get error if the account number does not exists in the sheet.

for(int i = 0; i < accno.size(); i++){
    for(int j = rowAccNo1+1; j < row.getRowNum(); j++){
           srcaccno = formatter.formatCellValue(sheet.getRow(j).getCell(0));
           totalamt = formatter.formatCellValue(sheet.getRow(j).getCell(10));

          if(accno.get(i).contains(srcaccno)){
                  totalamountdue.add(i, totalamt);
          }
      }
  }

Edit: Hi, I am using Apache POI.

I declared accno as below:

static ArrayList<String> accno = new ArrayList<String>();

and I am getting this error. perhaps Java can't find the account number that's why he throws this. But I do not know if I can add an empty or null on my arraylist.

at java.util.ArrayList.rangeCheckForAdd(Unknown Source) at java.util.ArrayList.add(Unknown Source) at com.joven.DataExtractionTool.App.compareMastertoSourceABC(App.java:372) at com.joven.DataExtractionTool.App.main(App.java:78) at com.joven.DataExtractionTool.AppTest.testApp(AppTest.java:17) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at junit.framework.TestCase.runTest(TestCase.java:154) at junit.framework.TestCase.runBare(TestCase.java:127) at junit.framework.TestResult$1.protect(TestResult.java:106) at junit.framework.TestResult.runProtected(TestResult.java:124) at junit.framework.TestResult.run(TestResult.java:109) at junit.framework.TestCase.run(TestCase.java:118) at junit.framework.TestSuite.runTest(TestSuite.java:208) at junit.framework.TestSuite.run(TestSuite.java:203) at org.eclipse.jdt.internal.junit.runner.junit3.JUnit3TestReference.run(JUnit3TestReference.java:131) at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)

Thank you for your response!

What I really like to do is that, if accno exists in the sheet, get totalamountdue. if it does not exists, put blank on totalamountdue so that it will display blank if i output the arraylist in console.

6
  • 1
    It would help if you also let us know which Excel Java library you are using (I'm guessing Apache). Commented Nov 15, 2016 at 8:05
  • How about using conditional Operation ? Commented Nov 15, 2016 at 8:05
  • What is the type of accno, can it contains null ? This doesn't seems right if(accno.get(i).contains(srcaccno)){ Commented Nov 15, 2016 at 8:06
  • Apologies. see my edit. thank you! Commented Nov 15, 2016 at 8:21
  • The short version, you add into the list into a specific index, when you don't find the account, you have a gap, List don't like to add value into a index bigger than their current size. Now, did you need to have the List to match the account one ? I guess, so you need to add a default value if the account is not foud (null, -1, ...) Commented Nov 15, 2016 at 8:58

2 Answers 2

1

Your problem come from this

if(accno.get(i).contains(srcaccno)){
     totalamountdue.add(i, totalamt); // ########
}

Since you add the total to a specific index in the list (the one corresponding to the account list), you need to insert a "default" value if you don't find the account in the sheet. If you do not, you will have a different length between the account list and the total list. Meaning that you try to add a value to far (out of bounds exception).

Actually, there is a much easier way (don't know why I didn't think first)

Before you even start to search into the sheet, insert a null value

totalamountdue.add(null);

Then, in the search loop, if you find a value replace this null with the total found.

if(accno.get(i).contains(srcaccno)){
     totalamountdue.set(i, totalamt); // use SET to replace the value at a specific index.
}

The full loop

totalamoutdue.add(null); //will insert at the end, i.
for(int j = rowAccNo1+1; j < row.getRowNum(); j++){
      srcaccno = formatter.formatCellValue(sheet.getRow(j).getCell(0));
      if(accno.get(i).contains(srcaccno)){
              totalamt = formatter.formatCellValue(sheet.getRow(j).getCell(10)); //No need to get the value if it is not the account you want
              totalamountdue.set(i, totalamt);
              break; //Break the current for loop, IF there is no need to read further
      }
  }
Sign up to request clarification or add additional context in comments.

5 Comments

you are correct, the problem is coming come that line. because if acc.get(i) is not on the excel file, it stops the loop. :( if I add else, like else{totalamountdue.add(i, ""); i get java.lang.IllegalArgumentException error.
@ashlrem Don't insert in the else part, this will add for each row of the sheet. I have edited my answer a bit. PS : It doesn't stopped the loop, it crashed ;)
your tip about not having else is great man. followed your suggestion about .set and break; and it works great!
@ashlrem The break is usefull if there is no duplicated row for a same account. But if this is not the case, you should use a tmp variable to do the sum of all corresponding values then set the result.
oh you are right once again. i doubt there would be duplicated row. or i hope there would be no duplicated row. for now, my code works. and it is all thanks to you!
0

I assume something is wrong with iterating over those lists, so I simplified code - hope it will work.

Map<String, BigDecimal> accountsDue = new HashMap<>();

for (int j = rowAccNo1 + 1; j < row.getRowNum(); j++) {
  String srcaccno = formatter.formatCellValue(sheet.getRow(j).getCell(0));
  BigDecimal amountDue = formatter.formatCellValue(sheet.getRow(j).getCell(10));
  if (accno.contains(srcaccno)) {
    putOrIncreaseDue(srcaccno, amountDue, accountsDue);
  }
}

private void putOrIncreaseDue(String srcaccno, BigDecimal amountDue, Map<String, BigDecimal> accountsDue) {
  if (accountsDue.containsKey(srcaccno)) {
    amountDue.add(accountsDue.get(srcaccno));
  }
  accountsDue.put(srcaccno, amountDue);
}

7 Comments

Hi, can i ask what do you mean by this? amountDue = amountDue.add(accountsDue.get(srcaccno)); }
can you kindly explain what the putOrIncreaseDue method does? thanks!
I created map - Account number as key, and AmountDue as value.
When I want to put parsed value to this map - first I need to check if it's already there. If so - get current AmountDue value add parsed value, and then put. Otherwise just put with parsed value.
This will duplicate the Account value in memory, once in the map, once in the list.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.