Outlook Addin and casting problems - vsto

Using VS2015 and Outlook 2016...
In my outlook addin, if I do this...
Dim item As Outlook.MailItem = DirectCast(selectedItem, Outlook.MailItem)
Then in the debug watch, it casts item as "system.__comobject" and I can't see properties right.
Same goes with attachements, eventhough I cast them as directcast(myMailItem.Attachment(0), Outlook.Attachment) then it's still a "system.__comobject".
Any idea how to cast them right?
Update:
Screenshot...

Try to use CType cast operator instead. Do you get the same results?
I can see all properties of the MailItem instance in the debug watch window.
UPD: I see that you don't use the mailItem object in the window. Try to expand its properties instead.

Related

vba code suddenly encounters problems with enumeration

This visual basic code related to outlook used to work without problems
Sub cmdExample()
Dim myOlApp As Object
Set myOlApp = CreateObject("Outlook.Application")
Set myoSession = myOlApp.Session
Set myoCalendar = myoSession.GetDefaultFolder(olFolderCalendar)
End Sub
Now I obtain the runtime error 5 (Invalid procedure call or argument)
Reason found from debugging: at runtime olFolderCalendar is empty (by the way, same problem for other enumerations like olAppointmentItem, olBusy). My workaround in the above code is calling .GetDefaultFolder(9).
However I would rather use the enumerations and I would like to understand why all of them are empty.
If you want to pass literal constants instead of numbers you need to add a COM reference to Outlook. Read more about that in the How to Add an Object Library Reference in VBA article.
Also, you may try to use the Logon method before getting the folder. See NameSpace.Logon for more information.

Late Binding & Type Issues In VB

I'm trying to run my code which was originally created using Visual Studio through another application where late bindings are disallowed and this option cannot be altered unfortunately. I am very new to programming in general and struggling to get my head around the issue. Here is the code im using in the invoke code stage:
Dim objIEShell As Object = CreateObject("Shell.Application")
Dim objIEShellWindows As Object = objIEShell.Windows
Dim objIEWin As Object
For Each objIEWin In objIEShellWindows
If InStr(objIEWin.LocationURL,"google")>0 Then
objIEWin.Quit
objIEWin = Nothing
End If
Next
The code simply closes all instances of Internet Explorer with "google" in the URL. This is the error message I get when trying to compile it:
Message: Error compiling code
error BC30574: Option Strict On disallows late binding. At line 2
error BC32023: Expression is of type 'Object', which is not a collection type. At line 4
From the research I've done so far I realise the first error message on line 2 is to do with the type difference between objIEShell and the Windows method. I think I have to convert objIEShell like this, CType(objIEShell,?), but I don't know the type of the .Windows method or how to find this out. Also any insight on how the fix the second error would be greatly appreciated as I'm not sure where to start with that one either.
This dates back to the wonky days when Microsoft still had plans to make Explorer behave like a web browser. Makes it pretty hard to arrive at the correct code, it is a combination of two separate COM components that don't have much to do with each other.
You need to first add two references to those components so the compiler understands the names. Use Project > Add Reference > COM tab and tick "Microsoft Internet Controls" and "Microsoft Shell Controls and Automation". That adds the Shell32 and SHDocVw namespaces.
Now you can write the code early-bound like this:
Dim objIEShell = New Shell32.Shell
Dim objIEShellWindows = CType(objIEShell.Windows, SHDocVw.IShellWindows)
Dim objIEWin As SHDocVw.WebBrowser
For Each objIEWin In objIEShellWindows
If InStr(objIEWin.LocationURL, "google") > 0 Then
objIEWin.Quit()
End If
Next
The CType() expression is probably the most unintuitive one, the Shell.Windows property is of type Object to break the dependency between those two components. The cast is the necessary voodoo to keep the compiler happy.

using item property inside an event procedure

I have a quick question. How can i check an item's properties within an event procedure? Here is a snippet of what I'm trying to do:
Private Sub application_ItemLoad(ByVal Item As Object)
Dim myolitem As Object
Set myolitem = Item
If myolitem.Class = olMail Then
If myolitem.UnRead Then
UserForm2.Show vbModal
End If
End If
End Sub
Thank you in advance for your help.
You code looks good, I don't see anything strange there.
Hope you will find the Getting Started with VBA in Outlook 2010 article helpful.
Some events (e.g. AfterWrite, ItemLoad) only allow a limited number of properties to be accessed. In your particular case, these are Class and MessageClass - see ApplicationEvents_11_Event.ItemLoad event.
I don't know if MAPIOBJECT is accessible in ItemLoad (I know for sure it is accessible in the AfterWrite event), you can (in theory) access the properties using Extended MAPI (C++ or Delphi) or Redemption (I am its author).

How to check type of Object in VB 6 ? - I do not want to use 'TypeOf' method

How to check type of object in VB 6.0 we have to modify existing code to use 'typeof' method, Is there any method like moving cursor over object variable or like quick watch where I can see its type.
I know following method but I do not want to use it -
Set fs = New Scripting.FileSystemObject
If TypeOf fs Is Scripting.FileSystemObject Then
Debug.Print "Is a FileSystemObject"
End If
Try the TypeName Function.
In your example if you enter TypeName(fs) in the Immediate Window you would get back "FileSystemObject"
Right click object variable and select "Quick Info" from context menu.

How do I keep RecipientTime when executing MailItem.Move in an Outlook macro?

In an Outlook 2003 macro; Is there a way to move a message between folders without changing the ReceivedTime-header?
I currently use the method MailItem.Move. But that automatically sets the ReceivedTime property to the current time, which isn't really what I want.
I just tried moving a mailitem from my inbox to the deleted items folder, and it seems to have kept the receivedtime without a problem...
You may want to try using the MailItem.copy function and moving the resulting mailitem object, but like I said I'm not seeing the same problem...
Hope that helps...
Do an item.Save() and then do item.Move(), It will stamp current timestamp.