Object variable or With Block variable not set error when accessing members of BuildingBlockEntries collection - vba

I am attemping to access members of a template's BuildingBlockEntries collection through a macro in Microsoft Word 2007. As it is a collection, I first thought a For Each loop would be the best way to to this:
For Each bBlock In NormalTemplate.BuildingBlockEntries
MessageBox.Show (bBlock.Name)
Next bBlock
However this attempt through the error: Object doesn't support property or method.
So I tried this method which was suggested here:
Templates.LoadBuildingBlocks
Dim iBB As Integer
iBB = NormalTemplate.BuildingBlockEntries.Count()
Dim bb As Word.BuildingBlock
Dim i As Integer
Dim objCounter As Object
If iBB > 0 Then
For i = 1 To iBB
objCounter = i
bb = NormalTemplate.BuildingBlockEntries.Item(objCounter)
MessageBox.Show (bb.Name)
Next
End If
However, this is resulting in the error shown in the title: Object variable or With Block variable not set.
I have tried just using an integer variable for the index, i specifically, but with now avail. How can I acheive the desired effect? What is wrong with my attempt?
Thank you for the help.

With your 2nd question the answer is that you need to use Set, as bb is an object:
Set bb = NormalTemplate.BuildingBlockEntries.Item(objCounter)
For more info on Set take a look at this SO question.
With your For/Next loop, it's not clear how you've declared bBlock. I guess it should be something like:
Dim bBlock as BuildingBlock
And perhaps the For line should reference BuildingBlocks instead of BuildingBlockEntries:
For Each bBlock In NormalTemplate.BuildingBlocks
I don't know for sure though, as I'm just looking at what pops up in Intellisense.

Related

How to get an object out of a collection in VBa

I used to have the following working code
Set result = DecodeJson(MyRequest.responseText)
Dim keys() As String
keys = GetKeys(result.issues)
Now, my approach has changed and instead of having result being the object, I receive a Collection based upon Array of class objects as class member in VBA
Dim resultsFromQueries As Collection
Set resultsFromQueries = GetAllJSonObjects(searchString) ' this calls DecodeJson(MyRequest.responseText) as per the code snippet above
Dim i As Integer
For i = 0 To resultsFromQueries.Count
Dim keys() As String
Dim item As Object
Set item = resultsFromQueries.item(i + 1) ' I guess it's not 0 based?
keys = GetKeys(item.result.issues) 'KABOOM
The issue I have now is I keep getting the following exception
Run time error '424':
Object required
Checking in the watch window, item shows as type Variant/String and has the value of "[object Object]"
Do I need to cast it?
I had that problem just a few weeks ago, the problem was the following:
The collection was collected with the follwing code:Collection.Add(OBJECT)
This however leads to the addition of the value of the Object into the Collection and can be solved as simple as leaving the parathesis.Collection.add OBJECT
So my advice is to go into the GetAllJSonObjects(searchString) function and
search for the addition process and make sure that it is without parethesis.
Like this the Collection will contain Objects and not variants and your code with item(i+1) should work properly.
Good luck!

A null reference could result in runtime

Dim policy_key() As RenewalClaim.PolicyKeyType
policy_key(0).policyEffectiveDt = date_format_string(ld_EffectiveDate)
Getting error at Line2.
An Error occured - Object reference not set to an instance of an object.
Each element of object arrays also needs to be declared as a new object too.
Dim policy_key() As RenewalClaim.PolicyKeyType
Redim policy_key(0)
policy_Key(0) = new RenewalClaim.PolicyKeyType
policy_key(0).policyEffectiveDt = date_format_string(ld_EffectiveDate)
QUICK TIP: When declaring classes structures etc, it is useful to name them so you can see what type they are....
e.g.
cls_Policy_Key for a class
str_Policy_Key for a structure etc.
When you come back to your code after a year.. you will thank yourself for doing so.
Dim policy_key() As RenewalClaim.PolicyKeyType
is part of your problem. When you are declaring policy_key() you are actually declaring it as an array with no elements. If you don't particularly need to use an array, for example, if you don't need to add objects to a particular element number, you might be better using a list and declaring it like this
Dim policy_key As New List(Of RenewalClaim.PolicyKeyType)
This way, you can add items easily without having to resize your array each time - The code is a little longer than Trevor's answer, but less prone to errors when you extend your code -
dim newPolicy_Key as RenewalClaim.PolicyKeyType
newPolicy_Key.policyEffectiveDt = date_format_string(ld_EffectiveDate)
policy_Key.add(newPolicyKey)

