X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;ds=sidebyside;f=octave_packages%2Fio-1.0.19%2Fgetusedrange.m;fp=octave_packages%2Fio-1.0.19%2Fgetusedrange.m;h=c2d153bb17984e71bc449bf59c1442ad2d3ea2a4;hb=c880e8788dfc484bf23ce13fa2787f2c6bca4863;hp=0000000000000000000000000000000000000000;hpb=1705066eceaaea976f010f669ce8e972f3734b05;p=CreaPhase.git diff --git a/octave_packages/io-1.0.19/getusedrange.m b/octave_packages/io-1.0.19/getusedrange.m new file mode 100644 index 0000000..c2d153b --- /dev/null +++ b/octave_packages/io-1.0.19/getusedrange.m @@ -0,0 +1,659 @@ +## Copyright (C) 2010,2011,2012 Philip Nienhuis +## +## This program is free software; you can redistribute it and/or modify it under +## the terms of the GNU General Public License as published by the Free Software +## Foundation; either version 3 of the License, or (at your option) any later +## version. +## +## This program is distributed in the hope that it will be useful, but WITHOUT +## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +## details. +## +## You should have received a copy of the GNU General Public License along with +## this program; if not, see . + +## -*- texinfo -*- +## @deftypefn {Function File} [ @var{toprow#}, @var{bottomrow#}, @var{leftcol#}, @var{rightcol#} ] = getusedrange (@var{spptr}, @var{shindex#}) +## Find occupied data range in worksheet @var{shindex#} in a spreadsheet +## pointed to in struct @var{spptr} (either MS-Excel or +## OpenOffice_org Calc). +## +## @var{shindex#} must be numeric and is 1-based. @var{spptr} can either +## refer to an MS-Excel spreadsheet (spptr returned by xlsopen) or an +## OpenOffice.org Calc spreadsheet (spptr returned by odsopen). +## None of these inputs are checked! +## +## Be aware that especially for OpenOffice.org Calc (ODS) spreadsheets +## the results can only be obtained by counting all cells in all rows; +## this can be fairly time-consuming. Reliable ods data size results can +## only be obtained using UNO interface. +## For the ActiveX (COM) interface the underlying Visual Basic call relies +## on cached range values and counts empty cells with only formatting too, +## so COM returns only approximate (but then usually too big) range values. +## +## Examples: +## +## @example +## [trow, brow, lcol, rcol] = getusedrange (ods2, 3); +## (which returns the outermost row & column numbers of the rectangle +## enveloping the occupied cells in the third sheet of an OpenOffice_org +## Calc spreadsheet pointedto in struct ods2) +## @end example +## +## @example +## [trow, brow, lcol, rcol] = getusedrange (xls3, 3); +## (which returns the outermost row & column numbers of the rectangle +## enveloping the occupied cells in the third sheet of an Excel +## spreadsheet pointed to in struct xls3) +## @end example +## +## @seealso {xlsopen, xlsclose, odsopen, odsclose, xlsfinfo, odsfinfo} +## +## @end deftypefn + +## Author: Philip Nienhuis +## Created: 2010-03-18 (First usable version) for ODS (java/OTK) +## Updates: +## 2010-03-20 Added Excel support (Java/POI) +## 2010-05-23 Added in support for jOpenDocument ODS +## 2010-05-31 Fixed bugs in getusedrange_jod.m +## 2010-08-24 Added support for odfdom 0.8.6 (ODF Toolkit) +## 2010-08-27 Added checks for input arguments +## '' Indentation changed from tab to doublespace +## 2010-10-07 Added COM support (at last!) +## 2011-05-06 Experimental support for Java/UNO bridge +## 2011-06-13 OpenXLS support added +## 2011-09-08 Style & layout updates +## 2012-01-26 Fixed "seealso" help string +## 2012-06-08 Replaced tabs by double space +## '' Added COM and OXS to message about supported interfaces +## +## Last subfunc update: 2012-06-08 (OTK) + +function [ trow, lrow, lcol, rcol ] = getusedrange (spptr, ii) + + # Some checks + if ~isstruct (spptr), error ("Illegal spreadsheet pointer argument"); endif + + if (strcmp (spptr.xtype, 'OTK')) + [ trow, lrow, lcol, rcol ] = getusedrange_otk (spptr, ii); + elseif (strcmp (spptr.xtype, 'JOD')) + [ trow, lrow, lcol, rcol ] = getusedrange_jod (spptr, ii); + elseif (strcmp (spptr.xtype, 'UNO')) + [ trow, lrow, lcol, rcol ] = getusedrange_uno (spptr, ii); + elseif (strcmp (spptr.xtype, 'COM')) + [ trow, lrow, lcol, rcol ] = getusedrange_com (spptr, ii); + elseif (strcmp (spptr.xtype, 'POI')) + [ trow, lrow, lcol, rcol ] = getusedrange_poi (spptr, ii); + elseif (strcmp (spptr.xtype, 'JXL')) + [ trow, lrow, lcol, rcol ] = getusedrange_jxl (spptr, ii); + elseif (strcmp (spptr.xtype, 'OXS')) + [ trow, lrow, lcol, rcol ] = getusedrange_oxs (spptr, ii); + else + error ("Only OTK, JOD, COM, POI, JXL and OXS interface implemented"); + endif + +endfunction + + +## Copyright (C) 2010,2011,2012 Philip Nienhuis, pr.nienhuis -at- users.sf.net +## +## This program is free software; you can redistribute it and/or modify it under +## the terms of the GNU General Public License as published by the Free Software +## Foundation; either version 3 of the License, or (at your option) any later +## version. +## +## This program is distributed in the hope that it will be useful, but WITHOUT +## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +## details. +## +## You should have received a copy of the GNU General Public License along with +## this program; if not, see . + +## getusedrange_otk - get used range from ODS spreadsheet using ODF Toolkit + +## Author: Philip Nienhuis +## Created: 2010-03-18 (First usable version) +## Updates: +## 2010-08-24 Support for odfdom (ODF Toolkit) 0.8.6 checked; we still need +## => TableTable API because 0.8.6 is fooled by empty lowermost +## filler rows comprising number-rows-repeated table attribute :-( +## '' Indentation changed from tab to double space +## 2010-11-13 Catched jOpenDocument bug (1.2bx) where string cells have no office:value-type +## attrib set (by JOD). Somehow OTK is more robust as it catches these cells; +## Currently this fix is just commented. +## 2011-06-06 Fixed wrong if clause for finding last filler cells (L.160 & L.176) +## 2011-09-12 Support for odfdom-0.8.7 added (API change for XPATH) +## 2012-06-08 Support for odsfdom-0.8.8-incubator + +function [ trow, lrow, lcol, rcol ] = getusedrange_otk (ods, ii) + + odfcont = ods.workbook; # Local copy just in case + + if (isfield (ods, 'odfvsn')) + if (strcmp (ods.odfvsn, '0.8.6') || strcmp (ods.odfvsn, '0.7.5')) + xpath = ods.app.getXPath; + else + # API changed in odfdom-0.8.7 + xpath = ods.workbook.getXPath; + endif + else + error ("ODS file ptr struct for OTK interface seems broken."); + endif + + # Create an instance of type NODESET for use in subsequent statement + NODESET = java_get ('javax.xml.xpath.XPathConstants', 'NODESET'); + # Get table-rows in sheet no. wsh. Sheet count = 1-based (!) + str = sprintf ("//table:table[%d]/table:table-row", ii); + sh = xpath.evaluate (str, odfcont, NODESET); + nr_of_trows = sh.getLength(); + + jj = 0; # Table row counter + trow = 0; drows = 0; # Top data row, actual data row range + nrows = 0; reprows = 0; # Scratch counter + rcol = 0; lcol = 1024; # Rightmost and leftmost data column + while jj < nr_of_trows + row = sh.item(jj); + # Check for data rows + rw_char = char (row) (1:min(500, length (char (row)))); + if (findstr ('office:value-type', rw_char) || findstr (' attribute when writing strings + #if (isempty (findstr ('office:value-type', cl_char)) || isempty (findstr (' +## +## This program is free software; you can redistribute it and/or modify it under +## the terms of the GNU General Public License as published by the Free Software +## Foundation; either version 3 of the License, or (at your option) any later +## version. +## +## This program is distributed in the hope that it will be useful, but WITHOUT +## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +## details. +## +## You should have received a copy of the GNU General Public License along with +## this program; if not, see . + +## getusedrange_jod + +## Author: Philip +## Created: 2010-05-25 +## Last updates: +## 2010-05-31 Fixed ignoring table-covered-cells; fixed count of sheets comprising just A1:A1 +## Added option for wsh being a string argument +## 2010-08-12 Little textual adaptations +## 2010-11-13 Catched jOpenDocument bug (1.2bx) where string cells have no office:value-type +## '' attrb set (by JOD). Somehow OTK is more robust as it catches these cells +## 2012-04-09 Fixed rowrepcnt (str2num not applied to tablerow) +## 2012-04-18 Added getUsedRange() method for JOD 1.3x and above + +function [ trow, brow, lcol, rcol ] = getusedrange_jod (ods, wsh) + + # This function works by virtue of sheets in JOD actually being a Java string. + # It works outside of the Java memory/heap space which is an added benefit... + # (Read: this is one big dirty hack...... prone to crash Java on BIG spreadsheets) + + if (isnumeric (wsh)) + sh = char (ods.workbook.getSheet (wsh - 1)); + else + sh = char (ods.workbook.getSheet (wsh)); + endif + + try + # Let's see if we have JOD v. 1.3x. If not, next call fails & we'll fall back to the old hack + sh_rng = char (sh.getUsedRange ()); + if (isempty (sh_rng)) + # Empty sheet + trow = brow = lcol = rcol = 0; + else + # Strip sheet name + sh_rng = sh_rng(length (sh.getName) + 2 : end); + # Get rid of period + sh_rng = strrep (sh_rng, '.', ''); + [~, nr, nc, trow, lcol] = parse_sp_range (sh_rng); + brow = trow + nr - 1; + rcol = lcol + nc - 1; + endif + + catch + # Fall back to the old hack :-( + sh = char (sh); + + # 1. Get table-row pointers + id_trow = strfind (sh, '') - 1; + id_trow = [id_trow id]; + + trow = rcol = 0; + lcol = 1024; brow = 0; + if (~isempty (id)) + # 2. Loop over all table-rows + rowrepcnt = 0; + for irow = 1:length (id_trow)-1 + # Isolate single table-row + tablerow = sh(id_trow(irow):id_trow(irow+1)-1); + # Search table-cells. table-c covers both table-cell & table-covered-cell + id_tcell = strfind (tablerow, '. + +## getusedrange_uno + +## Author: Philip Nienhuis +## Created: 2011-05-06 +## Updates: +## 2011-06-29 Fixed wrong address range inference in case of sheet names containing period(s) +## 2012-03-02 Adapted code to assess nr of range blocks to ';' separator fo LO3.5+ + +function [ srow, erow, scol, ecol ] = getusedrange_uno (ods, ii) + + # Get desired sheet + sheets = ods.workbook.getSheets (); + sh_names = sheets.getElementNames (); + unotmp = java_new ('com.sun.star.uno.Type', 'com.sun.star.sheet.XSpreadsheet'); + sh = sheets.getByName(sh_names(ii)).getObject.queryInterface (unotmp); + + # Prepare cell range query + unotmp = java_new ('com.sun.star.uno.Type', 'com.sun.star.sheet.XCellRangesQuery'); + xRQ = sh.queryInterface (unotmp); + Cellflgs = javaObject ("java.lang.Short", "23"); + ccells = xRQ.queryContentCells (Cellflgs); + + # Get addresses of all blocks containing data + addrs = ccells.getRangeAddressesAsString (); + + # Strip sheet name from addresses. Watch out, in LO3.5 they changed + # the separator from ',' to ';' (without telling me!) + # 1. Get nr of range blocks + nblks = numel (strfind (addrs, sh_names(ii))); + # 2. First try with ',' separator... + adrblks = strsplit (addrs, ','); + if (numel (adrblks) < nblks) + # Apparently we have a ';' separator, so try with semicolon + adrblks = strsplit (addrs, ';'); + endif + if (isempty (adrblks)) + srow = erow = scol = ecol = 0; + return + endif + + # Find leftmost & rightmost columns, and highest and lowest row with data + srow = scol = 1e10; + erow = ecol = 0; + for ii=1:numel (adrblks) + # Check if address contains a sheet name in quotes (happens if name contains a period) + if (int8 (adrblks{ii}(1)) == 39) + # Strip sheet name part + idx = findstr (adrblks{ii}, "'."); + range = adrblks{ii}(idx+2 : end); + else + # Same, but tru strsplit() + range = strsplit (adrblks{ii}, '.'){2}; + endif + [dummy, nrows, ncols, trow, lcol] = parse_sp_range (range); + brow = trow + nrows - 1; + rcol = lcol + ncols - 1; + srow = min (srow, trow); + scol = min (scol, lcol); + erow = max (erow, brow); + ecol = max (ecol, rcol); + endfor + +endfunction + + +## Copyright (C) 2010,2011,2012 Philip Nienhuis +## +## This program is free software; you can redistribute it and/or modify it under +## the terms of the GNU General Public License as published by the Free Software +## Foundation; either version 3 of the License, or (at your option) any later +## version. +## +## This program is distributed in the hope that it will be useful, but WITHOUT +## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +## details. +## +## You should have received a copy of the GNU General Public License along with +## this program; if not, see . + +## getusedrange_com + +## Author: Philip Nienhuis +## Created: 2010-10-07 + +function [ trow, brow, lcol, rcol ] = getusedrange_com (xls, ii) + + sh = xls.workbook.Worksheets (ii); + + # Decipher used range. Beware, UsedRange() returns *cached* rectangle of + # all spreadsheet cells containing *anything*, including just formatting + # (i.e., empty cells are included too). ==> This is an approximation only + allcells = sh.UsedRange; + + # Get top left cell as a Range object + toplftcl = allcells.Columns(1).Rows(1); + + # Count number of rows & cols in virtual range from A1 to top left cell + lcol = sh.Range ("A1", toplftcl).columns.Count; + trow = sh.Range ("A1", toplftcl).rows.Count; + + # Add real occupied rows & cols to obtain end row & col + brow = trow + allcells.rows.Count() - 1; + rcol = lcol + allcells.columns.Count() - 1; + + # Check if there are real data + if ((lcol == rcol) && (trow = brow)) + if (isempty (toplftcl.Value)) + trow = brow = lcol = rcol = 0; + endif + endif + +endfunction + + +## Copyright (C) 2010,2011,2012 Philip Nienhuis, prnienhuis at users.sf.net +## +## This program is free software; you can redistribute it and/or modify it under +## the terms of the GNU General Public License as published by the Free Software +## Foundation; either version 3 of the License, or (at your option) any later +## version. +## +## This program is distributed in the hope that it will be useful, but WITHOUT +## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +## details. +## +## You should have received a copy of the GNU General Public License along with +## this program; if not, see . + +## getusedrange_poi - get range of occupied data cells from Excel using java/POI + +## Author: Philip +## Created: 2010-03-20 + +function [ trow, brow, lcol, rcol ] = getusedrange_poi (xls, ii) + + persistent cblnk; cblnk = java_get ('org.apache.poi.ss.usermodel.Cell', 'CELL_TYPE_BLANK'); + + sh = xls.workbook.getSheetAt (ii-1); # Java POI starts counting at 0 + + trow = sh.getFirstRowNum (); # 0-based + brow = sh.getLastRowNum (); # 0-based + # Get column range + lcol = 1048577; # OOXML (xlsx) max. + 1 + rcol = 0; + botrow = brow; + for jj=trow:brow + irow = sh.getRow (jj); + if (~isempty (irow)) + scol = (irow.getFirstCellNum).intValue (); + lcol = min (lcol, scol); + ecol = (irow.getLastCellNum).intValue () - 1; + rcol = max (rcol, ecol); + # Keep track of lowermost non-empty row as getLastRowNum() is unreliable + if ~(irow.getCell(scol).getCellType () == cblnk && irow.getCell(ecol).getCellType () == cblnk) + botrow = jj; + endif + endif + endfor + if (lcol > 1048576) + # Empty sheet + trow = 0; brow = 0; lcol = 0; rcol = 0; + else + brow = min (brow, botrow) + 1; ++trow; ++lcol; ++rcol; # 1-based return values + endif + +endfunction + + +## Copyright (C) 2010,2011,2012 Philip Nienhuis, prnienhuis at users.sf.net +## +## This program is free software; you can redistribute it and/or modify it under +## the terms of the GNU General Public License as published by the Free Software +## Foundation; either version 3 of the License, or (at your option) any later +## version. +## +## This program is distributed in the hope that it will be useful, but WITHOUT +## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +## details. +## +## You should have received a copy of the GNU General Public License along with +## this program; if not, see . + +## getusedrange_jxl - get occupied data cell range from Excel sheet +## using java/JExcelAPI + +## Author: Philip +## Created: 2010-03-20 + +function [ trow, brow, lcol, rcol ] = getusedrange_jxl (xls, wsh) + + persistent emptycell = (java_get ('jxl.CellType', 'EMPTY')).toString (); + + sh = xls.workbook.getSheet (wsh - 1); # JXL sheet count 0-based + + brow = sh.getRows (); + rcol = sh.getColumns (); + + if (brow == 0 || rcol == 0) + # Empty sheet + trow = 0; lcol = 0; brow = 0; rcol = 0; + else + trow = brow + 1; + lcol = rcol + 1; + for ii=0:brow-1 # For loop coz we must check ALL rows for leftmost column + emptyrow = 1; + jj = 0; + while (jj < rcol && emptyrow) # While loop => only til first non-empty cell + cell = sh.getCell (jj, ii); + if ~(strcmp (char (cell.getType ()), emptycell)) + lcol = min (lcol, jj + 1); + emptyrow = 0; + endif + ++jj; + endwhile + if ~(emptyrow) trow = min (trow, ii + 1); endif + endfor + endif + +endfunction + + +## Copyright (C) 2010,2011,2012 Philip Nienhuis, +## +## This program is free software; you can redistribute it and/or modify it under +## the terms of the GNU General Public License as published by the Free Software +## Foundation; either version 3 of the License, or (at your option) any later +## version. +## +## This program is distributed in the hope that it will be useful, but WITHOUT +## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +## details. +## +## You should have received a copy of the GNU General Public License along with +## this program; if not, see . + +## getusedrange_oxs + +## Author: Philip +## Created: 2011-06-13 +## Updates: +## 2011-06-29 try-catch to be able to skip non-data (e.g., graph) sheets + +function [ trow, brow, lcol, rcol ] = getusedrange_oxs (xls, wsh) + + sh = xls.workbook.getWorkSheet (wsh - 1); + try + # Intriguing: sh.getFirst<> is off by one, sh.getLast<> = OK.... 8-Z + trow = sh.getFirstRow () + 1; + brow = sh.getLastRow (); + lcol = sh.getFirstCol () + 1; + rcol = sh.getLastCol (); + catch + # Might be an empty sheet + trow = brow = lcol = rcol = 0; + end_try_catch + # Check for empty sheet + if ((trow > brow) || (lcol > rcol)), trow = brow = lcol = rcol = 0; endif + +endfunction