Delphi Ole - Sudden Error - Interface not supported - excel

Delphi Tokyo, Office 2016. I have an existing app, been running great for a while. I went this morning to run the application, and all the sudden it is throwing an error. I open the source code and step through it. It is throwing the following error:
'Project ... raised exception class EIntfCastError with message 'Interface not supported'.
The line of code causing the issue is
oExcel := CreateOleObject('Excel.Application') as ExcelApplication;
The source code has not changed. The issue was first found in the executable. Excel appears to be working fine. There is one other fact, which may or may not be relevant... Every time I start Outlook I get a popup Error message 'Failed to load the elevation application'. This started approximately 1 month ago, and to my knowledge, I don't believe I have run my application since I started receiving this message. I cannot find any information about this, but it does not seem to effect Outlook. (I have performed both a Quick Repair as well as an Online Repair for MS Office 2016, but neither effort changes anything.) When I look at Outlook Plugins, I do NOT have any plugIn called 'Elevation'.
The Outlook issue may or may not be related to the Excel issue.
What is going on here? How do I debug this further?

I would split you code into two steps, one to create the Ole object and the other
to extract the ExcelApplication interface. This way, you can easily identify which
of the two steps is geneerating the exception. Something like this
var
oExcel : OleVariant;
...
oExcel := CreateOleObject('Excel.Application');
oExcel := IDispatch(oExcel) as ExcelApplication;
To be honest, when I first saw your code, I was surprised it compiled in the first
place, but I checked it and it did.
However, there is really not a lot of point in assigning the ExcelApplication interface
back to an OleVariant. It would be better to assign it to an interface variable and use
that to make use of the early-binding, type safety and code-completion that is available
in the IDE. So I would do something like this, instead:
var
oExcel : OleVariant;
Excel : ExcelApplication;
...
oExcel := CreateOleObject('Excel.Application');
Excel := IDispatch(oExcel) as ExcelApplication;
// then use the Excel interface instead of oExcel.
Tbh, I am not expert enough in COM/Ole to be sure why splitting the original single step into two makes the difference between it not working and working. Perhaps a COM expert will chip in on that.

Related

VBA EXCEL VBA How to enable (check) specific Type Library in Tools/References programmatically?

That's basically my question. Doing googling didn't return anything that I am looking for, but basically I am running SOLIDWORKS from Excel and for that I need "sldworks 2016 Type Library" and "SOLDIWORKS 2016 Constant Type Library" to be enabled. Of course you'd say to do it manually, BUT my program is being run both, by people with and without Solidworks installed and if a user doesn't have SOLDIWORKS on their PC - the entire thing won't even run. So I am looking to enable and disable those two type libraries upon necessity in the code.
Could, someone, please help me?
P.S. I am not looking for any workarounds etc.
BUT my program is being run both, by people with and without Solidworks installed and if a user doesn't have SOLDIWORKS on their PC - the entire thing won't even run.
Is this what you are trying? The below code will first try to bind with an open instance of SOLIDWORKS. If it is not open, then it will try to create a new instance. Obviously if SOLIDWORKS is not installed then the CreateObject will fail but the code will not crash because of On Error Resume Next. Finally check if objSolid is not nothing. This is late binding and you do not have to set any references.
Dim objSolid As Object
'~~> Establish an SOLIDWORKS application object
On Error Resume Next
Set objSolid = GetObject(, "SldWorks.Application")
'~~> If not found then create new instance
If Err.Number <> 0 Then Set objSolid = CreateObject("SldWorks.Application")
Err.Clear
On Error GoTo 0
If objSolid Is Nothing Then
MsgBox "SOLIDWORKS not installed"
Exit Sub
End If
'
'~~> Rest of your code
'
EDIT
You cannot say Solidworks is not properly documented without putting in the right efforts to search. It took me less than 30 seconds to find this SOLIDWORKS Example of Late Binding. Of course their code will fail if the user doesn't have SOLIDWORKS and that is because they have not done proper error handling. My answer above does that for you.
Their website has all the information that you need. You just need to put in the right efforts to search. As I mentioned in the chat below, when you convert the code into late binding, you will have to search for the value of those constants. No one will give them to you in a platter. :) You can either search Google with swDocPART Constant value or as #FunThomas pointed out, type ?swDocPART in Immediate Window to get the value when the reference to SOLIDWORKS has been established.