What is the lifetime of a global variable in excel vba?

I've got a workbook that declares a global variable that is intended to hold a COM object.
Global obj As Object
I initalize it in the Workbook_Open event like so:
Set obj = CreateObject("ComObject.ComObject");
I can see it's created and at that time I can make some COM calls to it.
On my sheet I have a bunch of cells that look like:
=Module.CallToComObject(....)
Inside the Module I have a function
Function CallToComObject(...)
If obj Is Nothing Then
CallToComObject= 0
Else
Dim result As Double
result = obj.GetCalculatedValue(...)
CallToComObject= result
End If
End Function
I can see these work for a bit, but after a few sheet refreshes the obj object is no longer initialized, ie it is set to Nothing.
Can someone explain what I should be looking for that can cause this?
Any of these will reset global variables:
Using "End"
An unhandled runtime error
Editing code
Closing the workbook containing the VB project
That's not necessarily an exhaustive list though...
I would suggest a 5th point in addition to Tim's 4 above: Stepping through code (debugging) and stopping before the end is reached. Possibly this could replace point number 3, as editing code don't seem to cause global variable to lose their values.

Outlook Redemption : GetNamesFromIDs

I'm trying to get all property names / values from an Outlook item. I have custom properties in addition to the default outlook item properties. I'm using redemption to get around the Outlook warnings but I'm having some problems with the GetNamesFromIDs method on a Redemption.RDOMail Item....
I'm using my redemption session to get the message and trying to use the message to get the names of all the properties.
Dim rMessage as Redemption.RDOMail = _RDOSession.GetMessageFromID(EntryID, getPublicStoreID())
Dim propertyList As Redemption.PropList = someMessage.GetPropList(Nothing)
For i As Integer = 1 To propertyList.Count + 1
Console.WriteLine(propertyList(i).ToString())
Console.WriteLine(someMessage.GetNamesFromIDs(________, propertyList(i)))
Next
I'm not totally sure what to pass in as the first parameter to getNamesFromIDs. The definition of GetNamesFromIDs is as follows:
GetNamesFromIDs(MAPIProp as Object, PropTag as Integer) As Redemption.NamedProperty
I'm not totally sure what should be passed in as the MAPIProp object. I don't see this property referenced in the documentation. http://www.dimastr.com/redemption/rdo/MAPIProp.htm#properties
Any help or insight would be greatly appreciated.
I think I figured it out. I have used VBA only, so you need to "think around" it's limitations, it will follow the same scheme in VB.NET.
The function signature is this:
Function GetNamesFromIDs(MAPIProp As Unknown, PropTag As Long) As NamedProperty
As the first parameter it requires an object which supports the IUnknown interface. Looking at the Redemption docs it became clear that there is an interface named _MAPIProp, from which many other RDO objects are derived (IRDOMail is among them). So this must be the very RDOMail you are trying to get data out of.
Knowing that, it needed only one other subtle hint from the docs to get it working:
Given a prop tag (>= 0x80000000),
returns the GUID and id of the named
property.
So property tag must be >= 0x80000000, this means it wont work for all properties, but just for the custom ones (I guess that is the distinction in this case, correct me if I'm wrong.) Passing in property tags not fulfilling this condition raises an error message (0x8000ffff "unexpected results").
Here is my code. It is VBA, so forgive me the Hex() blunder, as VBAs long integer overflows for numbers that big. I am sure you will get the picture.
Sub GetNamesFromIds()
Dim rSession As New Redemption.RDOSession
Dim rMessage As Redemption.RDOMail
Dim PropertyList As Redemption.PropList
Dim PropTag As Long
Dim EntryId As String
Dim i As Integer
rSession.MAPIOBJECT = Application.Session.MAPIOBJECT
' retrieve first random mail for this example '
EntryId = ActiveExplorer.CurrentFolder.Items(1).EntryId
Set rMessage = rSession.GetMessageFromID(EntryId)
Set PropertyList = rMessage.GetPropList(0)
For i = 1 To PropertyList.Count
PropTag = PropertyList(i)
If "0x" & Right("00000000" & Hex(PropTag), 8) > "0x80000000" Then
Debug.Print
If IsArray(rMessage.Fields(PropTag)) Then
Debug.Print Hex(PropTag), "(Array:", UBound(rMessage.Fields(PropTag)), "items)"
Else
Debug.Print Hex(PropTag), "(", rMessage.Fields(PropTag), ")"
End If
Debug.Print " GUID:", rMessage.GetNamesFromIds(rMessage, PropTag).GUID
Debug.Print " ID:", rMessage.GetNamesFromIds(rMessage, PropTag).ID
End If
Next
End Sub
First snippet from the output:
8041001E ( urn:content-classes:message )
GUID: {00020386-0000-0000-C000-000000000046}
ID: content-class
Well, for background info, the author suggests using something like OutlookSpy to see how Outlook stores the properties.
Looking at this exchange (make sure to read through all the follow-up responses), there isn't much more (in fact, I think at one point the Outlook MVP types GetNamesFromIDs when he means GetIDsFromNames).
What you might try is using GetIDsFromNames to see what that returns, and then use that to pass to GetNamesFromIDs.
I've used Redemption before, but not in this particular manner, so that's all I've got for you ...

object reference not set to an instance of object [duplicate]

This question already has answers here:
What is a NullReferenceException, and how do I fix it?
(27 answers)
Closed 2 years ago.
I have been getting an error in VB .Net
object reference not set to an instance of object.
Can you tell me what are the causes of this error ?
The object has not been initialized before use.
At the top of your code file type:
Option Strict On
Option Explicit On
Let's deconstruct the error message.
"object reference" means a variable you used in your code which referenced an object. The object variable could have been declared by you the or it you might just be using a variable declared inside another object.
"instance of object" Means that the object is blank (or in VB speak, "Nothing"). When you are dealing with object variables, you have to create an instance of that object before referencing it.
"not set to an " means that you tried to access an object, but there was nothing inside of it for the computer to access.
If you create a variable like
Dim aPerson as PersonClass
All you have done was tell the compiler that aPerson will represent a person, but not what person.
You can create a blank copy of the object by using the "New" keyword. For example
Dim aPerson as New PersonClass
If you want to be able to test to see if the object is "nothing" by
If aPerson Is Nothing Then
aPerson = New PersonClass
End If
Hope that helps!
sef,
If the problem is with Database return results, I presume it is in this scenario:
dsData = getSQLData(conn,sql, blah,blah....)
dt = dsData.Tables(0) 'Perhaps the obj ref not set is occurring here
To fix that:
dsData = getSQLData(conn,sql, blah,blah....)
If dsData.Tables.Count = 0 Then Exit Sub
dt = dsData.Tables(0) 'Perhaps the obj ref not set is occurring here
edit: added code formatting tags ...
In general, under the .NET runtime, such a thing happens whenever a variable that's unassigned or assigned the value Nothing (in VB.Net, null in C#) is dereferenced.
Option Strict On and Option Explicit On will help detect instances where this may occur, but it's possible to get a null/Nothing from another function call:
Dim someString As String = someFunctionReturningString();
If ( someString Is Nothing ) Then
Sysm.Console.WriteLine(someString.Length); // will throw the NullReferenceException
End If
and the NullReferenceException is the source of the "object reference not set to an instance of an object".
And if you think it's occuring when no data is returned from a database query then maybe you should test the result before doing an operation on it?
Dim result As String = SqlCommand.ExecuteScalar() 'just for scope'
If result Is Nothing OrElse IsDBNull(result) Then
'no result!'
End If
You can put a logging mechanism in your application so you can isolate the cause of the error. An Exception object has the StackTrace property which is a string that describes the contents of the call stack, with the most recent method call appearing first. By looking at it, you'll have more details on what might be causing the exception.
When working with databases, you can get this error when you try to get a value form a field or row which doesn't exist. i.e. if you're using datasets and you use:
Dim objDt as DataTable = objDs.Tables("tablename")
you get the object "reference not set to an instance of object" if tablename doesn't exists in the Dataset. The same for rows or fields in the datasets.
Well, Error is explaining itself. Since You haven't provided any code sample, we can only say somewhere in your code, you are using a Null object for some task. I got same Error for below code sample.
Dim cmd As IDbCommand
cmd.Parameters.Clear()
As You can see I am going to Clear a Null Object. For that, I'm getting Error
"object reference not set to an instance of an object"
Check your code for such code in your code. Since you haven't given code example we can't highlight the code :)
In case you have a class property , and multiple constructors, you must initialize the property in all constructors.