Version 1.22 – Hotfix

There was an issue with some of the features when a password protected VBA Project was loaded. This caused several of the tool window, most notably the Test Explorer, to fail to open. As many of the more popular add-ins are password protected, this was a pretty big problem.

This has been corrected and the 32bit installer is available now. This post will be updated when the 64bit installer is available.

Download the latest version here.

Naming is hard. Renaming is easy.

There are only two hard things in Computer Science: cache invalidation and naming things.

— Phil Karlton

How many VBA modules declare variables looking like this:

Dim v As Long, vWSs As Variant, Mrange As Range, Vrange As Range

Or like this:

Dim i As Long
Dim LR As Long

How many procedures have cryptic names that only the author knows what they mean?

How many Times did you refrain from renaming a procedure in fear of breaking the code?

Fear no more. Renaming doesn’t have to be the hardest part of using meaningful names in code.

With the next release of Rubberduck, finding a meaningful name is going to be the hardest part – I’m please to announce that Rubberduck 1.3 will feature a rename refactoring:

rename-const

Awesome. How does it work?

I’m tempted to say “Magic!” here. Rubberduck uses the current selection (/caret location) to guess what you’re trying to rename. If you’re on a constant usage, it knows to rename the constant and every single one of its references; if you’re just inside a procedure scope, it guesses you want to rename the procedure and affect every single call site; if you’re somewhere in the declarations section of a module, it lets you rename the module itself, and automatically adjusts every explicit reference to it.

The Rubberduck/Refactor menu will feature a new “Rename” button, accessible with Alt+B,R,R (Rubberduck/Refactor/Rename).

The Code Explorer‘s context menu will also feature a “Rename” button, so that any module/member can be renamed without even looking at the actual code.

Lastly, we’ll hijack the code pane context menu and add our “Refactor” menu in there, too.

Naming is hard. Renaming doesn’t have to be!

Rubberduck 1.3: When the VBE becomes a real IDE

Parsing is hard!

Rubberduck parsing is being refined again. The first few releases used a hand-made, regex-based parser. That was not only unmaintainable and crippled with bugs, it also had fairly limited capabilities – sure we could locate procedures, variables, parameters… but the task was daunting and, honestly, unachievable.

Version 1.2 changed everything. We ditched the regex solution and introduced a dependency on ANTLR4 for C#, using an admittedly buggy grammar intended for parsing VB6 code. Still, the generated lexer/parser was well beyond anything we could have done with regular expressions, and we could implement code inspections that wouldn’t have been possible otherwise. That was awesome… but then new flaws emerged as we realized we needed more than that.

Version 1.3 will change everything again. Oh, we’re still using ANTLR and a (now modified) buggy grammar definition, but then we’re no longer going to be walking the parse tree all the time – we’re walking it once to collect all declarations, and then once to collect all usages of every single identifier we can find.


What does that mean?

Imagine a table where, for every declaration, you lay down information such as the code module where you found it, the exact location in the code file, the scope it’s in, whether it’s a class module, a standard module, a procedure, a function, a property get/let/setter, an event, a parameter, a local variable, a global constant, etc. – and then whether it has a return/declared type, what that type is, whether it’s assigned a reference upon declaration (“As New”) – basically, on that table lays the entire code’s wireframe.

Then imagine that, for everything on that table, you’re able to locate every single reference to that identifier, whether it’s an assignment, and exactly where that reference is located – at which position in which code file and in which scope.

The result is the ability to make the difference between an array index assignment and a function call. If VBA can figure out the code, so can Rubberduck.

This means the next few versions will start seeing very cool features such as…

  • Find all references – from a context menu in the Code Explorer tree view, or heck, why not from a context menu in the code pane itself!
  • GoTo implementations – easily navigate to all classes that implement a specific interface you’ve written.
  • GoTo anything – type an identifier name in a box, and instantly navigate to its declaration… wherever that is.
  • Safe delete – remove an identifier (or module/class) only if it’s not used anywhere; and if it’s used somewhere, navigate to that usage and fix it before breaking the code.
  • Rename refactoring – rename foo to bar, and only the “foo” you mean to rename; this isn’t a Find & Replace, not even a RegEx search – it’s a full-fledged “rename” refactoring à la Visual Studio!

