Конец (xlUp) против Find
Этот пост относится к следующей части кода OP:
Dim NextCell As Range
Set NextCell = Cells(Rows.Count, "H").End(xlUp)
If NextCell.Row > 1 Then NextCell = NextCell.Offset(1, 0)
Болезнь
В строке
If NextCell.Row > 1 Then NextCell = NextCell.Offset(1, 0) ' Wrong
вы забыли использовать Set
(NextCell
- это объект). Используйте это вместо:
If NextCell.Row > 1 Then Set NextCell = NextCell.Offset(1, 0) ' Correct?
Почему "Правильно?" ?
Если NextCell
- это ячейка H1
, возможно, она пуста и код будет записан в нее. В следующий раз 'End(xlUp)
' снова вернет ячейку H1
, которая сейчас не пуста, и запишет в нее ... и снова и снова ... чтобы сделать вывод:
Если ячейка H1
пуста или нет, а все остальные ячейки пусты, код будет записан в ячейку H1
, суть в том, что чаще всего у вас есть заголовки в первой строке, и код не будет добавлять данные в следующие строки.
С другой стороны, код будет работать, если есть данные хотя бы во 2-й строке (например, заголовки во 2-й строке).
Напоминание
При использовании End(xlUp)
, вы всегда должны иметь в виду следующее:
Если в столбце нет данных или есть данные только в первой строке
, он вернется первая ячейка в столбце (см. FirstxlUp1
, FirstxlUp2
, FirstFind
).
Может также возвращать нежелательные результаты, когда строки скрыты или отфильтрованы (см. только в FirstFind
).
A Cure
Ниже приведены некоторые решения избежать предыдущих проблем. Для лучшего понимания они были упрощены.
Option Explicit
Sub FirstxlUp1()
Dim NextCell As Range
With ThisWorkbook.Worksheets("Sheet1")
Set NextCell = .Cells(.Rows.Count, "H").End(xlUp)
End With
If NextCell.Row = 1 Then
If NextCell.Value <> "" Then Set NextCell = NextCell.Offset(1)
Else
Set NextCell = NextCell.Offset(1)
End If
NextCell.Value = "TestxlUp1"
End Sub
Sub FirstxlUp2()
Dim NextCell As Range
With ThisWorkbook.Worksheets("Sheet1")
Set NextCell = .Cells(.Rows.Count, "H").End(xlUp)
End With
If NextCell.Row > 1 Then
Set NextCell = NextCell.Offset(1)
Else
If NextCell.Value <> "" Then Set NextCell = NextCell.Offset(1)
End If
NextCell.Value = "TestxlUp2"
End Sub
Sub FirstFind()
Dim NextCell As Range
With ThisWorkbook.Worksheets("Sheet1")
' Try to find a non-empty cell in the column; 'xlFormulas'
' includes finding cells with formulas evaluating to "".
Set NextCell = .Columns("H").Find(What:="*", LookIn:=xlFormulas, _
SearchDirection:=xlPrevious)
' Or:
'Set nextCell = .Columns("H").Find("*", , xlFormulas, , , xlPrevious)
' Check if a cell was found. If a non-empty cell was not found,
' the range evaluates to 'Nothing'.
If Not NextCell Is Nothing Then
' Found the last non-empty (bottom-most) cell in the column.
Set NextCell = NextCell.Offset(1)
Else
' All cells in the column are empty.
Set NextCell = .Cells(1, "H")
End If
End With
NextCell.Value = "TestFind"
End Sub
The Real Cure
На практике вы должны всегда использовать заголовки . Тогда вы можете избежать всего этого «If-ing» и использовать следующие однострочные, чтобы найти «первую» пустую ячейку в столбце, подобную этой:
Set NextCell = Cells(Rows.Count, "H").End(xlUp).Offset(1)
' or:
Set NextCell = Columns("H").Find(What:="*", LookIn:=xlFormulas, _
SearchDirection:=xlPrevious).Offset(1)
' Or:
'Set nextCell = Columns("H").Find("*", , xlFormulas, , , xlPrevious).Offset(1)
Если вы прячетесь или для фильтрации строк используйте исключительно метод поиска.