Clear Filters
Clear Filters

XLSREAD: "Subscript indices must either be real positive integers or logicals."

1 view (last 30 days)
Hello,
I get this error when trying to open XLSX files created by LabVIEW using the function XLSREAD() to open them.
I am calling the function as follows:
[NUM TXT RAW] = xlsread(filepath);
I am running MATLAB r2016a on Mac OS X Sierra, and the excel files are created via LabView 2016 on Windows 7. I have been able to get around this by opening the XLSX file with Excel, and saving it again.
While this does work, it slows down the process of parsing experimental data. I have been unable to locate any solutions via google search, since the error "Subscript indices must either be real positive integers or logicals" is common and not necessarily specific to XLSREAD.
I have attached an XLSX file that throws the error.
Any help appreciated.
  4 Comments
Walter Roberson
Walter Roberson on 1 Nov 2016
Okay, it will take me a few minutes to install R2016a on my Sierra virtual machine to check this with.

Sign in to comment.

Accepted Answer

Walter Roberson
Walter Roberson on 2 Nov 2016
.xlsx files are .zip files that contain directories and a series of different .xml files, including information about the different worksheet names.
The routine to parse the worksheet names is expecting that the XML will look like similar to
<sheet name="sheet1" sheetId="1" r:id="rId1"/>
but instead in that file it looks like
<sheet name= "sheet1" sheetId="1" r:id="rId1"/>
notice the space between the = and the " that follows it.
I do not know enough about the XML standards to know whether a space there is permitted or not, but what we do know is that in those files the space is there . And so whether it is "proper" or not, we can hack around that part of the problem fairly easily.
edit( fullfile(toolboxdir('matlab'),'iofun','private','getSheetNames.m') )
and head to line 19, which will have
match = regexp(workbook_xml, '<sheet[^>]+name="(?<sheetName>[^"]*)"[^>]*r:id="(?<rid>[^>]+?)"[^>]*/>|<sheet[^>]*r:id="(?<rid>[^>]+?)"[^>]*name="(?<sheetName>[^"]*)"[^>]*/>', 'names');
Change that to
match = regexp(workbook_xml, '<sheet[^>]+name=\s*"(?<sheetName>[^"]*)"[^>]*r:id="(?<rid>[^>]+?)"[^>]*/>|<sheet[^>]*r:id="(?<rid>[^>]+?)"[^>]*name=\s*"(?<sheetName>[^"]*)"[^>]*/>', 'names');
And save the file. You should then be able to xlsinfo() the file.
(You might need to do a "rehash toolboxcache", maybe)
However, more is needed to be done to xlsread() the file. It appears the xml does not have a dimension declaration; I will need to investigate how to deal with that.
  5 Comments
Walter Roberson
Walter Roberson on 4 Nov 2016
Improved code snippet. This is nearly the same as above, but avoids having to do another run through the entire XML text, making use of data that has already been extracted (now that I understand better how it all works.)
if isempty(range)
span = regexp(sheetData, '<dimension[^>]+ref="(?<start>[A-Z]+\d+)(?<end>:[A-Z]+\d+)?"[^>]*>', 'names', 'once');
%{
if isempty(span.end)
span.end = [':' span.start];
end
%}
if isempty(span)
colrefs = regexp({parsedSheetData.ranges}, '(?<clets>[A-Za-z]+)(?<cnums>\d+)', 'names');
colrefs = vertcat(colrefs{:});
uniq_lets = unique( {colrefs.clets} );
uniq_nums = unique( str2double({colrefs.cnums}) );
if ~isempty(uniq_lets)
span(1).start = sprintf('%s%d', uniq_lets{1}, uniq_nums(1));
span(1).end = sprintf('%s%d', uniq_lets{end}, uniq_nums(end));
range = [span.start ':' span.end];
else
range = []; %we could not figure out the range, now what?
end
else
if isempty(span.end)
span.end = [':' span.start];
end
range = [span.start span.end];
end
end
Walter Roberson
Walter Roberson on 4 Nov 2016
Once the regexp change is made in xlsinfo to handle the space that LabView puts in, it turns out that the simplest work-around for LabView files is to specify the range to read explicitly. When the user specifies the range to read, then the buggy code in xlsread, the code that crashes because of the missing (optional) property, would not be executed.

Sign in to comment.

More Answers (1)

Steven Lord
Steven Lord on 2 Nov 2016
You've created a variable with the same name as the function you're trying to call on the line where the error occurs. Set a breakpoint on that line (click on the dash to the left of that line of the file while it's open in the Editor) then run your code. Use the which function to confirm that there is a variable with the name of one of those functions. When you determine the name of the variable, rename or remove that variable in your code.
  3 Comments
Walter Roberson
Walter Roberson on 2 Nov 2016
Edited: Walter Roberson on 2 Nov 2016
Steven's reply is often the cause of such messages, but turns out not to have anything to do what the cause of this particular problem. I have (partly) solved it and will write it up now.
Steven Lord
Steven Lord on 2 Nov 2016
Yes, I jumped to the conclusion that this error was being caused by a variable shadowing a function. That is the most common cause of this error. But it sounds like Walter has done more investigation and uncovered a different cause for this same error. That was my mistake, and I've upvoted his answer to move it above mine.

Sign in to comment.

Categories

Find more on Startup and Shutdown in Help Center and File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!