🚀The world's best VBA AI has evolved. ExcelMaster is now an autonomous Agent.Read more →

The ExcelMaster.ai Blog

VBA Now, Date & Time in Excel — Read the Clock, and Why Date Is Also a Statement

VBA Now, Date & Time in Excel — Read the Clock, and Why Date Is Also a Statement

A VBA date is a Double — the whole-number part counts days since 1899-12-30 and the fraction is the time of day, so Now, Date and Time are three reads of the same clock. Now returns date plus time, Date returns today at midnight, Time returns the time only. The bug that breaks most code is comparing a stored Now value with Date and never matching, because Now carries a fractional time that the whole-number Date does not. Worse, Date and Time are also statements that reset the computer system clock. This guide shows what the Double really is, why the equality check fails, how to drop the time with Int or DateValue, and why Now is local time rather than UTC.

Henry
VBA DateAdd & DateDiff in Excel — Date Math Without the Month-Length Bug

VBA DateAdd & DateDiff in Excel — Date Math Without the Month-Length Bug

Because a VBA date is a Double, adding 1 moves one day and plain arithmetic is correct — for days. It breaks the moment you treat a month as 30 days or a year as 365, because months and leap years are not fixed lengths. DateAdd knows the calendar, so adding one month to 31 January returns 28 February rather than an impossible 31st. DateDiff counts the boundaries crossed, not the time elapsed, so the gap from 31 December to 1 January is one year even though a single day passed. DateSerial builds a date from year, month and day with no regional ambiguity and normalizes overflow, which gives the clean last-day-of-month idiom. This guide shows when plain plus is enough, the interval codes that trip people up, and why DateDiff is a boundary count.

Henry
VBA Weekday & DatePart in Excel — Extract Date Parts, and Why Monday Isn't 1

VBA Weekday & DatePart in Excel — Extract Date Parts, and Why Monday Isn't 1

Year, Month, Day, Hour, Minute and Second each pull one integer back out of a date — the Double you can already see into — and they are as simple as they look. Weekday is the one that bites — it returns 1 to 7, but the numbering depends on a second argument that defaults to Sunday equals 1, so in a plain call Monday is 2, not 1, and every weekend test built on a hardcoded number is quietly wrong. DatePart is the general extractor with the same interval codes as DateAdd, and it reaches parts that have no dedicated function such as the week number and the quarter, though its week rule is not ISO 8601 by default. WeekdayName and MonthName return names in the machine language, good for display but not for reading back. This guide shows how to extract every part and why Monday is not 1.

Henry
VBA FreeFile & the Open Statement in Excel — Get a File Number, Open a Text File (Not a Workbook)

VBA FreeFile & the Open Statement in Excel — Get a File Number, Open a Text File (Not a Workbook)

In built-in VBA a text file is reached through a numbered channel — you write Open path For Output As #n, and the number n is a handle you must take from FreeFile rather than pick by hand. Hardcode #1 and the moment two files are open you hit error 55 File already open; open For Output on a file that already holds data and it is truncated to empty; forget Close and the file stays locked until Excel quits. This guide shows why FreeFile hands you a channel number to catch in a variable, the difference between For Output, For Append and For Input, why the Open statement is not Workbooks.Open, and the cleanup pattern that always closes the channel.

Henry
VBA Print # vs Write # in Excel — Write a Text File or CSV (and Why Yours Has Quotes Around Everything)

VBA Print # vs Write # in Excel — Write a Text File or CSV (and Why Yours Has Quotes Around Everything)

Print # and Write # give opposite answers to what the bytes on disk should look like. Print # writes text exactly as it appears — no quotation marks, no commas, you build the layout — so it is right for a report or a hand-made CSV. Write # writes machine format — every string wrapped in quotation marks, commas between values, dates in hashes — designed to be read back by Input #, not by a human or Excel. This guide shows why Write # is the reason your CSV is full of quotes, why a comma in a Print # list inserts print zones instead of CSV commas, how For Output truncates while For Append adds, the decimal-comma locale trap, and why built-in writing is ANSI rather than UTF-8.

Henry
VBA Read Text File in Excel — Line Input vs Input #, and the EOF Loop That Doesn't Lose Rows

VBA Read Text File in Excel — Line Input vs Input #, and the EOF Loop That Doesn't Lose Rows

Reading a text file in VBA has three tools and picking the wrong one scrambles your data. Line Input # reads one raw line into a string and you split it yourself, which is predictable. Input # parses the delimited fields straight into variables — fast for a file that Write # produced, but it chokes on unquoted commas and stray quotation marks. Input(LOF(f), #f) slurps the whole file into one string. This guide shows the EOF loop that reads every row exactly once, why Input # is the twin of Write # and Line Input # the twin of Print #, how to avoid the off-by-one that raises error 62, and when a CSV is better opened as a workbook than parsed by hand.

Henry
VBA MkDir in Excel — Create a Folder, and Why It Can't Make a Nested Path

VBA MkDir in Excel — Create a Folder, and Why It Can't Make a Nested Path

