Excel macros for QOL formatting


'==============================================================
' MacabacusLite.bas  (v6)
'
' INSTALL
'   Alt+F11 > remove any old MacabacusLite module (No to export)
'   > right-click VBAProject (PERSONAL.XLSB) > Import File > this.
'   Ctrl+S. Then Alt+F8 > SetupShortcuts > Run (once; auto after that).
'
' KEY MAP
'   Ctrl+Shift+K        fill cycle (4 colours, last 2 are yours)
'   Ctrl+Shift+1        number  0/1/2 dp, commas, (neg), 0 -> em dash
'   Ctrl+Shift+2        date    dd-mmm-yy / 0000"A" / 0000"E"
'   Ctrl+Shift+5        percent 0/1/2 dp, commas
'   Ctrl+Shift+8        multiple 0/1/2 dp, commas ("x")
'   Ctrl+Shift+Alt+arrow toggle top/bottom/left/right edge border
'   Ctrl+Shift+7        outside border only (box, no interior lines)
'   Ctrl+Shift+-        remove all borders
'   Ctrl+,  Ctrl+.      increase / decrease decimals
'   Ctrl+;              font toggle black -> blue
'   Ctrl+'              font cycle black/blue/green/purple/red
'   Ctrl+Shift+[  ]     cycle precedents / dependents
'   Ctrl+Shift+G  B     trace go-deeper / back
'   Esc                 reset trace (next [ or ] starts fresh on current cell)
'==============================================================

Option Explicit

' ---- trace session state ----
Private gRe As Object
Private gStack As Collection
Private gSibs As Collection
Private gDir As String

'==============================================================
' SHORTCUT BINDING
'==============================================================
Sub Auto_Open()
   SetupShortcuts
End Sub

Sub SetupShortcuts()
   On Error Resume Next
   ' formatting
   Application.OnKey "+^k", "CycleFillColor"
   Application.OnKey "+^1", "CycleNumberFormat"
   Application.OnKey "+^2", "CycleDateFormat"
   Application.OnKey "+^5", "CyclePercentFormat"
   Application.OnKey "+^8", "CycleMultipleFormat"
   ' edge borders on Ctrl+Shift+Alt+arrows (Ctrl+Shift+arrow stays native select-to-edge)
   Application.OnKey "+^%{UP}", "BorderTop"
   Application.OnKey "+^%{DOWN}", "BorderBottom"
   Application.OnKey "+^%{LEFT}", "BorderLeft"
   Application.OnKey "+^%{RIGHT}", "BorderRight"
   Application.OnKey "+^7", "BordersOutline"
   Application.OnKey "+^-", "BordersNone"
   ' decimals
   Application.OnKey "^,", "IncreaseDecimals"
   Application.OnKey "^.", "DecreaseDecimals"
   ' font
   Application.OnKey "^;", "ToggleBlackBlue"
   Application.OnKey "^'", "CycleFontColorFull"
   ' tracing
   Application.OnKey "+^{[}", "PrecedentCycle"
   Application.OnKey "+^{]}", "DependentCycle"
   Application.OnKey "+^g", "TraceDescend"
   Application.OnKey "+^b", "TraceBack"
   Application.OnKey "{ESC}", "ResetTrace"
   On Error GoTo 0
End Sub

Sub RemoveShortcuts()
   Dim keys As Variant, k As Variant
   keys = Array("+^k", "+^1", "+^2", "+^5", "+^8", "+^7", "+^-", _
                "+^%{UP}", "+^%{DOWN}", "+^%{LEFT}", "+^%{RIGHT}", _
                "^,", "^.", "^;", "^'", _
                "+^{[}", "+^{]}", "+^g", "+^b", "{ESC}")
   On Error Resume Next
   For Each k In keys: Application.OnKey CStr(k): Next k
   On Error GoTo 0
End Sub

