VBA runtime error 91 even though variable is set - vba

I am struggling with a piece of code that places a custom class in a collection. Every time I run the code I get a runtime error 91. The error is occuring on the Set pjt = New CProject line.
Dim Projects As Collection
Private Sub BuildProjects()
Dim pjt As CProject
Set Projects = New Collection
Set pjt = New CProject '<-----ERROR OCCURS HERE
'Do some other stuff
End Sub
This is obviously the simplest form of the Sub, but it still throws the error! What am I doing wrong? Do I need to set the access for the CProject class file somehow?
All your help will be greatly appreciated.

The line Set pjt = New CProject is calling the constructor for CProject.
The error will most likely be in the constructor of CProject.
Error 91 is a null reference

Related

Creating a new IUI Automation Handler object in order to subscribe to an automation event

So, here it goes. To start, A disclaimer, I understand that MS Access is not built for this kind of work. It is my only option at this time.
I have done just a bit of Automation using UIAutomationClient and I have successfully used its other features, however I cannot for the life of me get it to subscribe to events.
Normally, it is supposed to be a bit like this:
Dim CUI as new CUIAutomation
Dim FocusHandler as IUIAutomationFocusChangedEventHandler
Set FocusHandler = new IUIAutomationFocusChangedEventHandler(onFocusChanged)
C.AddFocusChangedEventHandler(Element,TreeScope_Children, null, FocusHandler)
end function
'
'
Function onFocusChanged(src as Object, args as AutomationEventArgs)
''my code here
end function
Yet when I attempt this, I get the error "expected end of statement" on the line:
FocusHandler = new IUIAutomationFocusChangedEventHandler(onFocusChanged)
additionally, if I leave off the (onFocusChanged) I get the error "Invalid use of new Keyword".
It seems like I am missing a reference somewhere. The usual drop down when using "new" does not contain the IUI handler classes though they are in the object library.
I am not sure if there is just some piece I am not accounting for in the code since I am using vba, but all examples seem to be for .net or C#/C++. Any help would be appreciated.
Additionally, I have no problem finding the element in question and all other pieces work fine. If you need any other pieces of the code let me know.
Edit: added set to line 3. No change in the problem though.
After two years this probably isn't relevant any more, but perhaps somebody else encounters this problem... The answer is to create a new class that implements the HandleAutomationEvent method.
Here I created a class named clsInvokeEventHandler and (importantly) set the Instancing property to PublicNotCreatable:
Option Explicit
Implements IUIAutomationEventHandler
Private Sub IUIAutomationEventHandler_HandleAutomationEvent(ByVal sender As UIAutomationClient.IUIAutomationElement, ByVal eventId As Long)
Debug.Print sender.CurrentName
End Sub
And to use it:
Sub StartInvokeHandler()
Dim oUIA As New CUIAutomation8
Dim oRoot As IUIAutomationElement
Dim InvokeHandler As clsInvokeEventHandler
Set InvokeHandler = New clsInvokeEventHandler
Set oRoot = oUIA.GetRootElement
oUIA.AddAutomationEventHandler UIA_Invoke_InvokedEventId, oRoot, TreeScope_Descendants, Nothing, InvokeHandler
End Sub

Looping Through a dictionary with custom object items

I'm sure I'm missing the huge elephant in the room but I keep getting errors on this. I'm creating a public dictionary called Prompts and filling it with a custom class object in the sub below.
Public Sub SetPromptControls()
Dim PromptsRange As Range
Dim PromptRow As Range
Set PromptsRange = Range("LookUpTablePrompts")
Dim NewPrompt As clsPrompt
For Each PromptRow In PromptsRange.Rows
Set NewPrompt = New clsPrompt
NewPrompt.Name = PromptRow.Cells(1, 1)
NewPrompt.ControlType = PromptRow.Cells(1, 2)
NewPrompt.ComboboxValues = PromptRow.Cells(1, 3)
NewPrompt.HelpText = PromptRow.Cells(1, 4)
NewPrompt.TabIndex = PromptRow.Cells(1, 5)
NewPrompt.ColumnIndex = PromptRow.Cells(1, 6)
NewPrompt.TableIndex = PromptRow.Cells(1, 7)
NewPrompt.ControlName = PromptRow.Cells(1, 8)
Me.Prompts.Add NewPrompt.ControlName, NewPrompt
Next
End Sub
Now I'm trying to loop through the dictionary I just made in this next sub which is inside the same class. The problem is the for each loop keeps giving me object errors
Public Sub SetProductPromptMapping()
Dim ProductPromptMappingRange As Range
Dim SKURange As Range
Dim SKUPromptMapRow As Integer
Dim MapRow As Range
Dim Key As Variant
Dim Prompt As clsPrompt
Set ProductPromptMappingRange = Range("LookUpTablePromptMap")
Set SKURange = ProductPromptMappingRange.Find(PromptsForm.SKU, LookIn:=xlValues)
SKUPromptMapRow = SKURange.Row - 2
For Each Key In Prompts.Keys
Set Prompt = New clsPrompt
Prompt = Key
Me.ProductPromptMappingRow.Add Prompt.ControlName, ProductPromptMappingRange.Cells(SKUPromptMapRow, Prompt.TableIndex).Value
Next
End Sub
Ultimately I would like to loop through my Prompts dictionary and cast the current item back to my clsPrompt class object so that I can access its properties.
As Comintern correctly points out, you've been bit by a common mistake - trying to assign an object reference without the Set keyword. Here's the smallest example I can come up with that demonstrates the problem:
Option Explicit
Public Sub DoSomething()
Dim foo As MyClass
foo = New MyClass
End Sub
Here there's a local foo object variable that's assigned a reference (= New MyClass), but because the assignment is made without the Set keyword, running this would raise a runtime error 91:
Object variable or With block variable not set
Your code has that exact same issue:
Dim Prompt As clsPrompt
'...
'more code
'...
Prompt = Key
The code happily compiles, but will consistently raise that runtime error 91 when executed.
This mistake is common enough (just look at how many questions involve runtime error 91 right here on Stack Overflow), that I've decided to implement an inspection for it in the latest version of Rubberduck, an open-source COM add-in for the VBE that can help you clean up your code (I'm managing the project):
Object variable 'foo' is assigned without the 'Set' keyword
As far as Rubberduck can tell, this variable is an object variable, assigned without the 'Set' keyword. This causes run-time error 91 'Object or With block variable not set'.
Rubberduck would have caught that error =)
What it wouldn't have caught though, is that it doesn't make much sense to assign Prompt a new reference, just to re-assign it to some Variant right away. Again as Comintern correctly points out, you need to Set Prompt = Prompts(Key) here.

