1 ## Copyright (C) 2010,2011,2012 Philip Nienhuis <pr.nienhuis@users.sf.net>
3 ## This program is free software; you can redistribute it and/or modify it under
4 ## the terms of the GNU General Public License as published by the Free Software
5 ## Foundation; either version 3 of the License, or (at your option) any later
8 ## This program is distributed in the hope that it will be useful, but WITHOUT
9 ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 ## You should have received a copy of the GNU General Public License along with
14 ## this program; if not, see <http://www.gnu.org/licenses/>.
17 ## @deftypefn {Function File} [ @var{toprow#}, @var{bottomrow#}, @var{leftcol#}, @var{rightcol#} ] = getusedrange (@var{spptr}, @var{shindex#})
18 ## Find occupied data range in worksheet @var{shindex#} in a spreadsheet
19 ## pointed to in struct @var{spptr} (either MS-Excel or
20 ## OpenOffice_org Calc).
22 ## @var{shindex#} must be numeric and is 1-based. @var{spptr} can either
23 ## refer to an MS-Excel spreadsheet (spptr returned by xlsopen) or an
24 ## OpenOffice.org Calc spreadsheet (spptr returned by odsopen).
25 ## None of these inputs are checked!
27 ## Be aware that especially for OpenOffice.org Calc (ODS) spreadsheets
28 ## the results can only be obtained by counting all cells in all rows;
29 ## this can be fairly time-consuming. Reliable ods data size results can
30 ## only be obtained using UNO interface.
31 ## For the ActiveX (COM) interface the underlying Visual Basic call relies
32 ## on cached range values and counts empty cells with only formatting too,
33 ## so COM returns only approximate (but then usually too big) range values.
38 ## [trow, brow, lcol, rcol] = getusedrange (ods2, 3);
39 ## (which returns the outermost row & column numbers of the rectangle
40 ## enveloping the occupied cells in the third sheet of an OpenOffice_org
41 ## Calc spreadsheet pointedto in struct ods2)
45 ## [trow, brow, lcol, rcol] = getusedrange (xls3, 3);
46 ## (which returns the outermost row & column numbers of the rectangle
47 ## enveloping the occupied cells in the third sheet of an Excel
48 ## spreadsheet pointed to in struct xls3)
51 ## @seealso {xlsopen, xlsclose, odsopen, odsclose, xlsfinfo, odsfinfo}
55 ## Author: Philip Nienhuis <philip@JVC741>
56 ## Created: 2010-03-18 (First usable version) for ODS (java/OTK)
58 ## 2010-03-20 Added Excel support (Java/POI)
59 ## 2010-05-23 Added in support for jOpenDocument ODS
60 ## 2010-05-31 Fixed bugs in getusedrange_jod.m
61 ## 2010-08-24 Added support for odfdom 0.8.6 (ODF Toolkit)
62 ## 2010-08-27 Added checks for input arguments
63 ## '' Indentation changed from tab to doublespace
64 ## 2010-10-07 Added COM support (at last!)
65 ## 2011-05-06 Experimental support for Java/UNO bridge
66 ## 2011-06-13 OpenXLS support added
67 ## 2011-09-08 Style & layout updates
68 ## 2012-01-26 Fixed "seealso" help string
69 ## 2012-06-08 Replaced tabs by double space
70 ## '' Added COM and OXS to message about supported interfaces
72 ## Last subfunc update: 2012-06-08 (OTK)
74 function [ trow, lrow, lcol, rcol ] = getusedrange (spptr, ii)
77 if ~isstruct (spptr), error ("Illegal spreadsheet pointer argument"); endif
79 if (strcmp (spptr.xtype, 'OTK'))
80 [ trow, lrow, lcol, rcol ] = getusedrange_otk (spptr, ii);
81 elseif (strcmp (spptr.xtype, 'JOD'))
82 [ trow, lrow, lcol, rcol ] = getusedrange_jod (spptr, ii);
83 elseif (strcmp (spptr.xtype, 'UNO'))
84 [ trow, lrow, lcol, rcol ] = getusedrange_uno (spptr, ii);
85 elseif (strcmp (spptr.xtype, 'COM'))
86 [ trow, lrow, lcol, rcol ] = getusedrange_com (spptr, ii);
87 elseif (strcmp (spptr.xtype, 'POI'))
88 [ trow, lrow, lcol, rcol ] = getusedrange_poi (spptr, ii);
89 elseif (strcmp (spptr.xtype, 'JXL'))
90 [ trow, lrow, lcol, rcol ] = getusedrange_jxl (spptr, ii);
91 elseif (strcmp (spptr.xtype, 'OXS'))
92 [ trow, lrow, lcol, rcol ] = getusedrange_oxs (spptr, ii);
94 error ("Only OTK, JOD, COM, POI, JXL and OXS interface implemented");
100 ## Copyright (C) 2010,2011,2012 Philip Nienhuis, pr.nienhuis -at- users.sf.net
102 ## This program is free software; you can redistribute it and/or modify it under
103 ## the terms of the GNU General Public License as published by the Free Software
104 ## Foundation; either version 3 of the License, or (at your option) any later
107 ## This program is distributed in the hope that it will be useful, but WITHOUT
108 ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
109 ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
112 ## You should have received a copy of the GNU General Public License along with
113 ## this program; if not, see <http://www.gnu.org/licenses/>.
115 ## getusedrange_otk - get used range from ODS spreadsheet using ODF Toolkit
117 ## Author: Philip Nienhuis <philip@JVC741>
118 ## Created: 2010-03-18 (First usable version)
120 ## 2010-08-24 Support for odfdom (ODF Toolkit) 0.8.6 checked; we still need
121 ## => TableTable API because 0.8.6 is fooled by empty lowermost
122 ## filler rows comprising number-rows-repeated table attribute :-(
123 ## '' Indentation changed from tab to double space
124 ## 2010-11-13 Catched jOpenDocument bug (1.2bx) where string cells have no office:value-type
125 ## attrib set (by JOD). Somehow OTK is more robust as it catches these cells;
126 ## Currently this fix is just commented.
127 ## 2011-06-06 Fixed wrong if clause for finding last filler cells (L.160 & L.176)
128 ## 2011-09-12 Support for odfdom-0.8.7 added (API change for XPATH)
129 ## 2012-06-08 Support for odsfdom-0.8.8-incubator
131 function [ trow, lrow, lcol, rcol ] = getusedrange_otk (ods, ii)
133 odfcont = ods.workbook; # Local copy just in case
135 if (isfield (ods, 'odfvsn'))
136 if (strcmp (ods.odfvsn, '0.8.6') || strcmp (ods.odfvsn, '0.7.5'))
137 xpath = ods.app.getXPath;
139 # API changed in odfdom-0.8.7
140 xpath = ods.workbook.getXPath;
143 error ("ODS file ptr struct for OTK interface seems broken.");
146 # Create an instance of type NODESET for use in subsequent statement
147 NODESET = java_get ('javax.xml.xpath.XPathConstants', 'NODESET');
148 # Get table-rows in sheet no. wsh. Sheet count = 1-based (!)
149 str = sprintf ("//table:table[%d]/table:table-row", ii);
150 sh = xpath.evaluate (str, odfcont, NODESET);
151 nr_of_trows = sh.getLength();
153 jj = 0; # Table row counter
154 trow = 0; drows = 0; # Top data row, actual data row range
155 nrows = 0; reprows = 0; # Scratch counter
156 rcol = 0; lcol = 1024; # Rightmost and leftmost data column
157 while jj < nr_of_trows
159 # Check for data rows
160 rw_char = char (row) (1:min(500, length (char (row))));
161 if (findstr ('office:value-type', rw_char) || findstr ('<text:', rw_char))
163 # Check for uppermost data row
168 drows = drows + reprows;
172 # Get leftmost cell column number
173 lcell = row.getFirstChild ();
174 cl_char = char (lcell);
175 # Swap the following lines into comment to catch a jOpenDocument bug which foobars OTK
176 # (JOD doesn't set <office:value-type='string'> attribute when writing strings
177 #if (isempty (findstr ('office:value-type', cl_char)) || isempty (findstr ('<text:', cl_char)))
178 if (isempty (findstr ('office:value-type', cl_char)))
179 lcol = min (lcol, lcell.getTableNumberColumnsRepeatedAttribute () + 1);
184 # if rcol is already 1024 no more exploring for rightmost column is needed
186 # Get rightmost cell column number by counting....
188 for kk=1:row.getLength()
189 lcell = row.item(kk - 1);
190 rc = rc + lcell.getTableNumberColumnsRepeatedAttribute ();
192 # Watch out for filler tablecells
193 if (isempty (findstr ('office:value-type', char (lcell))) || isempty (findstr ('<text:', char (lcell))))
194 rc = rc - lcell.getTableNumberColumnsRepeatedAttribute ();
196 rcol = max (rcol, rc);
199 # Check for repeated tablerows
200 nrows = nrows + row.getTableNumberRowsRepeatedAttribute ();
202 reprows = reprows + row.getTableNumberRowsRepeatedAttribute ();
209 lrow = trow + drows - 1;
212 lrow = 0; lcol = 0; rcol = 0;
217 ## Copyright (C) 2010,2011,2012 Philip Nienhuis <prnienhuis -aT- users.sf.net>
219 ## This program is free software; you can redistribute it and/or modify it under
220 ## the terms of the GNU General Public License as published by the Free Software
221 ## Foundation; either version 3 of the License, or (at your option) any later
224 ## This program is distributed in the hope that it will be useful, but WITHOUT
225 ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
226 ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
229 ## You should have received a copy of the GNU General Public License along with
230 ## this program; if not, see <http://www.gnu.org/licenses/>.
234 ## Author: Philip <Philip@DESKPRN>
235 ## Created: 2010-05-25
237 ## 2010-05-31 Fixed ignoring table-covered-cells; fixed count of sheets comprising just A1:A1
238 ## Added option for wsh being a string argument
239 ## 2010-08-12 Little textual adaptations
240 ## 2010-11-13 Catched jOpenDocument bug (1.2bx) where string cells have no office:value-type
241 ## '' attrb set (by JOD). Somehow OTK is more robust as it catches these cells
242 ## 2012-04-09 Fixed rowrepcnt (str2num not applied to tablerow)
243 ## 2012-04-18 Added getUsedRange() method for JOD 1.3x and above
245 function [ trow, brow, lcol, rcol ] = getusedrange_jod (ods, wsh)
247 # This function works by virtue of sheets in JOD actually being a Java string.
248 # It works outside of the Java memory/heap space which is an added benefit...
249 # (Read: this is one big dirty hack...... prone to crash Java on BIG spreadsheets)
252 sh = char (ods.workbook.getSheet (wsh - 1));
254 sh = char (ods.workbook.getSheet (wsh));
258 # Let's see if we have JOD v. 1.3x. If not, next call fails & we'll fall back to the old hack
259 sh_rng = char (sh.getUsedRange ());
260 if (isempty (sh_rng))
262 trow = brow = lcol = rcol = 0;
265 sh_rng = sh_rng(length (sh.getName) + 2 : end);
267 sh_rng = strrep (sh_rng, '.', '');
268 [~, nr, nc, trow, lcol] = parse_sp_range (sh_rng);
269 brow = trow + nr - 1;
270 rcol = lcol + nc - 1;
274 # Fall back to the old hack :-(
277 # 1. Get table-row pointers
278 id_trow = strfind (sh, '<table:table-row');
279 id = strfind (sh, '</table:table>') - 1;
280 id_trow = [id_trow id];
283 lcol = 1024; brow = 0;
285 # 2. Loop over all table-rows
287 for irow = 1:length (id_trow)-1
288 # Isolate single table-row
289 tablerow = sh(id_trow(irow):id_trow(irow+1)-1);
290 # Search table-cells. table-c covers both table-cell & table-covered-cell
291 id_tcell = strfind (tablerow, '<table:table-c');
292 id_tcell = [id_tcell id];
293 rowl = length (tablerow);
294 if (isempty (id_tcell(1:end-1)))
297 rowend = id_tcell(1);
299 # Add in table-number-rows-repeated attribute values
300 rowrept = strfind (tablerow(1:rowend), 'number-rows-repeated');
301 if (~isempty (rowrept))
302 [st, en] = regexp (tablerow(rowrept:min (rowend, rowrept+30)), '\d+');
303 rowrepcnt += str2num (tablerow(rowrept+st-1:min (rowend, rowrept+en-1))) - 1;
306 # 3. Search table-cells. table-c is a table-covered-cell that is considered empty
307 id_tcell = strfind (tablerow, '<table:table-c');
308 if (~isempty (id_tcell))
309 # OK, this row has a value cell. Now table-covered-cells must be included.
310 id_tcell2 = strfind (tablerow, '<table:covered-t');
311 if (~isempty (id_tcell2)) id_tcell = sort ([id_tcell id_tcell2]); endif
312 id_tcell = [id_tcell rowl];
313 # Search for non-empty cells (i.e., with an office:value-type attribute). But:
314 # jOpenDocument 1.2b3 has a bug: it often doesn't set this attr for string cells
315 id_valtcell = strfind (tablerow, 'office:value-type=');
316 id_textonlycell = strfind (tablerow, '<text:');
317 id_valtcell = sort ([id_valtcell id_textonlycell]);
318 id_valtcell = [id_valtcell rowl];
319 if (~isempty (id_valtcell(1:end-1)))
320 brow = irow + rowrepcnt;
321 # First set trow if it hadn't already been found
322 if (~trow) trow = irow; endif
323 # Search for repeated table-cells
324 id_reptcell = strfind (tablerow, 'number-columns-repeated');
325 id_reptcell = [id_reptcell rowl];
326 # Search for leftmost non-empty table-cell. llcol = counter for this table-row
328 while (id_tcell (llcol) < id_valtcell(1) && llcol <= length (id_tcell) - 1)
332 # Compensate for repeated cells. First count all repeats left of llcol
335 if (~isempty (id_reptcell(1:end-1)))
337 while (ii <= length (id_reptcell) - 1 && id_reptcell(ii) < id_valtcell(1))
338 # Add all repeat counts left of leftmost data tcell minus 1 for each
339 [st, en] = regexp (tablerow(id_reptcell(ii):id_reptcell(ii)+30), '\d+');
340 repcnt += str2num (tablerow(id_reptcell(ii)+st-1:id_reptcell(ii)+en-1)) - 1;
343 # Next, add current repcnt value to llcol and update lcol
344 lcol = min (lcol, llcol + repcnt);
345 # Get last value table-cell in table-cell idx
347 while (id_tcell (jj) < id_valtcell(length (id_valtcell)-1))
351 # Get rest of column repeat counts in value table-cell range
352 while (ii < length (id_reptcell) && id_reptcell(ii) < id_tcell(jj))
353 # Add all repeat counts minus 1 for each tcell in value tcell range
354 [st, en] = regexp (tablerow(id_reptcell(ii):id_reptcell(ii)+30), '\d+');
355 repcnt += str2num (tablerow(id_reptcell(ii)+st-1:id_reptcell(ii)+en-1)) - 1;
359 # In case left column = A
360 lcol = min (lcol, llcol);
362 # Count all table-cells in value table-cell-range
363 ii = 1; # Indexes cannot be negative
364 while (ii < length (id_tcell) && id_tcell(ii) < id_valtcell(length (id_valtcell) - 1))
368 rcol = max (rcol, ii + repcnt);
373 # No data found, empty sheet
374 lcol = rcol = brow = trow = 0;
382 ## Copyright (C) 2011,2012 Philip Nienhuis
384 ## This program is free software; you can redistribute it and/or modify it under
385 ## the terms of the GNU General Public License as published by the Free Software
386 ## Foundation; either version 3 of the License, or (at your option) any later
389 ## This program is distributed in the hope that it will be useful, but WITHOUT
390 ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
391 ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
394 ## You should have received a copy of the GNU General Public License along with
395 ## this program; if not, see <http://www.gnu.org/licenses/>.
399 ## Author: Philip Nienhuis <prnienhuis@users.sf.net>
400 ## Created: 2011-05-06
402 ## 2011-06-29 Fixed wrong address range inference in case of sheet names containing period(s)
403 ## 2012-03-02 Adapted code to assess nr of range blocks to ';' separator fo LO3.5+
405 function [ srow, erow, scol, ecol ] = getusedrange_uno (ods, ii)
408 sheets = ods.workbook.getSheets ();
409 sh_names = sheets.getElementNames ();
410 unotmp = java_new ('com.sun.star.uno.Type', 'com.sun.star.sheet.XSpreadsheet');
411 sh = sheets.getByName(sh_names(ii)).getObject.queryInterface (unotmp);
413 # Prepare cell range query
414 unotmp = java_new ('com.sun.star.uno.Type', 'com.sun.star.sheet.XCellRangesQuery');
415 xRQ = sh.queryInterface (unotmp);
416 Cellflgs = javaObject ("java.lang.Short", "23");
417 ccells = xRQ.queryContentCells (Cellflgs);
419 # Get addresses of all blocks containing data
420 addrs = ccells.getRangeAddressesAsString ();
422 # Strip sheet name from addresses. Watch out, in LO3.5 they changed
423 # the separator from ',' to ';' (without telling me!)
424 # 1. Get nr of range blocks
425 nblks = numel (strfind (addrs, sh_names(ii)));
426 # 2. First try with ',' separator...
427 adrblks = strsplit (addrs, ',');
428 if (numel (adrblks) < nblks)
429 # Apparently we have a ';' separator, so try with semicolon
430 adrblks = strsplit (addrs, ';');
432 if (isempty (adrblks))
433 srow = erow = scol = ecol = 0;
437 # Find leftmost & rightmost columns, and highest and lowest row with data
440 for ii=1:numel (adrblks)
441 # Check if address contains a sheet name in quotes (happens if name contains a period)
442 if (int8 (adrblks{ii}(1)) == 39)
443 # Strip sheet name part
444 idx = findstr (adrblks{ii}, "'.");
445 range = adrblks{ii}(idx+2 : end);
447 # Same, but tru strsplit()
448 range = strsplit (adrblks{ii}, '.'){2};
450 [dummy, nrows, ncols, trow, lcol] = parse_sp_range (range);
451 brow = trow + nrows - 1;
452 rcol = lcol + ncols - 1;
453 srow = min (srow, trow);
454 scol = min (scol, lcol);
455 erow = max (erow, brow);
456 ecol = max (ecol, rcol);
462 ## Copyright (C) 2010,2011,2012 Philip Nienhuis
464 ## This program is free software; you can redistribute it and/or modify it under
465 ## the terms of the GNU General Public License as published by the Free Software
466 ## Foundation; either version 3 of the License, or (at your option) any later
469 ## This program is distributed in the hope that it will be useful, but WITHOUT
470 ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
471 ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
474 ## You should have received a copy of the GNU General Public License along with
475 ## this program; if not, see <http://www.gnu.org/licenses/>.
479 ## Author: Philip Nienhuis <prnienhuis@users.sf.net>
480 ## Created: 2010-10-07
482 function [ trow, brow, lcol, rcol ] = getusedrange_com (xls, ii)
484 sh = xls.workbook.Worksheets (ii);
486 # Decipher used range. Beware, UsedRange() returns *cached* rectangle of
487 # all spreadsheet cells containing *anything*, including just formatting
488 # (i.e., empty cells are included too). ==> This is an approximation only
489 allcells = sh.UsedRange;
491 # Get top left cell as a Range object
492 toplftcl = allcells.Columns(1).Rows(1);
494 # Count number of rows & cols in virtual range from A1 to top left cell
495 lcol = sh.Range ("A1", toplftcl).columns.Count;
496 trow = sh.Range ("A1", toplftcl).rows.Count;
498 # Add real occupied rows & cols to obtain end row & col
499 brow = trow + allcells.rows.Count() - 1;
500 rcol = lcol + allcells.columns.Count() - 1;
502 # Check if there are real data
503 if ((lcol == rcol) && (trow = brow))
504 if (isempty (toplftcl.Value))
505 trow = brow = lcol = rcol = 0;
512 ## Copyright (C) 2010,2011,2012 Philip Nienhuis, prnienhuis at users.sf.net
514 ## This program is free software; you can redistribute it and/or modify it under
515 ## the terms of the GNU General Public License as published by the Free Software
516 ## Foundation; either version 3 of the License, or (at your option) any later
519 ## This program is distributed in the hope that it will be useful, but WITHOUT
520 ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
521 ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
524 ## You should have received a copy of the GNU General Public License along with
525 ## this program; if not, see <http://www.gnu.org/licenses/>.
527 ## getusedrange_poi - get range of occupied data cells from Excel using java/POI
529 ## Author: Philip <Philip@DESKPRN>
530 ## Created: 2010-03-20
532 function [ trow, brow, lcol, rcol ] = getusedrange_poi (xls, ii)
534 persistent cblnk; cblnk = java_get ('org.apache.poi.ss.usermodel.Cell', 'CELL_TYPE_BLANK');
536 sh = xls.workbook.getSheetAt (ii-1); # Java POI starts counting at 0
538 trow = sh.getFirstRowNum (); # 0-based
539 brow = sh.getLastRowNum (); # 0-based
541 lcol = 1048577; # OOXML (xlsx) max. + 1
545 irow = sh.getRow (jj);
547 scol = (irow.getFirstCellNum).intValue ();
548 lcol = min (lcol, scol);
549 ecol = (irow.getLastCellNum).intValue () - 1;
550 rcol = max (rcol, ecol);
551 # Keep track of lowermost non-empty row as getLastRowNum() is unreliable
552 if ~(irow.getCell(scol).getCellType () == cblnk && irow.getCell(ecol).getCellType () == cblnk)
559 trow = 0; brow = 0; lcol = 0; rcol = 0;
561 brow = min (brow, botrow) + 1; ++trow; ++lcol; ++rcol; # 1-based return values
567 ## Copyright (C) 2010,2011,2012 Philip Nienhuis, prnienhuis at users.sf.net
569 ## This program is free software; you can redistribute it and/or modify it under
570 ## the terms of the GNU General Public License as published by the Free Software
571 ## Foundation; either version 3 of the License, or (at your option) any later
574 ## This program is distributed in the hope that it will be useful, but WITHOUT
575 ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
576 ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
579 ## You should have received a copy of the GNU General Public License along with
580 ## this program; if not, see <http://www.gnu.org/licenses/>.
582 ## getusedrange_jxl - get occupied data cell range from Excel sheet
583 ## using java/JExcelAPI
585 ## Author: Philip <Philip@DESKPRN>
586 ## Created: 2010-03-20
588 function [ trow, brow, lcol, rcol ] = getusedrange_jxl (xls, wsh)
590 persistent emptycell = (java_get ('jxl.CellType', 'EMPTY')).toString ();
592 sh = xls.workbook.getSheet (wsh - 1); # JXL sheet count 0-based
594 brow = sh.getRows ();
595 rcol = sh.getColumns ();
597 if (brow == 0 || rcol == 0)
599 trow = 0; lcol = 0; brow = 0; rcol = 0;
603 for ii=0:brow-1 # For loop coz we must check ALL rows for leftmost column
606 while (jj < rcol && emptyrow) # While loop => only til first non-empty cell
607 cell = sh.getCell (jj, ii);
608 if ~(strcmp (char (cell.getType ()), emptycell))
609 lcol = min (lcol, jj + 1);
614 if ~(emptyrow) trow = min (trow, ii + 1); endif
621 ## Copyright (C) 2010,2011,2012 Philip Nienhuis, <prnienhuis at users.sf.net>
623 ## This program is free software; you can redistribute it and/or modify it under
624 ## the terms of the GNU General Public License as published by the Free Software
625 ## Foundation; either version 3 of the License, or (at your option) any later
628 ## This program is distributed in the hope that it will be useful, but WITHOUT
629 ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
630 ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
633 ## You should have received a copy of the GNU General Public License along with
634 ## this program; if not, see <http://www.gnu.org/licenses/>.
638 ## Author: Philip <Philip@DESKPRN>
639 ## Created: 2011-06-13
641 ## 2011-06-29 try-catch to be able to skip non-data (e.g., graph) sheets
643 function [ trow, brow, lcol, rcol ] = getusedrange_oxs (xls, wsh)
645 sh = xls.workbook.getWorkSheet (wsh - 1);
647 # Intriguing: sh.getFirst<> is off by one, sh.getLast<> = OK.... 8-Z
648 trow = sh.getFirstRow () + 1;
649 brow = sh.getLastRow ();
650 lcol = sh.getFirstCol () + 1;
651 rcol = sh.getLastCol ();
653 # Might be an empty sheet
654 trow = brow = lcol = rcol = 0;
656 # Check for empty sheet
657 if ((trow > brow) || (lcol > rcol)), trow = brow = lcol = rcol = 0; endif