'==============================================================
' FILL CYCLE  (Ctrl+Shift+K)   none -> 1 -> 2 -> 3 -> 4 -> none
'==============================================================
Sub CycleFillColor()
   Dim cols As Variant
   cols = Array( _
       RGB(255, 255, 0), _
       RGB(210, 242, 255), _
       RGB(226, 239, 218), _
       RGB(252, 228, 214))    ' REPLACE cols 3 & 4 with your bank's RGB
   Dim c As Range: Set c = Selection.Cells(1, 1)
   Dim i As Long, idx As Long
   If c.Interior.Pattern = xlNone Then
       idx = 0
   Else
       idx = UBound(cols) + 1
       For i = LBound(cols) To UBound(cols)
           If c.Interior.Color = cols(i) Then idx = i + 1: Exit For
       Next i
   End If
   If idx > UBound(cols) Then
       Selection.Interior.Pattern = xlNone
   Else
       Selection.Interior.Color = cols(idx)
   End If
End Sub

'==============================================================
' NUMBER FORMAT CYCLES
'==============================================================
Sub CycleNumberFormat()
   Dim z As String: z = """" & ChrW(8211) & """"    ' zero shown as en dash:  "–"  (matches Macabacus)
   CycleFormat Array( _
       "#,##0;(#,##0);" & z, _
       "#,##0.0;(#,##0.0);" & z, _
       "#,##0.00;(#,##0.00);" & z)
End Sub

Sub CycleDateFormat()
   CycleFormat Array("dd-mmm-yy", "0000""A""", "0000""E""")
End Sub

Sub CyclePercentFormat()
   CycleFormat Array("#,##0%", "#,##0.0%", "#,##0.00%")
End Sub

Sub CycleMultipleFormat()
   CycleFormat Array("#,##0""x""", "#,##0.0""x""", "#,##0.00""x""")
End Sub

Private Sub CycleFormat(fmts As Variant)
   Dim cur As String, i As Long, idx As Long
   If Selection Is Nothing Then Exit Sub
   cur = Selection.Cells(1, 1).NumberFormat
   idx = -1
   For i = LBound(fmts) To UBound(fmts)
       If fmts(i) = cur Then idx = i: Exit For
   Next i
   idx = idx + 1
   If idx > UBound(fmts) Then idx = LBound(fmts)
   Selection.NumberFormat = fmts(idx)
End Sub

'==============================================================
' BORDERS
'==============================================================
Sub BorderTop():    ToggleEdge xlEdgeTop:    End Sub
Sub BorderBottom(): ToggleEdge xlEdgeBottom: End Sub
Sub BorderLeft():   ToggleEdge xlEdgeLeft:   End Sub
Sub BorderRight():  ToggleEdge xlEdgeRight:  End Sub

Private Sub ToggleEdge(edge As Long)
   Dim b As Border
   Set b = Selection.Borders(edge)
   If b.LineStyle = xlContinuous And b.Weight = xlThin Then
       b.LineStyle = xlNone               ' already a normal line -> remove it
   Else
       b.LineStyle = xlContinuous          ' none / dotted / thick -> force normal line
       b.Weight = xlThin
       b.ColorIndex = xlAutomatic
   End If
End Sub

Sub BordersOutline()   ' Ctrl+Shift+7 - outside edge of the whole selection only
   Dim edges As Variant, e As Variant
   edges = Array(xlEdgeLeft, xlEdgeRight, xlEdgeTop, xlEdgeBottom)
   For Each e In edges
       With Selection.Borders(e)
           .LineStyle = xlContinuous
           .Weight = xlThin
       End With
   Next e
End Sub

Sub BordersNone()      ' Ctrl+Shift+- - strip all borders from the selection
   Selection.Borders.LineStyle = xlNone
End Sub

'==============================================================
' INCREASE / DECREASE DECIMALS  (Ctrl+,  Ctrl+.)
'==============================================================
Sub IncreaseDecimals()
   Dim c As Range
   Application.ScreenUpdating = False
   For Each c In Selection.Cells
       c.NumberFormat = AdjustDecimals(c.NumberFormat, 1)
   Next c
   Application.ScreenUpdating = True
End Sub

Sub DecreaseDecimals()
   Dim c As Range
   Application.ScreenUpdating = False
   For Each c In Selection.Cells
       c.NumberFormat = AdjustDecimals(c.NumberFormat, -1)
   Next c
   Application.ScreenUpdating = True
End Sub

