[Question]
  [
Similar to [this](https://codegolf.stackexchange.com/q/5105/3862), [this](https://codegolf.stackexchange.com/q/132/3862), and [this](https://codegolf.stackexchange.com/q/173/3862) question... 
What general tips do you have for golfing in `VBA`? I'm looking for ideas that can be applied to code golf problems in general that are at least somewhat specific to `VBA` (e.g. "remove comments" is not an answer). Please post one tip per answer.
While I have worked with other languages, I'm strongest in `VBA`, and I don't see many golfers using `VBA` on this site.
  
[Answer]
# Exploit the `ByRef` default when calling subs
It is sometimes possible to use a `Sub` call in place of a `Function` to save a few additional characters...
This (**87** chars) 
```
Sub a()
b = 0
Do Until b = 5
b = c(b)
Loop
End Sub
Function c(d)
c = d + 1
End Function
```
can be re-worked to (**73** chars):
```
Sub a()
b = 0
Do Until b = 5
c b
Loop
End Sub
Sub c(d)
d = d + 1
End Sub
```
*Notice this will **NOT** loop forever, though it appears you are never reassigning `b`'s value.*
The above doesn't use a `Function` call, but instead exploits the `ByRef` ("By Reference") functionality of the `Sub` call. What this means is the passed argument is the same variable as in the calling function (as opposed to a `ByVal`, "By Value" passing, which is a copy). Any modifications to the passed variable will translate back to the calling function.
By default, [vba](/questions/tagged/vba "show questions tagged 'vba'") takes all arguments as `ByRef`, so there is no need to use up characters to define this.
The above example may not translate perfectly for you, depending on the return value of your function. (i.e. returning a different data type than what is passed), but this also allows for the possibility of getting a return value whilst still modifying your original variable.
For example:
```
Sub a()
b = 0
Debug.Print c(b) ' This will print 0, and b will equal 1.'
End Sub
Function c(d)
c = d
d = d + 1
End Function
```
[Answer]
## Write and run the VBA code in the Immediate Window
The Immediate Window evaluates any valid VBA executable statement. Simply enter a statement in the Immediate Window as you would in the code editor. It quickly executes VBA code and it can save many additional characters because:
1. Putting the question mark (?) at the beginning of the statement tells the Immediate Window to display the result of your code.
[![enter image description here](https://i.stack.imgur.com/BhZeH.gif)](https://i.stack.imgur.com/BhZeH.gif)
2. You don't need to use a Sub and End Sub in your code.
[![enter image description here](https://i.stack.imgur.com/uSMM9.gif)](https://i.stack.imgur.com/uSMM9.gif)
---
Here is the example of VBA code in the Immediate Window to answer PPCG's post with tag [code-golf](/questions/tagged/code-golf "show questions tagged 'code-golf'") : [The Letter A without A](https://codegolf.stackexchange.com/q/90349/58742)
```
?Chr(88-23);
```
answered by [Joffan](https://codegolf.stackexchange.com/a/90418/58742).
---
**Credit images:** [Excel Campus](https://www.excelcampus.com/)
[Answer]
## Conditional Checks Before Looping
Some conditional checks are redundant when used in conjunction with loops. For example, a `For` loop will not process if the starting condition is outside the scope of the running condition.
In other words, this (**49** chars):
```
If B > 0 Then
For C = A To A + B
'...
Next
End If
```
Can be turned into this (**24** chars):
```
For C = A To A + B ' if B is 0 or less, then the code continues past Next, unabated.
'...
Next
```
[Answer]
# `Evaluate()` And `[]`
As has been pointed out previously, hard-coded range calls can be reduced using the square brackets `[A1]` notation. However it has many more uses than just that.
According to [MSDN documentation](https://msdn.microsoft.com/VBA/Excel-VBA/articles/application-evaluate-method-excel), the `Application.Evaluate()` method takes a single argument, which is a `Name`, as defined by the naming convention of Microsoft Excel.
N.B. `[string]` is shorthand for `Evaluate("string")` (note the `""` speech marks denoting string datatype), although there are a few important differences which are covered at the end.
So what does that all mean in terms of usage?
Essentially, `[some cell formula here]` represents a cell in an excel worksheet, and you can put pretty much anything into it and get anything out of it that you could with a normal cell
## What goes in
In summary, with examples
* A1-style references. All references are considered to be absolute references.
	+ `[B7]` returns a reference to that cell
	+ As references are absolute, `?[B7].Address` returns `"B$7$"`
* Ranges You can use the range, intersect, and union operators (colon,
space, and comma, respectively) with references.
	+ `[A1:B5]` returns a range reference to `A1:B5` (Range)
	+ `[A1:B5 A3:D7]` returns a range reference to `A3:B5` (Intersect)
	+ `[A1:B5,C1:D5]` returns a range reference to `A1:D5`(technically `A1:B5,C1:D5`) (Union)
* Defined names
	+ User defined such as `[myRange]` referring to A1:G5
	+ Automatic, like table names `[Table1]` (possibly less useful for codegolf)
	+ Anything else you can find in the `[Formulas]`>`[Name Manager]` menu
* Formulas
	+ **Very useful**; any formula that can go in a cell can go in `Evaluate()` or `[]`
	+ `[SUM(1,A1:B5,myRange)]` returns arithmetic sum of values in the ranges *myRange here refers to a workbook name not a VBA variable*
	+ `[IF(A1=1,"true","false")]` (1 byte shorter than vba equivalent `Iif([A1]=1,"true","false")`)
	+ Array formulas`[CONCAT(IF(LEN(A1:B7)>2,A1:B7&" ",""))]` - joins all strings in range whose length is greater than 2 with a space
* External references
	+ You can use the `!` operator to refer to a cell or
	to a name defined in another workbook
	+ `[[BOOK1]Sheet1!A1]` returns a range reference to A1 in BOOK1 or `['[MY WORKBOOK.XLSM]Sheet1!'A1]` for the same in `MY WORKBOOK`
	+ Note the `'` for workbooks with spaces in their names, and the lack of extension for default named workbooks (`BOOK+n`)
* Chart Objects (See the MSDN article)
NB I asked a question over on SO for this info, so take a look [there](https://stackoverflow.com/q/45443323/6609896) for a better explanation
## What comes out
Similar to what goes in, what comes out includes anything that a worksheet cell can return. These are the standard Excel data types (and their VBA equivalents):
* Logical (`Boolean`)
* Text (`String`)
* Numerical (`Double`)
* Error (`Variant/Error`) (these are non-breaking errors, ie. they do not halt code execution, `?[1/0]` executes fine)
But there are a few things that can be returned which cells cannot:
* Range reference (`Range`) (see above sections)
* Arrays (`Variant()`)
### Arrays
As has been shown, `[]` can be used to evaluate array formulas which return one of the standard Excel data types; e.g. `[CONCAT(IF(LEN(A1:B7)>2,A1:B7&" ",""))]` which returns `Text`. However `Evaluate` can also return arrays of `Variant` type. These can be
**Hardcoded:**
`[{1,2;3,4}]` - outputs a 2D array: `,` is the column separator, `;` separates rows. Can output a 1D array
**Array Formulae:**
`[ROW(A1:A5)]` - outputs a **2D** array `{1,2,3,4,5}`, i.e (2,1) is the second item (yet some functions output 1D arrays)
* For whatever reason, some functions do not return arrays by default
`[LEN(A1:A5)]` only outputs the Length of the text in the 1st cell of a range
* However these can be coerced to give arrays
`Split([CONCAT(" "&LEN(A1:A5))])` gives a 1D array 0 to 5, where the first item is empty
`[INDEX(LEN(A1:A5),)]` is another workaround, essentially you must employ an array handling function to get the desired array returning behaviour, similar to adding in a meaningless `RAND()` to make your worksheet formulae volatile.
* I asked a [question on SO](https://stackoverflow.com/q/45458986/6609896) to try to get some better info on this *please edit/comment with better options if you find them*
## `Evaluate()` vs `[]`
There are a few differences between `Evaluate()` and `[]` to be aware of
1. Strings vs hardcoded
	* Perhaps the most important difference, Evaluate takes a string input where [] required a hardcoded input
	* This means your code can build up the string with variables e.g. `Evaluate("SUM(B1,1,"&v &",2)")` would sum `[B1]`,`1`,`2` and variable `v`
2. Arrays
When returning an Array, only Evaluate can be used with an array index, so
```
v=Evaluate("ROW(A1:A5)")(1,1) ''#29 bytes
```
is equivalent to
```
i=[ROW(A1:A5)]:v=i(1,1) ''#23 bytes
```
[Answer]
# Combine `Next` Statements
```
Next:Next:Next
```
May be condensed down to
```
Next k,j,i
```
where the iterators for the `For` loops are `i`,`j`, and `k` - in that order.
For example the below (69 Bytes)
```
For i=0To[A1]
For j=0To[B1]
For k=0To[C1]
Debug.?i;j;k
Next
Next
Next
```
May be condensed down to 65 Bytes
```
For i=0To[A1]
For j=0To[B1]
For k=0To[C1]
Debug.?i;j;k
Next k,j,i
```
And as far as how this impacts formatting and indentation, I think the best approach to handling this is left aligning the next statement with the outer most for statement. Eg.
```
For i=0To[A1]
    For j=0To[B1]
        For k=0To[C1]
            Debug.?i;j;k
Next k,j,i
```
[Answer]
## Reducing `If` Statements
When assigning a variable using a conditional `If ... Then ... Else` check, you can reduce the amount of code used by eliminating the `End If` by putting the entire check on one line.
For example, this (**37** chars):
```
If a < b Then
c = b
Else
c = a
End If
```
Can be reduced to this (**30** chars)
```
If a < b Then c = b Else c = a
```
If you have more than one nested conditional, you can minimize them this way as well:
```
If a Then If b Then If c Then Z:If d Then Y:If e Then X Else W Else V:If f Then U 'Look ma! No "End If"!
```
Note the `:` allows you to add more than one line/command within an `If` block.
In simple cases like this, you can usually also remove the `Else` by setting the variable in before the `If` check (**25** chars):
```
c = a
If a < b Then c = b
```
Even better, the above can be further reduced to this using the `IIf()` function (**20** chars):
```
c = IIf(a < b, b, a)
```
[Answer]
## Variable Declaration
In most cases in VBA, you can leave out `Option Explicit` (often omitted by default, anyway) and skip `Dim`'ing many of your variables.
In doing so, this (**96** Chars):
```
Option Explicit
Sub Test()
Dim S As String
Dim S2 As String
S = "Test"
S2 = S
MsgBox S2
End Sub
```
Becomes this (**46** chars):
```
Sub Test()
S = "Test"
S2 = S
MsgBox S2
End Sub
```
If you need to use certain objects (for example, arrays), you may still need to `Dim` that variable.
[Answer]
# Prepare For Pixel Art
Pixel art is by far one of Excel's strongest areas, as there is no need to construct a canvas, as it is already there for you - all you need to do is make some small adjustments
### 1) Make the cells square
```
Cells.RowHeight=48
```
or, Alternatively, for 1 byte more, but far easier to work with
```
Cells.ColumnWidth=2
```
Depending on the context, you may be able to get away without having to resize your cells at all. With the default `RowHeight` of \$15\$ and `ColumnWidth` of \$8.09\$, the aspect ratio of a default cell is \$\approx415:124\$.
If you use this to calculate what range needs to be selected to draw a given shape you may be able to drastically reduce your bytecount.
**Example:**
Golfing the Ukrainian flag with the correct \$2:3\$ aspect ratio can golfed down from
```
Cells.RowHeight=48:[A1:BZ52].Interior.Color=55265:[A1:BZ26].Interior.Color=12015360
```
to
```
[A1:NH830].Interior.Color=55265:[A1:NH415].Interior.Color=12015360
```
### 2) Color the needed range
Any `Range` object may be colored by calling
```
`MyRangeObj`.Interior.Color=`ColorValue`
```
***Note:** this can and should be combined with other tricks noted on this wiki, such as referencing ranges by the use of the `[]` notation (eg `[A1:R5,D6]`) over the use of a `Cells(r,c)` or a `Range(cellAddress)` call. Further, as noted on this wiki, this may be combined with negative color value to golf down the size of color references*
### Quick References
**Range Reference**
Cell `A1` may be referenced in any of the following ways
```
Range("A1")
Cells(1,1)
[A1]
```
and the Range `A1:D4` may be referenced in any of the following ways
```
Range("A1:D4")
Range("A1").Resize(4,4)
Cells(1,1).Resize(4,4)
[A1].Resize(4,4)
[A1:D4]
```
**Color Reference**
```
Black  0
White  -1
Red    255
Aqua   -256
```
[Answer]
# Reduce `Range("A1")` and Like Calls
`Range("A1").Value`(17 Bytes) and the simpler `Range("A1")`(11 Bytes) may be reduced down to `[A1]` (4 Bytes)
[Answer]
# STDIN and STDOUT
**Inputting to `Sub`routines and `Function`s via input variables**
```
Public Sub A(ByRef B as String)
```
May be reduced down to 
```
Sub a(b$) 
```
The `Public` and `ByRef` calls are the default for VBA and thus implicit, and may (almost) always be dropped.
The type literal `$` forces `b` to be of the type `String`.
Other type literals
* `!` Single
* `@` Currency
* `#` Double
* `%` Integer
* `$` String
* `&` Long
* `^` LongLong (64 Bit Only)
Furthermore, it is generally accepted that you may leave the input variable as the default type, `Variant` and leave any type-based errors unhandled. Eg. `Sub E(F)` in which `F` is expected to be of type `Boolean[]` (which would be passed to the routine like `E Array(True, False, False)`)
**Inputting to `Sub`routines and Immediate Window Functions via `Cells`**
VBA does not have a fully functional console and thus does not have any *official* STDIN, and thus allows for *some* play with passing input. 
In excel, it is generally accepted to take input from a cell or range of cells, which may be done like
```
s=[A1]
```
which implicitly puts the `.value` from the cell `[A1]` (which may also be referenced as `cells(1,1)` or `range("A1")`
Example Problem: Display the input in a messagebox
Via Subroutine `Sub A:msgbox[A1]:End Sub`
Via Immediates Window Function `msgbox[A1]`
**Inputting Via Conditional Compilation Arguments**
VBA Projects support taking arguments from the command line or via the VBAProject Properties (view via the project explorer -> [Your VBA Project] -(Right Click)-> VBAProject Properties -> Conditional Compilation Arguments)
This is largely useful for [Error Code Challenges](https://codegolf.stackexchange.com/a/107216/61846)
Given the Conditional Compilation Argument `n=`[some\_value] this allows for executing code that will produce an error code, based off of the value of `n`.
note, this calls for an addition of 2 bytes to your code for the `n=` in the conditional compilation arguments section of the VBAProject Properties Pane.
Example Code
```
...
#If n=3 then
return ''  Produces error code '3', Return without GoSub
#ElseIf n=20 then
resume ''  Produces error code '20', Resume without Error
#EndIf
...
```
**Outputting Via Function Value**
Not Much to say here, the general form of quoted below is about as compact as it can be made. 
```
Public Function A(b)
    ...
    A=C
End Function
```
NOTE: in the **vast majority** of cases it is more byte convert the method to a subroutine and output to the VBE immediates window (see Below) 
**Outputting From `Sub`routines and `Function`s via the VBE Immediates Window**
Outputting to the VBE immediates window (AKA the VBE Debug Window) is a common output method for VBA for text based challenges, however, it is important to remember that the `Debug.Print "Text"` call may be substantially golfed.
```
Debug.Print "Text"
```
is functionally identical to 
```
Debug.?"Text"
```
as `?` autoformats to `Print`.
**Outputting from `Sub`routines and VBE Immediates Window functions via Other Methods**
On ***rare*** occasion, when the situation is just right, you may take input from some of the more trivial inputs available to VBA such as the font size adjuster, font selector, and zoom. (Eg. [Emulating the Word Font Size Selector](https://codegolf.stackexchange.com/a/105605/61846))
[Answer]
# Remove Spaces
VBA will auto-format to add a lot of spacing that it doesn't actually need. There' an [answer on meta](https://codegolf.meta.stackexchange.com/a/10259/38183) that makes a lot of sense to me why we can discount bytes added by auto-formatting. It's important to always verify you haven't removed too much, though. For an example, here's [an answer of mine](https://codegolf.stackexchange.com/a/116404/38183) that was reduced almost 22% just by removing spaces:
Original version: (188 bytes)
```
Sub g(n)
For i = 0 To 1
For x = -3 To 3 Step 0.05
y = n ^ x * Cos(Atn(1) * 4 * x)
If y < m Then m = y
If i = 1 Then Cells(500 * (1 - y / m) + 1, (x + 3) * 100 + 1) = "#"
Next
Next
End Sub
```
Reduced version: (146 bytes)
```
Sub g(n)
For i=0To 1
For x=-3To 3Step 0.05
y=n^x*Cos(Atn(1)*4*x)
If y<m Then m=y
If i=1Then Cells(500*(1-y/m)+1,(x+3)*100+1)="#"
Next
Next
End Sub
```
If you copy / paste the reduced version into VBA, it will automatically expand into the original. You can play around with where it is valid to remove spaces. The ones I've found so far all seem to follow the pattern where VBA is expected a certain command to appear because, without it, it's not valid code. Here are some that I've found so far:
* Before and after any mathematical operation: `+-=/*^` etc.
* Before `To` and `Step` in a `For` statement: `For x=-3To 3Step 0.05`
* Actually, before any reserved word (`To`, `&`, `Then`, etc.) if it's preceded by a literal such as a number, `)`, `?`, `%`, etc.
* After the `&` when combining strings: `Cells(1,1)=Int(t)&Format(t,":hh:mm:ss")`
* After function calls: `If s=StrReverse(s)Then`
* Within function calls: `Replace(Space(28)," ",0)`
[Answer]
## Simplify built-in functions
When using certain functions frequently, reassign them to a user-defined function.
The following code (**127** chars) can be reduced from:
```
Sub q()
w = 0
x = 1
y = 2
z = 3
a = Format(w, "0.0%")
b = Format(x, "0.0%")
c = Format(y, "0.0%")
d = Format(z, "0.0%")
End Sub
```
to (**124** chars):
```
Sub q()
w = 0
x = 1
y = 2
z = 3
a = f(w)
b = f(x)
c = f(y)
d = f(z)
End Sub
Function f(g)
f = Format(g, "0.0%")
End Function
```
Combining this with the [ByRef trick](https://codegolf.stackexchange.com/a/5408/3862) and some [autoformatting tricks](https://codegolf.stackexchange.com/a/128932/61846), you can save even more characters (down to **81**):
```
Sub q
w=0
x=1
y=2
z=3
f w
f x
f y
f z
End Sub
Sub f(g)
g=Format(g,"0.0%")
End Sub
```
Do this judiciously, as VBA takes up a lot of characters to define a `Function`. The second code block would actually be larger than the first with *any* number fewer `Format()` calls.
[Answer]
# Quick Note on Formatting
Because StackExchange uses [Markdown](https://en.wikipedia.org/wiki/Markdown) and [Prettify.js](https://github.com/google/code-prettify) it is possible to add a language flag to your coding answers, which generally makes them look more professional. While I cannot guarantee that this will make you any better at golfing in VBA, I can guarantee that it will make you look like you are.
Adding either of the flags below will transform 
```
Public Sub a(ByRef b As Integer) ' this is a comment
```
to 
```
Public Sub a(ByRef b As Integer) ' this is a comment
```
**VBA Language Tags**
`<!-- language: lang-vb -->` 
`<!-- language-all: lang-vb -->` 
*Note: the latter transforms all code segments in your answer, while the prior transforms only the immediately following code segments*
[Answer]
# Multiple `If .. Then` checks
As in other languages, multiple `If` checks can usually be combined into a single line, allowing for the use of `And`/`Or` (i.e. `&&`/`||` in C and others), which in VBA replaces both a `Then` and an `End If`.
For example, with a nested conditional (**93** chars):
```
'There are MUCH easier ways to do this check (i.e. a = d).
'This is just for the sake of example.
If a = b Then
    If b = c Then
        If c = d Then
            MsgBox "a is equal to d"
        End If
    End If
End If
```
can become (**69** chars):
```
If a = b And b = c And c = d Then
    MsgBox "a is equal to d"
End If
```
This also works with non-nested conditionals.
Consider (**84** chars):
```
If a = b Then            
    d = 0
End If
If c = b Then            
    d = 0
End If
```
This can become (**51** chars):
```
If a = b Or c = b Then            
    d = 0
End If
```
[Answer]
# Ending `For` Loops
When using `For` loops, a `Next` line does not need a variable name (though it is probably better to use in normal coding).
Therefore,
```
For Variable = 1 to 100
    'Do stuff
Next Variable
```
can be shortened to:
```
For Variable = 1 to 100
    'Do stuff
Next
```
(The savings depends on your variable name, though if you're golfing, that's probably just 1 character + 1 space.)
[Answer]
# Split a string into a character array
Sometimes it can be useful to break apart a string into individual characters, but it can take a bit of code to do this manually in VBA.
```
ReDim a(1 To Len(s))
' ReDim because Dim can't accept non-Const values (Len(s))
For i = 1 To Len(s)
    a(i) = Mid(s, i, 1)
Next
```
Instead, you can use a single line, relatively minimal chain of functions to get the job done:
```
a = Split(StrConv(s, 64), Chr(0))
```
This will assign your string `s` to `Variant` array `a`. Be careful, though, as the last item in the array will be an empty string (`""`), which will need to be handled appropriately.
Here's how it works: The `StrConv` function converts a `String` to another format you specify. In this case, 64 = `vbUnicode`, so it converts to a unicode format. When dealing with simple ASCII strings, the result is a null character (not an empty string, `""`) inserted after each character.
The following `Split` will then convert the resulting `String` into an array, using the null character `Chr(0)` as a delimiter.
It is important to note that `Chr(0)` is not the same as the empty string `""`, and using `Split` on `""` will not return the array you might expect. The same is also true for `vbNullString` (but if you're golfing, then why would you use such a verbose constant in the first place?).
[Answer]
## Using `With` (Sometimes! See footnote)
Using the `With` statement can reduce your code size significantly if you use some objects repeatedly.
i.e. this (**80** chars):
```
x = foo.bar.object.a.value
y = foo.bar.object.b.value
z = foo.bar.object.c.value
```
can be coded as (**79** chars):
```
With foo.bar.object
    x = .a.value
    y = .b.value
    z = .c.value
End With
```
The above isn't even the best-case scenario. If using anything with `Application`, such as `Excel.Application` from within Access, the improvement will be much more significant. 
---
\*Depending on the situation, `With` may or may not be more efficient than this (**64** chars):
```
Set i = foo.bar.object
x = i.a.value
y = i.b.value
z = i.c.value
```
[Answer]
# Infinite Loops
Consider replacing
```
Do While a<b
'...
Loop
```
or
```
Do Until a=b
'...
Loop
```
with the antiquated but lower byte count
```
While a<b
'...
Wend
```
---
If you need to exit a `Sub` or `Function` prematurely, then instead of `Exit ...`
```
For i=1To 1000
    If i=50 Then Exit Sub
Next
```
consider `End`
```
For i=1To 1E3
    If i=50 Then End
Next
```
Note that `End` halts all code execution and clears out any global variables, so use wisely
[Answer]
# Use `Spc(n)` over `Space(n)`, `[Rept(" ",n)]` or `String(n," ")`
When trying to insert several spaces of length `n`, use
```
Spc(n)              ''  6  bytes
```
over
```
B1=n:[Rept(" ",B1)] ''  19 bytes
```
```
String(n," ")       ''  13 bytes
```
```
Space(n)            ''  8  bytes
```
*Note: I am not sure why, but it seems that you cannot assign the output of `Spc(n)` to a variable, and that it must rather be printed directly - so in certain cases `Space(n)` is still the best way to go.*
[Answer]
# Reduce `Debug.Print` and `Print` calls
```
Debug.Print [some value] 
```
(12 Bytes; note the trailing space) may be reduced to
```
Debug.?[some value]
```
(7 Bytes; note the lack of trailing space).
Similarly,
```
Print 
```
(6 Bytes) may be reduced to
```
?
```
(1 Byte).
Furthermore, when operating in the context of an anonymous VBE immediate window function the `Debug` statement may be dropped entirely, and instead printing to the VBE immediate window via `?` may be assumed to be STDIN/STDOUT
### Special characters
When printing strings you can also use special characters in place of `&`. These allow for alternate formats in what's printed or whitespace removal
To join variable strings, instead of
```
Debug.Print s1 &s2
```
You can use a semicolon `;`
```
Debug.?s1;s2
```
This semicolon is the default behaviour for consecutive strings, as long as there is no ambiguity
So these are valid:
```
Debug.?s1"a"
Debug.?"a"s1
```
But not
```
Debug.?s1s2 'as this could be interpreted as a variable named "s1s2", not 2 variables
            'use Debug.?s1 s2 instead (or s1;s2)
Debug.?"a""b" 'this prints a"b, so insert a space or ; for ab
```
*Note that a ; at the end of a line suppresses a newline, as newlines are by default added after every print. Counting bytes returned by VBA code is [under debate](https://codegolf.meta.stackexchange.com/q/12476/68602)*
To join with a tab use a comma `,` (actually 14 spaces, but according to )
```
Debug.?s1,s2 'returns "s1              s2"
```
Finally, you can use type declarations to join strings instead of ;, each having its own slight effect on formatting. For all of the below `a = 3.14159` is the first line
```
Debug.?a&"is pi" -> " 3 is pi" 'dims a as long, adds leading and trailing space to a
Debug.?a!"is pi" -> " 3.14159 is pi" 'dims a as single, adds leading and trailing space
Debug.?a$"is pi" -> "3.14159is pi" 'dims a as string, no spaces added
```
[Answer]
# Address Sheets By Name
Instead of Addressing a `WorkSheet` object by calling
```
Application.ActiveSheet
''  Or 
ActiveSheet   
```
One may use
```
Sheets(n)  ''  Where `n` is an integer
''  Or 
[Sheet1]
```
Or More preferably one may access the object directly and use
```
Sheet1
```
[Answer]
# Use a helper `Sub` to `Print`
If the code requires using *more than six* `Debug.?` statements you can reduce bytes by replacing all Debug.? lines with a call to a Sub like the one below. To print a blank line you need to call `p ""` since a parameter is required.
```
Sub p(m)
Debug.?m
End Sub
```
[Answer]
# Use `Array()` `Choose()` instead of `Select` or `If...Then`
When assigning a variable based on a the value of another variable, it makes sense to write out the steps with `If...Then` checks, like so:
```
If a = 1 Then
b = "a"
ElseIf a = 2 Then
b = "c"
'...
End If
```
However, this can take up a lot of code space if there are more than one or two variables to check (there are still generally better ways to do even that anyway).
Instead, the `Select Case` statement helps reduce the size of the checks by encasing everything in one block, like so:
```
Select Case a
Case 1:
b = "a"
Case 2:
b = "c"
'...
End Select
```
This can lead to much smaller code, but for very simple cases such as this, there is an even more efficient method: `Choose()` This function will pick a value from a list, based on the value passed to it.
```
b = Choose(a,"a","c",...)
```
The option to select (`a` in this case) is an integer value passed as the first argument. All subsequent arguments are the values to choose from (1-indexed, like most VBA). The values can be any data type so long as it matches the variable being set (i.e. objects don't work without the `Set` keyword) and can even be expressions or functions.
```
b = Choose(a, 5 + 4, String(7,"?"))
```
An additional option is to use the `Array` function to get the same effect while saving another character:
```
b = Array(5 + 4, String(7,"?"))(a)
```
[Answer]
# Bit-Shifted RGB Values
Because of the way that Excel handles colors, (unsigned, 6-character hexadecimal integer) you can make use of negatively signed integers, of which excel will only use the right 6 bytes to assign a color value
This is a bit confusing so some examples are provided below
Lets say you want to use the color white, which is stored as
```
rgbWhite
```
and is equivalent to
```
&HFFFFFF ''#value: 16777215
```
to golf this down all we need to do is find a **negative** hexadecimal value which terminates in `FFFFFF` and since negative Hex values in must be in the format of `FFFFXXXXXX` (such that `X` is a valid hexadecimal) counting down from `FFFFFFFFFF` (`-1`) to `FFFF000001` (`-16777215`)
Knowing this we can generalize that the formula
```
Let Negative_Color_Value = -rgbWhite + Positive_Color_Value - 1
                         = -16777215 + Positive_Color_Value - 1
                         = -16777216 + Positive_Color_Value
```
Using this, some useful conversions are
```
rgbWhite = &HFFFFFF = -1 
rgbAqua  = &HFFFF00 = -256
16747627 = &HFF8C6B = -29589
```
[Answer]
# Omit terminal `"` when printing to Immediate Window
Given the function below, which is to be used in the debug window
```
h="Hello":?h", World!"
```
The Terminal `"` may be dropped for -1 Byte, leaving the string unclosed and the program shall execute the same, without error
```
h="Hello":?h", World!
```
Even more surprising than this is that this may be done within fully defined subroutines.
```
Sub a
h="Hello":Debug.?h", World!
End Sub
```
The subroutine above runs as expected and autoformats to
```
Sub a()
h = "Hello": Debug.Print h; ", World!"
End Sub
```
[Answer]
# Use Truthy and Falsey Variables in conditionals
Sometimes called implicit type conversion - directly using a number type in a `If`,`[IF(...)]` or `IIf(...)` statement, by using the truthy and falsey nature of that number can absolutely save you some bytes. 
In VBA, any number type variable that is non-zero is considered to be truthy ( and thus zero, `0`, is the only value falsey) and thus
```
If B <> 0 Then 
    Let C = B
Else 
    Let C = D
End If 
```
may be condensed to 
```
If B Then C=B Else C=D
```
and further to 
```
C=IIf(B,B,D)
```
[Answer]
# Exponentiation and `LongLong`s in 64-Bit VBA
The general form of exponentiation,
```
A to the power of B
```
Can be represented as in VBA as
```
A^B 
```
***But Only in 32-Bit Installs of Office***, in 64-Bits installs of Office, the shortest way that you may represent without error this is
```
A ^B
```
This is because in 64-Bit versions of VBA `^` serves as both the exponentiation literal and the [`LongLong` type declaration character](https://msdn.microsoft.com/en-us/vba/language-reference-vba/articles/64-bit-visual-basic-for-applications-overview#summary-of-vba7-language-updates). This means that some rather odd-looking but valid syntax can arise such as
```
a^=2^^63^-1^
```
which assigns variable `a` to hold the max value of a `Longlong`
[Answer]
# Compress Byte Arrays as String
 
For challanges that require the solution to hold constant data, it shall may be useful to compress that data as a single string and to then iterate across the string to fetch the data. 
In VBA, any byte value may be directly converted to a character with 
```
Chr(byteVal)
```
And a `long` or `integer` value may be converted to two characters with
```
Chr(longVal / 256) & Chr(longVal Mod 256)
```
So for a `byte` array a compression algorithm would look something like 
```
For Each Var In bytes
    Select Case Var
        Case Is = Asc(vbNullChar)
            outstr$ = outstr$ & """+chr(0)+"""
        Case Is = Asc(vbTab)
            outstr$ = outstr$ & """+vbTab+"""
        Case Is = Asc("""")
            outstr$ = outstr$ & """"""
        Case Is = Asc(vbLf)
            outstr$ = outstr$ & """+vbLf+"""
        Case Is = Asc(vbCr)
            outstr$ = outstr$ & """+vbCr+"""
        Case Else
            outstr$ = outstr$ & Chr$(Var)
    End Select
Next
Debug.Print "t="""; outstr$
```
Noting that the `Select Case` section is implemented due to the characters which may not be stored as literals in the string. 
From the resulting string, which will look something like 
```
t="5¬º-‚Ñ¢)
:√≥‚Ñ¢ÀÜ"+vbTab+"
¬ª‚Äòv¬∂<¬ÆXn¬≥"+Chr(0)+"~√é¬Ø≈°√ê‚Äò≈°;$√î√ù‚Ä¢√≥≈Ω¬°¬°EÀÜ√µW'¬´¬°*{√∫
{√ìx.O√í/R)¬∞@¬ØÀÜ‚Äù'¬Æ√ØQ*<¬π√ßu¬∂√†¬™p~√ÖP>‚Äπ:<¬≠¬´a¬∞;!¬æy¬≠‚Ä∫/,‚Äù√å#¬•≈ì5*B)¬∑7    
```
The data may then be extracted using the `Asc` and `Mid` functions, eg
```
i=Asc(Mid(t,n+1))
```
[Answer]
# Use Improper Constants
 
VBA allows, in some cases, for the use of unlisted or improper constants in expressions which require constant values. These are often legacy values, and shorter in length than the proper values. 
For example the values below may be used when letting a value be held by the `rng.HorizantalAlignment` property. 
\$
\small
\begin{align}
\textbf{Improper} &&\textbf{Proper} && \textbf{General Constant}\hspace{1.3cm}&&& \texttt{xlHAlign}~~\textbf{Constant} \\\hline
1\hspace{1.25cm} && 1\hspace{.7cm} && \texttt{xlGeneral}\hspace{2.95cm} &&& \texttt{xlHAlignGeneral} \\
2\hspace{1.25cm} && -4131 && \texttt{xlLeft}\hspace{3.6cm} &&& \texttt{xlHAlignLeft} \\
3\hspace{1.25cm} && -4108 && \texttt{xlCenter}\hspace{3.18cm} &&& \texttt{xlHAlignCenter} \\
4\hspace{1.25cm} && -4152 && \texttt{xlRight}\hspace{3.39cm} &&& \texttt{xlHAlignRight} \\
5\hspace{1.25cm} && 5\hspace{.7cm} && \texttt{xlFill}\hspace{3.61cm} &&& \texttt{xlHAlignFill} \\
6\hspace{1.25cm} && -4130 && \texttt{xlJustify}\hspace{2.97cm} &&& \texttt{xlHAlignJustify} \\
7\hspace{1.25cm} && 7\hspace{.7cm} && \texttt{xlCenterAcrossSelection} &&& \texttt{xlHAlignCenterAcrossSelection} \\
8\hspace{1.25cm} && -4117 && \texttt{xlDistributed}\hspace{2.15cm} &&& \texttt{xlHAlignDistributed} 
\end{align}
\$
This means, for example that setting a cell to having its text centered with 
```
rng.HorizantalAlignment=-4108
```
may be shortened down to 
```
rng.HorizantalAlignment=3
```
by replacing the improper constant value `3` for the proper value `-4108`. Note that if you fetch the `rng.HorizantalAlignment` property value, it will return the proper value. In this case, that would be `-4108`.
[Answer]
# In Excel, Create Numeric Arrays by Coercing Ranges
When a constant single dimensional set of numerics of mixed length, \$S\$ is needed, it shall be more efficient to use `[{...}]` notation to declare a range and then coerce that into a numeric array rather than to use the `Split(String)` notation or similar. 
Using this method, a change of \$\Delta\_\text{byte count} =-5~\text{bytes}\$ shall be accrued for all \$S\$.
### Example
For instance, 
```
x=Split("1 2 34 567 8910")
```
may be written as
```
x=[{1,2,34,567,8910}]
```
It is further worth noting that while this method does not allow for direct indexing, it does allow for iteration over the for loop directly, ie
```
For Each s In[{1,3,5,7,9,2,4,6,8}]
```
]