I have found a few sources on here about individuals trying to get recipient information from a getTable() result and one of the sources pointed to a microsoft forum which the MVP indicates a potential solution but didnt expand on it all. My current code is as follows:
Set MyTable = MySearch.GetTable
MyTable.Columns.Add ("http://schemas.microsoft.com/mapi/proptag/0x0E03001E")
Do Until MyTable.EndOfTable
Set nextRow = MyTable.GetNextRow()
For Each OutRecip In Session.GetItemFromID(nextRow("EntryID")).Recipients
OutRecip.PropertyAccessor.GetProperty ("http://schemas.microsoft.com/mapi/proptag/0x39FE001E")
Next
Loop
Currently I have to pull the entry id then find the mail item and then get the recipient list from it. I find it slow and was hoping for a faster method considering I am using the advance search function which the point is to be efficient. Is there any schema property which has the to, cc, and bcc in which I can extract somehow with a text function of some sort in vba?
Recipient information cannot be pulled from a MAPI table. The best you can do is PR_DISPLAY_TO / PR_DISPLAY_CC / PR_DISPLAY_BCC, but these message properties do not (in general) contain email addresses or entry ids.
You can create search conditions based on the recipient properties, but you'd need Extended MAPI (C++ or Delphi) or Redemption (any language - I am its author) for that.
Related
A table in MS Access opened in Design View exposes several properties, as does the table's Property Sheet. Many of these properties are undocumented or documented only for other objects. The question is, to which object do these properties belong? Further, how does one identify them in code? Pressing F1 for context help in each case reveals no clues.
Examples include (and recognize that the names below follow from their visual context, not an object model):
Field.Description is a column in Design View (along with Field Name and Data Type) but is undocumented. Also, iterating DAO.Field.Properties reveals no Description field and references to the property fail.
Table.Description appears in the Property Sheet but also is undocumented.
Table.Filter and Table.OrderBy and their ~OnLoad counterparts appear on the Property Sheet but are documented only for other objects. I understand that information specified here is intended somehow to flow through to forms for which the table is the RecordSource, but the mechanism is not obvious and still leaves the initial question, flowing through from which object's property.
Table.LinkChildFields and Table.LinkMasterFields appear in the Property Sheet but are documented only for other objects. Also, their use in this context is not obvious.
Other table properties on the Property Sheet tell the same tale.
Any thoughts, in general or specific to any of the foregoing, would be most helpful and appreciated.
To show properties of some Access database object (table, query, form, report, ...), we can do this on VBA, defining this global function:
Function objShowProperties(ByVal xobj As Object)
Dim i As Long, varPropValue, prop As Object
On Error Resume Next
'
' loop over properties:
'
i = 0
For Each prop In xobj.Properties
varPropValue = prop.Value
'
' sometimes we have error accessing property value:
'
If (Err <> 0) Then
varPropValue = "[UNAVAILABLE]"
Err.Clear
End If
Debug.Print prop.Name, "=", varPropValue
i = i + 1
Next
On Error GoTo 0
Set prop = Nothing
objShowProperties = i
End Function
In my Acccess db I've a table named customers.
To show properties of this table, I call the above function like this:
objShowProperties CurrentDb.TableDefs("customers")
In my debug console, I got this:
All listed properties can then be accessed directly on VBA code, eg, RecordCount property:
dim lngRecords as long
lngRecords = CurrentDb.TableDefs("customers").Properties("RecordCount")
Hope this will help you.
A few things:
Field.Description is a column in Design View (along with Field Name and Data Type) but is undocumented.
No, it is not un-documented.
You are confusing DAO, and that of ms-access.
DAO "field" does not have a description property. So, it not un-documented at all.
Also in Access, there is help. You an put your cursor in the description, and hit help, and you get this:
so, place cursor here, and hit f1 for help:
And now you get this:
So, you are confusing the database engine object called DAO.FIELD with that of ms-access and it allowing you to have/enjoy/see a description in the table desinger.
I should point out that the DAO object model does not have a table designer!!!
In fact, what Access does is add's a custom property to the field, and then display's that. So, field.Description is not un-document, it in fact does not exist.
As noted in the other post here, you can "interate" all of the properties. However, if you use the database engine outside of ms-access, and EVEN create fields in code (or even by sql commands), you WILL STILL find that no descripton property exists. However, as noted, there is this thing called help, and you can give help a try, as it will explain what the description setting in ms-access does.
However, at the end of the day, field.description is not un-documented, and in fact does not exist.
so, if you read/look at/see documentaiton for the DAO field object, then these properties and options will not be found.
After all, you might be using c++, c# or some other system and that database engine that MS-Access just also happens to use.
MS-Access is not the database here. It is a tool that lets you build software, and forms and reports, and write code.
When you using MS-Access, you are not required to use the JET (now called ACE) database engine to store your data. You are free to use the Oracle database, or SQL server or whatever.
So, features of Access and things like link master fields etc.?
Those are MS-Access features, and not the database engine (ACE) features.
Is anyone have any documentation for MailItem AddressEntry.GetExchangeUser?
For example:
For each objItem in folder.Items
For Each Recipient In objItem.Recipients
Recipient.AddressEntry.GetExchangeUser.Name
Recipient.AddressEntry.GetExchangeUser.JobTitle
Next
Next
But there are other less obvious ones that are very useful (especially if you are building hierarchies) but undocumented (or at least I can't find it):
Recipient.AddressEntry.GetExchangeUser.GetExchangeUserManager.name
Maybe there are others for example .division (which doesn't seem to exist but
maybe there is a way to print all the available properties.)
there's no .division, but department, see https://learn.microsoft.com/en-us/office/vba/api/outlook.exchangeuser
I am trying to make a userform that loads all of your outlook contacts full name into a combo box and then based on what name is selected their phone number that matches that name will print in another textbox. After the name is selected how do you then go back to get the phone number and print it to the textbox?
This is copied code to put outlook contact names into combobox, maybe at the same time add item that is the phone number to a combobox instead of textbox but then how do you match the information to the right name? The idea is it makes a phone message sheet that you then e-mail to the person the message is for and this would help to see if the person has called before without manually going to look up their number or asking for it again
Private Sub UserForm_Initialize()
Dim MyOLApp As New Outlook.Application
Dim myNameSpace As Namespace
Dim myContacts As Items
Dim myContact As ContactItem
Dim newfax As MailItem
Set myNameSpace = MyOLApp.GetNamespace("MAPI")
Set myContacts = myNameSpace.GetDefaultFolder(olFolderContacts).Items
ComboBox1.Clear
For Each myContact In myContacts
ComboBox1.AddItem myContact.FullName
ComboBox1.Column(1, ComboBox1.ListCount - 1) = myContact.FullName
Next
Set myContacts = Nothing
Set myNameSpace = Nothing
Set MyOLApp = Nothing
End Sub
First of all, iterating over all items in the Contacts folder is not really a good idea. That can be a time-consuming operation, so the Outlook UI may be frozen until it is finished. Instead, you may consider using tables in Outlook.
The Table represents a read-only dynamic rowset of data in a Folder or Search object. You can use Folder.GetTable or Search.GetTable to obtain a Table object that represents a set of items in a folder or search folder. If the Table object is obtained from Folder.GetTable, you can further specify a filter (in Table.Restrict) to obtain a subset of the items in the folder. If you do not specify any filter, you will obtain all the items in the folder.
By default, each item in the returned Table contains only a default subset of its properties. You can regard each row of a Table as an item in the folder, each column as a property of the item, and the Table as an in-memory lightweight rowset that allows fast enumeration and filtering of items in the folder. Although additions and deletions of the underlying folder are reflected by the rows in the Table, the Table does not support any events for adding, changing, and removing of rows. If you require a writeable object from the Table row, obtain the Entry ID for that row from the default EntryID column in the Table and then use the GetItemFromID method of the NameSpace object to obtain a full item, such as a MailItem or ContactItem, that supports read-write operations. For more information on default columns in a Table, see Default Properties Displayed in a Table Object.
So, you may retrieve the table object with a contact's full name and EntryID which can be used to get the actual item if selected. Or just get the required properties into the table object, so you don't need to get the actual item instance in the code. Well, it depends on your needs...
I am reading data from my global Exchange Address Book.
This works for names that do not have duplicates.
When I find a name that is there many times, I need to loop through the whole address book.
I would rather try to get the first index of the name I am looking for.
For example "Peter Name" from the AddressEntry-Object and use this index to loop through the next AddressEntries.
If "Peter Name"'s index would be "1", I could then loop through for example from entry 2 to entry 10.
Is there an index to the AddressEntry object or do I need to rethink finding persons with the same name?
There is no intrinsic index property since there is no intrinsic sort order. There is the EntryID property, but it is not an index, but a unique id.
If you want to process all duplicate names, looping through all entries is a bad idea - some GALs contain tens of thousands of entries and might not even let you loop through them at all.
In Extended MAPI (C++ or Delphi), you can use a PR_ANR restriction to get a list of duplicates similar to what Outlook displays when you resolve a duplicate name in Outlook. That functionality is not however exposed in the Outlook Object Model. If using Redemption (I am its author) is an option, you can use RDOAddressList.ResolveNameEx method:
set Session = CreateObject("Redemption.RDOSession")
Session.MAPIOBJECT = Application.Session.MAPIOBJECT
set AdrrEntries = Session.AddressBook.GAL.ResolveNameEx("Peter Name")
for each AE in AdrrEntries
MsgBox AE.Name
next
I'm trying to figure out how to check whether an e-mail address is in the public address book by using VBA. I found some code on the Web, modified it but the code gives an error 91 at line, "Set doc = view.GetAllDocumentsByKey(ChkEmailAddr)." I think that the problem has to do with the declaration type of the variable "view" or the type of view in the line "Set view = b.GetView("People\By Internet Mail")."
I'm pretty certain that I have all of the proper references activated. "Lotus Notes Domino Objects" and "Lotus Notes Automation Classes" are chosen.
I tried to get a list of views but I couldn't figure out how to do it. Do you see the error in my code or have ideas as to what I could try to do some troubleshooting?
Sub CheckEmailAddress()
Dim books As Variant
Dim view As lotus.NotesView
'Dim view As Object
Dim doc As NotesDocumentCollection
Dim dc As NotesDocument
Dim done As Variant
Dim docarr(3, 50) As Variant
Dim ChkEmailAddr As String
ChkEmailAddr = "user#example.com"
Set Session = CreateObject("Notes.Notessession")
books = Session.AddressBooks
done = False
For Each b In books
' check every public address book,
' unless we're already done
If (b.IsPublicAddressBook) Then
Debug.Print TypeName(b)
Call b.Open("", "")
Debug.Print b.Title
' look up person's last name
' in People view of address book
Set view = b.GetView("People\By Internet Mail")
Debug.Print TypeName(view)
'Debug.Print view
'Set view = b.GetView("main")
'Debug.Print TypeName(view)
Set doc = view.GetAllDocumentsByKey(ChkEmailAddr)
' if person is found, display the phone number item
'from the Person document
If Not (doc Is Nothing) Then
For j = 0 To doc.Count
docarr(0, j) = doc.GetNthDocument(j).Items(11).Text
docarr(1, j) = doc.GetNthDocument(j).Items(93).Text
docarr(2, j) = doc.GetNthDocument(j).Items(95).Text
docarr(3, j) = doc.GetNthDocument(j).Items(14).Text
Next j
End If
End If
Next b
findEmailLotus = docarr
End Sub
I'm sorry to say this, but you have a lot of issues here. Whoever wrote that code that you started from did not know what he or she was doing.
First of all, unless you are requiring that the Notes client is running while your code is running, you should be using Lotus.NotesSession instead of Notes.NotesSession. (The former corresponds to the "Lotus Notes Domino Objects", and uses COM to talk to the Notes APIs, and the latter corresponds to the "Lotus Notes Automation Classes, and uses OLE to talk to the Notes client to talk to the APIs - hence the requirement that the client must be running.)
Secondly, you haven't mentioned what version of Lotus Notes you are dealing with, but more recent versions (8 and above) include the NotesDirectory class, which includes a LoookupNames method that would probably be a better solution for you than writing your own code to loop through address books.
Third, after doing your set view operation, you really ought to be doing an If Not view is Nothing test. That will tell you whether or not you actually have a problem opening the view.
Fourth, doc is a really bad variable name for the return value from GetAllDocumentsByKey. In 20+ years of writing Notes code, I can say that anybody reading Notes code expects the variable name doc to always refer to a single document. You are getting a NotesDocumentCollection, not a single document. Do yourself a favor and change it to docs or dc, or just about anything except doc.
Fifth, using GetNthDocument in this context is usually not recommended. It performs very badly in large collections. Even worse, however, is that you are calling it four times when you could be making only one call per iteration. Instead of a For loop, consider changing it to a call to GetFirstDocument followed by While Not doc is Nothing loop that retrieves your item values and stores them in your array, and then calls getNextDocument at the bottom of the loop.
Sixth, that code referencing .Items(11), .Items(93)... that's just plain wrong. The available items within any given document are variable because Notes is schemaless. Those item numbers will refer to different fields for different people - i.e., essentially random values. That can't possibly be what you want. You should be using getFirstItem() calls with the actual names of the items that you really want to be putting in your array. You will need to study the field names used in the Domino Directory to figure this out. I recommend NotesPeek as a good tool for exploring Notes databases and/or just opening up the Domino Directory in the Domino Designer client and looking at the Person form (and associated subforms) to figure out what you need.
As to the actual error you asked about, my guess is that by adding the recommended test of If Not view Is Nothing you will gain more information, but perhaps not enough. You haven't mentioned what your debug prints are generating, but I believe there are some cases where the title is available even if the database was not successfully opened, so I don't think you should trust that as a test of whether the call worked. In fact, you really shouldn't just be doing a Call db.open("","") call. You should be doing an If db.open("","") = true to test whether it actually worked.
For people who know lotus notes, it's trival. For those that don't, there might be an easier way using web access.
Request this address
Keep your cookies
http://server/names.nsf?login&username=MYUSERNAM&password=MYPASSWORD
Then access this url and look for a 404 status or a 200 status
http://server/names.nsf/($Users)/email#domain.com?opendocument
Of course, that requires that you have web access enabled on your server and in many cases putting your password in your code is bad, and it won't work if your servers are configured in some ways.
Before coding, test it on your server.