
1 要解決的問題:刪除某列中的空單元格/空行
暫時只實現了刪除一列中的空行,并沒有實現多行的判斷空行和刪除方法。----之后再做更復雜的
1.1 需求分析
用VBA刪除如下內容,解決思路都不同
- 刪除1列的空行(本文要做的)
- 刪除整個區域內的空行
- 刪除整個區域內的空格(這個一般很少有這種需求,用處不大----可用currentregion .specialcells()解決)
- 下面是原始數據,下面看看如何處理

2 如果是刪除全表/某區域的空單元格, 直接在當前列刪除
簡潔代碼:刪除區域內所有空單元格 cells ---實際需要少,so用處不大
使用 sheet.usedrange / region.currentregion .specialcells()
- 刪除,表格頁面內使用區域的空格所在的行
- 局限性就是表格的上方,左邊還會存在一些空行空列,不過這個手動刪下就可以了
- 這個只是刪除了空的cells 并不是刪除了空行
Sub 刪空單元格()
ActiveSheet.UsedRange.SpecialCells(xlCellTypeBlanks).Delete
End Sub
3 如果是刪一列的空行
3.1 代碼1:基礎代碼,假設確認知道這列的長度,關鍵是倒著刪
- 熟悉 isempty() 或者用 if xxxx=""
- 刪除單元格后,要設置屬性 shift:=xlup等
- 需要倒著刪除,否則會因為一邊刪除行,一遍重新排列有問題
Sub 刪一列的空行()
For i = 20 To 1 Step -1 '需要倒著刪除
If IsEmpty(Cells(i, 1)) Then
Cells(i, 1).Delete shift:=xlUp
End If
Next i
End Sub
3.2 改進版: 先查這一列的非空最大行數
Sub jackma_delete_row()
For i = Range("c65536").End(xlUp).Rows To 1 Step -1
If IsEmpty(Cells(i, 3)) Then
rows(i).Delete shift:=xlUp
End If
Next i
End Sub
3.3 也可以不用 isempty() 函數,直接判斷 if cells()=""
- 直接判斷 if cells(i,j) =""
- 這種刪除整行不合適 rows(i) .delete,會影響其他列的元素
Sub ponyma_del_row1()
For i = Range("c65536").End(xlUp).Row To 1 Step -1
If Cells(i, 3) = "" Then
Cells(i, 3).Delete
' Rows(i).Delete
End If
Next i
End Sub
4 不動原數據,將非空數據放到另外一列
4.1 錯誤版:
要明白“寫入列”的循環數,明顯和“輸出列”的循環數 應該不同!
這么寫相當于 輸出列 那行為空的時候,只是不往 寫入列寫,所以沒覆蓋,也是空的
Sub jackma_delete_row2()
For i = 1 To Range("c65536").End(xlUp).Rows
If Not IsEmpty(Cells(i, 3)) Then
Cells(i, 9) = Cells(i, 3)
End If
Next i
End Sub
4.2 正確版: 寫入列/輸出列,應該是單獨的循環變量!
Sub jackma_delete_row2()
k = 1
For i = 1 To Range("c65536").End(xlUp).Rows
If Not IsEmpty(Cells(i, 3)) Then
Cells(k, 9) = Cells(i, 3)
k = k + 1
End If
Next i
End Sub
5 先寫入數組array中,再寫到其他地方,據說這樣能大幅提高速度!
把需要的篩選的數據,存在數據,然后從數組寫到需要的地方,這是個好習慣
第1版:局限性很大,沒有自動查這列的 元素個數,以及 最大非空行是多少
Sub 刪除空格4()
Dim arr1() '定義了一個數組,并且是動態數組,因為沒指定大小
ReDim arr1(11) '動態數組,使用前必須重新redim,數組大小
j = 0 'j=1開始,不會越界,但arr1(0)為空,因為賦值跳過了它
For i = 1 To 11 Step 1
If Not IsEmpty(Cells(i, 1)) Then
arr1(j) = Cells(i, 1)
j = j + 1
End If
Next i
For j = 0 To UBound(arr1())
Cells(j + 1, 9) = arr1(j) '單元格得從1開始,arr(),默認得從0開始,但可以改
Next j
End Sub
第2版重寫
注意debug.print用來監測的時候,需要注意,放在循環的位置,尤其是在k=K+1這種變化時,和放在哪個for循環之內外!
Sub ponyma_array22()
Dim arr1() '當數組定義,且默認開始的index為0! preserve時需要有0的index
'dim arr1 當變量定義
k = 1
m = 1
ReDim arr1(0 To Application.WorksheetFunction.CountA(Range("c:c")))
For i = 1 To Range("c65536").End(xlUp).Row Step 1
If Cells(i, 3) <> "" Then
Debug.Print Cells(i, 3)
arr1(k) = Cells(i, 3)
Debug.Print arr1(k)
k = k + 1
' Debug.Print arr1(k),寫在這里問題1:k已經變了,下一個k還沒賦值為空,2最后的k越界
' 循環是很精巧的,放的地方很講究,放得不對,就錯誤百出
' Debug.Print arr1(k) 如果放在k=K+1 后,就看起來沒打印出東西,因為都打印的arr1的空元素
End If
Next i
For j = 1 To UBound(arr1(), 1)
Cells(m, 10) = arr1(j)
m = m + 1
Next j
End Sub
第3版
Option Explicit
Sub ponyma1()
Dim arr1()
Dim k1, k2, k
Dim i, j
k1 = WorksheetFunction.CountA(Range("a:a"))
k2 = Range("a65536").End(xlUp).Row
Debug.Print "這列非空數據個數k1=" & k1
Debug.Print "這列最后1個有數據的行數k2=" & k2
'arr1(0) = 1
'ReDim Preserve arr1(1, k)
'這樣會越界,因為你需要preserve數據。但是index系不符合
'但是,如果不preserve 就無所謂
'或者雖然 dim arr1() 是動態數據從index0開始,但是arr1()一直為空,preserve也不會出現index越界問題
ReDim Preserve arr1(1 To k1)
'ReDim Preserve arr1(1, k1) 這樣就會越界。。。因為語法是2維數組了!
'ReDim Preserve arr1(1 to k1) 這樣就對的
k = 1
For i = 1 To k2
If Cells(i, 1) <> "" Then
arr1(k) = Cells(i, 1)
Debug.Print arr1(k)
k = k + 1
End If
Next i
————————————————
版權聲明:本文為CSDN博主「奔跑的犀牛先生」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:【原創】VBA(實驗1)用VBA 刪除某列空單元格的3種方法:刪除法,轉移到其他列方法,數組方法