Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Only user-defined type defined in public object modules can be coerced when trying to call an external VBA function

I am trying to call an Access function from Excel and get this error:

Compile Error: Only user-defined types defined in public object modules can be coerced to or from a variant or passed to late-bound functions.

I tried to adopt this solution I found, but with no luck. Here is my code:

In the Excel Module ExternalStatistics

Option Explicit

    Public Type MyExternalStatistics
        esMyInvites As Single
        esMyInvitePerTalk As Single
    End Type

Public MyExtRecStats As MyExternalStatistics

In the Sheet1(A-Crunched Numbers) object:

Option Explicit

Public appRecruitingAccess As Access.Application

Public Sub Worksheet_Activate()
    Dim MyExtRecStats As MyExternalStatistics
    Dim RecruitWindow As Integer
    Dim test As String 

    Set appRecruitingAccess = New Access.Application
    With appRecruitingAccess
        .Visible = False
        .OpenCurrentDatabase "C:\Dropbox\RECRUITING\Remote0\Recruiting 0.accdb"
        RecruitWindow = DateDiff("d", Format(Date, Worksheets("ActivityAndIncentive").Range("IncentiveStart").Value), Format(Date, Worksheets("ActivityAndIncentive").Range("IncentiveEnd").Value))
        RecruitWindow = DateDiff("d", Format(Date, Worksheets("ActivityAndIncentive").Range("IncentiveStart").Value), Format(Date, Worksheets("ActivityAndIncentive").Range("IncentiveEnd").Value))
        MyExtRecStats = .Run("ExternalRecruitingStats", RecruitWindow) '*** ERROR HERE ***
        .CloseCurrentDatabase
        .Quit
    End With
    Set appRecruitingAccess = Nothing
End Sub

In the Access Module ExternalStatistics

Option Compare Database
Option Explicit

Public Type MyExternalStatistics
    esMyInvites As Single
    esMyInvitePerTalk As Single
end Type

Public Function ExternalRecruitingStats(StatWindow As Integer) As MyExternalStatistics 
    Dim MyRecStats As MyExternalStatistics
    Dim Invites As Integer, Talks As Integer

    Invites = 1
Talks = 2

    With MyRecStats
        .esMyInvites = CSng(Invites)
        .esMyInvitesPerTalk = CSng(Invites/Talks)
    End With
    ExternalRecruitingStats = MyRecStats 'return a single structure
End Function

It does not like the MyExtRecStats = .Run("ExternalRecruitingStats", RecruitWindow) statement. I would like to eventually assign several set in the Access function and bring them all back with one object. Then I can place those values where they should be in the spreadsheet.

like image 202
Rod Avatar asked Oct 01 '22 04:10

Rod


1 Answers

Type definitions in VBA are very local and they don't work well when you try to use them with objects that may not have access to the exact definition of the Type (which is probably the case here).

Sometimes, using a Class may work. You would need to make the class public and instantiate it before passing it around, but I have some doubts that it will actually work (for the same reason that the class definition won't be visible from one app to the other).

Another simple solution would be to use a simple Collection object instead, where you add your values as items to the collection. Of course the exact order of how you add/retrieve items is important.

There are a few interesting answers to a similar issue in User Defined Type (UDT) As Parameter In Public Sub In Class Module. It's about VB6 but it should also apply in great part to VBA.

Having said all this, you may be able to resolve all your issues by importing your Access code into Excel instead.
You can use DAO or ADO from Excel and manipulate Access databases just as if you were in Excel, for instance:

  • Connecting to Microsoft Access Database from Excel VBA, using DAO Object Model
  • Using Excel VBA to Export data to Ms.Access Table
like image 132
Renaud Bompuis Avatar answered Oct 04 '22 07:10

Renaud Bompuis