> ## Content Index
> Fetch the complete content index at: https://nolongerset.com/llms.txt
> Use this file to discover other available public pages before exploring further.

# Adding Procedure Parameters Without Breaking Backwards Compatibility in VBA
- URL: https://nolongerset.com/adding-procedure-parameters/
- Published: 2022-11-22T16:28:49.000Z
- Updated: 2026-05-08T12:53:26.000Z
- Description: Sometimes you need to add a parameter to a Function or Sub in VBA. But you don't need to break all of your calling code to do it.
- Author: Mike Wolfe
- Tags: Backwards Compatibility, #Import 2026-05-20 02:59

Making a commitment to never breaking backwards compatibility within your code will change your life as a developer.

- It allows you to *safely* reuse code
- It reduces the accumulation of [technical debt](https://nolongerset.com/sources-of-technical-debt/)
- It reduces the need for refactoring calling code

There are several techniques you can use to avoid breaking backwards compatibility in your code. I discuss one such technique below.

## Safely Changing Procedure Signatures

A procedure (`Function`, `Sub`, `Property`, etc.) signature is the procedure's declaration line, which comprises the procedure name, its required and optional arguments, and–where applicable–the return type.

Carelessly changing a procedure signature is a good way to break your calling code. But, as your code grows over time, you may want to be able to pass additional arguments to your procedure. So how can you allow passing additional arguments without breaking the calling code?

The solution to the problem is to use **optional** **parameters**.

## Using Optional Parameters to Avoid Breaking Backwards Compatibility

Let's go through a quick example.

### Starting Point

We start with a subroutine named `WarnUser`. This routine shows a warning message in a message box. It's an example of a [convenience function](https://nolongerset.com/convenience-functions/)–a short procedure that wraps a bit of functionality into a more readable form.

```vba
Sub WarnUser(Msg As String)
    MsgBox Msg, vbExclamation, "Be Warned!"
End Sub
```

Let's add some calling code:

```
Sub Foo()
    WarnUser "You are about to Foo."
    'Do Foo stuff
End Sub
```

### Adding a Second Parameter

Now, let's say you want to call `WarnUser` from a different place in your code but you want to customize the title to something other than, "Be Warned!" You could do this:

```vba
Sub WarnUser(Msg As String, Title As String)
    MsgBox Msg, vbExclamation, Title
End Sub
```

And call it like so:

```vba
Sub Bar()
    WarnUser "You are about to Bar.", "!!DANGER!!"
    'Do Bar stuff
End Sub
```

That would work, but it would break your calling code in `Foo`. You would have to go back and change that:

```vba
Sub Foo()
    WarnUser "You are about to Foo.", "Be Warned!"
    'Do Foo stuff
End Sub
```

That doesn't seem terrible, but what if you called `WarnUser` in fifty other places? That would require refactoring code all over the place and you would have to be really careful to avoid typos and make sure you didn't miss anything. Sounds like a recipe for disaster.

A **much better approach** is to make the new parameter optional and make its default value equal to what was previously hard-coded within the procedure:

```vba
Sub WarnUser(Msg As String, _
             Optional Title As String = "Be Warned!")
    MsgBox Msg, vbExclamation, Title
End Sub
```

With this approach, you can still use the extra parameter in `Bar`, but you don't need to make any changes to `Foo`:

```vba
Sub Foo()
    WarnUser "You are about to Foo."
    'Do Foo stuff
End Sub

Sub Bar()
    WarnUser "You are about to Bar.", "!!DANGER!!"
    'Do Bar stuff
End Sub
```

### Adding a Third Parameter

To drive the point home, let's assume your new procedure `Baz` requires showing the red "X" icon instead of the exclamation point icon. You would extract out the `Buttons` value into an optional parameter just as you did with the `Title` parameter.

The key point here is that any **new optional parameters must always be added to the end of the procedure signature**. 

The `Buttons` parameter comes before `Title` in the MsgBox definition. By reversing them in our `WarnUser` procedure we end up with an inconsistency between `WarnUser` and `MsgBox`. If we had added both parameters at the same time, it would have made sense to match the `MsgBox` parameter order. However, since we already have calling code that depends on `Title` being the second parameter, we must leave it in place.

**Backwards compatibility always trumps consistency.**

```vba
Sub WarnUser(Msg As String, _
             Optional Title As String = "Be Warned!", _
             Optional Buttons As VbMsgBoxStyle = vbExclamation)
    MsgBox Msg, Buttons, Title
End Sub
```

```vba
Sub Foo()
    WarnUser "You are about to Foo."
    'Do Foo stuff
End Sub

Sub Bar()
    WarnUser "You are about to Bar.", "!!DANGER!!"
    'Do Bar stuff
End Sub

Sub Baz()
    WarnUser "You are about to Baz.", , vbCritical
    'Do Baz stuff
End Sub
```

*Image by [PublicDomainPictures](https://pixabay.com/users/publicdomainpictures-14/?utm%5Fsource=link-attribution&utm%5Fmedium=referral&utm%5Fcampaign=image&utm%5Fcontent=70494) from [Pixabay](https://pixabay.com//?utm%5Fsource=link-attribution&utm%5Fmedium=referral&utm%5Fcampaign=image&utm%5Fcontent=70494)*