MS Office last updates causing some strange behavior in handling VBA code

Our admins ran some MS Office 2016 updates (Build 11929.20838) and all of a sudden I noticed a few unexpected errors in one of my previously written Excel VBA macros. For example below error is popping up against any variable which I have not defined explicitly. It was not the case before and unless I had mentioned Option Explicit, I had never experienced anything like this.
Compile error:
Can't find project or library
I am also getting the same error against the following 2 statements of my code, whereas it used to run smoothly before the last Microsoft Office 2016 update.
' Against the following two declarations, the compiler is highlighting
' Date in parenthesis and quoting same error "Can't find project or library"
xMonth = VBA.DateTime.Month(Date)
xYear = VBA.DateTime.Year(Date)
' And showing same error as above against defining an Array variable like below
srchString = Array("invoice_number", "invoice_date", "Category_wise_code", "Bill To Customer", "consignees_address_long")
'And even here, it is giving the same error:
[A1].Font.Bold = True
Does anyone have any idea about these errors and how to resolve this issue? All of this quite unexpected. Let me tell you this macro has been in my use for over 4 years and I never ran into issues like these.
You will find something fishy here:
https://www.google.com/search?rlz=1C1CHZL_enGB838GB838&ei=EOInX-ibPMeusAXFw7z4Cg&q=%22ms+office+2016%22+%22july+updates%22+%22VBA%22&oq=%22ms+office+2016%22+%22july+updates%22+%22VBA%22&gs_lcp=CgZwc3ktYWIQAzoECAAQRzoICCEQFhAdEB46BQghEKABUOTJCljq_gtgg4UMaABwAXgAgAHzAogByiiSAQYyLTIuMTSYAQCgAQGqAQdnd3Mtd2l6wAEB&sclient=psy-ab&ved=0ahUKEwjo4_6J5f7qAhVHF6wKHcUhD68Q4dUDCAw&uact=5
Although not all links are opening, but Google window is briefly showing that some people are also facing macro crash situation.
Thanks for your time reading my post.

Message filter indicated that the application is busy

I've looked through a lot of the other threads on this but none of those solutions has helped me. I'm trying to open Excel via Microsoft.Office.Interop.Excel to load data into a worksheet. I have tried this solution but that did not solve my issue. I have also seen others say that settings DispayAlerts to False helped them, however that did not resolve my issue. I even tried adding in a 5 second wait to give Excel time to fully open but still no luck. A small sample of my code that I'm using to open Excel is below. This is working without issues on two machines that I've installed my application on, but the third on (2012 R2 64-bit server running Excel 2010 32-bit) is causing me all kinds of headaches. Unfortunately, because I can't replicate this on my testing machine with Visual Studio installed, I can't debug the error. Any help would be greatly appreciated.
Dim _excel As New Excel.Application
Dim WBook As Excel.Workbook = Nothing
_excel.DisplayAlerts = False
WBook = _excel.Workbooks.Open(Path.Combine(FolderPath, FileName))
I was able to get this resolved. Creating an OleMessageFilter with this link and converting my BackgroundWorker to an STA Thread with help from this link seemed to do the trick. Had to pretty much rewrite my entire background process but at least it's working. Thanks for all the help!

Save Method of Application class failed when trying to save an Excel Document