The VBA MkDir statement creates exactly one folder level, not a whole path — MkDir on a path whose parent does not exist raises error 76, and MkDir on a folder that already exists raises error 75 instead of doing nothing. So the everyday task create this folder is really create every missing level, and only where it is absent. This guide shows why MkDir makes just one level, why FileSystemObject.CreateFolder does not recurse either, the existence-guarded loop that builds a full path safely, and why a bare folder name lands under CurDir instead of your workbook folder.

Henry
VBA RmDir in Excel — Delete a Folder, but Only If It's Empty

VBA RmDir in Excel — Delete a Folder, but Only If It's Empty

The VBA RmDir statement deletes a folder only when it is completely empty — point it at a folder that still contains files or subfolders and it raises error 75, the exact mirror image of Kill, which deletes any file with no mercy. So delete this folder is really empty it first, then remove it. This guide shows why RmDir refuses a non-empty folder, why it deletes folders but never files, how to empty a folder with Kill before RmDir, and when FileSystemObject.DeleteFolder wipes a whole tree in one call — with no Recycle Bin and no undo.

Henry
VBA CurDir & ChDir in Excel — Why a Relative Path Lands in the Wrong Folder

VBA CurDir & ChDir in Excel — Why a Relative Path Lands in the Wrong Folder

In VBA a relative path has no meaning until it is resolved against CurDir, the current working directory — and in Excel that directory is a roaming setting you do not control, not the folder your workbook is saved in. So MkDir Reports or Open data.csv can land somewhere different on every run, because a File Open dialog silently moves CurDir. This guide shows why CurDir is not ThisWorkbook.Path, why ChDir cannot change the drive without ChDrive, and the one habit that removes the whole class of wrong-folder bugs — anchor every path to ThisWorkbook.Path.

Henry
VBA Copy File in Excel — FileCopy, FileSystemObject.CopyFile, and Why It Cannot Copy an Open Workbook

VBA Copy File in Excel — FileCopy, FileSystemObject.CopyFile, and Why It Cannot Copy an Open Workbook

Copying a file in VBA is one line, but which line depends on whether the file is open. FileCopy is the built-in with no references to add, and it silently overwrites the destination, yet it cannot copy a file that is open and throws error 70 Permission denied on the one workbook you most want to back up. This guide draws the line between three copy tools for three situations — FileCopy for closed files on disk, FileSystemObject.CopyFile for wildcards and an explicit overwrite flag, and SaveCopyAs for the workbook that is open right now — and shows why the destination must be a full path including the file name, why the target folder must already exist, and how copy-then-delete becomes a move.

Henry
VBA Delete File in Excel — Kill, FileSystemObject.DeleteFile, and Why There Is No Undo

VBA Delete File in Excel — Kill, FileSystemObject.DeleteFile, and Why There Is No Undo

The VBA Kill statement deletes a file permanently — no Recycle Bin, no confirmation, no undo. That single fact is both the whole point and the whole danger, and every other rule about deleting files is a way of guarding that irreversible line. This guide shows why Kill errors instead of doing nothing when a file is missing or open, how a wildcard like Kill C colon backslash Temp backslash star dot tmp erases every match at once with no prompt, why Kill cannot remove a folder and how RmDir and DeleteFolder split that job, and when FileSystemObject.DeleteFile with its Force flag is the safer choice for read-only files.

Henry
VBA Rename File in Excel — The Name Statement That Also Moves Files (and Refuses to Overwrite)

VBA Rename File in Excel — The Name Statement That Also Moves Files (and Refuses to Overwrite)

The VBA Name statement renames a file, but it is really a rename-and-move statement — point the new path at a different folder and VBA moves the file there instead of renaming it in place. And unlike almost everything else on the disk, Name refuses to overwrite, raising error 58 when the target already exists, the exact opposite of FileCopy which overwrites silently. This guide shows why Name moves as well as renames, why it will not cross drives and how FileCopy plus Kill or FileSystemObject.MoveFile handles that case, and why you must guard the destination so an error on an existing file does not halt an unattended macro.

Henry
VBA Dir in Excel — Loop Through Files in a Folder, and the Stateful Iterator That Bites You

VBA Dir in Excel — Loop Through Files in a Folder, and the Stateful Iterator That Bites You

Dir looks like a function but behaves like an iterator with hidden memory — Dir(path) returns the first matching file name, then Dir() with no arguments returns the next, and an empty string when the folder is exhausted. The one rule that saves you is never call Dir again in the middle of a Dir loop, because a second Dir starts a new search and resets the first — the number-one cause of skipped files and infinite loops. Learn how to loop every .xlsx in a folder, why Dir returns only the name and not the path, why it cannot recurse into subfolders, and when to collect the names into an array before you touch the files.

Henry
VBA FileSystemObject in Excel — CreateObject vs Reference, Subfolders, and Why It Does Not Open Workbooks

VBA FileSystemObject in Excel — CreateObject vs Reference, Subfolders, and Why It Does Not Open Workbooks

The FileSystemObject turns the disk into an object model — folders and files you loop with For Each and read properties from, instead of Dir's single hidden cursor. The one decision that saves you is creating it with CreateObject and Scripting.FileSystemObject rather than Dim fso As New FileSystemObject, because late binding needs no reference and runs on any machine, while the early-bound version fails to compile the moment it lands on a PC without the Microsoft Scripting Runtime ticked. Learn when FSO beats Dir, how to recurse into subfolders its SubFolders collection makes trivial, how to read Size and DateLastModified, and why FSO opens text files but never opens an Excel workbook.

