Problem with AdvancedSearch method

  • Thread starter Chris O''''Neill
  • Start date
C

Chris O''''Neill

I'm trying to use the AdvancedSearch method to find a contact item using a
user-defined property attached to the item (not the folder). Here's the code
I have so far:

'********* Begin Code***********
Dim olApp As Object
Dim objContact As Object
Dim objContacts As Object
Dim objNameSpace As Object
Dim objProperty As Object
Dim objSearch As Object
Dim objResults As Object
Dim strF1 As String
Dim strS1 As String

Set olApp = CreateObject("Outlook.Application")
Set objNameSpace = olApp.getnamespace("MAPI")
Set objContacts = objNameSpace.GetDefaultFolder(olFolderContacts)
strF1 = "('DAV:isfolder' = false AND 'DAV:ishidden' = false) AND " & _

"('http://schemas.microsoft.com/mapi/string/{00020329-0000-0000-C000-000000000046}/" & _
"BalloonAppID' = '" & strContactID & "')"
strS1 = "*"
Set objSearch = _
olApp.AdvancedSearch(Scope:=strS1, Filter:=strF1,
SearchSubFolders:=True, Tag:="ContactSearch")

'********* End Code***********

When I run this I get the following error:

446: Object doesn't support named arguments

Does this mean that I can't use a variable (strContactID) in AdvancedSearch,
or have I got something else wrong? Also, I'm not sure but I think the
filter string is for the default contact folder field not a user-defined
contact item property.

Any help with this would be VERY much appreciated!

Regards, Chris
 
D

Dmitry Streblechenko

That sounds like you cannot use named arguments when calling
olApp.AdvancedSearch:
olApp.AdvancedSearch(strS1, strF1, True, "ContactSearch")

--
Dmitry Streblechenko (MVP)
http://www.dimastr.com/
OutlookSpy - Outlook, CDO
and MAPI Developer Tool
-
 
C

Chris O''''Neill

As per Dmitry's post, the offending line was this one:

olApp.AdvancedSearch(Scope:=strS1, Filter:=strF1, _
SearchSubFolders:=True, Tag:="ContactSearch")

I changed it to this:

olApp.AdvancedSearch(strS1, strF1, True, "ContactSearch")

And now I'm getting this error message:

-2147023281 Operation Failed

I'm pretty sure that the problem is my filter string:

strF1 = "('DAV:isfolder' = false AND 'DAV:ishidden' = false) AND " & _
"('http://schemas.microsoft.com/mapi/string/" & _
"{00020329-0000-0000-C000- 000000000046}/" & _
"BalloonAppID' = '" & strContactID & "')"

Or, maybe it's my scope string:

strS1 = "*"

It's gotta be one of these, right?!?!

Again, what I'm trying to do is AdvanceSearch all folders for a user-defined
item property called "BalloonAppID" that has been applied to a contact item.
Any help would be VERY much appreciated!

Regards, Chris
 
C

Chris O''''Neill

Once again, I've left out some information that might be important to solving
this problem. I'm doing all this in an Access XP (2002) application.

Not sure that's important, but figured I'd better mention it.

Regards, Chris
 
D

Dmitry Streblechenko

Try to leave one condition only and add the other conditions one at a time
until the problem comes back.

--
Dmitry Streblechenko (MVP)
http://www.dimastr.com/
OutlookSpy - Outlook, CDO
and MAPI Developer Tool
-
 
K

Ken Slovak - [MVP - Outlook]

The problem is your scope. You can't use a wildcard scope such as "*". If
you want Contacts and subfolders then set your scope to "Contacts". The
search subfolders argument takes care of the rest of what you want.
 
C

Chris O''''Neill

I had a feeling the wildcard might be problematic. Thank you for pointing
that out.

What I want is to be able to find the contact item no matter where it might
be. I'm originally creating it in the default Contacts folder, but the user
might move it. Since I'm not that familiar with Outlook, I have to ask...
is it possible to move a contact item into a folder that's *not* in the
"Contacts" folder tree? If so, what scope string can I use to start at the
top and work my way through *all* folders?

Thanks, so much, for your help and assistance, Ken.

Regards, Chris
 
C

Chris O''''Neill

