ByRef Argument Type MIsmatch (Compile Error) RRS feed

  • Question

  • I am completely confused why I am getting a ByRef Argument Type Mismatch error during compile in VBA module ThisOutlookSession

    I have a Sub (which used to be a function I could not get to work) which has two parameters. The Sub does a recursive search of all folders for all top level folders (the folders representing the email accounts/addresses) for a folder whose name is searched and known. The Sub returns the folder as an object in one of the parameters. (Note this was tried as a function, but efforts to get it to work by returning the object were met with errors. Another commenter on the web suggested creating it as a Sub with the return value put in one on the arguments; that worked)

    Arg 1 takes a string which represents the name of any folder located within an "account" (top level folder representing email address).

    Arg 2 is not set but is the parameter that returns the Folder object

    The code extract below shows 4 Subs. The first Sub (which will be Application_Startup when ready) is the calling sub that produces the "type mismatch" error in the 2nd argument of the call to GetFolderFromName. The 2nd Sub is another procedure that makes the call and actually works and was actually used to get the GetFolderFromName working.  The 3rd Sub is the GetFolderFromName procedure itself: it immediately calls the procedure that does all the work to find the folder in a deep recursive search and return it as an object. 

    The question is why the 1st sub produces the compiler error when the 2nd sub did not, despite all declarations seeming to be in order! The local variables are declared the same, and correctly. What is happening?

    ' The calling sub with the compile error
    Sub TestStartCode()
        Dim mainAccount, reportFolder As folder
        Dim response As Integer
        mainAccount = Nothing
        ' check for top level folder, exit with message if not present
        Call GetFolderFromName(INCOMING_CORRESPONDENCE_ACCOUNT, mainAccount)
        If mainAccount Is Nothing Then
            MsgBox ("Account '" & INCOMING_CORRESPONDENCE_ACCOUNT & "' designated " & vbCrLf & _
            "for incoming correspondence not found on this Outlook installation" & vbCrLf & vbCrLf & _
            "Make sure you have this account installed to make use of the system")
            Exit Sub
        End If
     End Sub
    ' Working test code that makes same call without a compile type mismatch error
    Sub TestFindFolderCode()
        Dim myFolderName As String
        Dim resultFolder As folder
        Let myFolderName = "Drafts"
        Call GetFolderFromName(myFolderName, resultFolder)
        If resultFolder Is Nothing Then
            Debug.Print "not found"
            Debug.Print "found!"
            Debug.Print "             Entry ID: " & resultFolder.EntryID
            Debug.Print "          Description: " & resultFolder.Description
            Debug.Print "          Folder Path: " & resultFolder.FolderPath
            Debug.Print "         Web View URL: " & resultFolder.WebViewURL
            Debug.Print "Default Message Class: " & resultFolder.DefaultMessageClass
        End If
    End Sub
    ' The called Sub, showing its declaration and working code
    Private Sub GetFolderFromName(targetFolderName As String, ByRef foundFolder As folder)
        Call ReadFoldersForTarget(targetFolderName, Application.GetNamespace("MAPI").Folders, foundFolder, -1)
    End Sub
    ' The workhorse procedure that does the deep recursive search called by the wrapper Sub
    ' sub doubles as folder hiearchy lister if level is set to 0 on the call
    Private Sub ReadFoldersForTarget(targetFolderName As String, _
                foldersCollection As Folders, ByRef foundTargetFolder As folder, ByRef level As Integer)
        Dim folder As folder
        Dim i As Integer
        Dim margin As String
        Dim searching As Boolean
        If level < 0 Then
            searching = True
            searching = False
        End If
        If searching = True Then
            For i = 0 To level
                margin = margin & "    "
            Next i
            Debug.Print margin & "|"
        End If
        For Each folder In foldersCollection
            If searching = True Then
                Debug.Print margin & "+--- " & folder.Name
                '& (EntryID: " & folder.EntryID & "), (StoreID: " & folder.StoreID & ")"
                Debug.Print " " & folder.Name
                If InStr(folder.Name, targetFolderName) > 0 Then
                    Set foundTargetFolder = folder
                    Exit Sub
                End If
            End If
            If folder.Folders.Count > 0 Then
                Call ReadFoldersForTarget(targetFolderName, folder.Folders, foundTargetFolder, level + 1)
                If Not foundTargetFolder Is Nothing Then
                    Exit Sub
                End If
            End If
        Next folder
        Set foundTargetFolder = Nothing
    End Sub

    • Edited by Doc Sys Saturday, February 10, 2018 4:48 AM errant code block displaying
    Saturday, February 10, 2018 4:46 AM

All replies

  • Perhaps the problem is that VBA is not case-sensitive but .Net is case-sensitive. If that is the problem then "Folder" is not the same type as "folder".

    Sam Hobbs

    Saturday, February 10, 2018 7:46 AM
  • I thought that might be the problem.

    And then quite accidentally (about 15 minutes after playing further with this after making my initial post), I discovered what was making the problem.

    It was the statement

    Dim mainAccount, reportFolder as folder

    Somehow, I got the impression that local variables in subs/functions of the same type could be declared on the same line in a comma-separated style.

    But then I saw this happening:

    ' Note that VBA editor in Outlook forced "Folder" type to "folder" type lowercase. Don't ask me why
    Dim mainAccount, reportFolder as folder
    ' did NOT cause compile time error type mismatch 
    GetFolderFromName("string of a folder for storing emailed reports of a processing task, folder under", reportFolder
    ' did cause compile time error type mismatch
    GetFolderFromName("string which is folder name to address", mainAccount) 

    So then I did this:

    Dim mainAccount as folder
    Dim reportFolder as folder

    And the problem went away. It all worked, and both variables in run-time show in the locals window that they are Outlook folder types, despite VBA editor forcing the spelling "folder" instead of "Folder"

    Perhaps I need a primer on how the VBA editor in Office apps really works.

    Saturday, February 10, 2018 1:57 PM
  • Doc Sys,
    re: how vba editor really works

    You must declare the type of each variable or you get a Variant...
       Dim  lngFirst as Long, sName as String - creates a Long and a String
       Dim  lngFirst, sName as String - creates a Variant and a String

    The error message you rec'd dealt with passing a Variant to a non-Variant (not allowed).
    The reverse, passing a non-variant to a variant is allowed.
    Jim Cone  (dropbox)

    Saturday, February 10, 2018 4:39 PM