Henry
VBA Check If File Exists — Dir vs FileSystemObject.FileExists (and the Trap Inside a Dir Loop)

VBA Check If File Exists — Dir vs FileSystemObject.FileExists (and the Trap Inside a Dir Loop)

There are two right ways to test whether a file exists in VBA and one wrong reflex. The reflex is to just open it and trap the error, which is slow and hides real failures. The right answers are a one-line Dir test and the stateless, clearer fso.FileExists — and the rule that saves you is never use the Dir check inside a Dir loop, because Dir shares one hidden cursor and the existence test silently resets your file enumeration. Learn why FileExists is the safer default, how Dir mishandles a folder path or a trailing backslash, and why checking then opening still needs an error guard.

Henry
VBA Open Workbook in Excel — Workbooks.Open, Catching the Return Value, and Why It Is Not Workbook_Open

VBA Open Workbook in Excel — Workbooks.Open, Catching the Return Value, and Why It Is Not Workbook_Open

Workbooks.Open is a function that returns the workbook it just opened, so the one rule that saves you is Set wb = Workbooks.Open(path) — capture that return value and talk to wb, never to ActiveWorkbook, which changes the instant anything steals focus. Learn the difference between Workbooks.Open (a method you call) and Workbook_Open (an event that runs automatically), how to guard a missing path so you get a message instead of run-time error 1004, how to handle a file that is already open, and which parameters silently pop a dialog and hang an unattended macro.

Henry
VBA Save Workbook in Excel — Save vs SaveAs, the FileFormat Trap, and Why Your Macros Disappear

VBA Save Workbook in Excel — Save vs SaveAs, the FileFormat Trap, and Why Your Macros Disappear

Save overwrites the file you already have, in place and with no dialog. SaveAs writes a new file or a new type, and the FileFormat number is the trap — save a macro workbook as xlOpenXMLWorkbook (51, the xlsx format) and Excel silently drops every line of your VBA; you need xlOpenXMLWorkbookMacroEnabled (52) for xlsm. Learn when to use Save, SaveAs, and SaveCopyAs, why Save on a brand-new workbook pops the Save As dialog and hangs an unattended macro, how DisplayAlerts turns the overwrite prompt into a pre-approval, and why wb.Saved = True marks a book clean without writing anything.

Henry
VBA Close Workbook in Excel — SaveChanges, the Prompt That Hangs Your Macro, and Closing Without Saving

VBA Close Workbook in Excel — SaveChanges, the Prompt That Hangs Your Macro, and Closing Without Saving

wb.Close on a workbook with unsaved changes throws up the modal Do you want to save changes dialog, and in an unattended macro that dialog waits forever. You answer it in code with the SaveChanges argument — wb.Close SaveChanges:=False discards, SaveChanges:=True saves first, and omitting it gets the prompt. Learn why closing without the argument is the number-one reason a scheduled macro never finishes, why the object variable is dead the instant you close, how Close differs from Application.Quit, and why closing the last workbook can leave an invisible EXCEL.EXE running.

Henry
VBA Wait in Excel — Application.Wait, Why It Freezes Excel, and When to Use Sleep Instead

VBA Wait in Excel — Application.Wait, Why It Freezes Excel, and When to Use Sleep Instead

Application.Wait is an alarm clock, not a stopwatch. You hand it a wall-clock moment to wake up at, not a number of seconds to count down, which is why Application.Wait 5 does almost nothing and the correct line is Application.Wait Now + TimeValue("0:00:05"). It resolves only to whole seconds and it freezes Excel solid while it waits, so it cannot repaint the screen, update a status bar, or let the user cancel. Learn the alarm-clock model, the absolute-time argument that trips everyone, why sub-second pauses need Sleep, and why a pause where Excel must stay alive is a DoEvents loop instead.

Henry
VBA Sleep in Excel — The Windows API Call, the 64-bit PtrSafe Trap, and Wait vs Sleep

VBA Sleep in Excel — The Windows API Call, the 64-bit PtrSafe Trap, and Wait vs Sleep

Sleep is not a VBA keyword. It is a Windows kernel32 function you borrow with a Declare statement to pause your macro for a number of milliseconds, which is why it gives you the sub-second precision Application.Wait cannot. The catch is the declaration itself. Old copy-pasted Declare Sub Sleep lines throw a compile error on 64-bit Excel until you add the PtrSafe attribute inside a VBA7 conditional-compilation guard. Learn the borrowed-API model, the exact 64-bit fix, why milliseconds are not precise, and why Sleep still freezes Excel so a responsive pause is a DoEvents loop instead.

Henry
VBA Timer in Excel — Measure How Long Your Macro Takes (and Why It Is Not a Scheduler)

VBA Timer in Excel — Measure How Long Your Macro Takes (and Why It Is Not a Scheduler)

The VBA Timer function is a stopwatch, not a countdown timer. Despite the name it never makes anything happen after N seconds and it never pauses your code. It simply returns the number of seconds elapsed since midnight, and you read it twice to measure how long a block of code took. That makes it the tool that proves ScreenUpdating = False actually made your macro faster, instead of guessing. Learn the stopwatch model, why people searching for a timer usually want Application.OnTime instead, the midnight-rollover bug that produces negative elapsed times, and its hundredth-of-a-second resolution.

