Find Exchange User's OfficeLocation in VBA - vba

When viewing someone's contact card in Outlook, there is a field for Office which gives their location. How can I find that using VBA? Here's my most functional code:
Private Function getLocation(username As String) As String
Dim olApp As Outlook.Application
Dim olNS As Outlook.Namespace
Dim olGAL As Outlook.AddressEntries
Dim olAddressEntry As Outlook.AddressEntry
Dim olUser As Outlook.ExchangeUser
Set olApp = New Outlook.Application
Set olNS = olApp.GetNamespace("MAPI")
Set olGAL = olNS.AddressLists("Global Address List").AddressEntries
Set olAddressEntry = olGAL.Item(username)
Set olUser = olAddressEntry.GetExchangeUser
Debug.Print olGAL.Count 'count is 646718
Debug.Print olUser.OfficeLocation
Debug.Print olUser.Address
Debug.Print olUser.Name
getLocation = olUser.OfficeLocation
Set olApp = Nothing
Set olNS = Nothing
Set olGAL = Nothing
Set olAddressEntry = Nothing
Set olUser = Nothing
End Function
This works when I search for their actual name (EG, John Smith), but it only returns the first John Smith. How can I use their email address or alias to search?
Note: I added a reference to the Microsoft Outlook 16.0 Object Library to take advantage of Intellisense, but I plan on switching to late binding once it works.

