How to display in Outlook, using VBA, a list of emails based on their EntryID (based on a list of EntryIDs stored in MS Access) - vba

I have an Access DB that interacts with Outlook, including capturing the EntryID of selected emails as needed (which are stored in a table in Access)
I have code that allows users to view any email whose EntryID is stored, using Outlook's GetItemFromID method. This works as needed - it opens up a single email based on its EntryID.
However, what I am now looking to do is to filter the main Outlook window, to show emails based on a list of EntryIDs I have saved. So, for clarification, if I have a list of eg 3 emails (with their respective EntryIDs), the main Outlook window would be filtered to show those 3 emails. So basically like a search, but based on EntryIDs.
I can't seem to find anyway to do this? Perhaps there is a way to add a search filter via VBA that will search based on EntryIDs, but I can't find anything on this.
Any ideas much appreciated.

Binary properties like EntryID can't be used in any search or filtering operation in Outlook. You need to use any other properties (custom or user-defined ones) for filtering items in Outlook.
The View.Filter property value is a string, in DAV Searching and Locating (DASL) syntax, that represents the current filter for the view. For more information about using DASL syntax to filter items in a view, see Filtering Items.
Private Sub FilterViewToLastWeek()
Dim objView As View
' Obtain a View object reference to the current view.
Set objView = Application.ActiveExplorer.CurrentView
' Set a DASL filter string, using a DASL macro, to show
' only those items that were received last week.
objView.Filter = "%lastweek(""urn:schemas:httpmail:datereceived"")%"
' Save and apply the view.
objView.Save
objView.Apply
End Sub
Be aware, the EntryID value can be changed when items are moved between stores or folders. Moreover, the value is unique only per store.
If you need to show some items with specific EntryIDs strings you can get these item instances by using the GetItemFromID method and then marking them with a specific user property to be able to apply a filter for it. Or just add another string field to the Db with a custom value which can be added to items in Outlook, so you could easily apply a filter in the UI.

Related

Identify Outlook meetings that include both a Teams meeting link and a Zoom meeting link

