Excel VBA Macro Codes: Ready-to-Use Examples
Last Updated: 27th April 2026 by Puneet Gogia
Jump to a Category
Macro codes can save you a ton of time. You can automate small as well as heavy tasks with VBA codes. And do you know? With the help of macros, you can break all the limitations of Excel which you think Excel has. And today, I have listed some of the useful codes examples to help you become more productive in your day to day work. You can use these codes even if you havenβt used VBA before that.
But hereβs the first thing to know:
What is a Macro (VBA Code) ?
In Excel, macro code is a programming code which is written in VBA (Visual Basic for Applications) language. The idea behind using a macro code is to automate an action which you perform manually in Excel, otherwise. For example, you can use a code to print only a particular range of cells just with a single click instead of selecting the range > File Tab > Print > Print Select > OK Button.
How to use a Macro in Excel (VBA Code)?
Before you use these codes, make sure you have your developer tab on your Excel ribbon to access VB editor. Once you activate developer tab you can use below steps to paste a VBA code into VB editor.
- Go to your developer tab and click on "Visual Basic" to open the Visual Basic Editor.
- On the left side in "Project Window", right click on the name of your workbook and insert a new module.
- Just paste your code into the module and close it.
- Now, go to your developer tab and click on the macro button.
- It will show you a window with a list of the macros you have in your file from where you can run a macro from that list.
All codes on this page have been tested in Excel 2016, 2019, 2021, 2024, and Microsoft 365 on Windows. Before using any macro, keep in mind:
- Save your workbook as .xlsm (macro-enabled) before running any code, .xlsx files cannot store macros.
- Codes marked Windows only use Shell commands or Outlook automation that do not work on Mac.
- To use macros in all your workbooks, save them to your Personal Macro Workbook.
- Always test a macro on a copy of your file first β some operations like deleting sheets or replacing values cannot be undone.
Add Serial Numbers
Automatically adds a sequential list of numbers downward from the active cell. An input box asks how many numbers to insert.
Sub AddSerialNumbers()
Dim i As Integer
On Error GoTo Last
i = InputBox("Enter Value", "Enter Serial Numbers")
For i = 1 To i
ActiveCell.Value = i
ActiveCell.Offset(1, 0).Activate
Next i
Last: Exit Sub
End Sub
Insert Multiple Columns
Inserts a specified number of columns to the right of the active cell in one step β no need to repeat the insert command manually.
Sub InsertMultipleColumns()
Dim i As Integer, j As Integer
ActiveCell.EntireColumn.Select
On Error GoTo Last
i = InputBox("Enter number of columns to insert", "Insert Columns")
For j = 1 To i
Selection.Insert Shift:=xlToRight, CopyOrigin:=xlFormatFromRightorAbove
Next j
Last: Exit Sub
End Sub
xlToRight to xlToLeft to insert columns before the selected cell instead.Insert Multiple Rows
Inserts multiple rows at once starting from the active cell. Enter the count in the input box when prompted.
Sub InsertMultipleRows()
Dim i As Integer, j As Integer
ActiveCell.EntireRow.Select
On Error GoTo Last
i = InputBox("Enter number of rows to insert", "Insert Rows")
For j = 1 To i
Selection.Insert Shift:=xlToDown, CopyOrigin:=xlFormatFromRightorAbove
Next j
Last: Exit Sub
End Sub
xlToDown to xlToUp to insert rows above the selected cell.Auto Fit Columns
Instantly auto-fits the width of every column in the active worksheet to match its content β no manual dragging needed.
Sub AutoFitColumns()
Cells.Select
Cells.EntireColumn.AutoFit
End Sub
Auto Fit Rows
Instantly auto-fits the height of every row in the active worksheet to match its content.
Sub AutoFitRows()
Cells.Select
Cells.EntireRow.AutoFit
End Sub
Remove Text Wrap (Entire Sheet)
Range("A1").WrapText = False which only removed wrap from cell A1. Now correctly applies to the entire sheet.Removes text wrap from every cell in the active worksheet, then auto-fits all rows and columns so your layout snaps back into shape.
Sub RemoveTextWrap()
Cells.WrapText = False
Cells.EntireRow.AutoFit
Cells.EntireColumn.AutoFit
End Sub
Cells with e.g. Range("A1:D50").Unmerge Cells
Unmerges all merged cells in the current selection. Add to your Quick Access Toolbar for one-click access.
Sub UnmergeCells()
Selection.UnMerge
End Sub
Selection with a fixed range like Range("A1:D10") to target a specific area.Unhide All Rows and Columns
Makes all hidden rows and columns in the active worksheet visible again β no need to unhide them one by one.
Sub UnhideRowsColumns()
Columns.EntireColumn.Hidden = False
Rows.EntireRow.Hidden = False
End Sub
Convert Range into a Static Image
Copies the selected range and pastes it as a static picture into the same sheet. Useful for locking down a table's appearance for reporting.
Sub PasteAsPicture()
Application.CutCopyMode = False
Selection.Copy
ActiveSheet.Pictures.Paste.Select
End Sub
Insert a Linked Picture
Pastes the selected range as a linked image β the picture updates automatically when the source data changes. Great for dashboards.
Sub LinkedPicture()
Selection.Copy
ActiveSheet.Pictures.Paste(Link:=True).Select
End Sub
To manage all of these codes, make sure to read about the Personal Macro Workbook so that you can use them in all the workbooks.
Highlight Duplicate Values
Checks each cell in the selection and highlights any duplicate values in yellow. Select your range before running.
Sub HighlightDuplicateValues()
Dim myRange As Range, myCell As Range
Set myRange = Selection
For Each myCell In myRange
If WorksheetFunction.CountIf(myRange, myCell.Value) > 1 Then
myCell.Interior.ColorIndex = 36
End If
Next myCell
End Sub
ColorIndex = 36 to any Excel color index number to use a different highlight colour.Highlight Active Row and Column on Double-Click
Double-click any cell to select its entire row and column β great for navigating large data tables. This goes in the sheet's own code window, not a module.
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
Dim strRange As String
strRange = Target.Cells.Address & "," & _
Target.Cells.EntireColumn.Address & "," & _
Target.Cells.EntireRow.Address
Range(strRange).Select
End Sub
Highlight Top 10 Values
Select a range and run this macro to highlight the top 10 values in green using a conditional formatting rule.
Sub HighlightTopTen()
Selection.FormatConditions.AddTop10
Selection.FormatConditions(Selection.FormatConditions.Count).SetFirstPriority
With Selection.FormatConditions(1)
.TopBottom = xlTop10Top
.Rank = 10
.Percent = False
End With
With Selection.FormatConditions(1).Interior
.Color = 13561798
End With
Selection.FormatConditions(1).StopIfTrue = False
End Sub
.Rank = 10 to highlight more or fewer values. Change xlTop10Top to xlTop10Bottom for the lowest values.Highlight Named Ranges
Highlights all named ranges in the workbook so you can see exactly which cells have names assigned to them.
Sub HighlightNamedRanges()
Dim RangeName As Name, HighlightRange As Range
On Error Resume Next
For Each RangeName In ActiveWorkbook.Names
Set HighlightRange = RangeName.RefersToRange
HighlightRange.Interior.ColorIndex = 36
Next RangeName
End Sub
Highlight Cells Greater Than a Value
Prompts for a threshold and highlights all cells in the selection that are greater than it in green.
Sub HighlightGreaterThanValues()
Dim i As Integer
i = InputBox("Enter Greater Than Value", "Enter Value")
Selection.FormatConditions.Delete
Selection.FormatConditions.Add Type:=xlCellValue, Operator:=xlGreater, Formula1:=i
Selection.FormatConditions(Selection.FormatConditions.Count).SetFirstPriority
With Selection.FormatConditions(1)
.Font.Color = RGB(0, 0, 0)
.Interior.Color = RGB(31, 218, 154)
End With
End Sub
Highlight Cells Lower Than a Value
Prompts for a threshold and highlights all cells in the selection that are below it in red.
Sub HighlightLowerThanValues()
Dim i As Integer
i = InputBox("Enter Lower Than Value", "Enter Value")
Selection.FormatConditions.Delete
Selection.FormatConditions.Add Type:=xlCellValue, Operator:=xlLess, Formula1:=i
Selection.FormatConditions(Selection.FormatConditions.Count).SetFirstPriority
With Selection.FormatConditions(1)
.Font.Color = RGB(0, 0, 0)
.Interior.Color = RGB(217, 83, 79)
End With
End Sub
Highlight Negative Numbers
Scans every cell in the selection and changes the font colour of any negative number to red.
Sub HighlightNegativeNumbers()
Dim Rng As Range
For Each Rng In Selection
If WorksheetFunction.IsNumber(Rng) Then
If Rng.Value < 0 Then
Rng.Font.Color = -16776961
End If
End If
Next
End Sub
Highlight Specific Text within Cells
Searches for a specific text string and highlights matching characters in red. Select two columns before running: column A = source text, column B = the text to find.
Sub HighlightSpecificText()
Dim myStr As String, myRg As Range
Dim I As Long, J As Long
On Error Resume Next
Set myRg = Application.InputBox("Select a two-column range:", "Selection Required", , , , , , 8)
If myRg Is Nothing Then Exit Sub
If myRg.Columns.Count <> 2 Then
MsgBox "Please select exactly two columns." : Exit Sub
End If
For I = 0 To myRg.Rows.Count - 1
myStr = myRg.Range("B1").Offset(I, 0).Value
With myRg.Range("A1").Offset(I, 0)
.Font.ColorIndex = 1
For J = 1 To Len(.Text)
If Mid(.Text, J, Len(myStr)) = myStr Then
.Characters(J, Len(myStr)).Font.ColorIndex = 3
End If
Next J
End With
Next I
End Sub
Highlight Cells with Comments
Applies the built-in "Note" style to all cells containing comments in the current selection, making them easy to spot at a glance.
Sub HighlightCommentCells()
Selection.SpecialCells(xlCellTypeComments).Select
Selection.Style = "Note"
End Sub
Highlight Alternate Rows (Banded/Striped)
rng.Value = rng ^ (1/3) which permanently replaced cell values with their cube roots. That line has been removed.Highlights every other row in the selection to create a striped/banded table effect that makes data easier to read.
Sub HighlightAlternateRows()
Dim rng As Range
For Each rng In Selection.Rows
If rng.Row Mod 2 = 1 Then
rng.Style = "20% - Accent1"
End If
Next rng
End Sub
"20% - Accent1" to Accent2βAccent6 for different colours. Change Mod 2 = 1 to Mod 2 = 0 to highlight even rows instead.Highlight Cells with Misspelled Words
Scans the entire used range and applies the "Bad" style to any cell containing a spelling error.
Sub HighlightMisspelledCells()
Dim rng As Range
For Each rng In ActiveSheet.UsedRange
If Not Application.CheckSpelling(Word:=rng.Text) Then
rng.Style = "Bad"
End If
Next rng
End Sub
Highlight All Error Cells
Scans the entire worksheet, highlights all error cells in red, and shows a count of how many were found.
Sub HighlightErrors()
Dim rng As Range, i As Integer
For Each rng In ActiveSheet.UsedRange
If WorksheetFunction.IsError(rng) Then
i = i + 1
rng.Style = "Bad"
End If
Next rng
MsgBox "There are total " & i & " error(s) in this worksheet."
End Sub
Highlight Cells with Specific Text
Prompts for a value, then highlights every matching cell in the used range and shows a count of matches found.
Sub HighlightSpecificValues()
Dim rng As Range, i As Integer, c As Variant
c = InputBox("Enter Value To Highlight")
For Each rng In ActiveSheet.UsedRange
If rng = c Then
rng.Style = "Note"
i = i + 1
End If
Next rng
MsgBox "There are total " & i & " " & c & " in this worksheet."
End Sub
Highlight Blank Cells with Hidden Spaces
Finds cells that look blank but contain a single space character β a common data quality issue β and highlights them.
Sub HighlightBlankWithSpace()
Dim rng As Range
For Each rng In ActiveSheet.UsedRange
If rng.Value = " " Then
rng.Style = "Note"
End If
Next rng
End Sub
Highlight Maximum Value in Selection
Finds the highest value in the selected range and highlights it in green.
Sub HighlightMaxValue()
Dim rng As Range
For Each rng In Selection
If rng = WorksheetFunction.Max(Selection) Then
rng.Style = "Good"
End If
Next rng
End Sub
Highlight Minimum Value in Selection
Finds the lowest value in the selected range and highlights it in green.
Sub HighlightMinValue()
Dim rng As Range
For Each rng In Selection
If rng = WorksheetFunction.Min(Selection) Then
rng.Style = "Good"
End If
Next rng
End Sub
Highlight Unique Values
Highlights all cells in the selection that contain a unique (non-duplicate) value using a conditional formatting rule.
Sub HighlightUniqueValues()
Dim rng As Range
Set rng = Selection
rng.FormatConditions.Delete
Dim uv As UniqueValues
Set uv = rng.FormatConditions.AddUniqueValues
uv.DupeUnique = xlUnique
uv.Interior.Color = vbGreen
End Sub
Highlight Column Differences
Highlights cells where the value differs from the corresponding cell in the reference column β ideal for comparing two data sets side by side.
Sub ColumnDifference()
Selection.ColumnDifferences(ActiveCell).Select
Selection.Style = "Bad"
End Sub
Highlight Row Differences
Highlights cells where the value differs from the corresponding cell in the reference row.
Sub RowDifference()
Selection.RowDifferences(ActiveCell).Select
Selection.Style = "Bad"
End Sub
Lock / Protect Cells with Formulas
Protects only formula cells, leaving all other cells editable. Useful for sharing workbooks where you want to prevent accidental formula deletion.
Sub LockCellsWithFormulas()
With ActiveSheet
.Unprotect
.Cells.Locked = False
.Cells.SpecialCells(xlCellTypeFormulas).Locked = True
.Protect AllowDeletingRows:=True
End With
End Sub
Highlight All Formula Cells
Scans the entire used range and highlights every cell containing a formula in yellow β useful for quickly auditing a sheet.
Sub HighlightFormulas()
Dim cell As Range
For Each cell In ActiveSheet.UsedRange
If cell.HasFormula Then
cell.Interior.Color = RGB(255, 255, 0)
End If
Next cell
End Sub
Convert to UPPER CASE
Converts all text in the selected cells to UPPER CASE. Non-text cells are left unchanged.
Sub ConvertToUpperCase()
Dim Rng As Range
For Each Rng In Selection
If Application.WorksheetFunction.IsText(Rng) Then
Rng.Value = UCase(Rng)
End If
Next
End Sub
Convert to lower case
Converts all text in the selected cells to lower case. Non-text cells are skipped.
Sub ConvertToLowerCase()
Dim Rng As Range
For Each Rng In Selection
If Application.WorksheetFunction.IsText(Rng) Then
Rng.Value = LCase(Rng)
End If
Next
End Sub
Convert to Proper Case
Capitalises The First Letter Of Every Word. Useful for cleaning name lists or titles.
Sub ConvertToProperCase()
Dim Rng As Range
For Each Rng In Selection
If WorksheetFunction.IsText(Rng) Then
Rng.Value = WorksheetFunction.Proper(Rng.Value)
End If
Next
End Sub
Convert to Sentence case
Capitalises only the first letter of the text in each cell. Perfect for sentence-style labels and descriptions.
Sub ConvertToSentenceCase()
Dim Rng As Range
For Each Rng In Selection
If WorksheetFunction.IsText(Rng) Then
Rng.Value = UCase(Left(Rng, 1)) & LCase(Right(Rng, Len(Rng) - 1))
End If
Next Rng
End Sub
Remove Extra Spaces from Cells
Trims leading, trailing, and extra internal spaces from every text cell in the selection β equivalent to applying Excel's TRIM function directly to the values.
Sub RemoveSpaces()
Dim myCell As Range
Select Case MsgBox("You Can't Undo This. Save Workbook First?", vbYesNoCancel, "Alert")
Case Is = vbYes: ThisWorkbook.Save
Case Is = vbCancel: Exit Sub
End Select
For Each myCell In Selection
If Not IsEmpty(myCell) Then myCell = Trim(myCell)
Next myCell
End Sub
Remove First N Characters (Custom Function)
A custom worksheet function that removes a specified number of characters from the start of a text string. Use it in a cell like a regular formula.
Public Function RemoveFirstC(rng As String, cnt As Long)
RemoveFirstC = Right(rng, Len(rng) - cnt)
End Function
=RemoveFirstC(A1, 3) removes the first 3 characters from A1. Paste into a module to use as a worksheet function.Remove a Specific Character from Selection
Prompts you to enter a character and removes every instance of it from all cells in the selection.
Sub RemoveChar()
Dim Rng As Range, rc As String
rc = InputBox("Character(s) to Remove", "Enter Value")
For Each Rng In Selection
Selection.Replace What:=rc, Replacement:=""
Next
End Sub
Reverse Text in a Cell (Custom Function)
A custom worksheet function that reverses the characters in a text string. Use it directly in cells like any Excel formula.
Public Function Rvrse(ByVal cell As Range) As String
Rvrse = VBA.StrReverse(cell.Value)
End Function
=Rvrse(A1) where A1 contains "Excel" returns "lecxE".Count Total Words in a Worksheet
Counts every word across all cells in the active worksheet and displays the total in a message box.
Sub WordCountWorksheet()
Dim WordCnt As Long, rng As Range
Dim S As String, N As Long
For Each rng In ActiveSheet.UsedRange.Cells
S = Application.WorksheetFunction.Trim(rng.Text)
N = 0
If S <> vbNullString Then
N = Len(S) - Len(Replace(S, " ", "")) + 1
End If
WordCnt = WordCnt + N
Next rng
MsgBox "There are total " & Format(WordCnt, "#,##0") & " words in the active worksheet"
End Sub
Convert Numbers to Words (Custom Function)
A custom worksheet function that converts any whole number to its written English equivalent. Use it in cells like a regular Excel formula: =NumberToWords(A1).
Function NumberToWords(ByVal MyNumber As Long) As String
Dim Units(1 To 9) As String, Teens(10 To 19) As String
Dim Tens(2 To 9) As String, Result As String
Units(1)="One":Units(2)="Two":Units(3)="Three":Units(4)="Four"
Units(5)="Five":Units(6)="Six":Units(7)="Seven"
Units(8)="Eight":Units(9)="Nine"
Teens(10)="Ten":Teens(11)="Eleven":Teens(12)="Twelve"
Teens(13)="Thirteen":Teens(14)="Fourteen":Teens(15)="Fifteen"
Teens(16)="Sixteen":Teens(17)="Seventeen"
Teens(18)="Eighteen":Teens(19)="Nineteen"
Tens(2)="Twenty":Tens(3)="Thirty":Tens(4)="Forty"
Tens(5)="Fifty":Tens(6)="Sixty":Tens(7)="Seventy"
Tens(8)="Eighty":Tens(9)="Ninety"
If MyNumber = 0 Then NumberToWords = "Zero": Exit Function
If MyNumber < 0 Then Result = "Negative ": MyNumber = Abs(MyNumber)
If MyNumber >= 1000 Then
Result = Result & Units(Int(MyNumber/1000)) & " Thousand "
MyNumber = MyNumber Mod 1000
End If
If MyNumber >= 100 Then
Result = Result & Units(Int(MyNumber/100)) & " Hundred "
MyNumber = MyNumber Mod 100
End If
If MyNumber >= 20 Then
Result = Result & Tens(Int(MyNumber/10)) & " "
MyNumber = MyNumber Mod 10
ElseIf MyNumber >= 10 Then
Result = Result & Teens(MyNumber): MyNumber = 0
End If
If MyNumber > 0 Then Result = Result & Units(MyNumber)
NumberToWords = Trim(Result)
End Function
=NumberToWords(1234) returns "One Thousand Two Hundred Thirty Four". Works for β9,999 to 9,999.Multiply All Values by a Number
Multiplies every number in the selection by a value you specify. The original code used addition (+) instead of multiplication (*) β now fixed. Also upgraded to Double so decimal multipliers like 1.5 work correctly.
Sub MultiplyAllValues()
Dim rng As Range, i As Double
i = InputBox("Enter the number to multiply by", "Multiply Values")
If i = 0 Then Exit Sub
For Each rng In Selection
If WorksheetFunction.IsNumber(rng) Then
rng.Value = rng.Value * i
End If
Next rng
End Sub
2 to double all values, 0.5 to halve them, or 1.1 to add 10%. Non-numeric cells are skipped automatically.Add a Number to All Values
Adds the same number to every cell in the selection. Enter a negative value (e.g. -10) to subtract from all values instead. Useful for bulk adjustments like adding a fixed fee or offset across a list of prices.
Sub AddToAllValues()
Dim rng As Range, i As Double
i = InputBox("Enter the number to add", "Add to Values")
For Each rng In Selection
If WorksheetFunction.IsNumber(rng) Then
rng.Value = rng.Value + i
End If
Next rng
End Sub
-10 to subtract 10 from every cell. Non-numeric cells are ignored.Calculate Square Root of All Values
Replaces every number in the selection with its square root, in-place β no helper column needed. Useful for bulk statistical transformations on a dataset.
Sub GetSquareRoot()
Dim rng As Range
For Each rng In Selection
If WorksheetFunction.IsNumber(rng) Then
rng.Value = Sqr(rng)
End If
Next rng
End Sub
Calculate Cube Root of All Values
Replaces every number in the selection with its cube root. Uses the exponent ^ (1/3) since VBA has no built-in cube root function.
Sub GetCubeRoot()
Dim rng As Range
For Each rng In Selection
If WorksheetFunction.IsNumber(rng) Then
rng.Value = rng ^ (1 / 3)
End If
Next rng
End Sub
Remove Decimals from Numbers
Strips the decimal portion from every number in the selection, rounding down to the nearest whole number using VBA's Int() function.
Sub RemoveDecimals()
Dim rng As Range
For Each rng In Selection
rng.Value = Int(rng)
rng.NumberFormat = "0"
Next rng
End Sub
Int() always rounds down (toward negative infinity). 2.9 becomes 2, -2.1 becomes -3. Use Round(rng, 0) instead if you want standard rounding.Remove Negative Signs (Convert to Absolute Values)
Converts all negative numbers in the selection to their absolute (positive) values using VBA's Abs() function. Non-numeric cells are skipped.
Sub RemoveNegativeSign()
Dim rng As Range
For Each rng In Selection
If WorksheetFunction.IsNumber(rng) Then
rng.Value = Abs(rng)
End If
Next rng
End Sub
Remove Apostrophe from Numbers
Removes leading apostrophes from numbers stored as text β a common problem when importing data from other systems. The apostrophe forces Excel to treat the number as text; this macro converts them back to true numeric values.
Sub RemoveApostrophes()
Selection.Value = Selection.Value
End Sub
Replace Blank Cells with Zero
Finds every empty cell (including cells with a single space) in the selection and fills it with 0. Prevents #DIV/0! and other formula errors that occur when calculations reference blank cells.
Sub ReplaceBlankWithZero()
Dim rng As Range
For Each rng In Selection
If rng = "" Or rng = " " Then
rng.Value = "0"
End If
Next rng
End Sub
Convert Roman Numerals to Arabic Numbers
Converts Roman numeral text (e.g. XIV, XLII) in selected cells to their Arabic number equivalents using Excel's built-in ARABIC worksheet function.
Sub ConvertRomanToArabic()
Dim rng As Range
For Each rng In Selection
If Not WorksheetFunction.IsNonText(rng) Then
rng.Value = WorksheetFunction.Arabic(rng)
End If
Next rng
End Sub
Add Degree Symbol to Numbers
Appends a degree symbol (Β°) to every number in the selection. Useful for temperature data, angles, or any measurement that requires the degree symbol but where you want to keep the values editable.
Sub AddDegreeSymbol()
Dim rng As Range
For Each rng In Selection
If IsNumeric(rng.Value) Then
rng.Value = rng.Value & "Β°"
End If
Next
End Sub
"0Β°") instead.Convert All Formulas to Static Values
Replaces every formula in the selection with its current calculated value β permanently locking in results and removing formula dependencies. A save prompt appears first because this action cannot be undone.
Sub ConvertToValues()
Dim MyRange As Range, MyCell As Range
Select Case MsgBox("You Can't Undo This. Save Workbook First?", vbYesNoCancel, "Alert")
Case Is = vbYes: ThisWorkbook.Save
Case Is = vbCancel: Exit Sub
End Select
Set MyRange = Selection
For Each MyCell In MyRange
If MyCell.HasFormula Then
MyCell.Formula = MyCell.Value
End If
Next MyCell
End Sub
Convert Dates to Day Numbers
Extracts the day number from each date in the selection and replaces the date with just the day (e.g. 25-Dec-2024 becomes 25). Useful for grouping or filtering data by day of month.
Sub DateToDay()
Dim tempCell As Range
For Each tempCell In Selection
If IsDate(tempCell) = True Then
With tempCell
.Value = Day(tempCell)
.NumberFormat = "0"
End With
End If
Next tempCell
End Sub
Convert Dates to Year Numbers
Extracts just the year from each date in the selection (e.g. 25-Dec-2024 becomes 2024). Useful for year-based grouping in reports or pivot tables.
Sub DateToYear()
Dim tempCell As Range
For Each tempCell In Selection
If IsDate(tempCell) = True Then
With tempCell
.Value = Year(tempCell)
.NumberFormat = "0"
End With
End If
Next tempCell
End Sub
Remove Time from Date-Time Values
Strips the time portion from cells that contain a combined date and time value, leaving just the date. Uses VBA.Int() to drop the decimal (time) part of the serial number.
Sub RemoveTime()
Dim Rng As Range
For Each Rng In Selection
If IsDate(Rng) = True Then
Rng.Value = VBA.Int(Rng.Value)
End If
Next
Selection.NumberFormat = "dd-mmm-yy"
End Sub
"dd-mmm-yy" to your preferred date format, e.g. "dd/mm/yyyy" or "mm/dd/yyyy".Remove Date from Date-Time Values
Strips the date from combined date-time cells, returning only the time value. Uses VBA.Fix() to subtract the integer (date) part and keep just the decimal (time) portion.
Sub RemoveDate()
Dim Rng As Range
For Each Rng In Selection
If IsDate(Rng) = True Then
Rng.Value = Rng.Value - VBA.Fix(Rng.Value)
End If
Next
Selection.NumberFormat = "hh:mm:ss am/pm"
End Sub
Insert a 24-Hour Time Range
Inserts a full 24-hour time sequence (1:00 AM through 12:00 AM) starting from the active cell, one hour per row going downward. Useful for building time-based schedules or logs.
Sub InsertTimeRange()
Dim i As Integer
For i = 1 To 24
ActiveCell.FormulaR1C1 = i & ":00"
ActiveCell.NumberFormat = "[$-409]h:mm AM/PM;@"
ActiveCell.Offset(RowOffset:=1, ColumnOffset:=0).Select
Next i
End Sub
Insert AβZ Alphabets in a Range
Inserts the full alphabet (AβZ or aβz) starting from the active cell, one letter per row. Two versions provided β uppercase and lowercase. Uses ASCII character codes with Chr().
' Uppercase A-Z
Sub InsertUppercaseAlphabets()
Dim i As Integer
For i = 65 To 90
ActiveCell.Value = Chr(i)
ActiveCell.Offset(1, 0).Select
Next i
End Sub
' Lowercase a-z
Sub InsertLowercaseAlphabets()
Dim i As Integer
For i = 97 To 122
ActiveCell.Value = Chr(i)
ActiveCell.Offset(1, 0).Select
Next i
End Sub
Switch Between A1 and R1C1 Reference Styles
Toggles between Excel's A1 (column letters + row numbers) and R1C1 (row and column numbers) reference styles without going into Excel Options. Run the matching Sub for the style you want.
' Switch to R1C1 style
Sub ActivateR1C1()
Application.ReferenceStyle = xlR1C1
End Sub
' Switch back to A1 style
Sub ActivateA1()
Application.ReferenceStyle = xlA1
End Sub
Activate R1C1 / A1 Reference Style (Shortcut)
A combined toggle macro β checks the current reference style and switches to the other one automatically. Run once to switch to R1C1, run again to switch back to A1.
Sub ToggleReferenceStyle()
If Application.ReferenceStyle = xlA1 Then
Application.ReferenceStyle = xlR1C1
MsgBox "Switched to R1C1 reference style.", vbInformation
Else
Application.ReferenceStyle = xlA1
MsgBox "Switched to A1 reference style.", vbInformation
End If
End Sub
Insert Multiple Worksheets at Once
Adds multiple new worksheets after the active sheet in one step. Enter the count when prompted.
Sub InsertMultipleSheets()
Dim i As Integer
i = InputBox("Enter number of sheets to insert.", "Insert Multiple Sheets")
Sheets.Add After:=ActiveSheet, Count:=i
End Sub
Hide All Sheets Except the Active One
Hides every worksheet in the workbook except the one you're currently viewing.
Sub HideAllButActiveSheet()
Dim ws As Worksheet
For Each ws In ThisWorkbook.Worksheets
If ws.Name <> ThisWorkbook.ActiveSheet.Name Then
ws.Visible = xlSheetHidden
End If
Next ws
End Sub
Unhide All Hidden Worksheets
Makes all hidden sheets in the workbook visible again with a single click.
Sub UnhideAllWorksheets()
Dim ws As Worksheet
For Each ws In ActiveWorkbook.Worksheets
ws.Visible = xlSheetVisible
Next ws
End Sub
Delete All Sheets Except the Active One
Permanently deletes every worksheet except the currently active one. Cannot be undone β save first.
Sub DeleteAllButActiveSheet()
Dim ws As Worksheet
For Each ws In ThisWorkbook.Worksheets
If ws.Name <> ThisWorkbook.ActiveSheet.Name Then
Application.DisplayAlerts = False
ws.Delete
Application.DisplayAlerts = True
End If
Next ws
End Sub
Delete All Blank Worksheets
Scans every sheet in the workbook and deletes any that are completely empty.
Sub DeleteBlankWorksheets()
Dim Ws As Worksheet
On Error Resume Next
Application.ScreenUpdating = False
Application.DisplayAlerts = False
For Each Ws In Application.Worksheets
If Application.WorksheetFunction.CountA(Ws.UsedRange) = 0 Then
Ws.Delete
End If
Next
Application.ScreenUpdating = True
Application.DisplayAlerts = True
End Sub
Protect a Worksheet
Protects the active worksheet with a password. Edit the password directly in the code before running.
Sub ProtectWorksheet()
ActiveSheet.Protect "mypassword", True, True
End Sub
"mypassword" with your actual password before running.Unprotect a Worksheet
Removes protection from the active worksheet using the password set in the code.
Sub UnprotectWorksheet()
ActiveSheet.Unprotect "mypassword"
End Sub
Protect All Worksheets at Once
Prompts for a password and applies it to every worksheet in the workbook simultaneously.
Sub ProtectAllWorksheets()
Dim ws As Worksheet, ps As String
ps = InputBox("Enter a Password.", vbOKCancel)
For Each ws In ActiveWorkbook.Worksheets
ws.Protect Password:=ps
Next ws
End Sub
Protect All Sheets with Confirmation
Password-protects every sheet in the workbook at once. An input box lets you set the password on the fly β no need to hardcode it.
Sub ProtectAllSheets()
Dim ws As Worksheet, pwd As String
pwd = InputBox("Enter a password to protect all sheets", "Protect Sheets")
If pwd = "" Then Exit Sub
For Each ws In ThisWorkbook.Sheets
ws.Protect Password:=pwd
Next ws
MsgBox "All sheets are now protected.", vbInformation
End Sub
Unprotect All Sheets in a Workbook
Removes password protection from every sheet in the workbook at once.
Sub UnprotectAllSheets()
Dim ws As Worksheet
For Each ws In ThisWorkbook.Sheets
ws.Unprotect Password:="password"
Next ws
End Sub
"password" with the password used when protecting the sheets.Sort Worksheets Alphabetically
Sorts all worksheets alphabetically. A message box lets you choose ascending or descending order.
Sub SortWorksheets()
Dim i As Integer, j As Integer, iAnswer As VbMsgBoxResult
iAnswer = MsgBox("Sort Ascending? Click No for Descending.", vbYesNoCancel + vbQuestion, "Sort Worksheets")
For i = 1 To Sheets.Count
For j = 1 To Sheets.Count - 1
If iAnswer = vbYes Then
If UCase$(Sheets(j).Name) > UCase$(Sheets(j+1).Name) Then
Sheets(j).Move After:=Sheets(j+1)
End If
ElseIf iAnswer = vbNo Then
If UCase$(Sheets(j).Name) < UCase$(Sheets(j+1).Name) Then
Sheets(j).Move After:=Sheets(j+1)
End If
End If
Next j
Next i
End Sub
Create a Table of Contents for All Sheets
Creates a new "Table of Content" sheet with a clickable hyperlink to every other sheet in the workbook β essential for large multi-sheet files.
Sub TableOfContent()
Dim i As Long
On Error Resume Next
Application.DisplayAlerts = False
Worksheets("Table of Content").Delete
Application.DisplayAlerts = True
On Error GoTo 0
ThisWorkbook.Sheets.Add Before:=ThisWorkbook.Worksheets(1)
ActiveSheet.Name = "Table of Content"
For i = 1 To Sheets.Count
With ActiveSheet
.Hyperlinks.Add Anchor:=ActiveSheet.Cells(i, 1), _
Address:="", _
SubAddress:="'" & Sheets(i).Name & "'!A1", _
ScreenTip:=Sheets(i).Name, _
TextToDisplay:=Sheets(i).Name
End With
Next i
End Sub
Save Each Worksheet as a Separate PDF
Exports every worksheet in the workbook as its own PDF file. Update the folder path in the code before running.
Sub SaveEachSheetAsPDF()
Dim ws As Worksheet
For Each ws In Worksheets
ws.ExportAsFixedFormat xlTypePDF, "C:\YourFolder\" & ws.Name & ".pdf"
Next ws
End Sub
"C:\YourFolder\" with your actual save location.Insert Blank Rows Between Each Existing Row
Inserts 2 blank rows after every existing row β useful for adding spacing in reports or room for annotations.
Sub InsertRowsBetweenRows()
Dim i As Long
For i = ThisWorkbook.Sheets("Sheet1").UsedRange.Rows.Count To 1 Step -1
ThisWorkbook.Sheets("Sheet1").Rows(i + 1).Resize(2).Insert
Next i
End Sub
"Sheet1" to your sheet name. Change Resize(2) to insert a different number of blank rows.Disable Page Breaks Across All Workbooks
Turns off the page break display on all worksheets across all open workbooks β cleans up the view after printing.
Sub DisablePageBreaks()
Dim wb As Workbook, Sht As Worksheet
Application.ScreenUpdating = False
For Each wb In Application.Workbooks
For Each Sht In wb.Worksheets
Sht.DisplayPageBreaks = False
Next Sht
Next wb
Application.ScreenUpdating = True
End Sub
Auto Sort Data in a Worksheet
Sorts data in a defined range by the first column in ascending order. Update the sheet name and range to match your data.
Sub AutoSortData()
With ThisWorkbook.Sheets("Sheet1").Range("A1:D100")
.Sort Key1:=.Cells(1, 1), Order1:=xlAscending, Header:=xlYes
End With
End Sub
"A1:D100" to your data range and adjust Key1:=.Cells(1,1) to sort by a different column.Create a Dated Backup of the Workbook
Saves a copy of the current workbook in the same folder with today's date appended to the filename.
Sub CreateBackup()
ThisWorkbook.SaveCopyAs Filename:=ThisWorkbook.Path & _
"\" & Format(Date, "mm-dd-yy") & " " & ThisWorkbook.Name
End Sub
Save a Timestamped Backup
Saves a backup with both date and time in the filename so multiple daily saves don't overwrite each other.
Sub SaveTimestampedBackup()
Dim backupPath As String
backupPath = "C:\Backup\MyWorkbook_" & Format(Now(), "yyyymmdd_hhmmss") & ".xlsm"
ThisWorkbook.SaveCopyAs backupPath
End Sub
"C:\Backup\" with your preferred backup folder path.Close All Open Workbooks
Closes every open workbook and prompts you to save any with unsaved changes.
Sub CloseAllWorkbooks()
Dim wbs As Workbook
For Each wbs In Workbooks
wbs.Close SaveChanges:=True
Next wbs
End Sub
Copy Active Sheet to a New Workbook
Copies the active worksheet into a brand new workbook β useful for sharing a single sheet without exposing the rest of the file.
Sub CopySheetToNewWorkbook()
ThisWorkbook.ActiveSheet.Copy _
Before:=Workbooks.Add.Worksheets(1)
End Sub
Combine Multiple Excel Files into One Workbook
Opens a file picker to select multiple Excel files, then moves all their sheets into the current workbook. Hold Ctrl to select multiple files.
Sub CombineWorkbooks()
Dim FilesToOpen As Variant, x As Integer
FilesToOpen = Application.GetOpenFilename( _
FileFilter:="Microsoft Excel Files (*.xls;*.xlsx;*.xlsm), *.xls;*.xlsx;*.xlsm", _
MultiSelect:=True, Title:="Select Files to Combine")
If TypeName(FilesToOpen) = "Boolean" Then Exit Sub
Application.ScreenUpdating = False
x = 1
While x <= UBound(FilesToOpen)
Workbooks.Open Filename:=FilesToOpen(x)
ActiveWorkbook.Sheets.Move After:=ThisWorkbook.Sheets(ThisWorkbook.Sheets.Count)
x = x + 1
Wend
Application.ScreenUpdating = True
MsgBox "Done! All sheets combined.", vbInformation
End Sub
Export Each Worksheet to a Separate Workbook
Saves each worksheet as its own .xlsx file in a specified folder. Update the path before running.
Sub ExportSheetsToWorkbooks()
Dim ws As Worksheet
For Each ws In ThisWorkbook.Worksheets
ws.Copy
ActiveWorkbook.SaveAs "C:\ExportedSheets\" & ws.Name & ".xlsx"
ActiveWorkbook.Close False
Next ws
End Sub
"C:\ExportedSheets\" with your target folder. Make sure the folder exists first.Count Open Unsaved Workbooks
Checks all open workbooks and displays a count of how many have unsaved changes.
Sub CountUnsavedWorkbooks()
Dim book As Workbook, i As Integer
For Each book In Workbooks
If book.Saved = False Then i = i + 1
Next book
MsgBox i & " workbook(s) have unsaved changes."
End Sub
Auto-Close Workbook After Inactivity
Closes the workbook automatically after 10 minutes of inactivity without saving. Useful for shared or sensitive files.
Sub AutoCloseAfterInactivity()
Dim countDown As Date
countDown = Now + TimeValue("00:10:00")
Do Until Now >= countDown
If Not Application.Interactive Then Exit Sub
DoEvents
Loop
ThisWorkbook.Close SaveChanges:=False
End Sub
"00:10:00" to adjust the timeout period.Create a New Folder via VBA
Creates a new folder on your computer from within Excel. Checks first whether the folder already exists to avoid errors.
Sub CreateDirectory()
Dim path As String
path = "C:\NewFolder"
If Not Dir(path, vbDirectory) <> "" Then
MkDir path
MsgBox "Folder created: " & path
Else
MsgBox "Folder already exists."
End If
End Sub
Show a Welcome Message on File Open
Displays a message box every time the workbook is opened. The macro must be named exactly Auto_Open to trigger automatically.
Sub Auto_Open()
MsgBox "Welcome! Thanks for opening this file."
End Sub
Show a Closing Message on File Close
Displays a message box when the workbook is closed. Must be named exactly Auto_Close to trigger automatically.
Sub Auto_Close()
MsgBox "Goodbye! Don't forget to check excelchamps.com for more tips."
End Sub
Save Selected Range as a PDF
Exports the selected range to a named PDF file saved in your default Excel folder. Enter a filename when prompted.
Sub SaveSelectionAsPDF()
Dim pdfPath As String, fileName As String
fileName = InputBox("Enter a name for the PDF file", "Save as PDF", "MySelection")
If fileName = "" Then Exit Sub
pdfPath = Application.DefaultFilePath & "\" & fileName & ".pdf"
Selection.ExportAsFixedFormat Type:=xlTypePDF, Filename:=pdfPath, _
Quality:=xlQualityStandard, IncludeDocProperties:=True, IgnorePrintAreas:=False
MsgBox "PDF saved to: " & pdfPath, vbInformation
End Sub
Print the Current Selection
Prints only the selected range without touching any print area settings.
Sub PrintSelection()
Selection.PrintOut Copies:=1, Collate:=True
End Sub
Print a Custom Page Range
Prompts for a start and end page number, then prints only that range of pages.
Sub PrintCustomPages()
Dim startpage As Integer, endpage As Integer
startpage = InputBox("Enter Start Page number.", "Enter Value")
If Not WorksheetFunction.IsNumber(startpage) Then
MsgBox "Invalid Start Page number." : Exit Sub
End If
endpage = InputBox("Enter End Page number.", "Enter Value")
If Not WorksheetFunction.IsNumber(endpage) Then
MsgBox "Invalid End Page number." : Exit Sub
End If
Selection.PrintOut From:=startpage, To:=endpage, Copies:=1, Collate:=True
End Sub
Print with Narrow Margins
Sets narrow margins and immediately prints one copy β no manual margin configuration required.
Sub PrintNarrowMargin()
With ActiveSheet.PageSetup
.LeftMargin = Application.InchesToPoints(0.25)
.RightMargin = Application.InchesToPoints(0.25)
.TopMargin = Application.InchesToPoints(0.75)
.BottomMargin = Application.InchesToPoints(0.75)
.HeaderMargin = Application.InchesToPoints(0.3)
.FooterMargin = Application.InchesToPoints(0.3)
End With
ActiveWindow.SelectedSheets.PrintOut Copies:=1, Collate:=True
End Sub
Print All Workbooks in a Folder
Opens every Excel file in a specified folder, prints one copy, then closes it. Update the folder path before running.
Sub PrintAllWorkbooksInFolder()
Dim folderPath As String, filename As String
folderPath = "C:\MyFolder\"
filename = Dir(folderPath & "*.xls*")
Do While filename <> ""
Workbooks.Open Filename:=folderPath & filename
ActiveWorkbook.PrintOut Copies:=1
ActiveWorkbook.Close False
filename = Dir()
Loop
End Sub
Refresh All Pivot Tables in the Workbook
Refreshes every pivot table across all worksheets in the workbook. The original only looped through the active sheet β now fixed to loop all sheets.
Sub RefreshAllPivots()
Dim ws As Worksheet, pt As PivotTable
For Each ws In ActiveWorkbook.Worksheets
For Each pt In ws.PivotTables
pt.RefreshTable
Next pt
Next ws
End Sub
Hide Pivot Table Subtotals
Removes subtotals from all fields in the pivot table where your cursor is placed. Click inside the pivot table first, then run.
Sub HidePivotSubtotals()
Dim pt As PivotTable, pf As PivotField
On Error Resume Next
Set pt = ActiveSheet.PivotTables(ActiveCell.PivotTable.Name)
If pt Is Nothing Then
MsgBox "Place your cursor inside a PivotTable first." : Exit Sub
End If
For Each pf In pt.PivotFields
pf.Subtotals(1) = True
pf.Subtotals(1) = False
Next pf
End Sub
Auto-Update Pivot Table Source Range
Dynamically updates the source data range of a pivot table to include new rows and columns. Update the sheet names and pivot table name before running.
Sub UpdatePivotTableRange()
Dim Data_Sheet As Worksheet, Pivot_Sheet As Worksheet
Dim StartPoint As Range, DataRange As Range
Dim PivotName As String, NewRange As String
Dim LastCol As Long, DownCell As Long
Set Data_Sheet = ThisWorkbook.Worksheets("PivotData")
Set Pivot_Sheet = ThisWorkbook.Worksheets("Pivot")
PivotName = "PivotTable1"
Data_Sheet.Activate
Set StartPoint = Data_Sheet.Range("A1")
LastCol = StartPoint.End(xlToRight).Column
DownCell = StartPoint.End(xlDown).Row
Set DataRange = Data_Sheet.Range(StartPoint, Cells(DownCell, LastCol))
NewRange = Data_Sheet.Name & "!" & DataRange.Address(ReferenceStyle:=xlR1C1)
Pivot_Sheet.PivotTables(PivotName).ChangePivotCache _
ActiveWorkbook.PivotCaches.Create(SourceType:=xlDatabase, SourceData:=NewRange)
Pivot_Sheet.PivotTables(PivotName).RefreshTable
Pivot_Sheet.Activate
MsgBox "Pivot Table range updated successfully."
End Sub
Enable / Disable GetPivotData
Toggles the GetPivotData function on or off without going into Excel Options.
Sub EnableGetPivotData()
Application.GenerateGetPivotData = True
End Sub
Sub DisableGetPivotData()
Application.GenerateGetPivotData = False
End Sub
Change Chart Type
Changes the selected chart to a clustered column chart. Click the chart first, then run. Change the constant to switch to other chart types.
Sub ChangeChartType()
ActiveChart.ChartType = xlColumnClustered
End Sub
xlColumnClustered with xlLine, xlPie, xlBarClustered, or any other Excel chart type constant.Paste Chart as a Static Image
Converts the selected chart into a static picture pasted into cell A1 β useful for reports that should not change dynamically.
Sub ConvertChartToPicture()
ActiveChart.ChartArea.Copy
ActiveSheet.Range("A1").Select
ActiveSheet.Pictures.Paste.Select
End Sub
Add a Title to a Chart
Prompts for a title and adds it above the selected chart. Click the chart first, then run the macro.
Sub AddChartTitle()
Dim i As Variant
i = InputBox("Please enter your chart title", "Chart Title")
On Error GoTo Last
ActiveChart.SetElement (msoElementChartTitleAboveChart)
ActiveChart.ChartTitle.Text = i
Last: Exit Sub
End Sub
Resize All Charts to the Same Size
Sets every chart in the active worksheet to the same width and height β great for consistent dashboard layouts.
Sub ResizeAllCharts()
Dim i As Integer
For i = 1 To ActiveSheet.ChartObjects.Count
With ActiveSheet.ChartObjects(i)
.Width = 300
.Height = 200
End With
Next i
End Sub
.Width and .Height (in points) to your required dimensions.Delete All Charts in a Worksheet
Removes every chart object from the active worksheet in a single run.
Sub DeleteAllCharts()
Dim cht As ChartObject
For Each cht In ActiveSheet.ChartObjects
cht.Delete
Next cht
End Sub
Send Active Workbook as Email Attachment
Opens an Outlook email with the current workbook already attached. Uses .Display to let you preview before sending β change to .Send to send immediately.
Sub SendWorkbookByEmail()
Dim OutApp As Object, OutMail As Object
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(0)
With OutMail
.To = "recipient@example.com"
.Subject = "Monthly Report"
.Body = "Hi, please find the report attached."
.Attachments.Add ActiveWorkbook.FullName
.Display ' Change to .Send to send without preview
End With
Set OutMail = Nothing : Set OutApp = Nothing
End Sub
Send a Custom Email via Outlook
Composes and sends a plain text email directly from Excel. Useful for automated notifications or status alerts triggered by a macro.
Sub SendCustomEmail()
Dim OutApp As Object, OutMail As Object
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(0)
With OutMail
.To = "recipient@example.com"
.Subject = "This is the Subject Line"
.Body = "Hello World!"
.Send
End With
Set OutMail = Nothing : Set OutApp = Nothing
End Sub
Quick Email Attachment (Built-In Dialog)
Opens Excel's built-in Send Mail dialog with the workbook attached β works without needing to reference Outlook directly.
Sub QuickEmailAttachment()
Application.Dialogs(xlDialogSendMail).Show
End Sub
Use Goal Seek via VBA
Runs Excel's Goal Seek tool programmatically. Update the cell references to match your workbook before running.
Sub GoalSeekVBA()
Dim Target As Long
On Error GoTo ErrorHandler
Target = InputBox("Enter the required value", "Enter Value")
Worksheets("Sheet1").Activate
With ActiveSheet.Range("C7")
.GoalSeek Goal:=Target, ChangingCell:=Range("C2")
End With
Exit Sub
ErrorHandler: MsgBox "Sorry, value is not valid."
End Sub
"C7" to your formula cell and "C2" to the variable cell for your Goal Seek setup.Open Excel's Built-In Data Entry Form
Opens Excel's default data entry form for the active sheet β a fast way to add rows to a table without scrolling or selecting cells.
Sub OpenDataForm()
ActiveSheet.ShowDataForm
End Sub
Use Text to Speech to Read Cells Aloud
Reads out all text values in the selected range using Excel's built-in text-to-speech engine, cell by cell.
Sub SpeakSelection()
Selection.Speak
End Sub
Open Windows Calculator
Opens the Windows Calculator directly from Excel. Updated to use the Shell method which is more reliable on Windows 10 and 11 than the original ActivateMicrosoftApp.
Sub OpenCalculator()
Shell "calc.exe", 1
End Sub
Search Google from Excel
Opens a Google search in your default browser. Updated to work without a hardcoded Chrome path β now opens in whatever browser is set as your default.
Sub SearchGoogle()
Dim query As String, searchURL As String
query = InputBox("Enter your search query", "Google Search")
If query = "" Then Exit Sub
searchURL = "https://www.google.com/search?q=" & _
Application.WorksheetFunction.Substitute(query, " ", "+")
Shell "cmd /c start """ & searchURL, vbHide
End Sub
Create a Countdown Timer
Runs a 1-minute countdown timer and shows a message box when time is up. Useful for timed tasks or reminders.
Sub SimpleTimer()
Dim countDown As Date
countDown = Now + TimeValue("00:01:00")
Do Until Now >= countDown
DoEvents
Loop
MsgBox "Time's up!"
End Sub
"00:01:00" to set a different duration β e.g. "00:05:00" for 5 minutes.Convert Text to Columns Automatically
Splits comma-delimited text in a column into separate columns β no need to use the Data β Text to Columns wizard.
Sub TextToColumnsAuto()
Dim rng As Range
Set rng = ThisWorkbook.Sheets("Sheet1").Range("A1:A100")
rng.TextToColumns Destination:=rng, DataType:=xlDelimited, Comma:=True
End Sub
"A1:A100" to your range. Replace Comma:=True with Tab:=True or Semicolon:=True for other delimiters.Add Today's Date to Page Header
Adds a dynamic date to the centre of the page header that updates automatically each time the sheet is printed.
Sub AddDateToHeader()
With ActiveSheet.PageSetup
.LeftHeader = ""
.CenterHeader = "&D"
.RightHeader = ""
End With
End Sub
"&D" to .LeftHeader or .RightHeader to change position. Use "&T" for time instead.Add Custom Text to Page Header
Prompts you to type custom text and adds it as the centre page header.
Sub CustomPageHeader()
Dim myText As String
myText = InputBox("Enter your header text", "Custom Header")
ActiveSheet.PageSetup.CenterHeader = myText
End Sub
Print Comments at End of Document
Configures print settings so all cell comments are printed together on a separate page at the end of the document.
Sub PrintCommentsAtEnd()
ActiveSheet.PageSetup.PrintComments = xlPrintSheetEnd
End Sub
Add a Watermark to a Worksheet
Adds a large "Confidential" watermark text effect to the active sheet. Adjust the text, font size, and position as needed.
Sub AddWatermark()
Dim shp As Object
Set shp = ActiveSheet.Shapes.AddTextEffect( _
msoTextEffect1, "Confidential", "Arial", 50, msoFalse, msoFalse, 100, 100)
With shp.Fill
.Visible = msoTrue
.ForeColor.RGB = RGB(217, 217, 217)
.Transparency = 0.5
End With
End Sub
Activate R1C1 / A1 Reference Style (Shortcut)
Quick toggle macros to switch reference styles without navigating Excel Options.
Sub UseR1C1Style()
Application.ReferenceStyle = xlR1C1
End Sub
Sub UseA1Style()
Application.ReferenceStyle = xlA1
End Sub
Insert a Watermark + Add a Timestamp
A combined utility macro that both watermarks the active sheet and inserts the current timestamp into cell A1 β useful for version tracking.
Sub WatermarkAndTimestamp()
' Add watermark
ActiveSheet.Shapes.AddTextEffect msoTextEffect1, "DRAFT", "Arial", 60, _
msoFalse, msoFalse, 150, 200
' Add timestamp to A1
ActiveSheet.Range("A1").Value = "Generated: " & Format(Now(), "dd-mmm-yyyy hh:mm")
End Sub
Basic On Error GoTo Handler
The most important error handling pattern in VBA. When an error occurs, execution jumps to the ErrorHandler label where you can show a user-friendly message, log the problem, and exit cleanly β instead of crashing with a confusing VBA error dialog. Every macro that does anything destructive (deleting, saving, printing) should use this pattern.
Sub MacroWithErrorHandling()
On Error GoTo ErrorHandler
' --- Your main code goes here ---
Range("A1").Value = "Hello"
Exit Sub ' IMPORTANT: stops code falling into the handler on success
ErrorHandler:
MsgBox "An error occurred: " & Err.Description & _
vbNewLine & "Error number: " & Err.Number, _
vbCritical, "Macro Error"
End Sub
Exit Sub before the ErrorHandler: label β otherwise the error message shows even when the macro succeeds. Err.Description gives a plain-English explanation. Err.Number is the numeric code you can look up in the VBA documentation.On Error Resume Next β Skip Errors Silently
On Error Resume Next tells VBA to ignore any error and continue to the next line. This is useful in specific situations β like checking whether a sheet exists, or accessing an object that may or may not be there. The crucial rule: always turn it off again with On Error GoTo 0 immediately after the risky line, otherwise errors silently swallow real problems later in your code.
Sub CheckIfSheetExists()
Dim ws As Worksheet
On Error Resume Next ' Try the risky operation
Set ws = ThisWorkbook.Sheets("Data")
On Error GoTo 0 ' ALWAYS restore error handling immediately after
If ws Is Nothing Then
MsgBox "Sheet 'Data' does not exist.", vbExclamation
Else
MsgBox "Sheet 'Data' found!", vbInformation
End If
End Sub
On Error Resume Next at the top of a macro and leave it running throughout β this hides every bug. Use it only around the one line that might intentionally fail, then immediately restore with On Error GoTo 0.Error Logger β Write Errors to a Sheet
Instead of showing a message box, this pattern writes every error to a dedicated "Error Log" sheet with a timestamp, error number, description, and which Sub caused it. This is invaluable in complex workbooks or when macros run automatically β you get a full history of what went wrong and when, without interrupting the user.
' Add this reusable Sub to any module
Sub LogError(subName As String, errNum As Long, errDesc As String)
Dim logSheet As Worksheet
Dim nextRow As Long
On Error Resume Next
Set logSheet = ThisWorkbook.Sheets("Error Log")
On Error GoTo 0
' Create the log sheet if it doesn't exist yet
If logSheet Is Nothing Then
Set logSheet = ThisWorkbook.Sheets.Add
logSheet.Name = "Error Log"
logSheet.Range("A1:D1").Value = Array("Timestamp", "Sub Name", "Error #", "Description")
logSheet.Range("A1:D1").Font.Bold = True
End If
nextRow = logSheet.Cells(logSheet.Rows.Count, 1).End(xlUp).Row + 1
logSheet.Cells(nextRow, 1).Value = Now()
logSheet.Cells(nextRow, 2).Value = subName
logSheet.Cells(nextRow, 3).Value = errNum
logSheet.Cells(nextRow, 4).Value = errDesc
logSheet.Columns.AutoFit
End Sub
' Example: call LogError from any macro's error handler
Sub MyMacro()
On Error GoTo EH
' ... your main code here ...
Range("A1").Value = "Test"
Exit Sub
EH:
LogError "MyMacro", Err.Number, Err.Description
MsgBox "An error was logged. Check the 'Error Log' sheet.", vbExclamation
End Sub
LogError Sub into any module. Then in any other macro's error handler, call LogError "SubName", Err.Number, Err.Description. The "Error Log" sheet is created automatically on first use. This is the professional standard for production Excel workbooks.Validate Input Before Running a Macro
It happens when you are trying to run a macro, and that macro has to do something with a cell or a range, but for some reason that cell or range is blank, and the data that the macro requires to run is not the correct one. So, in those cases, you can also have a predefined check or something like that that can verify whether that data is correct or of the correct type. These kinds of verifications can help you avoid a lot of errors, specifically in codes where the process has different steps.
Sub MacroWithValidation()
Dim ws As Worksheet
Dim val As Variant
' Check 1: Is the correct sheet active?
If ActiveSheet.Name <> "Data" Then
MsgBox "Please run this macro from the 'Data' sheet.", vbExclamation
Exit Sub
End If
' Check 2: Is the required input cell empty?
val = ActiveSheet.Range("B2").Value
If IsEmpty(val) Or val = "" Then
MsgBox "Cell B2 is empty. Please enter a value before running.", vbExclamation
Exit Sub
End If
' Check 3: Is the value numeric?
If Not IsNumeric(val) Then
MsgBox "Cell B2 must contain a number, not text.", vbExclamation
Exit Sub
End If
' Check 4: Is the value in a sensible range?
If val < 1 Or val > 1000 Then
MsgBox "Value in B2 must be between 1 and 1000.", vbExclamation
Exit Sub
End If
' --- All checks passed β safe to run ---
MsgBox "Validation passed. Value is: " & val, vbInformation
End Sub
If...Exit Sub block with a specific message telling the user exactly what they need to fix. This prevents confusing runtime errors and makes your macros feel professional.Safe Delete β Confirm Before Destroying Data
There are a lot of activities that, when you perform them with VBA, you cannot undo. And if you are trying to delete something, such as data, a worksheet, or even a workbook, then in those kinds of VBA codes or macros, you need to have a confirmation before actually deleting that workbook or performing that activity. So, in those cases, you can use a message box that asks for the user's consent with Yes or No before proceeding.
Sub SafeDelete()
Dim answer As VbMsgBoxResult
answer = MsgBox( _
"This will permanently delete the selected data." & vbNewLine & _
"This action cannot be undone. Are you sure?", _
vbYesNo + vbCritical, "Confirm Delete")
If answer <> vbYes Then
MsgBox "Cancelled. Nothing was deleted.", vbInformation
Exit Sub
End If
' --- User confirmed β proceed with deletion ---
Selection.ClearContents
MsgBox "Done. Data cleared.", vbInformation
End Sub
Selection.ClearContents with whatever your macro actually deletes or modifies. Use vbYesNo + vbCritical for irreversible actions β the red icon signals danger to the user. For non-destructive confirmations, use vbYesNo + vbQuestion instead.Refresh All Power Query Connections
Refreshes every Power Query connection in the workbook and waits for each to fully complete before moving on. Without setting BackgroundQuery = False, VBA continues executing before the data has finished loading β which causes problems if you have code that runs immediately after the refresh, such as pivot table updates or copy-paste operations.
Sub RefreshAllPowerQueries()
Dim conn As WorkbookConnection
For Each conn In ThisWorkbook.Connections
If conn.Type = xlConnectionTypeOLEDB Or _
conn.Type = xlConnectionTypePowerQuery Then
conn.OLEDBConnection.BackgroundQuery = False
conn.Refresh
End If
Next conn
MsgBox "All Power Query connections refreshed.", vbInformation
End Sub
BackgroundQuery = False makes VBA wait for each query to finish before moving to the next line. This is critical for any automation sequence that uses the refreshed data downstream. Works in Excel 2016 and later with Power Query installed.Refresh a Specific Power Query by Name
Refreshes a single named Power Query connection rather than all of them. Useful when you have multiple queries and only want to update one β for example, refreshing a fast "Sales" query without triggering a slow "Historical Data" query that takes minutes to run.
Sub RefreshQueryByName(queryName As String)
Dim conn As WorkbookConnection
On Error GoTo NotFound
Set conn = ThisWorkbook.Connections("Query - " & queryName)
conn.OLEDBConnection.BackgroundQuery = False
conn.Refresh
MsgBox "Query '" & queryName & "' refreshed.", vbInformation
Exit Sub
NotFound:
MsgBox "Query '" & queryName & "' not found." & vbNewLine & _
"Check the name in Data > Queries & Connections.", vbExclamation
End Sub
' Call it like this:
Sub RunRefresh()
RefreshQueryByName "Sales Data"
End Sub
List All Power Query Names in the Workbook
Writes the name of every Power Query connection in the workbook to a new sheet. Run this first to discover the exact connection names before using the "Refresh by Name" macro β because names must match exactly, including case and spacing.
Sub ListAllQueryNames()
Dim conn As WorkbookConnection
Dim ws As Worksheet
Dim i As Integer
Set ws = ThisWorkbook.Sheets.Add
ws.Name = "Query List"
ws.Range("A1").Value = "Connection Name"
ws.Range("B1").Value = "Type"
ws.Range("A1:B1").Font.Bold = True
i = 2
For Each conn In ThisWorkbook.Connections
ws.Cells(i, 1).Value = conn.Name
ws.Cells(i, 2).Value = conn.Type
i = i + 1
Next conn
ws.Columns.AutoFit
MsgBox (i - 2) & " connection(s) listed on the 'Query List' sheet.", vbInformation
End Sub
Disable Background Refresh for All Queries
Sets all Power Query connections to foreground (synchronous) refresh mode. By default Excel refreshes queries in the background while you continue working β but this causes problems when a macro needs to use the data immediately after refreshing. Run this macro once to ensure all subsequent refreshes complete fully before Excel moves on to the next step.
Sub DisableBackgroundRefresh()
Dim conn As WorkbookConnection
For Each conn In ThisWorkbook.Connections
On Error Resume Next
conn.OLEDBConnection.BackgroundQuery = False
On Error GoTo 0
Next conn
MsgBox "Background refresh disabled for all connections.", vbInformation
End Sub
Refresh Queries Then Auto-Update Pivot Tables
A complete end-to-end refresh sequence: first refreshes all Power Query connections (waiting for each to finish), then refreshes all pivot tables across every worksheet. Assign this to a "Refresh All" button on your dashboard β one click updates everything in the correct order.
Sub RefreshQueriesThenPivots()
Dim conn As WorkbookConnection
Dim ws As Worksheet
Dim pt As PivotTable
Application.ScreenUpdating = False
' Step 1: Refresh all Power Query connections
For Each conn In ThisWorkbook.Connections
On Error Resume Next
conn.OLEDBConnection.BackgroundQuery = False
conn.Refresh
On Error GoTo 0
Next conn
' Step 2: Refresh all pivot tables across all sheets
For Each ws In ThisWorkbook.Worksheets
For Each pt In ws.PivotTables
pt.RefreshTable
Next pt
Next ws
Application.ScreenUpdating = True
MsgBox "All queries and pivot tables refreshed.", vbInformation
End Sub
How to Use ChatGPT to Write a VBA Macro
ChatGPT, Claude, and similar AI tools can write working VBA code from a plain English description β no programming knowledge required. The quality of the code depends almost entirely on how well you describe what you need. Vague prompts get vague code. Specific prompts with context about your data, sheet names, and exact goal get code you can paste and run.
Here's what a good prompt looks like:
How to Use Microsoft Copilot for VBA in Excel 365
Microsoft 365 Copilot can generate VBA macros from inside Excel when you have a Copilot licence. Unlike ChatGPT which gives you code to copy and paste, Copilot can insert the code directly into a module and sometimes run it for you. Here is how to use it effectively:
Step 1: Open your workbook and click the Copilot button in the ribbon (Home tab, far right). If you don't see it, your organisation may not have a Copilot licence.
Step 2: In the Copilot pane, type your request. Use the same specificity rules as ChatGPT β name your sheets, columns, and describe the exact behaviour you want.
Step 3: Copilot may offer to run the macro directly. Always choose "Explain" or "Preview" first on anything that modifies data β review what it will do before letting it run.
5 Things to Always Check in AI-Generated VBA Code
AI tools write surprisingly good VBA code, but they make specific types of mistakes consistently. Before running any AI-generated macro on real data, check for these five issues:
1. Hardcoded ranges instead of dynamic ranges. AI often writes Range("A1:A100") when your data might have 500 rows. Always check that loops use .End(xlDown).Row to find the last row dynamically.
2. No error handling. AI-generated code rarely includes On Error GoTo handlers. Add the error handling template from the previous section to any macro that modifies data.
3. ActiveSheet instead of named sheets. Code that references ActiveSheet will run on whatever sheet is active when the macro fires β which may not be what you intended. Replace with ThisWorkbook.Sheets("YourSheetName").
4. Missing Application.ScreenUpdating = False. AI code rarely optimises for speed. For any macro that loops through many cells, add Application.ScreenUpdating = False at the start and True at the end to make it run significantly faster.
5. Test on a copy first. Always paste AI-generated code into a copy of your workbook before running it on your real file. This is non-negotiable.
Use AI to Debug and Explain a Broken Macro
AI tools are just as useful for fixing broken code as they are for writing new code. When a macro throws an error or produces wrong results, you can paste the code plus the error message into ChatGPT and get a diagnosis immediately β often faster than searching forums.
Detect Whether a Workbook is on OneDrive or Local
One of the most common VBA problems with OneDrive is that ThisWorkbook.Path returns a long URL starting with https:// instead of a local file path like C:\Users\.... Many operations β SaveCopyAs, Shell commands, folder creation β fail when given a URL path. This function detects which type of path you have and returns the correct local path in either case.
Function GetLocalPath() As String
Dim filePath As String
filePath = ThisWorkbook.FullName
' Check if it's a OneDrive/SharePoint URL
If Left(filePath, 4) = "http" Then
Dim oneDrivePath As String
oneDrivePath = Environ("OneDrive") ' Personal OneDrive
If oneDrivePath = "" Then
oneDrivePath = Environ("OneDriveCommercial") ' Work/school OneDrive
End If
GetLocalPath = oneDrivePath
Else
GetLocalPath = ThisWorkbook.Path ' Already a local path
End If
End Function
' Test it:
Sub ShowLocalPath()
MsgBox "Local path: " & GetLocalPath(), vbInformation
End Sub
GetLocalPath() function to any module. Then anywhere you would normally use ThisWorkbook.Path, use GetLocalPath() instead. Example: backupPath = GetLocalPath() & "\Backup.xlsm". Works for both local files and OneDrive-synced files.Save a Backup Copy to OneDrive
Saves a timestamped backup of the current workbook directly to your local OneDrive sync folder. Because OneDrive automatically syncs the local folder to the cloud, the file appears in OneDrive online without needing URLs or web APIs. This is the most reliable way to save to OneDrive from VBA.
Sub SaveCopyToOneDrive()
Dim oneDrivePath As String
Dim savePath As String
' Get OneDrive local sync folder
oneDrivePath = Environ("OneDrive")
If oneDrivePath = "" Then oneDrivePath = Environ("OneDriveCommercial")
If oneDrivePath = "" Then
MsgBox "OneDrive folder not found on this computer.", vbExclamation
Exit Sub
End If
' Create Backups subfolder if it doesn't exist
If Dir(oneDrivePath & "\Backups", vbDirectory) = "" Then
MkDir oneDrivePath & "\Backups"
End If
savePath = oneDrivePath & "\Backups\" & _
Format(Now(), "yyyymmdd_hhmmss") & "_backup.xlsm"
ThisWorkbook.SaveCopyAs savePath
MsgBox "Backup saved to OneDrive:" & vbNewLine & savePath, vbInformation
End Sub
"\Backups\" to any subfolder name you prefer.Check if a File is Locked by Another User
When a file is on SharePoint or a shared network drive, another user may have it open and locked. Trying to open or write to a locked file causes a runtime error. This function checks whether a file is currently locked before attempting to open it β saving your macro from an unexpected crash.
Function IsFileLocked(filePath As String) As Boolean
Dim fileNum As Integer
fileNum = FreeFile
On Error Resume Next
Open filePath For Input Lock Read As #fileNum
If Err.Number <> 0 Then
IsFileLocked = True ' File is locked
Else
Close #fileNum
IsFileLocked = False
End If
On Error GoTo 0
End Function
' Example β check before opening:
Sub SafeOpenFile()
Dim path As String
path = "C:\Shared\Report.xlsx"
If IsFileLocked(path) Then
MsgBox "This file is currently open by another user." & vbNewLine & _
"Please try again in a few minutes.", vbExclamation
Else
Workbooks.Open path
End If
End Sub
https:// SharePoint URLs β those require SharePoint's own API to check lock status. For cloud URLs, use the GetLocalPath() function from the previous macro to get the local sync path first.Force Save When Using OneDrive (Disable AutoSave Conflict)
When a workbook is open from OneDrive, ThisWorkbook.Save triggers an AutoSave sync which can be slow, cause version conflicts, or fail entirely with a co-authoring error. This macro temporarily disables AutoSave, forces a clean local save, then restores AutoSave to its original state β giving you a fast, reliable save that doesn't depend on your internet connection.
Sub ForceSaveLocal()
Dim wasAutoSave As Boolean
' Remember current AutoSave state and turn it off
On Error Resume Next
wasAutoSave = ThisWorkbook.AutoSaveOn
ThisWorkbook.AutoSaveOn = False
On Error GoTo 0
' Save the workbook
ThisWorkbook.Save
' Restore AutoSave to its original state
On Error Resume Next
ThisWorkbook.AutoSaveOn = wasAutoSave
On Error GoTo 0
MsgBox "File saved successfully.", vbInformation
End Sub
ThisWorkbook.Save with a call to ForceSaveLocal in any macro that runs in a OneDrive or SharePoint environment. The On Error Resume Next around AutoSaveOn is intentional β older Excel versions (2016, 2019) don't support that property and would error without it.Frequently Asked Questions
These are some of the frequently asked questions that can help you to use these codes.
Why can't I undo after running a macro?
This is by design β VBA macros clear Excel's undo stack the moment they run. Once a macro executes any action that modifies data, all previous undo history is wiped and you cannot use Ctrl+Z to reverse the macro's changes.
The only safe way to protect yourself is to save a backup copy of your file before running any macro that modifies data. Many of the macros on this page include a save prompt for exactly this reason. You can also use the timestamped backup macro from the Workbook Management section to create an automatic backup before running anything destructive.
Why is my macro not running? I get a "Macro not found" or security error.
There are four common causes for a macro not running:
- Macros are disabled: Go to Developer β Macro Security β and set it to "Disable all macros with notification" or "Enable all macros". Excel blocks macros by default on files downloaded from the internet.
- File saved as .xlsx: Files saved as .xlsx cannot store or run macros. Save your file as
.xlsm(Excel Macro-Enabled Workbook) and try again. - Developer tab not enabled: Go to File β Options β Customize Ribbon β check the Developer box.
- Code pasted into the wrong place: The code must be in a Module (Insert β Module), not in a Sheet's code window or the ThisWorkbook module β unless the instructions specifically say otherwise.
Do these VBA codes work on Excel for Mac?
Most codes work on Mac. Excel for Mac supports VBA and the majority of codes on this page run without any changes. However, there are exceptions:
- Windows-only codes are clearly marked with a
warning. These include codes that use the
Shellcommand (Open Calculator, Search Google), Outlook automation (Send Email macros), and the Text to Speech feature. - Excel for the web does not support VBA at all. If you are using Excel in a browser (office.com or SharePoint), these macros will not run. Microsoft's equivalent for web-based Excel is Office Scripts.
If a code is not marked Windows-only, it should work on Excel for Mac 2016 or later.
I get a "Sub or Function not defined" error. What does it mean?
This error means VBA cannot find a function or Sub name that is referenced in your code. The most common causes are:
- Typo in a function name: VBA is case-insensitive but spelling must be exact. Check that every function name in the code matches exactly what is in the module.
- Missing library reference: Some codes use functions from external libraries. If a code references something like
SetFirstPriorityand it fails, your code may have been copied with a line break in the wrong place β look for lines ending in.Sor.SetFwhich indicate a broken line continuation. - Code pasted in two parts: When copying code from a webpage, sometimes a long line gets split mid-word. Check any line that looks like it ends abruptly mid-function-name.
- Custom function not in a Module: Custom worksheet functions like
=RemoveFirstC()and=NumberToWords()must be pasted into a Module, not a Sheet code window. Paste them via Insert β Module in the VB Editor.
How do I run a macro automatically when a file opens?
There are two ways to run a macro automatically on file open:
- Method 1 β Name your Sub Auto_Open: Any Sub named exactly
Auto_Openruns automatically when the workbook opens. This is the simplest method and works in all Excel versions. - Method 2 β Workbook_Open event: In the VB Editor, double-click "ThisWorkbook" in the Project Explorer, then select "Workbook" from the left dropdown and "Open" from the right dropdown. Paste your code inside the
Workbook_OpenSub that appears. This is the more reliable and professional method.
How do I use these macros in all my Excel workbooks, not just one file?
Save your most-used macros to the Personal Macro Workbook (PERSONAL.XLSB). This is a hidden workbook that Excel loads automatically every time it opens, making all macros inside it available in every file you work with β without copying the code into each workbook.
To access it: Record a macro (Developer β Record Macro) and set "Store macro in" to "Personal Macro Workbook". This creates the file. Then open the VB Editor (Alt+F11), expand PERSONAL.XLSB in the Project Explorer, insert a Module, and paste your codes there.
Read the full guide: Personal Macro Workbook β
The "Insert Multiple Rows" macro always inserts rows above β how do I insert below?
This is a known quirk of how Excel handles row insertion. Regardless of whether you use xlToDown or xlToUp, Excel always inserts rows above the selected row when you use Selection.Insert.
To insert rows below the current row instead, select the row below your target first, or use this modified approach:
- Select the row below where you want to insert, then run the macro β the new rows will appear above your selection, which is effectively below your original position.
- Alternatively, move
ActiveCell.Offset(1, 0).EntireRow.Selectbefore the insert loop to shift the selection down by one row first.
How do I copy data from one sheet to another with VBA?
This is the most commonly requested code in our comments. Here is a basic template that copies a row from one sheet to another based on a value in column A, then deletes the original:
Sub CopyRowToAnotherSheet()
Dim sourceSheet As Worksheet
Dim destSheet As Worksheet
Dim lastRow As Long
Dim i As Long
Dim matchValue As String
Set sourceSheet = ThisWorkbook.Sheets("Sheet1") ' Change to your source sheet
Set destSheet = ThisWorkbook.Sheets("Sheet2") ' Change to your destination sheet
matchValue = "Done" ' Change to your criteria value
lastRow = sourceSheet.Cells(sourceSheet.Rows.Count, "A").End(xlUp).Row
For i = lastRow To 2 Step -1 ' Loop bottom to top to avoid row-shift errors
If sourceSheet.Cells(i, 1).Value = matchValue Then
sourceSheet.Rows(i).Copy _
destSheet.Cells(destSheet.Rows.Count, 1).End(xlUp).Offset(1, 0)
sourceSheet.Rows(i).Delete
End If
Next i
MsgBox "Done! Matching rows moved.", vbInformation
End Sub
Can I use ChatGPT or AI to write custom VBA macros?
Yes β and it works very well when you give it enough detail. AI tools like ChatGPT and Claude can generate working VBA code from plain English descriptions. The key is being specific: include your sheet names, column letters, what you want to happen, and any conditions or edge cases.
A vague prompt like "write a macro to format my sheet" gives poor results. A specific prompt like "write a VBA macro that loops through column A from row 2 to the last row, and if the value in column C is blank, deletes that entire row" gets you working code immediately.
See our full guide in the AI + VBA section above, including 5 things to always check in AI-generated code before running it on your real data.
Hi Dear,
May I have your assistance for VBA code Tab Order, I have made Invoice, I would like to use Tab for certain cells to fillup, for example, the cells are C3,C7,C9,D9,F7,F9,F11 and so on.
Please, simple VBA code Tab Order, as simple as you can.
Many thanks,
Hi,
i have a query with regard macro.
Function timestamp(Reference As Range)
If Reference.Value “” Then
timestamp = Format(Now, “dd-mmm-yy hh:mm:ss”)
Else
Ok = “”
End If
End Function
this code show text format show date but i want date format please help sir.
Excuse me,
can you tell me what is the wrong in this code
Dim Name As String
Dim Barcode As Long
Dim vender As String
Name = Sheets(“Add”).Range(“c5”).Value
Barcode = Sheets(“Add”).Range(“c8”).Value
vender = Sheets(“Add”).Range(“f14”).Value
because this can’t run ( Barcode=sheets…………….)
The ” simbol you are using is incorrect.
Looks similar but not the same.
Any advice on how to automate a search on Excel for over 3000 words/phrases from 20 different categories in a cell and return the category that contains the phrase? I don’t know any macro coding but am exploring this as an option since the manual formula is longer than the maximum cell character limit.
Tried two subs – neither worked – at least not in 2016.
Hey Pwyller, which two?
Hi Everyone,
Thanks for gathering all Codes. It takes lot of work.
I want to write code for Adding Rows for below details.
A B C D E F
1 24
2 25
3 28
4 33
Add 2 rows between A2 & A3 and
Add 4 rows between A3 & A4.
Thanks in advance.
Hi Puneet,
I need your help, Actually I’m stuck with an error-> run-time error: ‘1004’, Method ‘Run’ of object ‘_Application’ failed and the highlighted line in {Application.Run Macro:=Range(“Datablock”)} where datablock is a named range which has already defined. It is very important to me. So, please Reply ASAP
Hi Everyone… i’m used report merging macro using text box and command button.
Private Sub CommandButton2_Click()
Dim fd As Object
Dim add As String
Dim wb As Workbook, wk As Workbook
Dim myfiles As String
Dim name As String
If TextBox1.Text = “” Then
MsgBox “Pls Select Path”, vbInformation
Else
Set fd = Application.FileDialog(msoFileDialogFilePicker)
myfiles = Dir(“” + TextBox1.Text + “*.xlsx”)
If myfiles = “” Then
MsgBox “This folder haven’t Excel files… Can’t do further Process..”, vbInformation
Else
ThisWorkbook.Activate
Worksheets.add
On Error GoTo errHandler:
ActiveSheet.name = “Summary”
Sheets(“Lables”).Activate
ActiveSheet.Range(“A1:AM1”).Select
Selection.Copy
ActiveSheet.Range(“A1”).Select
Sheets(“Summary”).Activate
ActiveSheet.Range(“A1”).Select
ActiveSheet.Paste
ActiveSheet.Range(“A2”).Select
Do While myfiles “”
Set wb = Workbooks.Open(“” + TextBox1.Text + “” & myfiles)
name = ActiveSheet.name
wb.Sheets(name).Activate
wb.Sheets(name).Range(“A2:AM2”).Select
wb.Sheets(name).Range(Selection, Selection.End(xlDown)).Select
Selection.Copy
myfiles = Dir
ThisWorkbook.Activate
ThisWorkbook.Sheets(“Summary”).Activate
If ActiveSheet.Range(“A2”) = “” Then
ActiveSheet.Paste
Application.CutCopyMode = False
ThisWorkbook.Sheets(“Summary”).Columns.AutoFit
ThisWorkbook.Sheets(“Summary”).Range(“A1”).Select
Selection.End(xlDown).Select
add = ActiveCell.Address
wb.Sheets(name).Activate
Application.CutCopyMode = False
ActiveWorkbook.Close
Else
ActiveCell.Offset(1, 0).Select
ActiveSheet.Paste
Application.CutCopyMode = False
ThisWorkbook.Sheets(“Summary”).Columns.AutoFit
ThisWorkbook.Sheets(“Summary”).Range(“A1”).Select
Selection.End(xlDown).Select
add = ActiveCell.Address
wb.Sheets(name).Activate
Application.CutCopyMode = False
ActiveWorkbook.Close
End If
Loop
ActiveSheet.Range(“A1”).Select
MsgBox “Process completed”, vbInformation
End If
End If
errHandler:
num = Sheets.Count
If num > 3 Then
MsgBox “Kindly delete previous data..!”, vbInformation
ThisWorkbook.Sheets(“Summary”).Activate
End If
End Sub
How to import a tif,pdf,img,etc… these types files by clicking button
Hi Puneet,
Thanks for gathering all this code! Amazing work! I’m looking forward to test some of it during my day to day excel work.
Keep it up! π
Hi Sir,
I have a query with regards to macros in excel, could I contact you via email?
WIth Regards,
Ankitha
i want to hyperlink my image with website url plz help me for hyperling my image! and i want to send it to outlook
Sub Send_email_fromexcel()
Dim edress As String
Dim subj As String
Dim message As String
Dim filename, fname2 As String
Dim outlookapp As Object
Dim outlookmailitem As Object
Dim myAttachments As Object
Dim path As String
Dim lastrow As Integer
Dim attachment As String
Dim x As Integer
x = 2
Set outlookapp = CreateObject(“Outlook.Application”)
Set outlookmailitem = outlookapp.createitem(0)
Set myAttachments = outlookmailitem.Attachments
path = “C:UsersUserDesktopstatements”
edress = Sheet1.Cells(x, 1)
subj = Sheet1.Cells(x, 2)
filename = Sheet1.Cells(x, 3)
fname2 = “Weddingplz-Safe-Gold.jpg”
attachment = path + filename
outlookmailitem.to = edress
outlookmailitem.cc = “”
outlookmailitem.bcc = “”
outlookmailitem.Subject = subj
outlookmailitem.Attachments.Add path & fname2, 1
outlookmailitem.htmlBody = “Thank you for your contract” _
& “nicely done this work” _
& “”
outlookmailitem.htmlBody = “” & outlookmailitem.htmlBody & “”
‘outlookmailitem.body = “Please find your statement attached” & vbCrLf & “Best Regards”
outlookmailitem.display
‘outlookmailitem.send
lastrow = lastrow + 1
edress = “”
x = x + 1
Set outlookapp = Nothing
Set outlookmailitem = Nothing
End Sub
hi, what is the vba code to highlight the entire row based on cell value?
Sub ColorRow()
Dim cel As Range
Dim rng As Range
Dim wrksht As Worksheet
Set wrksht = ThisWorkbook.Worksheets(“Sheet1”) ‘put your worksheet name in place of sheet1
Set rng = wrksht.Range(“A1:A10”) ‘Change “A1:A10” to your range
For Each cel In rng
If cel = “Whatever value” Then ‘insert your value in place of “Whatever Value”
cel.EntireRow.Interior.ColorIndex = 3 ‘colors row red
End If
Next cel
End Sub
Can you share a code which combines certain numbers (positive & negative) from a given table and calculates to a certain number (say ‘0’)?
Thank you for sharing this make internet better!!, good tips & tricks
Please I want you to help me
Thank you so much!
thanks a lot .
hi guys,
thanks for lot of codes posted, quite helpful,
please i need a code to extract a particular worksheet from multiple workbooks saved in a folder without opening the workbook, using the sheet name as a criteria to search
so much thank you
i need more helpful code for time function.
1.i need to perfom the procedure/action in specific duration (not to start or scheduling the action). For example playing the game only for 1 minute, if > 1 minute the game stop automatically.
2.If i have a cell with time format, how to execute the function? For example, i want to move the shape if the cell less or equal to “0:10:00” but if the cell contain over, lets say “0:15:00”, you can’t not activate the movement
Thanks
Hi puneet
Very useful blog
Pl suggest any online classes
As I am on maternity leave can give only around 1 hrs a dag.
Secondly no knowledge of programming..
Codes required for
Auto sorting
Removing duplicates
Subtotaling of auto sorted
Automatically adding the new name in the previously sorted data.
Creating a balance sheet from trial balance
Creating a customized bom…