Not to mention everything else that’s in store for v1.3 (did I say IDE-Integrated GitHub Source Control?) – stay tuned!

v1.21 is here! (yes, including for 64-bit Office!)

64-bit Office

At long last, after countless hours of mucking around with InstallShield Express, a working installer for 64-bit Office was finally released.

It unfortunately still requires admin privileges, but at that point all I wanted was to get something that works out – we’ll polish later and certainly end up properly addressing issue #310. But the good news is that 64-bit Office users can now enjoy all the goodies we’ve packed into this release!

What’s New?

Code Explorer

v1.21 was honestly meant to be nothing but a quick bug-fix release. But when I started addressing the Code Explorer issues, I couldn’t help adding, and adding, and adding… here’s what the new Code Explorer looks like:

code-explorer

Just like with the VBE’s Project Explorer, you can now toggle folders on/off, add forms, modules, classes, and show form designers. But here’s something the VBE doesn’t do: display full signatures (well, it doesn’t even display member names, but nevermind), run code inspections and unit tests, and add a new test module from a nifty little context menu!

Unit Testing

You asked for it, we implemented it. Unit tests now support setup & teardown methods:

  • TestInitialize methods run before each test
  • TestCleanup methods run after each test
  • ModuleInitialize methods run before the tests in the test module they’re in
  • ModuleCleanup methods run after the tests in the test module they’re in

Method stubs have been added to the new test module template to show how it’s done.

Code Inspections

Nobody really asked for this one, but I wanted to be able to bring inspection results into the clipboard, so the toolbar in the Code Inspections toolwindow now features a “Copy” button that does just that – and then you can paste inspection results wherever you like.

About Box

