How to Remove Blank Rows in Excel Safely
Remove only rows that meet a precise blank definition. Physically delete truly empty worksheet rows, create a non-destructive Microsoft 365 output that excludes formula-empty rows, or load a refreshable Power Query table without all-null records.
I have worksheet Orders with headers in row 1 and data in A1:D10. Row 2 O-101 | Acme | 4 | Open Row 3 [truly empty across A:D] Row 4 O-102 | Beacon | 0 | Closed Row 5 O-103 | [truly empty B5] | 2 | Open Row 6 [truly empty across A:D] Row 7 O-104 | Delta | [truly empty C7] | Pending Row 8 [truly empty A8:C8] | Note only in D8 Row 9 O-105 | Echo | 7 | Closed Row 10 [truly empty across A:D] Rows 3, 6, and 10 contain no values or formulas in A:D. Rows 5, 7, and 8 are partial records and must remain. Numeric 0 in C4 must remain. Give a safe helper-column/filter method that physically deletes only rows 3, 6, and 10. Put Delete row? in E1 and use exactly =COUNTA(A2:D2)=0 in E2 filled through E10. First clear existing filters and unhide rows 2:10. Apply the filter to A1:E10, filter E to TRUE, verify the results, select only visible worksheet row headers 3, 6, and 10 (not row 1), and choose Delete Sheet Rows/Delete Rows. Never delete cells or shift cells up. Clear the filter and optionally remove E afterward. Expected survivors in original order: O-101 Acme 4 Open; O-102 Beacon 0 Closed; O-103 [blank] 2 Open; O-104 Delta [blank] Pending; [blank, blank, blank, Note only]; O-105 Echo 7 Closed. Explain that COUNTA counts formulas returning "" as nonblank, so this test is specifically for truly empty cells. This deletion is destructive: work on a copy or confirm filtered rows first. Include Windows/Mac menu wording differences.
Use when rows are physically empty across the complete data width and should be deleted.
I use Microsoft 365 Excel. Source sheet Import has headers in A1:D1 and data A2:D10. Row 2 T-201 | Ana | 3 | Ready Row 3 [truly empty across A:D] Row 4 T-202 | [truly empty B4] | 0 | Hold Row 5 every A:D cell contains ="" and displays blank Row 6 T-203 | Bo | [truly empty C6:D6] Row 7 [truly empty A7:C7] | Comment in D7 Row 8 T-204 | Cy | 5 | Done Row 9 every A:D cell contains ="" and displays blank Row 10 T-205 | Di | 2 | [truly empty D10] On separate sheet Clean, create a non-destructive output that includes headers; excludes rows 3, 5, and 9; retains partial rows 4, 6, 7, 10; retains zero in C4; preserves order; and updates without changing Import. Use exactly this in Clean!A1: =LET(data,Import!A2:D10,header,Import!A1:D1,keep,BYROW(data,LAMBDA(r,SUM(--(LEN(r)>0))>0)),IF(SUM(--keep)=0,header,VSTACK(header,FILTER(data,keep)))) Expected output: header plus T-201 Ana 3 Ready; T-202 [blank] 0 Hold; T-203 Bo [blank, blank]; [blank, blank, blank, Comment]; T-204 Cy 5 Done; T-205 Di 2 [blank]. Explain why LEN treats true blanks and formula "" results as zero-length while LEN(0)>0. Whitespace-only values count as populated and remain. Enter the formula in an empty area with room to spill. Require a current Microsoft 365 build or Excel 2024 with LET, FILTER, BYROW, VSTACK, and dynamic arrays on Windows/Mac; older builds without these functions cannot use it as written.
Use a clean spill when blank-looking formula rows should disappear but the source must remain untouched.
I have Excel Table tblTransactions on sheet Source with six rows: 1 TX-301 | Sales | 125.50 | Posted 2 [null] | [null] | [null] | [null] 3 TX-302 | Refunds | 0 | Review 4 TX-303 | [null] | 42.00 | [null] 5 [null] | [null] | [null] | Imported note 6 [null] | [null] | [null] | [null] Rows 2 and 6 are all null. Rows 3, 4, and 5 are partial or contain zero and must remain. There are no empty strings or whitespace-only values; the rule is specifically all four fields null. Starting with Data → From Table/Range, create a refreshable Power Query result that removes only all-null rows, preserves source order, and loads to a separate new-worksheet table without changing tblTransactions. After the source/type step, use exactly: #"Removed Fully Null Rows" = Table.SelectRows(#"Changed Type", each List.NonNullCount(Record.FieldValues(_)) > 0) and return it from the in line. Include the required comma after the preceding step and replace #"Changed Type" only if the actual previous step has another name. Expected output: TX-301 Sales 125.50 Posted; TX-302 Refunds 0 Review; TX-303 [blank] 42.00 [blank]; [blank, blank, blank, Imported note]. Explain that empty strings and whitespace are non-null and would remain; hidden/filtered worksheet rows normally still belong to the source table/query. Load to a new worksheet and do not overwrite/delete the source. Require current Excel with Get & Transform/Power Query; Windows/Mac UI and older Mac availability vary, and Excel for the web may not offer the same authoring workflow.
Use Power Query for a refreshable clean table based strictly on all-null records.
| Row | Order ID | Customer | Qty | Status |
|---|---|---|---|---|
| 2 | O-101 | Acme | 4 | Open |
| 3 | [empty] | [empty] | [empty] | [empty] |
| 4 | O-102 | Beacon | 0 | Closed |
| 5 | O-103 | [blank] | 2 | Open |
| 6 | [empty] | [empty] | [empty] | [empty] |
| 7 | O-104 | Delta | [blank] | Pending |
| 8 | [blank] | [blank] | [blank] | Note only |
| 9 | O-105 | Echo | 7 | Closed |
| 10 | [empty] | [empty] | [empty] | [empty] |
E2: =COUNTA(A2:D2)=0 → TRUE only for rows 3, 6, 10.| Order ID | Customer | Qty | Status |
|---|---|---|---|
| O-101 | Acme | 4 | Open |
| O-102 | Beacon | 0 | Closed |
| O-103 | [blank] | 2 | Open |
| O-104 | Delta | [blank] | Pending |
| [blank] | [blank] | [blank] | Note only |
| O-105 | Echo | 7 | Closed |
| Row | Ticket | Owner | Hours | Note |
|---|---|---|---|---|
| 2 | T-201 | Ana | 3 | Ready |
| 3 | [empty] | [empty] | [empty] | [empty] |
| 4 | T-202 | [blank] | 0 | Hold |
| 5 | ="" | ="" | ="" | ="" |
| 6 | T-203 | Bo | [blank] | [blank] |
| 7 | [blank] | [blank] | [blank] | Comment |
| 8 | T-204 | Cy | 5 | Done |
| 9 | ="" | ="" | ="" | ="" |
| 10 | T-205 | Di | 2 | [blank] |
| Ticket | Owner | Hours | Note |
|---|---|---|---|
| T-201 | Ana | 3 | Ready |
| T-202 | [blank] | 0 | Hold |
| T-203 | Bo | [blank] | [blank] |
| [blank] | [blank] | [blank] | Comment |
| T-204 | Cy | 5 | Done |
| T-205 | Di | 2 | [blank] |
=LET(data,Import!A2:D10,header,Import!A1:D1,keep,BYROW(data,LAMBDA(r,SUM(--(LEN(r)>0))>0)),IF(SUM(--keep)=0,header,VSTACK(header,FILTER(data,keep))))| Source row | Transaction | Account | Amount | Comment |
|---|---|---|---|---|
| 1 | TX-301 | Sales | 125.50 | Posted |
| 2 | [null] | [null] | [null] | [null] |
| 3 | TX-302 | Refunds | 0 | Review |
| 4 | TX-303 | [null] | 42.00 | [null] |
| 5 | [null] | [null] | [null] | Imported note |
| 6 | [null] | [null] | [null] | [null] |
| Transaction | Account | Amount | Comment |
|---|---|---|---|
| TX-301 | Sales | 125.50 | Posted |
| TX-302 | Refunds | 0 | Review |
| TX-303 | [blank] | 42.00 | [blank] |
| [blank] | [blank] | [blank] | Imported note |
#"Removed Fully Null Rows" = Table.SelectRows(#"Changed Type", each List.NonNullCount(Record.FieldValues(_)) > 0)How to remove blank rows safely
Define the data width
Test blankness across every column that belongs to the record, not one convenient key column.
Distinguish blank types
Truly empty cells, formulas returning "", Power Query nulls, whitespace, and numeric zero behave differently.
Choose destructive or non-destructive output
Use verified whole-row deletion only when physical removal is required. Otherwise create a spill or query table.
Verify partial rows
Confirm incomplete records and note-only rows remain before deleting or loading the result.
Preserve alignment
Never delete arbitrary blank cells and shift upward. Delete complete worksheet rows or create a separate output.
"" and an empty text value still occupy a cell. Match the method to the exact blank definition.Frequently asked questions
=COUNTA(A2:D2)=0, fill it down, filter to TRUE, verify the visible records, and delete the entire visible worksheet rows. This avoids deleting individual blank cells and shifting data out of alignment.