Henry
VBA DoEvents in Excel — Stop Excel Going Not Responding (and Why It Lets Your Macro Run Twice)

VBA DoEvents in Excel — Stop Excel Going Not Responding (and Why It Lets Your Macro Run Twice)

DoEvents pauses your macro for an instant and lets Excel process the clicks, keystrokes, and repaints that piled up while your code was running, which is what stops the window greying out into Not Responding and what makes a working cancel button possible. But the same yield that keeps Excel alive also hands control back to the user mid-macro, so they can click the same button again and start a second copy of your macro inside the first. That re-entrancy, not performance, is the real hazard. Learn where to place DoEvents, how to guard against re-entrancy with a running flag, why you must throttle it, and why it is not multithreading.

Henry
VBA StatusBar in Excel — Show Macro Progress Without a UserForm (and the Message That Gets Stuck Forever)

VBA StatusBar in Excel — Show Macro Progress Without a UserForm (and the Message That Gets Stuck Forever)

Application.StatusBar lets you write your own text into the bar along the bottom of the Excel window, which is the lightest way to show a running macro's progress with no UserForm and no flicker. The one line everyone forgets is the reset. Whatever text you last wrote stays pinned there after the macro ends, because Excel does not take the bar back until you set Application.StatusBar equals False. And it will not visibly update inside a tight loop unless Excel gets a moment to repaint, which is where DoEvents comes in. Learn the write-and-reset pattern, why False beats an empty string, the progress-percent idiom, and when a real progress bar is worth the extra work.

Henry
VBA DisplayAlerts in Excel — Suppress Confirmation Prompts for Unattended Macros (and Why It Auto-Confirms the Dangerous Ones)

VBA DisplayAlerts in Excel — Suppress Confirmation Prompts for Unattended Macros (and Why It Auto-Confirms the Dangerous Ones)

Application.DisplayAlerts equals False tells Excel to stop showing its confirmation and warning dialogs while your macro runs, so an unattended macro does not stall waiting for someone to click OK. But it does not silence the warning so much as answer it for you with Excel's default response, and for prompts like delete this sheet or overwrite this file the default is go ahead. It resets to True on its own when the macro ends, so the real trap is not leaving it off forever but suppressing a warning that was protecting you. Learn where it helps, the narrow-window rule, why it is not the same as error handling, and how it pairs with ScreenUpdating and Calculation.

