> ## 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.

# One if ByRef, and Two if ByVal
- URL: https://nolongerset.com/one-if-by-val-two-if-by-ref/
- Published: 2020-09-20T03:46:08.000Z
- Updated: 2026-05-08T13:05:34.000Z
- Description: Arguments in VBA are passed by reference by default. What does that mean? And what are the differences between passing by reference and by value?
- Author: Mike Wolfe
- Tags: Basic, #Import 2026-05-20 02:59

Let's talk a bit about `ByVal` and `ByRef`. Arguments in VBA are [passed by reference](https://docs.microsoft.com/en-us/office/vba/language/concepts/getting-started/passing-arguments-efficiently) by default. What does that mean? And what are the differences between passing by reference and by value?

## Helpful background

To understand the difference between the two modes of passing variables, it helps to have a bit of background knowledge about what's actually happening with our data at the lowest level. When we assign a value to a variable, say `x = 5`, that value (`5`) has to be physically stored somewhere. It's not just floating around in thin air. The values are stored in binary form in memory.

To simplify things, we'll use an Excel worksheet to represent memory. Each cell is a single bit (0 or 1). 

![](https://storage.ghost.io/c/eb/d7/ebd732c1-5f03-4f07-b386-5d08557e15c9/content/images/2020/09/image-10.png)

The Byte variable `x` *references* C2 where the *value* 5 is stored in binary form

Now let's imagine we have the following code:

```vba
Dim x As Byte
x = 5

```

The VBA type of `Byte` is an 8-bit data type that supports values from 0 to 255\. In bit form, those values are `0000 0000` through `1111 1111`. When we declare `x As Byte`, VBA sets aside 8 bits in memory to hold the *value* of `x`. Since the actual value is stored in memory, VBA assigns `x` a *reference* to the location in memory where the value is stored. In other words:

- `x`'s *reference*: **C2**
- `x`'s *value*: **5**

### Passing by reference

When we pass the variable `x` to a procedure *by reference* (the default), what we're actually passing is a *pointer* to the location of `x`'s value in memory (i.e., **C2**). Thus, any changes we make to the argument inside the procedure will change the original value.

### Passing by value

If instead, we pass the variable `x` to a procedure *by value*, there is an extra step that happens under the hood. The 8 bits located in C2:J2 are copied into a different location in memory, say G5:N5\. We still end up passing a pointer to our value, but in this case the pointer is to **G5**, where we've stored a copy of our original value.

Since we're passing a copy of the original value, we can make whatever changes we want to the argument in our procedure without affecting the original value of the variable in the calling function. 

### Sample Code

Let's see how this works with some sample code. My comments refer back to the simplistic concept of memory as an Excel spreadsheet that I referenced above.

```vba
Sub TestTriple()
    Dim x As Byte   'x points to C2
    x = 5           '0000 0101 stored in C2
    
    TripleByVal x   '0000 0101 copied to G5 and passed to TripleByVal
    Debug.Print x   'no change to C2's value
    
    TripleByRef x   'pointer to C2 passed to TripleByRef
    Debug.Print x   'C2's value gets tripled
    
    Triple x        'pointer to C2 passed to Triple
    Debug.Print x   'C2's value gets tripled a second time
End Sub

Sub TripleByVal(ByVal Foo As Byte)
    'G5: 0000 0101 -> 0000 1111  (5 -> 15)
    Foo = Foo * 3
End Sub

Sub TripleByRef(ByRef Foo As Byte)
    'C2: 0000 0101 -> 0000 1111  (5 -> 15)
    Foo = Foo * 3
End Sub

Sub Triple(Foo As Byte)  'Passed by ref by default
    'C2: 0000 1111 -> 0010 1101  (15 -> 45)
    Foo = Foo * 3
End Sub

```

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

---

***UPDATE (4/3/2021):*** *I changed the title from "One if ByVal, and Two if ByRef" to "One if ByRef, and Two if ByVal" to reflect the fact that when passing by reference there is only a single copy of the value stored in memory, while passing by value results in a second copy being created and passed to the called routine.*