Private Function AdjustDecimals(fmt As String, delta As Long) As String
   If StrComp(Trim$(fmt), "General", vbTextCompare) = 0 Then
       AdjustDecimals = IIf(delta > 0, "0.0", "General")
       Exit Function
   End If
   Dim sec() As String, i As Long
   sec = Split(fmt, ";")
   For i = LBound(sec) To UBound(sec)
       sec(i) = AdjustSection(sec(i), delta)
   Next i
   AdjustDecimals = Join(sec, ";")
End Function

Private Function AdjustSection(s As String, delta As Long) As String
   AdjustSection = s
   If Len(s) = 0 Then Exit Function
   Dim i As Long, ch As String
   Dim inQuote As Boolean, esc As Boolean
   Dim dotPos As Long, lastDigit As Long, lastDec As Long, hasDigit As Boolean
   For i = 1 To Len(s)
       ch = Mid$(s, i, 1)
       If esc Then
           esc = False
       ElseIf ch = "\" Then
           esc = True
       ElseIf ch = """" Then
           inQuote = Not inQuote
       ElseIf Not inQuote Then
           If ch = "0" Or ch = "#" Or ch = "?" Then
               hasDigit = True: lastDigit = i
               If dotPos > 0 Then lastDec = i
           ElseIf ch = "." And dotPos = 0 Then
               dotPos = i
           End If
       End If
   Next i
   If Not hasDigit Then Exit Function

   If delta > 0 Then
       If dotPos = 0 Then
           AdjustSection = Left$(s, lastDigit) & ".0" & Mid$(s, lastDigit + 1)
       Else
           Dim insAt As Long: insAt = IIf(lastDec > 0, lastDec, dotPos)
           AdjustSection = Left$(s, insAt) & "0" & Mid$(s, insAt + 1)
       End If
   ElseIf delta 0 And dotPos > 0 And lastDec > 0 Then
       Dim t As String, after As String
       t = Left$(s, lastDec - 1) & Mid$(s, lastDec + 1)
       after = Mid$(t, dotPos + 1, 1)
       If Not (after = "0" Or after = "#" Or after = "?") Then
           t = Left$(t, dotPos - 1) & Mid$(t, dotPos + 1)
       End If
       AdjustSection = t
   End If
End Function

'==============================================================
' FONT COLOUR
'==============================================================
Sub ToggleBlackBlue()    ' Ctrl+;
   If Selection.Cells(1, 1).Font.Color = RGB(0, 0, 255) Then
       Selection.Font.Color = RGB(0, 0, 0)
   Else
       Selection.Font.Color = RGB(0, 0, 255)
   End If
End Sub

Sub CycleFontColorFull()  ' Ctrl+'
   Dim cols As Variant
   cols = Array(RGB(0, 0, 0), RGB(0, 0, 255), RGB(0, 128, 0), RGB(128, 0, 128), RGB(255, 0, 0))
   Dim cur As Long, i As Long, idx As Long
   cur = Selection.Cells(1, 1).Font.Color
   idx = 0
   For i = LBound(cols) To UBound(cols)
       If cols(i) = cur Then idx = i + 1: Exit For
   Next i
   If idx > UBound(cols) Then idx = LBound(cols)
   Selection.Font.Color = cols(idx)
End Sub

'==============================================================
' TRACE
'==============================================================
Sub PrecedentCycle():  CycleDir "P": End Sub
Sub DependentCycle():  CycleDir "D": End Sub

Sub TraceDescend()
   ' Re-anchor on the cell you're parked on and trace from there.
   If gDir = "" Then gDir = "P"
   Set gSibs = Nothing          ' clear current list so CycleDir rebuilds on ActiveCell
   CycleDir gDir
End Sub

Sub ResetTrace()   ' Esc - drop the current cycle so the next [ or ] starts fresh
   Set gSibs = Nothing
   gDir = ""
   On Error Resume Next
   Application.CutCopyMode = False   ' keep Esc's normal "clear the copy marquee" behaviour
   On Error GoTo 0
End Sub

Sub TraceBack()
   If gStack Is Nothing Then Exit Sub
   If gStack.Count = 0 Then MsgBox "Nothing to step back to.", vbInformation: Exit Sub
   Dim r As Range
   On Error Resume Next
   Set r = gStack(gStack.Count)
   gStack.Remove gStack.Count
   On Error GoTo 0
   If Not r Is Nothing Then GoToRange r
End Sub

Private Sub CycleDir(dir As String)
   ' If we already have a list for this direction AND the cursor is on one of
   ' its members, step to the next member. This keeps the cycle locked to the
   ' ORIGINAL cell's precedents/dependents - it never drills into a member's
   ' own inputs. (Use Ctrl+Shift+G to deliberately drill into a member.)
   If gDir = dir And Not gSibs Is Nothing Then
       Dim pos As Long: pos = IndexInList(ActiveCell, gSibs)
       If pos > 0 Then
           pos = pos + 1
           If pos > gSibs.Count Then pos = 1
           GoToRange gSibs(pos)
           Exit Sub
       End If
   End If

   ' Otherwise treat the active cell as a fresh anchor and build its list.
   Dim cur As Range: Set cur = ActiveCell
   Dim lst As Collection
   Application.ScreenUpdating = False
   Application.Cursor = xlWait
   If dir = "P" Then
       Set lst = PrecedentsOf(cur)
   Else
       Application.StatusBar = "Scanning workbook for dependents..."
       Set lst = DependentsOf(cur)
   End If
   Application.StatusBar = False
   Application.Cursor = xlDefault
   Application.ScreenUpdating = True

   If lst Is Nothing Then
       MsgBox "VBScript.RegExp unavailable (Trust Center?). Ask for the regex-free build.", vbExclamation
       Exit Sub
   End If
   If lst.Count = 0 Then
       If dir = "P" Then
           MsgBox cur.Address(External:=True) & " has no inputs - it's a hardcoded value.", vbInformation
       Else
           MsgBox "No cell in this workbook references " & cur.Address(External:=True) & ".", vbInformation
       End If
       Exit Sub
   End If

   PushHistory cur
   Set gSibs = lst
   gDir = dir
   GoToRange lst(1)
End Sub

Private Function PrecedentsOf(cell As Range) As Collection
   Dim out As New Collection
   Set PrecedentsOf = out
   If Not cell.HasFormula Then Exit Function
   Dim re As Object: Set re = Rgx()
   If re Is Nothing Then Set PrecedentsOf = Nothing: Exit Function
   Dim m As Object, mt As Object, refStr As String, rng As Range
   Set m = re.Execute(cell.Formula)
   For Each mt In m
       refStr = mt.Value
       If InStr(refStr, "[") = 0 Then
           Set rng = ResolveRef(refStr, cell.Worksheet)
           If Not rng Is Nothing Then
               On Error Resume Next
               out.Add rng, rng.Address(External:=True)
               On Error GoTo 0
           End If
       End If
   Next mt
End Function

Private Function DependentsOf(target As Range) As Collection
   Dim out As New Collection
   Set DependentsOf = out
   Dim re As Object: Set re = Rgx()
   If re Is Nothing Then Set DependentsOf = Nothing: Exit Function
   Dim tgt As Range: Set tgt = target.Cells(1, 1)
   Dim ws As Worksheet, fcells As Range, c As Range
   For Each ws In tgt.Parent.Parent.Worksheets
       Set fcells = Nothing
       On Error Resume Next
       Set fcells = ws.UsedRange.SpecialCells(xlCellTypeFormulas)
       On Error GoTo 0
       If Not fcells Is Nothing Then
           For Each c In fcells
               If FormulaHits(c, tgt, re) Then
                   On Error Resume Next
                   out.Add c, c.Address(External:=True)
                   On Error GoTo 0
               End If
           Next c
       End If
   Next ws
End Function

Private Function FormulaHits(formulaCell As Range, tgt As Range, re As Object) As Boolean
   Dim m As Object, mt As Object, refStr As String, rng As Range
   Set m = re.Execute(formulaCell.Formula)
   For Each mt In m
       refStr = mt.Value
       If InStr(refStr, "[") = 0 Then
           Set rng = ResolveRef(refStr, formulaCell.Worksheet)
           If Not rng Is Nothing Then
               If rng.Worksheet Is tgt.Worksheet Then
                   If Not Application.Intersect(rng, tgt) Is Nothing Then
                       FormulaHits = True: Exit Function
                   End If
               End If
           End If
       End If
   Next mt
End Function

Private Function Rgx() As Object
   If gRe Is Nothing Then
       On Error Resume Next
       Set gRe = CreateObject("VBScript.RegExp")
       On Error GoTo 0
       If gRe Is Nothing Then Exit Function
       gRe.Global = True
       gRe.IgnoreCase = True
       gRe.Pattern = "(?:(?:'[^']+'|\[[^\]]+\][^!'()]*|[A-Za-z_][A-Za-z0-9_.]*)!)?" & _
                     "\$?[A-Za-z]{1,3}\$?[0-9]+(?::\$?[A-Za-z]{1,3}\$?[0-9]+)?(?![A-Za-z0-9_(])"
   End If
   Set Rgx = gRe
End Function

Private Function ResolveRef(refStr As String, srcSheet As Worksheet) As Range
   On Error Resume Next
   Dim ws As Worksheet, addr As String, sheetPart As String, p As Long
   p = InStr(refStr, "!")
   If p > 0 Then
       sheetPart = Left$(refStr, p - 1)
       addr = Mid$(refStr, p + 1)
       If Left$(sheetPart, 1) = "'" And Right$(sheetPart, 1) = "'" Then
           sheetPart = Mid$(sheetPart, 2, Len(sheetPart) - 2)
           sheetPart = Replace(sheetPart, "''", "'")
       End If
       Set ws = srcSheet.Parent.Worksheets(sheetPart)
       If ws Is Nothing Then Exit Function
       Set ResolveRef = ws.Range(addr)
   Else
       Set ResolveRef = srcSheet.Range(refStr)
   End If
End Function

Private Sub GoToRange(rng As Range)
   On Error Resume Next
   Application.Goto Reference:=rng, Scroll:=False
   On Error GoTo 0
End Sub

Private Sub PushHistory(r As Range)
   If gStack Is Nothing Then Set gStack = New Collection
   gStack.Add r
End Sub

Private Function IndexInList(c As Range, lst As Collection) As Long
   On Error Resume Next
   Dim i As Long, key As String
   key = c.Worksheet.Name & "!" & c.Cells(1, 1).Address
   For i = 1 To lst.Count
       If (lst(i).Worksheet.Name & "!" & lst(i).Cells(1, 1).Address) = key Then
           IndexInList = i
           Exit Function
       End If
   Next i
   On Error GoTo 0
End Function
 

0 Comments

Career Advancement Opportunities

June 2026 Investment Banking

  • Evercore 01 99.4%
  • Moelis & Company 01 98.8%
  • JPMorgan 01 98.2%
  • Guggenheim Partners 01 97.7%
  • Morgan Stanley 07 97.1%

Overall Employee Satisfaction

June 2026 Investment Banking

  • Moelis & Company No 99.4%
  • Morgan Stanley 02 98.8%
  • Evercore 01 98.2%
  • BMO Capital Markets 12 97.6%
  • Banco Santander 01 97.1%

Professional Growth Opportunities

June 2026 Investment Banking

  • Evercore 01 99.4%
  • Moelis & Company 01 98.8%
  • Morgan Stanley 05 98.2%
  • JPMorgan No 97.7%
  • BMO Capital Markets 12 97.1%

Total Avg Compensation

June 2026 Investment Banking

  • Vice President (14) $434
  • Associates (44) $258
  • 3rd+ Year Analyst (8) $210
  • 2nd Year Analyst (22) $179
  • Intern/Summer Associate (13) $156
  • 1st Year Analyst (77) $151
  • Intern/Summer Analyst (72) $101
notes
16 IB Interviews Notes

“... there’s no excuse to not take advantage of the resources out there available to you. Best value for your $ are the...”

Leaderboard

1
redever's picture
redever
99.2
2
BankonBanking's picture
BankonBanking
99.0
3
kanon's picture
kanon
99.0
4
Secyh62's picture
Secyh62
99.0
5
dosk17's picture
dosk17
98.9
6
GameTheory's picture
GameTheory
98.9
7
Betsy Massar's picture
Betsy Massar
98.9
8
DrApeman's picture
DrApeman
98.9
9
CompBanker's picture
CompBanker
98.9
10
bolo up's picture
bolo up
98.8
success
From 10 rejections to 1 dream investment banking internship

“... I believe it was the single biggest reason why I ended up with an offer...”