Henry
VBA ScreenUpdating in Excel — Stop the Flicker and Speed Up Macros (and Why It Won't Fix a Slow One)

VBA ScreenUpdating in Excel — Stop the Flicker and Speed Up Macros (and Why It Won't Fix a Slow One)

Application.ScreenUpdating equals False tells Excel to stop repainting the screen while your macro runs and redraw once at the end, which removes the flicker and gives a modest speed-up. But it only helps when your code writes, selects, or scrolls — bolt it onto a calculation-bound macro and you gain nothing. The rule that saves you is that a crash can leave the screen frozen and gray, so you restore it in an error handler, never by trusting it to reset itself. Learn where it helps, where it does not, the nested-restore flicker trap, and the CleanExit pattern that pairs it with Calculation and EnableEvents.

Henry
VBA Calculation in Excel — Set Calculation to Manual for Speed (and the Silent Trap of Leaving It Off)

VBA Calculation in Excel — Set Calculation to Manual for Speed (and the Silent Trap of Leaving It Off)

Application.Calculation equals xlCalculationManual tells Excel to stop recalculating after every write and defer it to one pass, which is the real speed-up on formula-heavy workbooks. But it is the most dangerous switch in VBA because its failure is silent — leave it on Manual and formulas stop updating with no visual cue, so totals go stale and nobody sees it. The rule that saves you is to save the calculation state, force a recalc with Application.Calculate when a later step needs a result, and restore the saved state in an error handler rather than hardcoding Automatic. Learn the manual mode gotchas, the error 1004 when no workbook is open, and the CleanExit pattern.

Henry
VBA EnableEvents in Excel — Stop Your Macro Triggering Its Own Events (and Why a Crash Leaves Them Dead)

VBA EnableEvents in Excel — Stop Your Macro Triggering Its Own Events (and Why a Crash Leaves Them Dead)

Application.EnableEvents equals False stops your macro's writes from triggering event handlers like Worksheet_Change, which is what breaks the infinite loop where a handler edits a cell and re-fires itself. It is a correctness switch, not a speed switch. The rule that saves you is that EnableEvents is an application-level property that does not reset on its own, so a crash with it left False leaves every event across every open workbook dead until Excel restarts — which is why users report that their buttons stopped working. Learn the recursive Worksheet_Change fix, the CleanExit restore, and why this switch matters even more than the others.

Henry
VBA SpecialCells in Excel — Select Blanks, Visible Cells & Constants (and Why It Throws When It Finds None)

VBA SpecialCells in Excel — Select Blanks, Visible Cells & Constants (and Why It Throws When It Finds None)

SpecialCells lets Excel pick the cells for you by type instead of by address — all blanks, all visible rows, all formulas, all constants. It is the code twin of Go To Special. The one rule that saves you is that SpecialCells raises error 1004 when it finds nothing at all, so a bare call is a time bomb; the mature form is always On Error Resume Next plus If Not result Is Nothing. Learn the cell types that matter, the fill-blanks and copy-visible-rows patterns, and why the result is a multi-area reference.

Henry
VBA Union in Excel — Combine Non-Adjacent Ranges into One Reference (and Why It Doesn't Deduplicate)

VBA Union in Excel — Combine Non-Adjacent Ranges into One Reference (and Why It Doesn't Deduplicate)

Union glues scattered rectangles into a single reference so you can color, clear, or copy several non-adjacent blocks in one operation — the code version of Ctrl-clicking multiple areas. The rule that trips everyone is that Union concatenates, it does not deduplicate; overlapping cells are counted twice, so .Count lies and Union is a batch list, not a set union. Learn the accumulate pattern that avoids the Union of Nothing error, why it is one operation per reference instead of a per-cell loop, and how Union differs from Intersect.

Henry
VBA Intersect in Excel — Find Where Two Ranges Overlap (and the Worksheet_Change Guard Everyone Uses)

VBA Intersect in Excel — Find Where Two Ranges Overlap (and the Worksheet_Change Guard Everyone Uses)

Intersect returns only the cells two ranges share, and returns Nothing when they do not touch — and that Nothing is the whole point. Its number-one use is the Worksheet_Change guard, If Not Intersect(Target, Range) Is Nothing, which stops an event from firing on every edit on the sheet. The rule that saves you is that no overlap returns Nothing, so any property access without an Is Nothing check crashes with error 91. Learn the full event guard with EnableEvents, how to restrict a macro to a target area, and how Intersect differs from Union.

Henry
VBA Cells vs Range in Excel — Reference Cells by Number (and Why Cells(1, 2) Is B1, Not A2)

VBA Cells vs Range in Excel — Reference Cells by Number (and Why Cells(1, 2) Is B1, Not A2)

Cells is Range addressed by number. Range(A1) points at a cell with a string in the order your eye reads it, column letter then row; Cells(row, column) points at one cell with two integers in the order Excel stores it, row down first then column across. That is why Cells(1, 2) is B1, not A2 — and why Cells, whose coordinates you can compute, is the reference built for loops. Learn when to use Cells versus Range, how to build a block from computed corners with Range(Cells, Cells), why a bare Cells means the whole sheet, and why you should qualify Cells with a worksheet.

Henry
VBA Resize in Excel — Reshape a Range from Its Anchor (and Why It's a Count, Not a Delta)

VBA Resize in Excel — Reshape a Range from Its Anchor (and Why It's a Count, Not a Delta)

Resize pins the top-left anchor of a range and redraws the rectangle to a new size. It does not move the reference the way Offset does, and it does not select anything — it returns a new range starting at the same corner. The rule that trips everyone is that Resize(rows, columns) is an absolute one-based count of the final size, not a delta to add, so Range(A1).Resize(5, 3) is A1:C5 and Resize(0) throws error 1004. Learn how to omit an argument to leave a dimension alone, why the anchor is always the top-left, and the two patterns that pay off — dropping a header with Offset plus Resize, and writing an array back to a block that fits it.

Henry
VBA CurrentRegion in Excel — Grab the Whole Data Block in One Line (and What a Blank Row Does to It)

VBA CurrentRegion in Excel — Grab the Whole Data Block in One Line (and What a Blank Row Does to It)

CurrentRegion is the contiguous block of cells around a cell. Excel starts at your cell and expands outward until it hits a fully blank row and a fully blank column, returning the smallest rectangle that encloses that unbroken island — exactly what Ctrl+Shift+asterisk selects. You do not compute the edges; Excel finds them. The trap is that a single fully blank row or column is a wall that silently splits the block, so you get half your data with no error. Learn why CurrentRegion includes the header and how to drop it with Offset and Resize, how it differs from UsedRange and from End(xlUp), and when to use a real Table instead.

Henry
VBA Borders in Excel — Draw Cell Borders in Code (and Why the Whole Block Got Boxed)

VBA Borders in Excel — Draw Cell Borders in Code (and Why the Whole Block Got Boxed)

A border in Excel VBA is a property of an edge, not a switch on the cell. A range has eight addressable borders — four outer edges, two sets of interior gridlines, and two diagonals — and the bare Range.Borders collection means all of them at once. That is why Range.Borders.LineStyle = xlContinuous boxes every single cell instead of drawing one outline. Learn when to use BorderAround for just the frame, how LineStyle, Weight and Color combine, how to set one edge with xlEdgeBottom, and how to clear borders with xlLineStyleNone.

Henry
VBA Merge Cells in Excel — Merge and Unmerge in Code (and Why You Usually Shouldn't)

VBA Merge Cells in Excel — Merge and Unmerge in Code (and Why You Usually Shouldn't)

Merging cells in Excel VBA is not formatting — it is a structural change to the grid. Range(A1:C1).Merge fuses three cells into one that spans three columns, and only the top-left value survives while the others are erased. That is why merged cells silently break sorting, Range math, column inserts and loops. Learn Merge, UnMerge, MergeCells and MergeArea, why the pros reach for Center Across Selection instead, and how to find and clean up merged cells safely in code.

Henry
VBA Column Width & Row Height in Excel — Resize and AutoFit in Code (and the Units That Trip You Up)

VBA Column Width & Row Height in Excel — Resize and AutoFit in Code (and the Units That Trip You Up)

Sizing cells in Excel VBA works on the whole column or row, and the two dimensions use different units — ColumnWidth is measured in characters of the Normal font, RowHeight is measured in points. That mismatch is why a width of 10 and a height of 10 look nothing alike. AutoFit is the other trap. It only runs on an entire column or row, and it measures displayed text, so it silently ignores merged cells. Learn ColumnWidth versus the read-only Width, RowHeight and wrap text, EntireColumn.AutoFit, and why setting width to zero is the wrong way to hide a column.

Henry
VBA Font in Excel — Set Color, Bold and Size in Code (and the ColorIndex Trap)

VBA Font in Excel — Set Color, Bold and Size in Code (and the ColorIndex Trap)

The Font object is the text layer of a cell in Excel VBA — color, bold, italic, size and name, none of which touch the value underneath. The catch is color. There are three ways to set it and they use different number spaces. Range.Font.Color takes a 24-bit RGB number, Range.Font.ColorIndex takes a 1 to 56 palette index, and the two are not interchangeable. Learn which one to use, how to bold or resize part of a cell with Characters, why value-based coloring belongs to Conditional Formatting, and how to read a font color back without getting the wrong number.

Henry
VBA Cell Color in Excel — Set the Background Fill in Code (and Why Color Is Not Data)

VBA Cell Color in Excel — Set the Background Fill in Code (and Why Color Is Not Data)

Range.Interior is the fill layer of a cell in Excel VBA — the paint behind the text. Set it with Interior.Color and RGB, clear it with Interior.ColorIndex set to xlNone, and know that a white fill is not the same as no fill. The deeper point is that a colored cell carries no data. SUM and SUMIF ignore it, so if you are using color to categorize you are hiding information where formulas cannot read it. Learn the color properties, how to highlight by condition without a loop that goes stale, and how to fill many ranges fast.

Henry
VBA NumberFormat in Excel — Change How a Number Displays Without Changing Its Value

VBA NumberFormat in Excel — Change How a Number Displays Without Changing Its Value

Range.NumberFormat is the display layer of a cell in Excel VBA. It changes how a stored number reads on screen and never changes the number itself, so formatting a cell to show 5 while it holds 5.4999 is not rounding and the sum still uses 5.4999. This is where appearance versus value actually bites, because a date is really a serial number wearing a costume. Learn the format code language, how NumberFormat differs from the Format function, the locale trap with NumberFormatLocal, and when you need Round instead.

Henry
VBA WorksheetFunction in Excel — Call Excel's Own Functions from Code (and the Two Ways They Fail)

VBA WorksheetFunction in Excel — Call Excel's Own Functions from Code (and the Two Ways They Fail)

Application.WorksheetFunction lets VBA borrow Excel's 450-plus built-in functions instead of rewriting SUM, VLOOKUP or COUNTIF as a loop. The catch is that there are two ways to call them and they fail differently. WorksheetFunction.X raises a run-time error when there is no match, while Application.X returns an error value you test with IsError. Learn which call style to use, why the result must be a Variant, which functions you should not call this way, and when to pass a whole range instead of looping cell by cell.

Henry
VBA Remove Duplicates in Excel — Dedupe in One Line (and Why It Deletes With No Undo)

VBA Remove Duplicates in Excel — Dedupe in One Line (and Why It Deletes With No Undo)

Range.RemoveDuplicates is Excel's Remove Duplicates button in a single line of code, but it is destructive in ways a loop is not. It deletes rows in place, keeps the first occurrence, and cannot be undone after a macro runs. The argument that trips everyone is Columns, whose numbers are offsets inside the range, not sheet column letters. Learn the range-offset trap, why Header xlYes matters, how to keep the last row instead of the first, and when to reach for Advanced Filter or a Dictionary instead.

Henry
VBA Advanced Filter in Excel — Extract Unique Values and Filter to a New Range (Without a Loop)

VBA Advanced Filter in Excel — Extract Unique Values and Filter to a New Range (Without a Loop)

Range.AdvancedFilter is the one filter that outputs data instead of a view. It can pull a unique list or a criteria-matched set of rows to another location in a single call, without a loop and without deleting anything. The part that feels alien is that its WHERE clause lives in cells, a criteria range whose header must match the data exactly. Learn xlFilterInPlace versus xlFilterCopy, how the criteria range works, how Unique True dedupes non-destructively, the header-match trap that returns empty output, and how it differs from AutoFilter and Remove Duplicates.

Henry
VBA Find in Excel — Search Cells the Right Way (It Returns a Range, Not a Position)

VBA Find in Excel — Search Cells the Right Way (It Returns a Range, Not a Position)

The VBA Range.Find method is Excel's Ctrl+F for code, and it trips people up because it returns a Range object (or Nothing when there is no match) instead of a number. Learn the one check that stops the error-91 crash, the sticky-arguments trap that makes Find behave differently every run, how LookAt xlWhole versus xlPart decides whole-cell versus contains, and how to loop FindNext to get every match without an infinite loop.

Henry
VBA AutoFilter in Excel — Filter Rows in Code (and Why Hidden Isn't Deleted)

VBA AutoFilter in Excel — Filter Rows in Code (and Why Hidden Isn't Deleted)

The VBA AutoFilter method filters a table in code, but the rows it hides are still there — they still count in SUM, still copy, and still sit in your range. Learn the mental model that prevents the classic bugs, why you must go through SpecialCells xlCellTypeVisible to touch only visible rows, how criteria and operators work, the toggle trap that turns your filter off on the second run, and the fast filter-then-delete pattern for bulk row removal.

Henry
VBA Sort in Excel — Range.Sort vs the Sort Object (and How to Get the Original Order Back)

VBA Sort in Excel — Range.Sort vs the Sort Object (and How to Get the Original Order Back)

Sorting in VBA is a permanent reorder with no Ctrl+Z, so the first rule is to protect the original order before you touch it. Learn the mental model that separates a view from a mutation, why Header xlYes matters or your titles end up in the data, the difference between the quick Range.Sort and the unlimited Sort object, the SortFields.Clear trap that inherits old sort keys, and why numbers stored as text sort in the wrong order.

Henry
VBA Delete Rows in Excel — Delete Rows, Blank Rows and Rows by Condition (Loop Backwards!)

VBA Delete Rows in Excel — Delete Rows, Blank Rows and Rows by Condition (Loop Backwards!)

Deleting a row in VBA is a structural edit, not a clear — every row below slides up to fill the gap, which is why a forward loop skips rows. Learn the one rule that fixes it (loop bottom to top, or delete in a single Union), how EntireRow.Delete differs from clearing a cell, the fast way to strip blank rows, and how to delete rows by condition without corrupting your data or reference formulas.

Henry
VBA Insert Rows and Columns in Excel — Shift the Grid the Right Way (and Insert in a Loop Without Chaos)

VBA Insert Rows and Columns in Excel — Shift the Grid the Right Way (and Insert in a Loop Without Chaos)

Inserting is deleting's mirror — it pushes existing rows down (or columns right) to make room, so the same shifting that breaks a delete loop breaks an insert loop too. Learn EntireRow.Insert versus a partial range with the Shift argument, why CopyOrigin decides which neighbour's formatting the new row inherits, the safe direction to insert inside a loop, and the one-call way to add many rows at once.

Henry
VBA Hide Columns and Rows in Excel — Hidden Isn't Deleted (and Why Your Totals Don't Change)

VBA Hide Columns and Rows in Excel — Hidden Isn't Deleted (and Why Your Totals Don't Change)

Hiding a column in VBA is not deleting it and not filtering it — the data is still there, still in every SUM, still copied by a range copy, just given zero display width. Learn why .Hidden lives on EntireColumn and EntireRow, why hidden cells still count in formulas, the unhide-everything line that rescues a stuck sheet, and how manually hidden rows differ from AutoFilter-hidden rows when you loop.

Henry
VBA Worksheet_BeforeDoubleClick in Excel — Turn a Double-Click Into an Action (and Suppress Edit Mode)

VBA Worksheet_BeforeDoubleClick in Excel — Turn a Double-Click Into an Action (and Suppress Edit Mode)

Worksheet_BeforeDoubleClick is the event Excel fires the instant you double-click a cell, before it enters edit mode, and it hands you the Target cell plus a Cancel flag. Set Cancel to True to suppress edit mode and run your own action instead — toggle a checkmark, mark a row done, or drill down to detail. Learn how to scope it to one column with Intersect, why forgetting Cancel drops the cell into edit mode, and where the code must live.

Henry
VBA Worksheet_BeforeRightClick in Excel — Replace the Right-Click Menu (and Why Disabling It Isn't Security)

VBA Worksheet_BeforeRightClick in Excel — Replace the Right-Click Menu (and Why Disabling It Isn't Security)

Worksheet_BeforeRightClick is the event Excel fires the instant you right-click a cell, before the context menu appears, and it hands you the Target cell plus a Cancel flag. Set Cancel to True to suppress the built-in menu and run your own action or show a custom menu instead. Learn how to scope it with Intersect so you don't cripple Copy and Paste, why disabling right-click is UX rather than protection, and where the code must live.

Henry
VBA Workbook_BeforePrint in Excel — Block a Print, Stamp a Header, and the Print-Preview Gotcha

VBA Workbook_BeforePrint in Excel — Block a Print, Stamp a Header, and the Print-Preview Gotcha

Workbook_BeforePrint is the event Excel fires before anything in the workbook is printed, and it hands you a Cancel flag. Set Cancel to True and the print is blocked — validate before printing, or stop a draft going out. Learn why the event fires for Print Preview too (so heavy work makes preview crawl), why it runs once for the whole workbook rather than per sheet, why a silent Cancel is a bug, and where the code must live.

Henry
VBA Worksheet_Activate and Deactivate in Excel — Run Code When You Switch Sheets (and Why You Can't Cancel a Leave)

VBA Worksheet_Activate and Deactivate in Excel — Run Code When You Switch Sheets (and Why You Can't Cancel a Leave)

Worksheet_Activate fires when a sheet becomes the active one and Worksheet_Deactivate fires just as you leave it — the arrival and departure events for a sheet. The catch that defines them — unlike BeforeClose and BeforeSave, neither gives you a Cancel, so you can watch a sheet switch but you can't block it. Learn the refresh-on-view pattern, the bounce-back workaround, and sheet-level versus workbook-level handlers.

Henry
VBA Class Module in Excel — Build Your Own Object (Blueprint vs Instance, and the As New Trap)

VBA Class Module in Excel — Build Your Own Object (Blueprint vs Instance, and the As New Trap)

A VBA class module lets you define your own object type — a blueprint that bundles data and behaviour — then stamp out independent instances with New. The catch that trips everyone is that objects are reference types, so Set b = a makes both names point at the same instance, and Dim x As New hides a lazy-instantiation trap. Learn how the module name becomes the type name, when a class beats a Type, and how to avoid the classic New pitfalls.

Henry
VBA Type in Excel — Group Related Fields Into One Variable (User-Defined Types vs a Class)

VBA Type in Excel — Group Related Fields Into One Variable (User-Defined Types vs a Class)

A VBA Type — a user-defined type declared with Type ... End Type — bundles several related fields into one variable, so Name, Age and Salary travel together instead of as three parallel arrays. It is a value type, which means assigning one Type variable to another copies every field, unlike objects, which share. Learn where the declaration must live, why copy-not-share matters, and the exact point where you should reach for a class module instead.

Henry
VBA Property in Excel — Get, Let and Set (Controlled Access to a Class's Fields)

VBA Property in Excel — Get, Let and Set (Controlled Access to a Class's Fields)

Property Get, Let and Set turn a class field into a gate — a small procedure that runs your code whenever the outside reads or writes it, so you can validate input, compute values on the fly, or make a field read-only. The distinction that trips everyone is Let versus Set — Let assigns a value, Set assigns an object — and using the wrong one is a compile or run-time error. Learn the backing-field pattern, when a plain Public variable is the honest choice, and how to build a read-only property.

Henry
VBA ActiveCell in Excel — The One Cell With the Cursor (ActiveCell vs Selection, and When It Breaks)

VBA ActiveCell in Excel — The One Cell With the Cursor (ActiveCell vs Selection, and When It Breaks)

ActiveCell is a live pointer to the one cell that has the cursor right now — always exactly one cell, on the active sheet, sitting inside the current Selection. Learn how it differs from Selection, how to read and write it with .Value and .Offset, and the number-one reason it breaks — it follows whatever sheet and cursor the user left behind, so it is the wrong tool for code that is not about where the user is.

Henry
VBA Selection in Excel — Work With What's Highlighted (and Why It Isn't Always a Range)

VBA Selection in Excel — Work With What's Highlighted (and Why It Isn't Always a Range)

Selection is a live pointer to whatever is highlighted right now — usually a range of cells, but it can also be a chart, a shape, or nothing at all. That is why code that assumes Selection is a range crashes the moment a chart is selected. Learn how to loop the selected cells, handle multi-area selections with .Areas, guard with TypeName, and when to skip Selection entirely and name your range.

Henry
VBA Select vs Activate in Excel — Break the Macro Recorder's .Select Habit

VBA Select vs Activate in Excel — Break the Macro Recorder's .Select Habit

The macro recorder writes what your mouse does — Select a sheet, Select a cell, act on the Selection — because that is how a person works, not how code should. Learn the real difference between Select (highlight one or many cells) and Activate (set the one active cell), why almost every .Select is a slow, fragile detour you can delete, the rare times you genuinely need to select, and how to refactor recorder code to act on qualified range references directly.

Henry
VBA Worksheet_Change in Excel — Run Code When a Cell Is Edited (and the Infinite Loop to Avoid)

VBA Worksheet_Change in Excel — Run Code When a Cell Is Edited (and the Infinite Loop to Avoid)

Worksheet_Change is the event Excel fires every time a user edits a cell on the sheet, handing you the changed cell as Target. The trap that catches everyone — your handler writes a cell, that write fires the event again, and Excel loops forever. Learn the Application.EnableEvents fix, how to scope it with Intersect, why it ignores formula recalcs, and where the code must live.

Henry
VBA Worksheet_SelectionChange in Excel — Run Code When the Cursor Moves (Highlight the Active Row Without Lag)

VBA Worksheet_SelectionChange in Excel — Run Code When the Cursor Moves (Highlight the Active Row Without Lag)

Worksheet_SelectionChange is the event Excel fires every time the cursor moves — a click, an arrow key, an Enter. It hands you the new selection as Target, which makes cursor-following tricks like highlighting the active row possible. But it fires constantly, so heavy code makes the whole sheet lag. Learn the highlight-active-row pattern done right, why it can loop, and how to keep it featherlight.

Henry
VBA Collection in Excel — The Ordered, Growable List (and Why It Isn't a Dictionary)

VBA Collection in Excel — The Ordered, Growable List (and Why It Isn't a Dictionary)

A VBA Collection is an ordered list that grows as you Add to it — no ReDim, no size guessing. But it has four sharp edges beginners hit every time — it is 1-based not 0-based, you cannot overwrite an item (only Add/Remove), duplicate keys throw error 457, and it has no built-in Exists check. Learn when a Collection beats an Array or a Dictionary, and when it quietly costs you.

Henry