From: <prn...@us...> - 2009-12-13 20:48:32
|
Revision: 6642 http://octave.svn.sourceforge.net/octave/?rev=6642&view=rev Author: prnienhuis Date: 2009-12-13 20:48:21 +0000 (Sun, 13 Dec 2009) Log Message: ----------- Moved range limit calculations from xlsread to parsecell; fixed parse_sp_range for larger column capacities(OOXML & ODS). Modified Paths: -------------- trunk/octave-forge/main/io/inst/parse_sp_range.m trunk/octave-forge/main/io/inst/parsecell.m trunk/octave-forge/main/io/inst/xlsread.m Modified: trunk/octave-forge/main/io/inst/parse_sp_range.m =================================================================== --- trunk/octave-forge/main/io/inst/parse_sp_range.m 2009-12-13 14:47:03 UTC (rev 6641) +++ trunk/octave-forge/main/io/inst/parse_sp_range.m 2009-12-13 20:48:21 UTC (rev 6642) @@ -21,15 +21,14 @@ ## Author: Philip Nienhuis ## Created: 2009-06-20 -## Latest update 2009-12-11 +## Latest update 2009-12-13 function [topleft, nrows, ncols, toprow, lcol] = parse_sp_range (range_org) - # This entire function needs fixing or replacement for OOXML (larger ranges) - range = deblank (toupper (range_org)); range_error = 0; nrows = 0; ncols = 0; + # Basic checks if (index (range, ':') == 0) if (isempty (range)) range_error = 0; @@ -37,10 +36,15 @@ rightcol = 'A'; else # Only upperleft cell given, just complete range to 1x1 + # (needed for some routines) range = [range ":" range]; endif endif + + # Split up both sides of the range [topleft, lowerright] = strtok (range, ':'); + + # Get toprow and clean up left column [st, en] = regexp (topleft, '\d+'); toprow = str2num (topleft(st:en)); leftcol = deblank (topleft(1:st-1)); @@ -51,6 +55,7 @@ [st, en2] = regexp (leftcol,'\D+'); leftcol = leftcol(en1+1:en2); + # Get bottom row and clean up right column [st, en] = regexp (lowerright,'\d+'); bottomrow = str2num (lowerright(st:en)); rightcol = deblank (lowerright(2:st-1)); @@ -60,33 +65,30 @@ endif [st, en2] = regexp (rightcol,'\D+'); rightcol = rightcol(en1+1:en2); + + # Check nr. of rows nrows = bottomrow - toprow + 1; if (nrows < 1) range_error = 1; endif if (range_error == 0) - # Get columns. - # FIXME for OOXML! We provisonally assume Excel 97 format, max 256 columns - ncols = 0; - [st, en1] = regexp (leftcol, '\D+'); - [st, en2] = regexp (rightcol, '\D+'); - i1= 0; i2 = 0; - if (en2 > en1) - i1 = rightcol(2:2) - leftcol(1:1) + 1; - i2 = rightcol(1:1) - 'A'+ 1; - lcol = leftcol(1:1) - 'A' + 1; - elseif (en2 == en1) - i1 = rightcol(en2) - leftcol(en2) + 1; - lcol = leftcol(1:1) - 'A' + 1; - if (en2 == 2) - i2 = rightcol(1) - leftcol(1); - lcol = lcol * 26 + (leftcol(2:2) - 'A' + 1); - endif - else - range_error = 1; - endif - ncols = i1 + 26 * i2; + # Get left column nr. + [st, en] = regexp (leftcol, '\D+'); + lcol = (leftcol(st:st) - 'A' + 1); + while (++st <= en) + lcol = lcol * 26 + (leftcol(st:st) - 'A' + 1); + endwhile + + # Get right column nr. + [st, en] = regexp (rightcol, '\D+'); + rcol = (rightcol(st:st) - 'A' + 1); + while (++st <= en) + rcol = rcol * 26 + (rightcol(st:st) - 'A' + 1); + endwhile + + # Check + ncols = rcol - lcol + 1 if (ncols < 1) range_error = 1; endif Modified: trunk/octave-forge/main/io/inst/parsecell.m =================================================================== --- trunk/octave-forge/main/io/inst/parsecell.m 2009-12-13 14:47:03 UTC (rev 6641) +++ trunk/octave-forge/main/io/inst/parsecell.m 2009-12-13 20:48:21 UTC (rev 6642) @@ -38,11 +38,11 @@ ## @end deftypefn ## Author: Philip Nienhuis -## Created: 2009-12-11 +## Created: 2009-12-13 -function [ numarr, txtarr, lim ] = parsecell (rawarr) +function [ numarr, txtarr, lim ] = parsecell (rawarr, rawlimits=[]) - lim = struct ( "numlimits", [], "txtlimits", [] ); + lim = struct ( "numlimits", [], "txtlimits", []); numarr = []; txtarr = {}; @@ -59,7 +59,7 @@ endif # Prepare parsing [nrows, ncols] = size (rawarr); - + # Find text entries in raw data cell array txtptr = cellfun ('isclass', rawarr, 'char'); if (~no_txt) @@ -82,6 +82,11 @@ # Crop textarray txtarr = txtarr(irowt:irowb, icoll:icolr); lim.txtlimits = [icoll, icolr; irowt, irowb]; + if (~isempty (rawlimits)) + correction = [1; 1]; + lim.txtlimits (:,1) = lim.txtlimits(:,1) + rawlimits(:,1) - correction; + lim.txtlimits (:,2) = lim.txtlimits(:,2) + rawlimits(:,1) - correction; + endif else # If no text cells found return empty text array txtarr = {}; @@ -118,8 +123,16 @@ endfor numarr = cat (2, tmparr{:}); lim.numlimits = [icoll, icolr; irowt, irowb]; + if (~isempty (rawlimits)) + correction = [1; 1]; + lim.numlimits(:,1) = lim.numlimits(:,1) + rawlimits(:,1) - correction(:); + lim.numlimits(:,2) = lim.numlimits(:,2) + rawlimits(:,1) - correction(:); + endif endif endif + + lim.rawlimits = rawlimits; + endif endfunction Modified: trunk/octave-forge/main/io/inst/xlsread.m =================================================================== --- trunk/octave-forge/main/io/inst/xlsread.m 2009-12-13 14:47:03 UTC (rev 6641) +++ trunk/octave-forge/main/io/inst/xlsread.m 2009-12-13 20:48:21 UTC (rev 6642) @@ -101,11 +101,11 @@ ## @end example ## ## @example -## [An, Tn, Ra, status] = xlsread ('Sales2009.xls', 'Third_sheet'); +## [An, Tn, Ra, limits] = xlsread ('Sales2009.xls', 'Third_sheet'); ## (which returns the numeric contents in range C3:AB40 in worksheet ## 'Third_sheet' in file test4.xls into array An, the text data into -## array Tn, the raw cell data into cell array Ra and the return status -## in status) +## array Tn, the raw cell data into cell array Ra and the ranges from +## where the actual data came in limits) ## @end example ## ## @seealso xlswrite, xlsopen, xls2oct, xlsclose, xlsfinfo, oct2xls @@ -116,7 +116,7 @@ ## Created: 2009-10-16 ## Latest update: 2009-12-11 -function [ numarr, txtarr, rawarr, limits ] = xlsread (fn, wsh, datrange, reqintf=[]) +function [ numarr, txtarr, rawarr, lims ] = xlsread (fn, wsh, datrange, reqintf=[]) rstatus = 0; @@ -164,22 +164,10 @@ xls = xlsclose (xls); if (rstatus) - [numarr, txtarr, lims] = parsecell (rawarr); - limits = []; - - # Rebase various limits to original spreadsheet limits - if ((strcmp (xtype, 'POI') || strcmp (xtype, 'JXL')) && ~isempty (rawlimits)) - correction = [1; 1]; - if (~isempty(lims.numlimits)) - limits.numlimits(:,1) = rawlimits(:,1) + lims.numlimits(:,1) - correction(:); - limits.numlimits(:,2) = limits.numlimits(:,1) + lims.numlimits(:,2) - lims.numlimits(:,1); - endif - if (~isempty(lims.txtlimits)) - limits.txtlimits(:,1) = rawlimits(:,1) + lims.txtlimits(:,1) - correction(:); - limits.txtlimits(:,2) = limits.txtlimits(:,1) + lims.txtlimits(:,2) - lims.txtlimits(:,1); - endif - limits.rawlimits = rawlimits; - endif + [numarr, txtarr, lims] = parsecell (rawarr, rawlimits); + # Wipe lims if using Excel (that doesn't return reliable rawlimits). + # The user can get the limits relative to the rawarr by parsecell (rawarr). + if (strcmp (xtype, 'COM')) lims = []; endif else rawarr = {}; numarr = []; txtarr = {}; endif This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |