How to find if any compile errors exists due to missing DLL reference? - excel

We have developed a program in Excel VBA.
Say for instance we are having a compiler problem in one of the functions (Debug->Compile VBAProject gives some type mismatch error).
Without clicking that option, is there any way after the program load, we can intimate the user by showing a message like "You have compiler error in your test program, please click Debug->Compile VBAProject and fix the compiler errors"?
Actual problem is, a program (Excel VBA) is having compiler error, but the user doesn't know it. He just started running the program which results in failure.
So after the program load, without manually clicking Debug->Compile, after the excel is launched, it should throw a pop-up saying "you are having compiler errors, Do Debug->Compile VBAProject and fix it".
The actual error is "Compiler error: User-defined type not defined".
As part of our software installation, we are installing certain DLLs in the customer machine. The customer can add those DLLs as reference and edit their program.
As the Excel program is having a compiler error, "OnProgramLoaded interpose" function is not called. So the code inside that function is not executed. The user has no clue that this code is not called.
Additional information: Earlier we have the "Compile On Demand" checkbox as checked. So even though there is a compiler error in the program, the "OnProgramLoaded interpose" function is getting called. Now for different reason, we have removed the check box from "Compile On Demand", so what happens now is, since there is compiler error, it is not executing the other functions too.
So what we are trying to do is, as soon as the program is launched, we need to give the message to user that the program is having compiler errors. Fix it and restart the program.

You can check, if your desired VBA references are already enabled:
Private Sub CheckVBAReferences()
Dim dict As Object
Dim oRef As Object
Dim i As Long
Set dict = CreateObject("Scripting.Dictionary")
For Each oRef In ThisWorkbook.vbProject.References
dict.Add oRef.Description & ", " & oRef.fullpath, oRef.GUID
Debug.Print oRef.Description & ", " & oRef.fullpath
Next oRef
If Not dict.Exists("Microsoft Excel 16.0 Object Library, " & _
"C:\Program Files\Microsoft Office\Root\Office16\EXCEL.EXE") Then
MsgBox "Please add a VBA reference to ..."
' or set it according to following link
End If
dict.RemoveAll
Set dict = Nothing
End Sub
And then you may set a missing reference according to this answer.

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.

How to suppress excel compiler error from VB6

I am executing the Excel 'Debug -> Compile VBAProject' from a VBA project like below,
Public Function CheckForCompilerErrors()
On Error GoTo compileerr
ExcelObject.ActiveWorkbook.VBProject.VBE.CommandBars.findcontrol(ID:=578).Execute
Exit Function
compilerErr:
MsgBox "Compilation failed. Give Debug->Compile VBAProject and fix the compilation errors."
End Function
Here after running the .Execute, Excel VBA is throwing the error "Compiler Error: User-defined type not defined.".
But actually I want to suppress this Excel VBA error. That's the reason why I added error handler. But in the above case, it is not going to error handler.
Maybe what I am suspecting is, since the .Execute got successfully called (which invokes Debug->Compile VBAProject) whether there is any error or not, it returns success and not going to error handler.
Is there anyway, I can suppress the Excel VBA compiler error.
When you are sending the click to the Compile button, there will be an error if the button is unavailable, which it is if you just compiled something. That error you can catch and suppress.
If there is a compilation error, you won't be able to catch it this way.

msoFileDialogFilePicker resulting in error

Please don't comment with anything about naming conventions, approaches, asking what the code is supposed to DO, or anything that isn't directly related to my issue:
This runs perfectly for me, everytime--A window pops up, and I select multiple Excel files and their data is uploaded into my sheet (Code not pictured). My client says he gets an error when he runs it, and naturally I assumed it was because he ran it on a Mac...but he says he gets the error on both PC and Mac. I can't recreate the error...and here we are.
Here's the code in question, the erring line highlighted in yellow:
Code for your copying:
Sub Import_Employee_Sheet()
With Application.FileDialog(msoFileDialogFilePicker)
.AllowMultiSelect = True
If .Show = True Then
End If
End With
End Sub
This is probably because he hasn't set the Microsoft Object [Version number] Library reference under Tools/References in the IDE, or because it's broken. Also see this post on how to fix the problem WITHOUT setting the object reference in order to avoid similar problems in the future.
Edit
It should read "...without setting the library reference" above.

