Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I deliver an Excel VBA app without Rubberduck TestModules?

I have been using the Rubberduck VBA Add-in.

I want to "deliver" my Excel application without the Rubberduck Add-in in the References. How do you manage that? Is it possible to "hide" the TestModules and not compile them, for instance?

like image 298
Ben Avatar asked Nov 08 '19 16:11

Ben


People also ask

What is replacing VBA?

What Will Replace VBA? Short answer: JavaScript. JavaScript is a language Microsoft has been heavily investing in as it moves to unify Office across all devices (PC, Mac, Browser, & Mobile).

How easy is it to learn VBA?

With the right training, learning Microsoft VBA is easy. The Microsoft VBA Introduction course makes it easy to learn VBA primarily for Excel. There's also an Advanced VBA training course if you're looking for a higher difficulty level.

Is VBA Excel still used?

Yes, VBA is still useful and used by individuals interacting with Microsoft products. However, newer languages such as Python, C#, or R can be used to code in place of VBA. In addition, new tools such as Power Query may be able to perform tasks that could previously only be performed when using VBA.

Is Excel VBA a programming language?

VBA is a programming language that was developed by Microsoft Corp., and it is integrated into the major Microsoft Office applications, such as Word, Excel, and Access. The VBA programming language allows users to access functions beyond what is available in the MS Office applications.


1 Answers

If your test modules were early-bound (which is a great idea when developing!), then you should remove the reference to the Rubberduck type library before delivering.

Of course you could simply remove the test modules, but that becomes an annoyance of re-importing and exporting... and you don't want to do that.

You can ship the project as-is (with the test modules, but without the reference to Rubberduck), because the test modules won't be in any execution path for the actual live code: the project won't compile, but it will still run fine (unless someone tries to invoke a test method.. then the test module(s) will be loaded, and the missing library will be noticed by the compiler).

But my recommendation would be to go one step further and late-bind the AssertClass instance (and the FakesProvider, if you're using that API):

Option Explicit
Option Private Module

'@TestModule
'@Folder("Tests")

Private Assert As Object
Private Fakes As Object

'@ModuleInitialize
Private Sub ModuleInitialize()
    'this method runs once per module.
    Set Assert = CreateObject("Rubberduck.AssertClass")
    Set Fakes = CreateObject("Rubberduck.FakesProvider")
End Sub

'@ModuleCleanup
Private Sub ModuleCleanup()
    'this method runs once per module.
    Set Assert = Nothing
    Set Fakes = Nothing
End Sub

With the tests late-bound, the project will now compile with the test modules included. Of course invoking a test method will blow up (unless Rubberduck is on that machine!), but then again the test modules shouldn't be in any execution path of your VBA project.

You can configure Rubberduck to late-bind new test modules by default:

Unit Test Settings

If you're using "Permissive assert" (it implements type equality in a VBA-like permissive way), the ProgID you'll want to use for late-binding is Rubberduck.PermissiveAssertClass.

A relatively new possible configuration, is "dual binding", which sets up new test modules as follows:

Option Explicit
Option Private Module

'@TestModule
'@Folder("Tests")

#Const LateBind = LateBindTests

#If LateBind Then
    Private Assert As Object
    Private Fakes As Object
#Else
    Private Assert As Rubberduck.PermissiveAssertClass
    Private Fakes As Rubberduck.FakesProvider
#End If

'@ModuleInitialize
Private Sub ModuleInitialize()
    'this method runs once per module.
    #If LateBind Then
        Set Assert = CreateObject("Rubberduck.PermissiveAssertClass")
        Set Fakes = CreateObject("Rubberduck.FakesProvider")
    #Else
        Set Assert = New Rubberduck.PermissiveAssertClass
        Set Fakes = New Rubberduck.FakesProvider
    #End If
End Sub

'@ModuleCleanup
Private Sub ModuleCleanup()
    'this method runs once per module.
    Set Assert = Nothing
    Set Fakes = Nothing
End Sub

Configured like this, you can easily toggle between late and early binding modes:

#Const LateBind = True '/False

If you have multiple test modules, you can define a project-level precompiler constant named LateBindTests, and toggle late/early binding for all Rubberduck test modules at once. You can do this in the Project Properties (from the Tools menu, or right-click your project in the Code Explorer and select Project Properties):

Project Properties VBIDE dialog

(side note: the Help File project property (no one uses that, right?) is being hijacked by Rubberduck to assign and persist a unique ID to the project - changing this value without immediately saving & closing will break stuff)

like image 105
Mathieu Guindon Avatar answered Oct 25 '22 20:10

Mathieu Guindon