The about box got a serious facelift. I know, not exactly a feature, but I had to mention it! The new about box actually links to our official website (http://www.rubberduck-vba.com) and to our social media accounts.

And it’s much prettier than the old one.


That’s just new features – a number of annoying bugs were also taken care of.

We’re very, very happy about this release – and if you like what you’re seeing, know one thing: you ain’t seen nothin’ yet! (see our GitHub repository for everything we have in store for release 1.3)

64-bit Rubberduck: a work-around until release 1.21 (soon)

If you’re running 64-bit Microsoft Office, an out-of-the-box Rubberduck install will fail to load in the VBE.

Here’s a work-around until we get to re-test everything and release 1.21:

First, make sure the Rubberduck.Extension key is defined under Addins64, not just Addins:

rubberduck-addins64-key

But then, being registered against the .net 2.0 runtime, the add-in still refuses to load – registering it against 4.0 with regasm.exe fixes this.

c:\Windows\Microsoft.NET\Framework64\v4.0.30319\RegAsm.exe /codebase $(TargetPath) /tlb

where $(TARGETPATH) is the Rubberduck.dll file, in its installation folder.

Trouble with 64 bit Versions of Office

Today has been… surreal. Just surreal. It seems Rubberduck has reached the other side of the globe.

Or, as translated by Google.

Outrageous things had been dropped on Twitter timeline. In of one of such VBA has stopped when from the early 1990s development environment VBE (Visual Basic Editor), modern integrated development environment (IDE) seems crazy add-in to add a parallel features have appeared. Very incarnation of madness and flew down to modern times, also the name Rubberduck.

Just as I was starting to get excited though, I realized we had a problem with 64 bit versions of Office.

But, in the hand of the environment (Windows8.1 + Office2013 (64bit)), even if you install the add-in Rubberduck was not recognized from the VBE

I think I know what’s causing the issue, but I don’t have a 64 bit version of Office to test on. Which is problematic to say the least. However, one of the followers of our repo seems to be stepping up to test a theory, so hopefully we can get this corrected soon. I’d like to see a really glowing review out of @igeta in the new future.

Code Explorer – does it replace the VBE’s Project Explorer?

Version 1.21 will feature a Code Explorer getting closer to where we envision it:

Just like the Project Explorer we can now toggle folders on and off, and components are sorted alphabetically. We can add standard and class modules, even test modules, open the designer when a form is selected – we can even run all tests from there if we want.

The Code Explorer is a bit of an hybrid between the VBE’s Project Explorer and Object Browser windows – we see all the members of every module, and we can double-click navigate anywhere.

We’re planning to implement a number of refactorings in 1.3, and some of them are going to be available from the Code Explorer‘s context menu. 1.3 will also integrate GitHub source control, and the Code Explorer‘s context menu will be usable to commit or undo changes to a specific file – importing and exporting files is also going to be in that menu by then.

What else would you use the Code Explorer for? Does the Code Explorer replace the VBE’s Project Explorer for you?

Overcoming Limitations: Testing that an event was raised

Why?

Rubberduck unit tests live in standard modules (.bas) for a reason: they are executed with Application.Run, which is meant to execute macros. In an ideal world, Rubberduck unit tests would live in class modules (.cls) and be executed with CallByName. The problem is that CallByName is a VBA function, not an API member – and we can’t just execute arbitrary VBA code magically, so until that’s figured out, we have a little bit of a limitation here.

On top of that, not all Office applications feature an Application.Run method, which means Rubberduck unit tests can’t work in, say, Outlook.

It also means Rubberduck unit tests can’t declare a WithEvents object variable, because like the Implements keyword, that keyword is reserved for use in class modules.


Now, what?

So if one has a class with a method that raises an event, a test that would ensure the event is raised with the expected parameters, needs to take a little detour.

Say we have MyClass looking like this:

Option Explicit
Public Event Foo(ByVal value As String)

Public Sub DoSomething(ByVal value As String)
 RaiseEvent Foo(value)
End Sub

We will want to write a test to verify that DoSomething raises event Foo with the specified value argument.

TestHelper class

First step is to declare a WithEvents object variable to handle the event. Since that can only be done in a class module, we’ll need a new class module – call it TestHelper.

Option Explicit
Private WithEvents sut As MyClass
Private RaisedCount As Long
Private LastValue As String

Public Property Get SystemUnderTest() As MyClass
 Set SystemUnderTest = sut
End Property

Public Property Set SystemUnderTest(ByVal value As MyClass)
 Set sut = value
End Property

Public Property Get HasRaisedEvent() As Boolean
 RaisedCount > 0
End Property

Public Property Get Count() As Long
 Count = RaisedCount
End Property

Public Property Get LastEventArg() As String
 LastEventArg = LastValue
End Property

Private Sub sut_Foo(ByVal value As String)
 RaisedCount = RaisedCount + 1
 LastValue = value
End Sub

Now that we have encapsulated the knowledge of whether and how our event was raised, we’re ready to write a test for it.

TestMethod

'@TestMethod
Public Sub TestMethod1() 'TODO: Rename test
 On Error GoTo TestFail
 
 'Arrange:
 Dim sut As New MyClass
 Dim helper As New TestHelper
 Set helper.SystemUnderTest = sut
 
 Const expected As String = "foo"
 
 'Act:
 sut.DoSomething expected

'Assert:
 Assert.IsTrue helper.HasRaisedEvent
 Assert.AreEqual expected, helper.LastEventArg

TestExit:
 Exit Sub

TestFail:
 Assert.Fail "Test raised an error: #" & Err.Number & " - " & Err.Description
End Sub

This test will pass as is, and will fail when the tested method’s logic changes:

Public Sub DoSomething(ByVal value As String)
 RaiseEvent Foo(value & "A")
End Sub

test-failed


Until we figure out a way to move Rubberduck unit tests to class modules and run them with CallByName, using a helper class will be the only way to test event raising.

Version 1.2 is here!

I’m really excited to announce this, so I’ll get to the point…

Version 1.2 just released!

The most visible change is all of the new Code Inspections. There were only a handful of them in Version 1.1, but now Rubberduck is finding all kinds of issues with VBA code. Everything from obsolete syntax to unused variables. It’s really very cool.

The other very visible change is the addition of an Extract Method refactoring tool. Highlight some code, and extract it into its own method. Awesome. This one is very much like the static code analysis was in the last version, just a glimpse at the great things to come.

There were also a lot of improvements under the hood. We entirely swapped out the parser that allows us to do much of what we’ve done. Along with that, we’ve fixed a verifiable crap ton of bugs and UX problems. I’m really proud of this release.

So, what are you waiting for? Check it out for yourself. It’s free, so you’ve nothing to lose but all that bad code.