Ayak973 Ayak973 - 1 month ago 24
C++ Question

Excel interop C++: Workbook SaveAs exception - Code 0x800A03EC

I'm working with VBE6EXT and MSO to import/export excel files from my C++ application. I'm using the following code:

#import "C:\\Program Files (x86)\\Common Files\\Microsoft Shared\\OFFICE14\\MSO.DLL" \
rename("RGB", "MSORGB")
using namespace Office;
#import "C:\Program Files (x86)\\Common Files\\Microsoft Shared\\VBA\\VBA6\\VBE6EXT.OLB"
using namespace VBIDE;
#import "C:\\Program Files (x86)\\Microsoft Office\\Office14\\EXCEL.EXE" rename( "DialogBox", "ExcelDialogBox" ) \
rename( "RGB", "ExcelRGB" ) \
rename( "CopyFile", "ExcelCopyFile" ) \
rename( "ReplaceText", "ExcelReplaceText" ) \
exclude( "IFont", "IPicture" ) no_dual_interfaces


I've office 2010 installed, activated, up to date and I'm using Visual Studio 2015 Community Edition with Update 3 on Windows 10.

When I try to open a xlsx file and read value, everything works well, but when I try to create a file from scratch and save it, my program crash and throw a
_com_error
, with the following code:

Code :

Excel::_ApplicationPtr pApplication;

HRESULT hr = CoInitialize(nullptr);
if (FAILED(hr)) throw std::runtime_error("Impossible d'initialiser la librairie excel ! Code: " + std::to_string(hr));

if (FAILED(pApplication.CreateInstance("Excel.Application"))) throw std::runtime_error("CreateInstance failed ! (Office est pas installé?)");

pApplication->PutVisible(VARIANT_FALSE, 0);

Excel::_WorkbookPtr pBook = pApplication->Workbooks->Add(Excel::xlWorksheet);
if (pBook == nullptr) {
pApplication->Quit();
throw std::runtime_error("Impossible de créer le workbook !");
}


Excel::_WorksheetPtr pSheet = pApplication->ActiveSheet;

if (pSheet == nullptr) {
pBook->Close(VARIANT_FALSE);
pApplication->Quit();
throw std::runtime_error("Impossible de créer le worksheet !");
}

pSheet = pApplication->Worksheets->Add();
pSheet->Name = "Results";

pApplication->PutDisplayAlerts(LOCALE_USER_DEFAULT, VARIANT_FALSE);

try {
//always throws here
pBook->SaveAs("C:\\test.xls", vtMissing, vtMissing, vtMissing, false, false, Excel::XlSaveAsAccessMode::xlShared, false, false, vtMissing, vtMissing, vtMissing);
}
catch (_com_error& comErr) {
printComError(comErr);
}
pBook->Close();

pApplication->PutDisplayAlerts(LOCALE_USER_DEFAULT, VARIANT_TRUE);
pApplication->Quit();

CoUninitialize();


Function printComError():

static inline void printComError(const _com_error& e) {
_bstr_t bstrSource(e.Source());
_bstr_t bstrDescription(e.Description());

AllocConsole();
freopen("CONOUT$", "w", stdout);
freopen("CONOUT$", "w", stderr);

// Print Com errors.
std::cerr << "Error" << std::endl;
std::cerr << "\tCode = " << e.Error() << std::endl;
std::cerr << "\tCode meaning = " << e.ErrorMessage() << std::endl;
std::cerr << "\tSource = " << bstrSource << std::endl;
std::cerr << "\tDescription = " << bstrDescription << std::endl;
}


I've added a try/catch block and the function
printComError(comErr)
is always called with the following error:


Error
Code = -2146827284
Code meaning = 0975EB58
Source = Microsoft Excel
Description = Microsoft Excel ne peut accÚder au fichier ½áC:\CB7A7C80á╗. Plusieurs raisons sont possiblesá:

ò Le nom du fichier ou le chemin d'accÞs nÆexiste pas. ò Ce fichier
est actuellement utilisÚ par un autre programme. ò Le classeur que
vous essayez dÆenregistrer porte le mÛme nom quÆun classeur
actuellement ouvert.


wich means, in english:


Error
Code = -2146827284
Code meaning = 0975EB58
Source = Microsoft Excel
Description = Microsoft Excel can't access file ½áC:\CB7A7C80á╗. Many reasons are possibleá:

ò File name or path didn't exist. ò This file is in use by another application
ò The sheet that you want to save has the same name that another opened sheet


Apparently, error -2146827284 is like 0x800A03EC wich means NAME_NOT_FOUND, but its a newly created file, and didn't exist. The weird thing is that the error report that the filename is '½áC:\CB7A7C80á╗', but the first parameter of the SaveAs function is "c:\\test.xls".

I've seen related questions in Stackoverflow, but I didn't find useful answers.

Is this error related to an encoding of my string? Have you some hints to get the SaveAs function working?

Answer

This is just a rights/permission problem. If you use Excel itself as an end user, it will display a dialog box that say this

You don’t have permission to save in this location. Contact the administrator to obtain permission. Would you like to save in the Documents folder instead?

But, if you run Excel as admin, it will work fine, or it can work, because, at least, it works for me.

Note however that, programmatically, it indeed reports the error with a funny name like CB7A7C80 (it's a temp file it uses behind the scene) instead of the original one (the corruption is only at beginning and end of your string). I do reproduce that funny name also.