I'm getting close. With some mucking around, I managed to get my subroutine
working by using "Contacts" as the scope. However...

I created a new folder ("My Special Contacts") in the "My Shortcuts" folder
and moved a contact into that. Of course, I now can't find that contact
using my subroutine because it's no longer in the "Contacts" folder.

How do I change the scope string so that it will look in all folders? I
tried using "My Special Contacts" and "Folders" and "My Shortcuts" but these
don't work.

Again, thanks so much for any help and assistance provided.

Regards, Chris
 
K

Ken Slovak - [MVP - Outlook]

It depends on whether you're using PST files or Exchange mailboxes. As an
example, say for an Exchange mailbox, you'd use something like this:

strScope = "SCOPE ('shallow traversal of "SCOPE ('shallow traversal of"
strScope = strScope & Chr(34) & "\\Mailbox - Ken Slovak" & Chr(34) & "')"

Then you'd set the SearchSubfolders argument = true.

The best way to see what you need to supply is to use the Immediate window
of the Outlook VBA project. In that window type this, after selecting the
top level folder where you want your search to start:

? Application.ActiveExplorer.CurrentFolder.FolderPath

That folder path is what you want as the top level of your search scope.
 
C

Chris O''''Neill

Thank you VERY much for that hint, Ken. Btw, I'm not using Exchange Server.
This is a generic "Outlook on standard PC" setup.

When I open Outlook, I'm automatically put into the "Outlook Today" folder
(or is that a view????) Anyway, when I run that code you gave me into the
VBE Immediate Window, I get the following result:

\\Personal Folders

I then change into the folder where I moved the contact item. When I run
that code you gave me, I now get this:

\\Personal Folders\My Special Contacts

So, obviously, the "My Special Contacts" folder is a subdirectory of the
"Personal Folders" folder. The problem is, when I use any of these as my
scope string:

strScope = "Personal Folders"
strScope = "Personal Folders\My Special Contacts"

I get error this error message:

"Error: -2147023281 Description: Operation Failed"

When I use either of these:

strScope = "\\Personal Folders"
strScope = "\Personal Folders"
strScope = "\Personal Folders\My Special Contacts"
strScope = "\Personal Folders\My Special Contacts"

I get this error message:

"Error: 5 Description: Invalid Procedure Call or Argument"

If I use this scope string:

strScope = "My Special Contacts"

It works (of course!) but I don't want that because the scenario I'm working
with is that the user has moved it somewhere that I don't know about and I
have to go and find it. That's why I want to search the whole tree. But
how????

(SIGH!) I'm sure that I'm VERY close to figuring this out, but I just can't
seem to get it.

Regards, Chris
 
K

Ken Slovak - [MVP - Outlook]

Boy, I really screwed up with copy/paste in that scope example, didn't I?

You should use the shallow traversal piece and also enclose your scope in
single or double quotes. For personal folders that means it should look
something like this:

strScope = "SCOPE ('shallow traversal of "
strScope = strScope & Chr(34) & "\\Personal Folders" & Chr(34) & "')"

So in the end the scope string, if printed out to the immediate window,
would look like this:

SCOPE ('shallow traversal of "\\Personal Folders"')

That should work for you.
 
C

Chris O''''Neill

Ken Slovak - said:
Boy, I really screwed up with copy/paste in that scope example, didn't I?

LOL! I didn't notice because that scope example was for Exchange Server
which I'm not using. Anyway...
You should use the shallow traversal piece and also enclose your scope in
single or double quotes. For personal folders that means it should look
something like this:

strScope = "SCOPE ('shallow traversal of "
strScope = strScope & Chr(34) & "\\Personal Folders" & Chr(34) & "')"

So in the end the scope string, if printed out to the immediate window,
would look like this:

SCOPE ('shallow traversal of "\\Personal Folders"')

That should work for you.

Yes!!!!! Yes!!!!! Yes!!!!! (Jumping for joy....) That certainly does
work! Whew!!! That was a most painful process, but the subroutine now works
very well. Thank you VERY, VERY much for your help!

Btw, this is a really *minor* and picky thing, but maybe you can help me
with just one more tinsey-weensy issue with this routine?

It seems that AdvancedSearch requires some time to complete so if I go and
look at the results object immediately after starting the AdvancedSearch
object I don't get any hits. To get around this, I have put the following
loop in my code right after the AdvancedSearch object starts:

i = 0
While i < 1000
DoEvents
i = i + 1
Wend

This does work, but I'm wondering if there's a more "elegant" way of doing
it? I know you can put some code in Outlook's AdvancedSearchComplete event,
but I'm doing this in Access not Outlook so I don't think I have access to
Outlook's AdvancedSearchComplete event.... or do I?!?!?

Anyway, like I said, this is getting *very* picky, but if you know of a more
"elegant" way of introducing a pause in Access while Outlook completes the
AdvancedSearch method I'm all ears.

Thanks, again, for your patience and all your help.

Regards, Chris
 
C

Chris O''''Neill

Just in case anyone in the future is having problems with Outlook's
AdvancedSearch method and comes across this thread, here's the final working
code to use the AdvancedSearch method to search all folders for an Outlook
contact item.

Enjoy!

Regards, Chris

********* Begin Code ***************
Public Function FindOutlookContact(ByVal strContactID As String)
On Error GoTo ERR_FindOutlookContact

'---------------------------------------------------------------------------------------
' Procedure : FindOutlookContact
' Purpose : Finds an Outlook Contact Item using the AdvancedSearch method
' and displays it
'---------------------------------------------------------------------------------------

Dim olApp As Object
Dim objContacts As Object
Dim objNameSpace As Object
Dim objSearch As Object
Dim objResults As Object
Dim strFilter As String
Dim strScope As String
Dim blnSearchComp As Boolean
Dim i As Integer

Set olApp = CreateObject("Outlook.Application")
Set objNameSpace = olApp.getnamespace("MAPI")

strFilter =
"http://schemas.microsoft.com/mapi/string/{00020329-0000-0000-C000-000000000046}/BalloonID = " & strContactID
'strScope = "BalloonAppID"
strScope = "SCOPE ('shallow traversal of "
strScope = strScope & Chr(34) & "\\Personal Folders" & Chr(34) & "')"


'strScope = "Personal Folders"
Set objSearch = olApp.AdvancedSearch(strScope, strFilter, True)

i = 0

' While blnSearchComp = False
While i < 1000
DoEvents
i = i + 1
Wend

Set objResults = objSearch.Results
If objSearch.Results.Count <> 0 Then
For i = 1 To objResults.Count
objResults.Item(i).Display
Next
Else
MsgBox "Cannot find the Outlook Contact Item!", vbCritical, "Contact
Item Missing!"
End If

Exit_FindOutlookContact:
Set olApp = Nothing
Set objNameSpace = Nothing
Set objSearch = Nothing
Set objResults = Nothing
Exit Function

ERR_FindOutlookContact:
msgbox "Error Number: " & Err.Number & " Description: " &
Err.Description, _
vbcritical, "Error!"
Resume Exit_FindOutlookContact

End Function
********* End Code ***************
 
K

Ken Slovak - [MVP - Outlook]

You certainly do have access (bad pun) to the complete event, and that's the
way to go, not a loop.

Make sure your search has a unique tag property and then when the event
fires just check the tag to make sure it's the search you're interested in.
 
K

Ken Slovak - [MVP - Outlook]

Dim WithEvents olApp As Outlook.Application
Dim strTag As String

strTag = "myadvancedsearch"

' blah, blah

Set objSearch = olApp.AdvancedSearch(strScope, strFilter, True, strTag)


' event handler:

Private Sub olApp_AdvancedSearchComplete(SearchObject As Search)

If SearchObject.Tag = strTag Then
' whatever
End If
End Sub
 
K

Ken Slovak - [MVP - Outlook]

No, you can't do nested subs. The WithEvents declaration would be at module
level. olApp_AdvancedSearchComplete is a separate sub in a module that's the
complete event handler.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top