So, I haven't found a way to query Exchange by email or alias because the .Item method (from the line olGAL.Item(username)) requires Either the index number of the object, or a value used to match the default property of an object in the collection. I did find a way to ensure I am getting the correct user however. The default property for the GAL is the user's name, which in my case (but may not be in everyone's case...can't find good documentation to verify this) the DistinguishedName in Active Directory. So if I search AD with the user's SAM account, I can get the user's DN. I can then search Exchange with that DN to ensure I have the correct "John Smith".
Here is my combined code:
'I pass the username (EG: johnsmit) and get the DN (eg John Smith - VP of Sales).
' This DN gets passed to the function in my question, and returns the correct location.
Private Function GetFullName(strUsername As String) As String
Dim objConnection As Object
Dim objCommand As Object
Dim objRecordSet As Object
Dim strDN As String
Dim temp As Variant
Const ADS_SCOPE_SUBTREE = 2
Set objConnection = CreateObject("ADODB.Connection")
Set objCommand = CreateObject("ADODB.Command")
objConnection.Provider = "ADsDSOObject"
objConnection.Open "Active Directory Provider"
Set objCommand.ActiveConnection = objConnection
objCommand.Properties("Page Size") = 1000
objCommand.Properties("Searchscope") = ADS_SCOPE_SUBTREE
objCommand.CommandText = "SELECT distinguishedName FROM 'LDAP://dc=mydomain,dc=com' WHERE objectCategory='user' AND sAMAccountName='" & strUsername & "'"
Set objRecordSet = objCommand.Execute
objRecordSet.MoveFirst
Do Until objRecordSet.EOF
strDN = objRecordSet.Fields("distinguishedName").Value
temp = Split(strDN, ",")
GetFullName = Replace(temp(0), "CN=", "")
objRecordSet.MoveNext
Loop
objConnection.Close
Set objConnection = Nothing
Set objCommand = Nothing
Set objRecordSet = Nothing
End Function
If anyone has a better, faster, cheaper (one that doesn't hit the AD servers) method, I'd love to hear it.

Related

Getting Alias from items in Outlook AddressBook with VBA

My code below gives me the following error at the Debug.Print(oExuser.Alias), why?
Sub Test()
Dim AliasName, FullName As String
Dim outlookApp As Outlook.Application
Dim myNameSpace As Outlook.nameSpace
Dim myAddrList As AddressList
Dim myAddrEntries As AddressEntries
Dim myAddrEntry As Outlook.AddressEntry
Dim myAlias As Object
Dim oExUser As Outlook.ExchangeUser
Set outlookApp = New Outlook.Application
Set myNameSpace = outlookApp.GetNamespace("MAPI")
Set myAddrList = myNameSpace.GetGlobalAddressList()
Set myAddrEntries = myAddrList.AddressEntries
Set myAddrEntry = myAddrEntries.Item(1)
Set oExUser = myAddrEntry.GetExchangeUser
Debug.Print (oExUser.Alias)
End Sub
You need to check that the returned ExchangeUser object (oExUser) is not null. It will be null for the non-Exchange (e.g., SMTP) address entries even if you have Exchange in the current Outlook profile:
If not (oExUser Is Nothing) Then
Debug.Print (oExUser.Alias)
End If
You have to be connected to the Exchange server to use the AddressEntry.GetExchangeUser method. The following code makes sense only for the Exchange accounts:
Set oExUser = myAddrEntry.GetExchangeUser
Debug.Print (oExUser.Alias)
The Alias property returns an empty string if this property has not been implemented or does not exist for the ExchangeUser object.

Add Reference Library to an outside MS Access Database

I have a code that creates new MS Access Databases. I'd like to add reference libraries to these newly created MS Access Databases.
Here is the code that I wrote but is not working:
Sub makeDb(fl As String)
Dim fs
Set fs = CreateObject("Scripting.FileSystemObject")
'check if the file already exists
If fs.FileExists(fl) = False Then
'create new ms access database
Dim accessApp As Access.Application
Set accessApp = New Access.Application
accessApp.DBEngine.CreateDatabase fl, dbLangGeneral
'loop through all references in current database and add them to the newly created dbs
Dim cur_vbProj As VBIDE.VBProject: Set cur_vbProj = Application.VBE.VBProjects(1)
Dim cur_vbRefs As VBIDE.References: Set cur_vbRefs = cur_vbProj.References
Dim cur_vbRef As VBIDE.Reference
For Each cur_vbRef In cur_vbRefs
Dim cur_guid As String: cur_guid = cur_vbRef.Guid
Dim cur_major As Long: cur_major = cur_vbRef.Major
Dim cur_minor As Long: cur_minor = cur_vbRef.Minor
'here is the code that doesn't work
Dim vbProj As VBIDE.VBProject: Set vbProj = accessApp.Application.VBE.VBProjects(1)
Dim vbRefs As VBIDE.References: Set vbRefs = vbProj.References
vbRefs.AddFromGuid Guid:=cur_guid, Major:=cur_major, Minor:=cur_minor
Next
accessApp.Quit
Set accessApp = Nothing
End If
End Sub
The line Set vbProj = accessApp.Application.VBE.VBProjects(1) throws Run-Time error '9' Subscript out of range. How should I modify the code? Is it even possible to add references to an outside database?
Following works for me:
Sub makeDb(f1 As String)
Dim accApp As Access.Application
Dim cur_vbRefs As References
Dim cur_vbRef As Reference
If Dir(f1) = "" Then
Access.DBEngine.CreateDatabase f1, dbLangGeneral
Set accApp = New Access.Application
accApp.OpenCurrentDatabase f1
'loop through all references in current database and add them to the newly created dbs
Set cur_vbRefs = Application.References
For Each cur_vbRef In cur_vbRefs
On Error Resume Next
accApp.References.AddFromGuid cur_vbRef.Guid, cur_vbRef.Major, cur_vbRef.Minor
Next
End If
End Sub

NullReferenceException was unhandled by user code - declaring Excel.Worksheet object

I'm transitioning from Excel VBA to VB.NET, so if this is a dumb question, please go easy on me. I get a NullReferenceException was unhandled by user code on this line of the following sub:
Dim objSheet As Excel.Worksheet = objBook.Sheets("SQL Creator")
VS says that the Object reference is not set to an instance of the object. I'm not sure why it's asking for that, because I've already declared a new instance of Excel in the objApp variable. Why would I need to declare a new instance of each object under that class? It's very possible I'm not thinking about that correctly, but I just wanted to mention my thoughts. Overall, I'm just trying to test the sub below to see if it will open and close a connection to a PostgreSQL database.
Imports Microsoft.Office.Interop
Public Sub QueryData(ByVal ribbonUI As Office.IRibbonControl)
Dim objApp As New Excel.Application
Dim objBook As Excel.Workbook = objApp.ActiveWorkbook
Dim objSheet As Excel.Worksheet = objBook.Sheets("SQL Creator")
Dim pgconn As String
pgconn = "Driver={PostgreSQL};" &
"Server = localhost;" &
"Port = 5432;" &
"Database = CFABudget;" &
"Uid = postgres;" &
"Pwd = budgeto;"
Dim SQL As String = objSheet.Range("BudgetSQL").Text
Dim conn As New Data.Odbc.OdbcConnection(pgconn)
Dim cmd As Data.Odbc.OdbcCommand = New Data.Odbc.OdbcCommand(SQL)
conn.Open()
MsgBox("Success!", vbOKOnly)
conn.Close()
End Sub
Thank you all for your help!
Replace
Dim objApp As New Excel.Application
With:
Dim objApp As Excel.Application = System.Runtime.InteropServices.Marshal.GetActiveObject("Excel.Application")
You were trying to get active workbook from new empty instance of excel.

Update sql database using Lotusscript

I am trying to update rows of my database through lotusscript. My database connection working well. But the result.update command doesn't work and my rows aren't updated by the query. The problem is in the query result.updaterow because it doesn't make errors anywhere else.
Anyone have a solution to make it work;
Option Public
Option Declare
UseLSX "*LSXODBC"
Sub Initialize
Dim session As New NotesSession
Dim db As NotesDatabase
Dim dbcontacts As NotesDatabase
Dim doc As NotesDocument
Dim DocContact As NotesDocument
Dim CandidatView As NotesView
Dim ContactView As NotesView
Dim connection As ODBCConnection
Dim query As ODBCQuery
Dim result As ODBCResultSet
Dim consultantref As String
Set db = session.CurrentDatabase
Set connection = New ODBCConnection
Set dbcontacts= session.GetDatabase("", "names.nsf")
Set query = New ODBCQuery
Set result = New ODBCResultSet
Set query.Connection = connection
Set result.Query = query
On Error Resume Next
Set CandidatView=db.GetView( "Persons" )
Set ContactView=dbcontacts.GetView( "(PersonsTestImport)" )
Call connection.ConnectTo("datasource", "username", "password")
If connection.IsConnected Then
Set doc=CandidatView.GetFirstDocument
CandidatView.AutoUpdate = False
While Not ( doc Is Nothing )
query.SQL="select * from users where id_toucan='"+doc.can_doc_ID(0)+"'"
result.Execute
If result.IsResultSetAvailable Then
Do
result.NextRow
namepers=doc.can_pers(0)
Set DocContact=ContactView.Getdocumentbykey(consultantref)
Call result.SetValue("first_name",DocContact.FirstName(0))
Call result.SetValue("last_name", DocContact.LastName(0))
Call result.SetValue("email", DocContact.MailAddress(0))
result.UpdateRow
Loop Until result.IsEndOfData
End If
Set doc = CandidatView.GetNextDocument( doc )
Wend
Else
MsgBox"Not connected"
End If
result.Close(DB_CLOSE)
connection.Disconnect
End Sub
I tried it with the sql query UPDATE and it's working now :
Option Public
Option Declare
UseLSX "*LSXODBC"
Sub Initialize
Dim session As New NotesSession
Dim db As NotesDatabase
Dim dbcontacts As NotesDatabase
Dim doc As NotesDocument
Dim DocContact As NotesDocument
Dim CandidatView As NotesView
Dim ContactView As NotesView
Dim connection As ODBCConnection
Dim query As ODBCQuery
Dim result As ODBCResultSet
Dim consultantref As String
Set db = session.CurrentDatabase
Set connection = New ODBCConnection
Set dbcontacts= session.GetDatabase("", "names.nsf")
Set query = New ODBCQuery
Set result = New ODBCResultSet
Set query.Connection = connection
Set result.Query = query
On Error Resume Next
Set CandidatView=db.GetView( "Persons" )
Set ContactView=dbcontacts.GetView( "(PersonsTestImport)" )
Call connection.ConnectTo("datasource", "username", "password")
If connection.IsConnected Then
Set doc=CandidatView.GetFirstDocument
CandidatView.AutoUpdate = False
While Not ( doc Is Nothing )
namepers=doc.can_pers(0)
Set DocContact=ContactView.Getdocumentbykey(consultantref)
Set DocContact=ContactView.Getdocumentbykey(consultantref)
first_name_ref=DocContact.FirstName(0)
last_name_ref=DocContact.LastName(0)
email_ref=DocContact.MailAddress(0)
query.SQL="UPDATE users SET email_consult_ref='"+email_ref+"', first_name_consult_ref='"+first_name_ref+"',last_name_consult_ref='"+last_name_ref+"' where id_toucan='"+doc.can_doc_ID(0)+"'"
result.Execute
If result.IsResultSetAvailable Then
Do
result.NextRow
Loop Until result.IsEndOfData
End If
Set doc = CandidatView.GetNextDocument( doc )
Wend
End If
result.Close(DB_CLOSE)
connection.Disconnect
End Sub

Access another Inbox which is not mine Outlook Addin

How would I get a folder that I, as a user, have been added to.
I need to do an addin for work, how would I access an inbox which isn't mine?
So the top one is my personal inbox, I need to access the inbox within 'MIS'.
Private Sub ThisApplication_NewMail() Handles Application.NewMail
Dim myNameSpace = Application.GetNamespace("MAPI")
Dim oParentFolder = myNameSpace.Folders("MIS")
Dim mis = oParentFolder.Folders.Item("Inbox")
Dim moveMail As Outlook.MailItem = Nothing
Dim mItems As Outlook.Items = mis.Items
mItems.Restrict("[Read] = true")
Dim destFolder As Outlook.MAPIFolder = mis.Folders("Test")
Dim SubjName = "TestingAddin123"
Dim sender As String = "michael"
Dim FName As String = "[Some recurring subject]"
Dim tStamp As String = Format(DateTime.Now, "ddMMyy").ToString()
Try
For Each eMail As Object In mItems
moveMail = TryCast(eMail, Outlook.MailItem)
If Not moveMail Is Nothing Then
If InStr(moveMail.SenderEmailAddress, sender) Then
If InStr(moveMail.Subject, SubjName) > 0 Then
Dim rn As New Random
Dim n = rn.Next(1, 9999)
'n()
moveMail.SaveAs("W:\NS\" & FName & "_" & tStamp & n.ToString() + ".html", Outlook.OlSaveAsType.olHTML)
moveMail.Move(destFolder)
End If
End If
End If
Next eMail
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Sub
So I'm using the above code so far but I don't seem to be able to find the MIS Inbox.
How would I achieve this?
Try to use the Namespace.CreateRecipient / Namespace.GetSharedDefaultFolder methods.