I havea a method in Delphi that saves some data into a ExcelFile. The Program works fine for any kind of Excel except Excel 2013.
Here is the code
try
// If no instance of Word is running, try to Create a new Excel Object
ExcelApp := CreateOleObject('Excel.Application');
except
ShowMessage('Cannot start Excel/Excel not installed ?');
Exit;
end;
ExcelApp.DisplayAlerts := False;
ExcelApp.Workbooks.Add(xlWBatWorkSheet);
// fill the Excel file
ExcelApp.Visible := True;
// Save the Workbook
ExcelApp.save;
if not VarIsEmpty(ExcelApp) then begin
ExcelApp.DisplayAlerts := False; // Discard unsaved files....
ExcelApp.Quit;
end;
So As I said, this worked fine for Excel untill the 2013 Version. When I try to use this on a computer with Excel 2013 I get the error
Save Method of Application class failed.
Any Ideas why is this happening and any possible Workaround?
PS I tried with
ExcelApp.Workbooks[1].SaveAs('c:\test.xlsx', xlWBATWorksheet);
I also get an error :
SaveAS Method of Workbook class failed.
I also read that I could be that I don't have acces to save on that location, but i'm the administrator on the computer.
If I help the time of executing this operation takes a lot more time that It usually did in Excel 2010 or Excel 2007.
According to the documentation, the Excel Application object has no Save method. Use SaveAs from the Workbook object.
You are trying to save a file to the root directory of the system volume, and by default, that is secured so that standard user cannot create files in that location. Even though you are an administrator, UAC means that your process runs with a standard user token.
The other problem I see is that xlWBATWorksheet is not a file format constant. You mean to use xlOpenXMLWorkbook. This should be fine:
Workbook.SaveAs('c:\somedir\test.xlsx', xlOpenXMLWorkbook);
where you replace c:\somedir with some suitable path on your machine.
Switching to early bound COM might alleviate some of your travails but the answers can always be found in the documentation. You don't need to do this blind.
I haven't done any Microsoft Office automation myself but I do remember from the time that I still used Delphi 7 that when you installed it the installer actually asked you for which version of office do you wanna install the extensions for.
So I would gues that there are some differences in COM implementation that different versions of Microsoft Office use so it is posible that components your Delphi use for Microsoft Office Automation are not compatible with Office 2013.
May not be relevant but had same error message in VB6 (yes, 2016 and I still use it for odd things on Windows 10!) because the sheet was selected. Selected another object before saving and it worked.
You need to install KB2830391 HF460904 for Excel 2013 issue for AX 2009. Change in one sysExcel class on how the transfer/save are made!

Compatibility Between MS-Access 2003 and MS-Excel 2013

This is similar to a question that I've asked yesterday, but I've managed to find a fair bit more information: enough to warrant a new question, I feel.
My office has recently moved to Windows 7 along with Office 2013 - with the except of Access which has stayed as 2003.
Access works absolutely fine except when I try to automate Excel. This is a feature of nearly all my applications.
When I load an old project, the reference is automatically updated to "Microsoft Excel 15.0 Object Library" - it is held as an EXE file in Program Files (x86). Note: it does not say the reference is missing.
When I try to run any code which uses early binding, it fails with the following error message: "Error in loading DLL"
I've since tried late binding by doing the following:
Dim app As Object
Dim wb As Object
Set app = CreateObject("Excel.Application")
app.Visible = True
Set wb = app.Workbooks.Add
This creates the Application, it becomes visible, a Workbook is added, but then I get the following error: "Run-time error '1004':
Application-definted or object-defined error"
If I try to access VBA in the new Workbook I get the following error: "An error occurred initializing the VBA libraries (1004)" The Workbook is loaded in "Compatibility Mode"
The above leads me to believe that the 2 applications may not be compatable, but the following is worth considering:
If I try to use early binding I don't get the Intellisense drop-downs but words like Workbook and Worksheet do auto-capitalise themselves as you would normally expect them to. The code won't compile at all if I don't have the reference set, but it does compile - and throw and error - when it is. I've since tried Word 2013 - who's Object Reference is an OLB file rather than EXE - and I get the full Intellisense features I would except, but it still throws the same error when trying to run.
In a nut shell, does anyone know if I stand any chance of having the 2 work together?
Thanks

Resources