1

I am trying to adapt this answer, which I believe is in VB.NET, for use with Outlook VBA.

I made some progress by getting the syntax corrected for VBA, but I do not know how to resolve "Compile error: User-defined type not defined" on the line

Dim CurrentXML As XmlDocument

Tool > References includes Microsoft XML, v6.0 but searching for XmlDocument in Object Browser returns no results.

The complete code is as follows:

Sub Search2()
' https://stackoverflow.com/a/50145011/18573

Dim sFilter As String
Dim CurrentExplorer As Outlook.Explorer
Set CurrentExplorer = Nothing
Dim CurrentView As Outlook.View
Set CurrentView = Nothing

' ERROR ON THE FOLLOWING LINE
Dim CurrentXML As XmlDocument
Set CurrentXML = New XmlDocument

Dim CurrentFilterNodes, CurrentViewNodes As XmlNodeList
Dim CurrentFilterNode, CurrentParentNode As XmlNode


sFilter = "urn:schemas:httpmail:subject LIKE '%Build Error%'"

CurrentExplorer = TryCast(ExplorerObj, Outlook.Explorer)

If (CurrentExplorer Is Not Nothing) Then
    CurrentView = CurrentExplorer.CurrentView
    If (CurrentView Is Not Nothing) Then

    CurrentXML.LoadXML (CurrentView.xml)
    CurrentFilterNodes = _
        CurrentXML.getElementsByTagName("filter")
    If CurrentFilterNodes.Count > 0 Then
        For y = 0 To CurrentFilterNodes.Count - 1
            CurrentFilterNode = CurrentFilterNodes(y)
            If CurrentFilterNode.HasChildNodes Then
                For i = CurrentFilterNode.ChildNodes.Count - 1 To 0 Step -1
                    CurrentFilterNode.RemoveChild (CurrentFilterNode.ChildNodes(i))
                Next i
            End If
        Next y
        CurrentFilterNode = CurrentFilterNodes(0)
        CurrentFilterNode.appendChild ( _
            CurrentXML.createTextNode(sFilter))
    Else
        CurrentViewNodes = CurrentXML.getElementsByTagName("view")
        If CurrentViewNodes Is Not Nothing Then
            CurrentParentNode = CurrentViewNodes(0)
            CurrentFilterNode = CurrentXML.createElement("filter")
            CurrentParentNode.appendChild (CurrentFilterNode)
            CurrentFilterNode.appendChild (CurrentXML.createTextNode(sFilter))
        End If
    End If
    CurrentView.xml = CurrentXML.InnerXml
    CurrentView.Apply

    Marshal.ReleaseComObject (CurrentView)

End If
End Sub
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
Miserable Variable
  • 28,432
  • 15
  • 72
  • 133
  • 1
    Try `XmlDocument` -> `DOMDocument`, `XmlNodeList` -> `IXMLDOMNodeList`, `XmlNode` -> `IXMLDOMNode`. Also be aware of using comma for `Dim` statement in VBA. Or just don't use comma there. – omegastripes Jul 30 '18 at 22:46
  • Thanks @omegastripes, and for the additional advise on commas in Dim statement. I did not know about that and would have certainly tripped on it. If you can please convert your comment to an answer then I can accept it. – Miserable Variable Jul 31 '18 at 00:52
  • There are a lot of other issues like `TryCast`, `Not Nothing`, `Marshal`, and missing `Set` keywords. Also what is the `ExplorerObj`? – omegastripes Jul 31 '18 at 01:20

1 Answers1

1

The VBA code for Outlook should look like as follows

Option Explicit

Sub Search2()

    ' https://stackoverflow.com/a/50145011/18573
    ' Add reference Microsoft XML, v6.0

    Dim sFilter As String
    Dim oExplorer As Explorer
    Dim oView As View
    Dim oXML As DOMDocument60
    Dim cFilterNodes As IXMLDOMNodeList
    Dim cViewNodes As IXMLDOMNodeList
    Dim oFilterNode As IXMLDOMNode
    Dim oParentNode As IXMLDOMNode
    Dim y As Long
    Dim i As Long

    sFilter = "urn:schemas:httpmail:subject LIKE '%Build Error%'"
    Set oXML = New DOMDocument60
    Set oExplorer = ActiveExplorer

    If Not oExplorer Is Nothing Then
        Set oView = oExplorer.CurrentView
        If Not oView Is Nothing Then
            oXML.LoadXML oView.XML
            Set cFilterNodes = oXML.getElementsByTagName("filter")
            If cFilterNodes.Length > 0 Then
                For y = 0 To cFilterNodes.Length - 1
                    Set oFilterNode = cFilterNodes(y)
                    If oFilterNode.HasChildNodes Then
                        For i = oFilterNode.ChildNodes.Length - 1 To 0 Step -1
                            oFilterNode.RemoveChild oFilterNode.ChildNodes(i)
                        Next
                    End If
                Next
                Set oFilterNode = cFilterNodes(0)
                oFilterNode.appendChild oXML.createTextNode(sFilter)
            Else
                Set cViewNodes = oXML.getElementsByTagName("view")
                If cViewNodes.Length > 0 Then
                    Set oParentNode = cViewNodes(0)
                    Set oFilterNode = oXML.createElement("filter")
                    oParentNode.appendChild oFilterNode
                    oFilterNode.appendChild oXML.createTextNode(sFilter)
                End If
            End If
        Else
            Set cViewNodes = oXML.getElementsByTagName("view")
            If cViewNodes.Length > 0 Then
                Set oParentNode = cViewNodes(0)
                Set oFilterNode = oXML.createElement("filter")
                oParentNode.appendChild oFilterNode
                oFilterNode.appendChild oXML.createTextNode(sFilter)
            End If
        End If
        oView.XML = oXML.XML
        oView.Apply
    End If

End Sub
Miserable Variable
  • 28,432
  • 15
  • 72
  • 133
omegastripes
  • 12,351
  • 4
  • 45
  • 96
  • Thanks a ton for doing this. I had to change `DOMDocument` to `DOMDocument60`. That was easy, but there is another issue: after `Set cFilterNodes = oXML.getElementsByTagName("filter")` the length is empty, since I haven't set any filters. So I followed your example and added a node like you did when there is no current view. Actually I am not sure when CurrentView would be null but that is not very important. – Miserable Variable Aug 02 '18 at 01:49