changeset 12274:b55a0fa638db octave-forge

Fix __OCT_xlsx_getusedrange__ range scanner for empty sheets
author prnienhuis
date Wed, 01 Jan 2014 22:08:05 +0000
parents d6aa088d1a9b
children a8b95bb1a8b9
files main/io/inst/private/__OCT_getusedrange__.m
diffstat 1 files changed, 14 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/main/io/inst/private/__OCT_getusedrange__.m	Wed Jan 01 21:54:07 2014 +0000
+++ b/main/io/inst/private/__OCT_getusedrange__.m	Wed Jan 01 22:08:05 2014 +0000
@@ -31,7 +31,8 @@
 ## 2013-10-01 Gnumeric subfunction added
 ## 2013-11-03 Fix wrong variable name "xml"->"sheet" in __OCT_ods_getusedrange__ 
 ## 2013-11-16 Replace fgetl calls by fread to cope with EOLs
-## 2013-12-14 (OOXML) Insert scanning to circumvent faulty "A1" range from POI
+## 2013-12-14 (OOXML) Insert scanning to circumvent faulty "A1" range from POI
+## 2014-01-01 Beware of empty sheets in __OCT_xlsx_getusedrange__ range scanner
 
 function [ trow, brow, lcol, rcol ] = __OCT_getusedrange__ (spptr, ii)
 
@@ -73,18 +74,24 @@
   node = getxmlnode (xml, "dimension");
   crange = getxmlattv (node, "ref");
   if (strcmpi (crange, "A1"))
-    ## Looks like it has been written by POI OOXML. We need a better guess
+    ## Looks like it has been written by POI OOXML or UNO. We need a better guess
     ## 1. Re-read entire worksheet
     fid = fopen (sprintf ('%s/xl/worksheets/sheet%d.xml', spptr.workbook, ii));
     xml = fread (fid, Inf, "char=>char").';
     fclose (fid);
     ## 2. Scan for cell addresses
     addr = cell2mat (regexp (xml, '<c r="(\w+)?"', "tokens"));
-    ## 3. Split in rows & columns, then sort
-    rows = sort (str2double (cell2mat (regexp (addr, '\d+', "match"))));
-    cols = sort (strjust (char (cell2mat (regexp (addr, '\D*', "match")))));
-    ## 4. Extract range by taking outer row/col limits
-    crange = sprintf ("%s%d:%s%d", cols(1), rows(1), cols(end), rows(end));
+    if (isempty (addr))
+      ## Empty sheet
+      trow = brow = lcol = rcol = 0;
+      return
+    else
+      ## 3. Split in rows & columns, then sort
+      rows = sort (str2double (cell2mat (regexp (addr, '\d+', "match"))));
+      cols = sort (strjust (char (cell2mat (regexp (addr, '\D*', "match")))));
+      ## 4. Extract range by taking outer row/col limits
+      crange = sprintf ("%s%d:%s%d", cols(1), rows(1), cols(end), rows(end));
+    endif
   endif
   [~, nrows, ncols, trow, lcol] = parse_sp_range (crange);
   brow = trow + nrows - 1;