A recent Outlook updates automated the addition of Team links to every meeting invite.
I've had several meetings go sideways because the person distributing the meeting invite wasn't aware.
Is there a configuration or script to scan meetings on my calendar and identify any that have multiple meeting links (e.g., Zoom + Outlook)?
If I have a list I can either fix myself (if I'm the meeting owner) or follow up with the organizer.
Taking a quick look at an appointment set to use both Teams and Zoom, I see in OutlookSpy (I am its author) that there are a few Teams and Zoom specific named properties set (see the screenshot below).
You can search for items with both sets of properties present. The following script should find appointments like that. Assuming you run it from Outlook VBA:
set folder = Application.Session.GetDefaultFolder(olFolderCalendar)
set items = folder.Items.Restrict("#SQL=(""http://schemas.microsoft.com/mapi/string/{00020329-0000-0000-C000-000000000046}/cecp-propertyNames/0x0000001F"" IS NOT NULL) AND " & _
" (""http://schemas.microsoft.com/mapi/string/{00020329-0000-0000-C000-000000000046}/SkypeTeamsMeetingUrl/0x0000001F"" IS NOT NULL) ")
Debug.Print(items.Count)
for each item in items
Debug.Print item.Subject
next
You can create a VBA macro where you could iterate over all appointments/meetings on the calendar and check the RTFBody property whether it contains one or another meeting URL. Also you may optimize the code a bit by getting only specific calendar items or process them in chunks. To get only items that corresponds to your conditions you may use the Find/FindNext or Restrict methods of the Items class. Read more about them in the following articles:
How To: Use Restrict method in Outlook to get calendar items
How To: Retrieve Outlook calendar items using Find and FindNext methods

How to get the top X items in the active folder based on the current view

I would like to find a way of getting the top X (say 10) mail items in the current folder based on the sort order and filters the user may have applied.
The main issue is that the folder's Items collection gives all of the mail items in date order and there is no obvious way to sort and filter the collection based on the current view.
Sub foo()
Dim i As Long
Dim objFolder As Outlook.Folder
Dim objItem As Outlook.MailItem
Set objFolder = Outlook.Application.ActiveExplorer.CurrentFolder
For i = 1 To 10
Set objItem = objFolder.Items(i)
Debug.Print objItem.Subject
Next i
End Sub
It would be great if someone would point me to the correct places in the Outlook object model so that I can achieve this.
You are on the right avenue. There is a difference between the view and the Items collection which you are trying to use in the code.
To get the filter applied on the UI you need to use the following sequence of property and method calls:
Explorer.CurrentView.SortFields
The CurrentView property of the Explorer or Folder class returns an object representing the current view. The View object allows you to create customizable views that allow you to better sort, group and ultimately view data of all different types. There are a variety of different view types that provide the flexibility needed to create and maintain your important data. Views are defined and customized using the View object's XML property. The XML property allows you to create and set a customized XML schema that defines the various features of a view.
The View.Filter property returns or sets a string value that represents the filter for a view. The value of this property is a string, in DAV Searching and Locating (DASL) syntax, that represents the current filter for the view. For more information about using DASL syntax to filter items in a view, see Filtering Items.
Also, you can cast the View object to the TableView and use its properties for detecting the sorting mechanisms. The SortFields property returns an OrderFields object that represents the set of fields by which the items displayed in the TableView object are ordered.
So, then you can apply the filter retrieved to the Items collection to get the right order. Or the opposite, to set the order in the Outlook UI.
Private Sub FilterViewToLastWeek()
Dim objView As View
' Obtain a View object reference to the current view.
Set objView = Application.ActiveExplorer.CurrentView
' Set a DASL filter string, using a DASL macro, to show
' only those items that were received last week.
objView.Filter = "%lastweek(""urn:schemas:httpmail:datereceived"")%"
' Save and apply the view.
objView.Save
objView.Apply
End Sub
Finally, I'd suggest observing the View.XML property which returns or sets a String value that specifies the XML definition of the current view. The XML definition describes the view type by using a series of tags and keywords corresponding to various properties of the view itself. When the view is created, the XML definition is parsed to render the settings for the new view.
To determine how the XML should be structured when creating views, you can create a view by using the Outlook user interface and then you can retrieve the XML property for that view.

Create an `Items` collection containing references to already existing `Item`s

I mean to create an Items collection, and add to it several already existing Items.
For instance, if I have two references to MailItems, I want to set an Items collection containing those two Items.
It would be something like
' ...
' Code that assigns references to olMail1 and olMail2, of type Outlook.MailItem
' ...
Dim MyItems As Outlook.Items
' Assign with Set / create the object
MyItems.Add olMail1
MyItems.Add olMail2
' Code that can use MyItems(1) to get a reference to olMail1
How can that be done?
Things to clarify are:
How to setup the new collection.
How to add items.
Documentation on Items.Add seems to indicate that it is used for adding newly created objects, not references to existing Items.
I would later iterate through that collection, for instance. I would also apply Find or Restrict; this allows for applying the methods on a much smaller collection than a whole Folder.
PS: I cannot get an Items collection even from
Application.ActiveExplorer.Selection (i.e., without need for creating the collection and add Items one by one). This would be good for a starter.
Background
I mean to find what Items have a sender matching a given string. The aspects that perhaps make my case somewhat more complex than a "base case" are:
I mean to apply the filter only on a selected group of items. E.g., only on the Items that are selected in the Inbox index.
I want to do partial matching. At this point I do not need regular expressions, or even full use of wildcards *?. But at least partial matching as in InStr.
I mean to have a specific Function for the minimal unit: testing one Item, for a single condition. Then loop through all target Items, and all conditions.
I conceived 3 approaches:
Use Rules.
Use Filter or Restrict. These do not accept wildcards (in principle?).
"Manually" check conditions, with InStr, e.g.
Each of the aspects above may bear some complexity for one or more of the approaches.
At this point, I was exploring approach 2. I have a reference to a single Item, and I found how to apply a Filter with a matching condition (see
http://www.outlookcode.com/news.aspx?id=30 ,
http://blogs.msdn.com/b/andrewdelin/archive/2005/05/11/416312.aspx , and the non-accepted answer of VBA Search in Outlook). But to apply the Filter, I need an Items collection, containing my single item.
I have something working with approach 3 (as suggested in the accepted answer of VBA Search in Outlook).
Related links
Identify MailItems satisfying a Rule
You can just use a regular collection:
Dim myItems As Collection
Set myItems = New Collection
myItems.Add olMail1
myItems.Add olMail2
Now if you're looking to restrict the type of objects than can be contained by myItems, then it becomes a bit more complicated, but here's a way to do it:
Restrict type in a Collection inside a class module
I'd suggest starting from the Getting Started with VBA in Outlook 2010 article in MSDN.
An instance of the Items class can't be created in the code. It is asociated and belongs to any folder. You can create a folder to get a new Items instance.
You can use the Copy method of Outlook items to create another instance of the object. Then the Move method can be used to move the item to another Items collection (folder).
1.I mean to apply the filter only on a selected group of items. E.g., only on the Items that are selected in the Inbox index.
You need to iterate over all selected items instead. The Find/FindNext and Restrict methods belong to the Items class only. So, you can apply them to the Folder items only.
2.I want to do partial matching. At this point I do not need regular expressions, or even full use of wildcards *?. But at least partial matching as in InStr.
See Filtering Items Using a String Comparison. You can use the ci_startswith or ci_phrasematch operators.
3.I mean to have a specific Function for the minimal unit: testing one Item, for a single condition. Then loop through all target Items, and all conditions.
Take a look at the Filtering Items section in MSDN which describes the general rules for specifying properties in filters that are supported by various objects in Outlook.
The Filter method of the View class is applied to the Outlook view only. The Items property will return the full list of items.
It would be better if you specify the final goal, not possible way to solve the problem which is not clear for us.

creating fields in lotus notes document?

I am trying to export items from my access database into lotus notes. The document I am trying to export to is a stationary, and has all the data written into it, I just need to somehow mark placeholders and then update the values. I have read the documentation and it appears I will need to address fields and then call a method to replace the text like so:
'where body is the field and the following string is what to replace field with
Call doc.ReplaceItemValue("body", "REPLACE BODY")
To be clear, my entire code looks like:
Set session = CreateObject("Notes.NotesSession")
Set maildb = session.GetDatabase("server", "mail\box.nsf")
Set View = maildb.GetView("Stationery")
Set entries = View.AllEntries
Set entry = entries.GetFirstEntry
Set doc = entry.Document
Call doc.ReplaceItemValue("Subject", "Report - " & Date)
'add code here
Call doc.send(False, "person.to.receive#thisemail.com")
End Sub
I have noticed that while perusing documentation, there seems to be an ability to create fields, and then address those fields to update values. So for example, if I have a field named $COST, then one could do:
Call doc.ReplaceItemValue("$COST", "The cost is $3000")
And that field should be updated to reflect the value I passed through the method. My big problem is, even looking through documentation, I cannot figure out where I need to go to add in my custom fields. It seems that the documentation assumes that you know how to create these fields and just address them. Or am I only supposed to create these fields programatically and then fill in the data? My client is Lotus Notes 8. Thanks!
Yes, that is the cool thing about IBM Lotus Notes databases: you can put items (=fields) in a Notes document without a prior definition of fields.
If you create items in a document with doc.ReplaceItemValue() and save or send the document then the items are just there. You can check the items when you open the property box for a selected document. All items are listed on document properties' second tab.
Another question is of course to define fields in a form so that the created items are visible to user without looking at document properties box. Open database in Designer and put the fields in right position and size to form.
Your question and comments telling that you want to create a document, fill it with data and send it to users.
If all users have access to your Notes server then you can create that document in your existing database and send just a link mail to users. This way you can create a good looking form and position all your data fields. Users will access the document in database through link.
An alternative is to create an nice looking HTML file, attach it to the mail and send it.
In this case you would add this code to your example at 'add code here:
Call doc.RemoveItem("Body")
Set rtitem = doc.CreateRichTextItem( "Body" )
Call rtitem.AppendText("your mail text")
Call rtitem.EmbedObject(EMBED_ATTACHMENT, "", "report.html")
Based on the comment thread on #Knut Herrmann's answer, I believe that the solution you really want involves using "stored form". The first argument to the NotesDocument.Send() method is a boolean that specifies whether you want to store the form or not.
Normally, you would use Domino Designer to create a stored form. You would not need Designer rights to anyone's mailbox. You would just need to create an empty database of your own, and put a form into it. You woould change your code to open that database and create the document in there instead of in a mailbox database as you are doing now. (One of the other cool things about Notes is that you don't actually have to be working in a mailbox database in order to mail a document. You can mail any document from any database, as long as you put the approporiate fields into it.)
There is also a way to do this without Domino Designer, and you could even dynamically generate the form with truly custom fields that your code only discovers as it runs. You could do this with DXL, which is an XML format for describing Lotus Notes objects, including forms. You would just need some sample DXL to work from. Preferably that should be of an empty database that contains a simple form that is set up more or less in the layout that you would want, though again you would need Domino Designer for that. You could just use the same mailbox database that your code is currently using, but that will leave you with a lot of extra stuff in the DXL that doesn't need to be there; and given that you're not all that familiar with Notes, it would likely be difficult for you to navigate through it all to find what you need.
Either way, though, you could use the NotesDXLExporter class to generate the DXL file. Your code could manipulate the DXL, adding/changing elements as needed (following the pattern that you see in sample, of course), and they you could use NotesDXLImporter to create the database that your code will actually use to create the document in and mail the message with the stored form.

Syntax for SharePoint 2010 BCS URL Action to populate New form

Have seen several posts with solutions for native SharePoint lists, including the very useful SPUtility.js (only for native SharePoint lists). But nothing to pass a value from a BCS list to a new BCS list. The Query string filter will not connect on the New form (no web part to connect it to) and does me no good on the lists page (already have that working).
A "go write custom code for everything" is not a solution for me.
There should be a way to 1) pass the value in the URL (ideal - what's the syntax?) or 2) make some other simple change, perhaps to the select list for the item -- I just can't find it. Have seen quite a few posts with similar questions. The Microsoft documentation is not useful and there are more questions on the "social" topics than answers.
Here's what I have:
I have a BCS list (sends item) tied to a BCS related list (receives item).
I have an action on the related list (ECT) to create a new item. Works fine with no parameters. I get a blank new form. The new form allows me to enter two items and choose two items (exactly as intended).
What I would like to have is the necessary ?something=something string so that my user does not have to select one of the choice items (MNumber - set as a key / required value)
User selects "New" from Actions.
Form Opens
MNumber is automatically filled in based on the MNumber of the current item displayed in the BCS related list.
The string I supply is accepted. Does nothing.
/intake/Lists/ContactsList/NewForm.aspx
/intake/Lists/ContactsList/NewForm.aspx?MNumber=1234
The string I supply is rejected - cannot be saved or insufficient values.
/intake/Lists/ContactsList/NewForm.aspx?MHICNumber={$MHICNumber}
Have also tried passing a string to one of the text fields (instead of the select field). Can't get that to work either. I've spent quite a few hours with the various boards. Nothing helpful.
Would also be nicer if I could set the New form to display in a pop-over window (as it does when I select New from the list view). Opening a new browser window is hokey and replacing the existing one is a navigation pain for the user.
Have this working ... Thanks to Kit Menke!
Created an Action on the External Content Type in the BCS....
/intake/Lists/ContactsList/NewForm.aspx?IDnumber={0}&Source=/intake/scheduling.aspx
where
parameter property 0 is the IDNumber from the ECT
The NewForm.aspx was edited to add a hidden content editor web part with references to three scripts Kit wrote - two supporting and one that sets the values.
http://site/list/NewForm.aspx?toolpaneview=2
User selects the Action on the displayed ECT list
Action uses the URL to go to the New page with the data
Kit's script adds the data to the form and puts in the date and time.
Note: The ID field needs to be a text field. Cannot be a selection list.