Err.Number not populating for 'Excel Ran Out of Resources' error

I've developed a program using Excel VBA which occasionally causes an 'Excel Ran Out of Resources' error.
Closing the file, reopening, and rerunning the macro always fixes whatever issue created the error. I know that preventing the error in the first place is best practice, but am resigned to believe that it's unavoidable.
So, I would like to alert the user of the error, instead of Excel doing it, and perform some actions once the error has been detected. The problem is that I can't get VBA to recognize the error using the On Error GoTo ErrorHandler routine or the Err.Number property. I never get to the msgbox below:
My code is as follows:
Sub test()
On Error GoTo ErrorHandler
Calculate
ProcedureDone:
Exit Sub
ErrorHandler:
MsgBox "Error", vbOKOnly, "Oops"
Resume ProcedureDone
End Sub
Any insight would be fantastic since I've been searching for several days and haven't been able to find a work around.
I just happened to run across another issue that sounds like yours.
The point from the other thread is that Excel does not treat these application method results as VBA errors. Rather, they are Excel alerts, and they can be suppressed but not trapped in VBA as errors.
The way I interpret this is that when you execute certain application methods from VBA, it does not raise errors that VBA can trap. Rather, Excel interacts with the user as if the user had issued a GUI command. On the other hand, if an application method is designed to interact with VBA (e.g., if it returns a value), then VBA might be able to handle its errors.
This is distinct from the way VBA handles worksheet functions rather than application methods. VBA can intercept errors raised by worksheet functions, as noted in "Error Handling With Worksheet Functions" here.
I realize this does not solve your problem, but it gives you an idea of why.

Compile error during workbook open

I have a workbook which uses a certain type, let's call it T, that's in a module (DLL) defined in my References -- all good.
I created some code that's called in Workbook_Open() that will add a reference to the DLL if it's not already in the list of references. This is so I can give the workbook to someone and they won't have to deal with creating the reference by hand.
My problem is that when I open the workbook (double-click), before Workbook_Open() gets executed (and the Refence can be set) I get thrown into the debugger which points to and complains that type T, defined in the not-yet-referenced DLL, is not defined. Well no kidding it's not.
This seems a little chick and egg. Anyone seen this before? How did you fix it?
Like other people have said, if you are not going to add the reference to the DLL until Workbook_Open, you have to use late binding to connect to the stuff in the DLL.
However, I think you are going about this the wrong way. Instead of adding a reference to the DLL in Workbook_Open, have it already referenced and check .IsBroken instead. Then you can have code to do what ever is needed to fix the broken reference.
This keeps the benefit of early binding and you won't get the same kind of compile errors if the reference to the DLL is broken.
NOTE: You can still get compile errors, but they won't be for the missing DLL. While you have a broken reference, any use of functions from the VBA Strings module will trigger a compile error if the function isn't prefaced with Strings. For example, the following code will cause a compiler error before Workbook_Open runs if you have any broken references.
Private Sub Workbook_Open()
Dim r As Reference
For Each r In ThisWorkbook.VBProject.References
If r.IsBroken Then
MsgBox "Found broken reference." & vbCrLf _
& Mid(r.FullPath, InStrRev(r.FullPath, "\") + 1)
End If
Next r
End Sub
To fix, prefix Mid and InStrRev with Strings..
MsgBox "Found broken reference." & vbCrLf _
& Strings.Mid(r.FullPath, Strings.InStrRev(r.FullPath, "\") + 1)

Resources