Search code examples
vb.netvbacom-interop

Error Using An Object Array With .NET COM Interop DLL


I've found a lot of other references to this error using Google but I'm having trouble making sense out of how they apply to what I'm doing.

Here's the VBA error I'm getting at compile time: "Function or interface marked as restricted, or the function uses an Automation type not supported in Visual Basic."

VBA Code that causes the error:

'ftp is also a com object created in code not posted here
Dim f() As wooxter.FTPFile
f = ftp.GetFileList 'Returns an object array of type FTPFile
Dim i As Integer
For i = 1 To (UBound(f) - 1)
    If fFileExists(stg.LocalPicDir & "\" & f(i).FileName) = True Then
        If fGetFileSize(stg.LocalPicDir & "\" & f(i).FileName) = f(i).FileSize Then
        'Error occurs on the above line at compile time
            'The error occurs specifically on f(i).FileSize, but not on f(i).FileName
            'fGetFileSize returns a VBA Long. f(i).FileSize is a VB.NET Long
    End If
    End If
Next

Here's my relevant .NET code:

Public Interface IFTPFile
    ReadOnly Property FileSize() As Long
    ReadOnly Property FileName() As String
End Interface

<ClassInterface(ClassInterfaceType.None)> _
Public Class FTPFile : Implements IFTPFile
    Private sFileName As String = ""
    Private lFileSize As Long

    Public Sub New(ByVal FName As String, ByVal FSize As Long)
        sFileName = FName
        lFileSize = FSize
    End Sub
End Class

'Fragment of a different class
Public Function GetFileList() As FTPFile() Implements IFTP.GetFileList
    Dim ftpfiles() As EnterpriseDT.Net.Ftp.FTPFile
    ftpfiles = fCon.GetFileInfos
    Dim result(ftpfiles.Length - 1) As FTPFile
    For i As Integer = 0 To ftpfiles.Length - 1
        result(i) = New FTPFile(ftpfiles(i).Name, ftpfiles(i).Size)
    Next
    Return result
End Function

Solution

  • COM has no notion of constructors. Or more to the point, constructors with arguments. If you declare any constructors for your class then it must include a parameterless constructor. The one that the client code will always use. You'll need to make FileName and FileSize properties.

    The next problem is that VBA doesn't have a 64-bit integral data type. Change the FileSize property from Long to, say, Integer or Double. Avoid Single, it doesn't have enough significant digits to accurately store a file size. It cannot store 16777217.