Dario,

You should try a recent svn. There were changes to improve named ranges across separate worksheets.

I think you have a good idea. It allows all types of advantages. We are doing something similar although we are focused now on the creation side, we recognize the possibilities of reading in the users adjustments.

You do need to be careful if your workbook uses any User Defined Functions. These aren't implemented, I do begin to wonder if a plug-in technology might allow people to roll in their own implementations of custom functions.

Regards,
Dave

On Jan 6, 2009, at 4:47 PM, Darío Vasconcelos wrote:

Hi Josh,

I know, and I've done simple proof-of-concept tests where formulas are
evaluated and values are updated automatically, even if there is a number of
formulas in the middle that need updating in the way.

But it's not working for this specific sheet, and now I'm questioning myself if HSSF should be used as an "in-server" Excel engine. Most of the questions that I've read in the mailing list regard creating Excel files from scratch, or modifying existing ones so the final user opens them later in Excel. In my case, all I want is HSSF to recalculate values based on existing formulas
on an existing file and let me retrieve the result.

Regards,



On Tue, Jan 6, 2009 at 4:21 PM, Josh Micich <[email protected]> wrote:

Hello Dario,

So this is my question: is this a good idea? Is POI supposed to do such
things?

POI has supported formula evaluation since version 3. There have been many
improvements as of late including
Speed optimisations




So this is my question: is this a good idea? Is POI supposed to do such things? Because so far, my tests have shown that the recalculation isn't fully working: if I change the value of A1, and A2 and A3 have formulas
that
depend on its value, only A2 is updated but A3 not. Of course this is a
trivial example: in reality, some cells have more than 20 levels of
dependency, sometimes the formulas refer to cells that are "before" them,
other times refer to cells that are after.

The process I'm using is as follows:
* Open the workbook
* Create a HSSFFormulaEvaluator
* Get the value of a cell (with getSheetAt, getRow, getCell)
* Set its value to some double
* Traverse all rows and all cells (using sheet.lastRowNum() and
row.getLastCellNum() and do an evaluateFormulaCell on each one
* Get the value of a result cell

And the value isn't even the same as Excel shows before changing the
value
of the cell. I'm worried because for some process we're implementing a MonteCarlo method, thus we're going to to this whole process 500 times, retrieving the results each cycle, and plotting these points in graphs.

The actual code is as follows:

                       FileInputStream fis = new


FileInputStream("/Users/dariovasconcelos/Documents/desa/QA76/ Bancomext/src_paramext/poi/riesgo4.xls");
HSSFWorkbook wb = new HSSFWorkbook(fis); // or new
                       HSSFFormulaEvaluator evaluator = new
HSSFFormulaEvaluator(wb);

                       BufferedWriter out = new BufferedWriter(new



FileWriter("/Users/dariovasconcelos/Documents/desa/QA76/Bancomext/ src_paramext/poi/sinCambios.txt"));
                       HSSFSheet hoja = wb.getSheetAt(0);
                       HSSFRow renglon = hoja.getRow(686);
                       HSSFCell celda = renglon.getCell(8);
                       celda.setCellValue((double)0.483);
                       evaluator.notifySetFormula(celda);
                       evaluator.clearAllCachedResultValues();

                       n = recalculateAll(wb, evaluator, out, n);

And recalculateAll is coded like this:

          private int recalculateAll(HSSFWorkbook wb,
HSSFFormulaEvaluator evaluator, BufferedWriter out,
int
n) {
           try {
               // Recalculo todos los renglones
               //for(int sheetNum = 0; sheetNum <
wb.getNumberOfSheets();sheetNum++) {
               for(int sheetNum = 0; sheetNum < 1; sheetNum++) {
                   //int sheetNum =0;
                   HSSFSheet sheet = wb.getSheetAt(sheetNum);
                   for (int i = 0; i < sheet.getLastRowNum(); i++) {
                       HSSFRow r = sheet.getRow(i);
                       if (r == null)
                           continue;
                       for (int j=0; j < r.getLastCellNum(); j++) {
                           HSSFCell c = r.getCell(j);
                           if (c == null)
                               continue;
                           int tipo = c.getCellType();
                           int row = c.getRowIndex();
                           int col = c.getColumnIndex();
                           switch (tipo) {
                               case HSSFCell.CELL_TYPE_NUMERIC:
miPrint(out, n++, sheetNum, row, col
,
                                           "" +
c.getNumericCellValue());
                                   break;
                                   /*
                               case HSSFCell.CELL_TYPE_STRING:
miPrint(out, n++, sheetNum, row, col,
                                           c.getStringCellValue());
                                   break;
                                   */
                               case HSSFCell.CELL_TYPE_FORMULA:
miPrint(out, n++, sheetNum, row, col,

c.getCellFormula().replace("$",
                                           ""));
                                   int tipoRes =
evaluator.evaluateFormulaCell(c);
                                   if (tipoRes ==
HSSFCell.CELL_TYPE_NUMERIC)
miPrint(out, n++, sheetNum, row,
col,
                                               "" +
c.getNumericCellValue());
                                   else if (tipoRes ==
HSSFCell.CELL_TYPE_STRING)
miPrint(out, n++, sheetNum, row,
col,
c.getStringCellValue());
                                   else if (tipoRes ==
HSSFCell.CELL_TYPE_ERROR)
miPrint(out, n++, sheetNum, row,
col,
                                               "" +
c.getErrorCellValue());
                                   /*
                                   HSSFCell celdaTmp =
evaluator.evaluateInCell(c);
                                   if (celdaTmp.getCellType()
                                           ==
HSSFCell.CELL_TYPE_NUMERIC)
miPrint(out, n++, sheetNum, row,
col,
                                               "" +
c.getNumericCellValue());
                                               */
                                   break;
                           }
                       }
                   }
               }
           } catch (Exception e) {
               e.printStackTrace();
           }

           return n;
          }


"miPrint" is simply a routine to print the value of the cell to a
Buffered
Writer.

Regards,

Dario
--
Here's a rule I recommend: Never practice two vices at once.
- Tallulah Bankhead





--
Here's a rule I recommend: Never practice two vices at once.
- Tallulah Bankhead


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to