私の苦境を説明するために簡単なコードを書きました。
Sub test()
Dim sh As Worksheet
Set sh = ThisWorkbook.Sheets("Sheet1")
Dim k As Long
k = sh.Range("A1", sh.Range("A1").End(xlDown)).Rows.Count
End Sub
これは、A1から始まる値を含む行をカウントします。値を含む行の数が1より大きい場合、コードは問題なく機能します。ただし、A1が任意の値を含む唯一のセルである場合、Excelで許可される最大行数はk = 1,048,576です。
なぜk = 1ではないのですか?
ピクチャー:
編集:私が使用している回避策は次のとおりです。
Sub test()
Dim sh As Worksheet
Set sh = ThisWorkbook.Sheets("Sheet1")
Dim k As Long
k = sh.Range("A1", sh.Range("A1").End(xlDown)).Rows.Count
If k = 1048576 Then
k = 1
End If
MsgBox (k)
End Sub
値のある行の数が1の場合、kは常に1048576に等しいため、このようなことをしなければならないのは少しばかげているように感じます。
おそらく、より良い解決策は、下から上に向かって作業することです。
k=sh.Range("A1048576").end(xlUp).row
代わりにUsedRange
を使用する必要があります。
Sub test()
Dim sh As Worksheet
Dim rn As Range
Set sh = ThisWorkbook.Sheets("Sheet1")
Dim k As Long
Set rn = sh.UsedRange
k = rn.Rows.Count + rn.Row - 1
End Sub
+ rn.Row - 1
部分は、UsedRangeが使用される最初の行と列でのみ開始されるためです。したがって、行3〜10に何かがあり、行1と2が空の場合、rn.Rows.Count
は8になります。
また、Ron de Bruinの「最後の」関数( http://www.rondebruin.nl/win/s9/win005.htm )を使用することもできます。必要に応じて最後の列とセル。最後の行を取得するには、次のように使用します
lastRow = Last(1,yourRange)
これは非常に便利です。
Function Last(choice As Long, rng As Range)
'Ron de Bruin, 5 May 2008
' 1 = last row
' 2 = last column
' 3 = last cell
Dim lrw As Long
Dim lcol As Long
Select Case choice
Case 1:
On Error Resume Next
Last = rng.Find(What:="*", _
After:=rng.Cells(1), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row
On Error GoTo 0
Case 2:
On Error Resume Next
Last = rng.Find(What:="*", _
After:=rng.Cells(1), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByColumns, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Column
On Error GoTo 0
Case 3:
On Error Resume Next
lrw = rng.Find(What:="*", _
After:=rng.Cells(1), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row
On Error GoTo 0
On Error Resume Next
lcol = rng.Find(What:="*", _
After:=rng.Cells(1), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByColumns, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Column
On Error GoTo 0
On Error Resume Next
Last = rng.Parent.Cells(lrw, lcol).Address(False, False)
If Err.Number > 0 Then
Last = rng.Cells(1).Address(False, False)
Err.Clear
End If
On Error GoTo 0
End Select
End Function
CountRows = ThisWorkbook.Worksheets(1).Range("A:A").Cells.SpecialCells(xlCellTypeConstants).Count
それはいい質問です:)
1セル(A1)の状況がある場合、2番目に宣言されたセルが空ではない(sh.Range("A1").End(xlDown)
)かどうかを識別することが重要です。それが本当なら、それはあなたの範囲が制御不能になったことを意味します:)以下のコードを見てください:
Dim sh As Worksheet
Set sh = ThisWorkbook.Sheets("Arkusz1")
Dim k As Long
If IsEmpty(sh.Range("A1").End(xlDown)) = True Then
k = 1
Else
k = sh.Range("A1", sh.Range("A1").End(xlDown)).Rows.Count
End If
k = sh.Range("A2", sh.Range("A1").End(xlDown)).Rows.Count
または
k = sh.Range("A2", sh.Range("A1").End(xlDown)).Cells.Count
または
k = sh.Range("A2", sh.Range("A1").End(xlDown)).Count
誰かがこれをもう一度見る場合、これを使用できます:
Sub test()
Dim sh As Worksheet
Set sh = ThisWorkbook.Sheets("Sheet1")
Dim k As Long
k = sh.Range("A1", sh.Range("A1").End(xlDown).End(xlDown).End(xlUp)).Rows.Count
End Sub
これは、フィルター処理された列のデータを含むセルの数が必要な場合、特にピボットテーブルフィルター処理に役立ちます。フィルタリング用のヘッダー行がある場合は、それに応じてk
を(k - 1)
に減らします。
k = Sheets("Sheet1").Range("$A:$A").SpecialCells(xlCellTypeVisible).SpecialCells(xlCellTypeConstants).Count
やってみました :-
Sub test()
k = Cells(Rows.Count, "A").End(xlUp).Row
MsgBox (k)
End Sub
/ only /キャッチは、データがない場合でも1を返すことです。