Generic Way to Determine if Invoking a Property Throws an Error

Say you have one slide with one chart on it, and you run this code(in a version of Office later than 2007):
Dim pptWorkbook As Object
Dim result As Object
Set pptWorkbook = ActivePresentation.slides(1).Shapes(1).Chart.ChartData.Workbook
Set result = pptWorkbook.ContentTypeProperties
You will generate an error:
Application-defined or object-defined error
I believe this is because "Smart tags are deprecated in Office 2010."(Source), Generally to avoiding this sort of issue from throwing an error and exiting your VBA you can take one of two different approaches:
//Method 1
If OfficeVersion <= 2007
Set result = pptWorkbook.ContentTypeProperties
//Method 2
On Error Resume Next // or GOTO error handler
Set result = pptWorkbook.ContentTypeProperties
Method one requires that you know the specific reason why the property would cause an error, which is easy in this case but may not be as easy with other properties. Method two requires that you use some form of error handling to deal with the error AFTER the fact, my understanding of most other Microsoft languages is that is typically discouraged(example, another example). Is this standard practice in VBA?
In VBA, is there any other way to determine whether a property of an object would throw an error if invoked, BEFORE invoking that property, and without knowing the specifics of that invoked property?
What I like to do for this situation is create a separate function that checks if the property exists and returns a Boolean. In this case it would look something like this:
Public Function CheckIfExists(targetObj As Object) As Boolean
Dim testObj As Object
On Error GoTo failedTest:
Set testObj = targetObj.ContentTypeProperties
CheckIfExists = True
Exit Function
failedTest:
CheckIfExists = False
End Function
Which would return false if that property causes an error and true if not-
Then modify your sub to be:
Public Sub FooSub()
Dim pptWorkbook As Object
Dim result As Object
Set pptWorkbook = ActivePresentation.slides(1).Shapes(1).Chart.ChartData.Workbook
If CheckIfExists(pptWorkbook) Then
Set result = pptWorkbook.ContentTypeProperties
End If
... rest of your code or appropriate error handling...
Hope this helps,
TheSilkCode

Null Reference Exception on using Adobe3D Reviewer class

I am new to programming in VB. I am trying to use a built-in interface in the Adobe3DReviewer in my code. I need to use a method of the interface so I am trying to create an object. However, when I try to use the object to access the method I get this error:
System.NullReferenceException was unhandled.Object reference not set to an instance of an object.
I am not sure where I am going wrong. Any suggestions/comments will be greatly appreciated.Here is my code snippet:
Module Module1
Sub Main()
Dim attVal As New Object
Dim geomItemObject As Adobe3DReviewer.GeomItem
geomItemObject = Nothing
attVal = "value"
//The error is thrown at this line.
geomItemObject.AddAttribute("hi", attVal)
End Sub
End Module
You set geomItemObject to Nothing, which is causing the exception. Perhaps you need Dim geomItemObject as New Adobe3DReviewer.GeomItem.
Sorry, can't be more specific but i don't know Adobe3DReviewer.

Runtime Error 424 Object Required

Hey so I get this error in this code:
Private Sub Request_Stuff_button_Click()
Call Main.createObjects
Call My_Control.requestStuff
End Sub
at the 'Call My_Control.requestStuff' line.
The 'Main' module looks like this:
Public My_Control As ControlObject
Public Sub createObjects()
If My_Control Is Nothing Then
Set My_Control = New ControlObject
End If
End Sub
The weirdest thing is that when I add
Dim x As Integer
x = My_Control.dummyInt
right before the line that gets me the error, x gets the correct value right before the error happens which means My_Control is definitely an object and is definitely not nothing.
This error is killing me, thanks in advance.
Thanks but that wasn't the problem, the issue was actually in the requestStuff method but the debugger was freezing on that line instead of in the method and silly me forgot to check for that.