Yet Another Excel COM Problem -- SAVEAS
Show older comments
Have a whole bunch of older Excel files that must process -- and for going forward would like to convert them to the current default .xlsx form programmatically rather than having to do all by hand.
But, as usual, COM is not very cooperative and the error feedback is zilch to figure out what it doesn't like. Can anybody spot the flaw here? Gets to the SaveAs method reliably but then goes boom--
function SaveXlsAsXlsx(filename)
% Takes a .xls file and saves as same name in .xlsx format
% MS VBA Enumerations
% XlFileFormat Enumeration
xlWorkbookDefault = 51; % Workbook default *.xlsx
% XlSaveAsAccessMode Enumeration
xlExclusive = 3; % Exclusive mode
xlNoChange = 1; % Default (does not change the access mode)
xlShared = 2; % Share list
% XlSaveConflictResolution Enumeration
xlLocalSessionChanges = 2; % The local user's changes are always accepted.
xlOtherSessionChanges = 3; % The local user's changes are always rejected.
xlUserResolution = 1; % A dialog box asks the user to resolve the conflict.
% Parse input file name; make sure is .xls
[folder, baseFileName, extension] = fileparts(filename);
if ~strcmpi(extension, '.xls')
error('filename not .XLS type. Aborting.')
end
% Now open Excel COM and do the deed...
try
Excel = matlab.io.internal.getExcelInstance;
catch exc %#ok<NASGU>
warning(message('MATLAB:xlsread:ActiveX'));
basicMode = true;
end
readOnly = false;
[~, workbookHandle,workbookState] = openExcelWorkbook(Excel, filename, readOnly);
c = onCleanup(@()xlsCleanup(Excel,filename,workbookState));
% Substitute .xlsx for .xls as file extension to write
filename=fullfile(folder, baseFileName, '.xlsx');
% and save new file
workbookHandle.SaveAs(filename,xlWorkbookDefault)
%workbookHandle.SaveAs(filename,xlWorkbookDefault,[],[],[],[],xlLocalSessionChanges)
workbookHandle.Close(false);
end
function xlsCleanup(Excel, filePath, alertState)
% Suppress all exceptions
try %#ok<TRYNC> No catch block
% Explicitly close the file just in case. The Excel API expects just the
% filename and not the path. This is safe because Excel also does not
% allow opening two files with the same name in different folders at the
% same time.
[~, name, ext] = fileparts(filePath);
fileName = [name ext];
Excel.Workbooks.Item(fileName).Close(false);
Excel.DisplayAlerts = alertState;
end
end
The pieces of
Answers (1)
Image Analyst
on 25 May 2020
Fixes made:
function SaveXlsAsXlsx(filename)
% Takes a .xls file and saves as same name in .xlsx format
% MS VBA Enumerations
% XlFileFormat Enumeration
xlWorkbookDefault = 51; % Workbook default *.xlsx
% XlSaveAsAccessMode Enumeration
xlExclusive = 3; % Exclusive mode
xlNoChange = 1; % Default (does not change the access mode)
xlShared = 2; % Share list
% XlSaveConflictResolution Enumeration
xlLocalSessionChanges = 2; % The local user's changes are always accepted.
xlOtherSessionChanges = 3; % The local user's changes are always rejected.
xlUserResolution = 1; % A dialog box asks the user to resolve the conflict.
% Parse input file name; make sure is .xls
[folder, baseFileName, extension] = fileparts(filename);
if ~strcmpi(extension, '.xls')
error('filename not .XLS type. Aborting.')
end
% Now open Excel COM and do the deed...
try
Excel = matlab.io.internal.getExcelInstance;
catch exc %#ok<NASGU>
warning(message('MATLAB:xlsread:ActiveX'));
basicMode = true;
end
readOnly = false;
if ~isfile(filename)
errorMessage = sprintf('Warning: %s does not exist and it needs to!', filename);
uiwait(errordlg(errorMessage));
return;
end
% If it's not the full path, it will throw an error
if ~(contains(filename, '/') || contains(filename, '\'))
filename = fullfile(pwd, filename); % Prepend current folder.
end
Excel.workbooks.Open(filename);
workbookHandle = Excel.ActiveWorkbook;
% [~, workbookHandle,workbookState] = openExcelWorkbook(Excel, filename, readOnly);
c = onCleanup(@()xlsCleanup(Excel,filename,workbookState));
% Substitute .xlsx for .xls as file extension to write
newFileName = strrep(filename, '.xls', '.xlsx');
% and save new file
workbookHandle.SaveAs(newFileName,xlWorkbookDefault)
%workbookHandle.SaveAs(filename,xlWorkbookDefault,[],[],[],[],xlLocalSessionChanges)
workbookHandle.Close(false);
end
12 Comments
dpb
on 25 May 2020
dpb
on 25 May 2020
Image Analyst
on 25 May 2020
If I have fixed content, and I want to use a pre-formatted workbook (cell colors, fonts, etc.) for my results, I'll use xlswrite().
If I have variable content (number of worksheets or columns varies), and I want to use a pre-formatted workbook for my results, I'll use ActiveX.
If I have any content and don't want to use a pre-formatted workbook template, then I'll use writecell() and writematrix() because these are faster than xlswrite(). However writecell() and writematrix() will blow away any formatting you'd done to the workbook, such as cell shading, borders, fonts, etc. Grrrrr... I've complained about that to them and they've put in on the feature request list.
For what it's worth, I'm attaching my ActiveX Excel class that you can use as static methods. You just need to instantiate the Excel variable with getActivexserver() first.
dpb
on 25 May 2020
Image Analyst
on 25 May 2020
What happens if you just rename the workbooks from .xls to .xlsx? It pops up a warning but you can just click through that. Might be the simplest option if you can live with the warning that the document is an xls instead of an xlsx.
dpb
on 26 May 2020
Himanshu Verma
on 8 Nov 2021
Is it possible to save the excel sheet as .htm file using MATLAB as we would do manually? I'm exporting text and images to excel sheet and saving it. But I want to save the same as .htm file automatically using Actxserver in MATLAB. What's the possible workaround. TIA
Image Analyst
on 8 Nov 2021
@Himanshu Verma, did you try having the filename use an htm or html extension? Otherwise you'd have to look at the API documentation
Himanshu Verma
on 10 Nov 2021
@Image Analyst yes, I tried having the extension as '.htm' but that didn't work.
Ok, I'll take a look at it. Thank you
Cris LaPierre
on 11 Nov 2021
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!