190

最後に使用されたセル値を検索する場合は、次を使用します。

Dim LastRow As Long

LastRow = Range("E4:E48").End(xlDown).Row

Debug.Print LastRow

単一の要素をセルに入れると、間違った出力が得られます。しかし、セルに複数の値を入力すると、出力は正しくなります。この背後にある理由は何ですか?

4

14 に答える 14

344

Correct:これを「ワンストップポスト」にして、最後の行を見つける方法を使用できるようにするつもりです。これは、最後の行を見つけるときに従うべきベストプラクティスもカバーします。したがって、新しいシナリオ/情報に出くわすたびに、それを更新し続けます。


最後の行を見つける信頼できない方法

信頼性が非常に低く、したがって決して使用されるべきではない最後の行を見つける最も一般的な方法のいくつか。

  1. UsedRange
  2. xlDown
  3. CountA

UsedRangeデータを持つ最後のセルを見つけるために使用しないでください。信頼性が非常に低いです。この実験を試してください。

セルに何かを入力しA5ます。次に、以下のいずれかの方法で最後の行を計算すると、5が得られます。セルをA10赤に着色します。以下のコードのいずれかを使用した場合でも、5が得られます。使用した場合Usedrange.Rows.Count、何が得られますか?5にはなりません。

これがどのように機能するかを示すシナリオUsedRangeです。

ここに画像の説明を入力してください

xlDown同様に信頼性がありません。

このコードを検討してください

lastrow = Range("A1").End(xlDown).Row

データを持つセル()が1つしかない場合はどうなりA1ますか?ワークシートの最後の行に到達することになります!これは、セルを選択してからキーをA1押してからキーを押すようなものです。これにより、範囲内に空白のセルがある場合にも信頼性の低い結果が得られます。EndDown Arrow

CountAまた、間に空白のセルがあると誤った結果が得られるため、信頼性が低くなります。

したがって、の使用を避け、UsedRange最後のセルを見つける必要がxlDownあります。CountA


列の最後の行を検索

列Eの最後の行を見つけるには、これを使用します

With Sheets("Sheet1")
    LastRow = .Range("E" & .Rows.Count).End(xlUp).Row
End With

あなたが私たちが.前に持っていることに気づいたらRows.Count。私たちはしばしばそれを無視することを選びました。発生する可能性のあるエラーについては、この質問を参照してください。私はいつも.前にRows.Count使用することをお勧めしColumns.Countます。この質問は、 Excel2003以前とExcel2007以降のRows.Countリターンが原因でコードが失敗する典型的なシナリオです。同様に、それぞれとを返します。655361048576Columns.Count25616384

Excel 2007+に行があるという上記の事実は、エラーが発生する代わりに1048576、行の値を保持する変数を常に宣言する必要があるという事実も強調しています。LongIntegerOverflow

このアプローチでは、非表示の行がスキップされることに注意してください。上記の列Aのスクリーンショットを振り返ると、行8が非表示になっている場合、このアプローチは5の代わりに戻ります8


シートの最後の行を検索

Effectiveシートの最後の行を見つけるには、これを使用します。の使用に注意してくださいApplication.WorksheetFunction.CountA(.Cells)。ワークシートにデータを含むセルがない場合は、次のようになるため、これが必要.Findです。Run Time Error 91: Object Variable or With block variable not set

With Sheets("Sheet1")
    If Application.WorksheetFunction.CountA(.Cells) <> 0 Then
        lastrow = .Cells.Find(What:="*", _
                      After:=.Range("A1"), _
                      Lookat:=xlPart, _
                      LookIn:=xlFormulas, _
                      SearchOrder:=xlByRows, _
                      SearchDirection:=xlPrevious, _
                      MatchCase:=False).Row
    Else
        lastrow = 1
    End If
End With

テーブルの最後の行を検索(ListObject)

同じ原則が適用されます。たとえば、テーブルの3番目の列の最後の行を取得する場合です。

Sub FindLastRowInExcelTableColAandB()
Dim lastRow As Long
Dim ws As Worksheet, tbl as ListObject
Set ws = Sheets("Sheet1")  'Modify as needed
'Assuming the name of the table is "Table1", modify as needed
Set tbl = ws.ListObjects("Table1")

With tbl.ListColumns(3).Range
    lastrow = .Find(What:="*", _
                After:=.Cells(1), _
                Lookat:=xlPart, _
                LookIn:=xlFormulas, _
                SearchOrder:=xlByRows, _
                SearchDirection:=xlPrevious, _
                MatchCase:=False).Row
End With

End Sub
于 2012-06-23T13:33:16.590 に答える
38

注:この回答は、このコメントによって動機付けられました。の目的はUsedRange、上記の回答に記載されているものとは異なります。

最後に使用されたセルを見つける正しい方法については、最初に何が使用されたと見なされるかを決定し、次に適切な方法を選択する必要があります。私は少なくとも3つの意味を考えています:

  1. 使用済み=空白以外、つまりデータがあります。

  2. 使用済み="...使用中、データまたはフォーマットを含むセクションを意味します。" 公式ドキュメントによると、これは保存時にExcelで使用される基準です。この公式ドキュメントも参照してください。これに気付いていない場合、基準は予期しない結果をもたらす可能性がありますが、たとえば、最終的にデータがない可能性がある特定の領域を強調表示または印刷するために、意図的に悪用される可能性もあります。そしてもちろん、ワークブックを保存するときに使用する範囲の基準として、作業の一部を失わないようにすることが望ましいです。

  3. 使用済み="...使用中、データまたはフォーマットを含むセクションを意味します"または条件付きフォーマット。 2.と同じですが、条件付き書式ルールのターゲットであるセルも含まれます。

最後に使用されたセルを見つける方法は、必要なもの(基準)によって異なります

基準1については、この回答を読むことをお勧めします。UsedRange信頼できないとして引用されていることに注意してください。データを含む最後のセルを報告することを単に意図していないので、それは誤解を招く(つまり、に「不公平」であるUsedRange)と思います。UsedRangeしたがって、その回答に示されているように、この場合は使用しないでください。このコメントも参照してください。

基準2UsedRangeの場合、この用途向けに設計された他のオプションと比較して、最も信頼性の高いオプションです。最後のセルが更新されていることを確認するためにワークブックを保存する必要さえありません。 Ctrl+End保存する前に間違ったセルに移動します(「ワークシートを保存するまで最後のセルはリセットされません」、 http://msdn.microsoft.com/en-us/library/aa139976%28v=office.10%から) 29.aspx。これは古いリファレンスですが、この点では有効です)。

基準3については、組み込みの方法がわかりません。基準2は、条件付き書式を考慮していません。UsedRangeまたはCtrl+で検出されない数式に基づいて、セルをフォーマットした可能性がありますEnd。この図では、フォーマットが明示的に適用されているため、最後のセルはB3です。セルB6:D7には、条件付き書式ルールから派生した書式があり、これは。によっても検出されませんUsedRange。これを説明するには、VBAプログラミングが必要になります。

ここに画像の説明を入力してください


あなたの特定の質問に関してこれの背後にある理由は何ですか?

コードでは、範囲E4:E48の最初のセルをトランポリンとして使用し、。でジャンプダウンしEnd(xlDown)ます。

「誤った」出力は、おそらく最初のセル以外に空白以外のセルが範囲内にない場合に取得されます。次に、暗闇の中で、つまりワークシートを下にジャンプします(空白の文字列と空の文字列の違いに注意する必要があります!)。

ご了承ください:

  1. 範囲に連続していない非空白のセルが含まれている場合も、間違った結果になります。

  2. 空白でないセルが1つだけあるが、それが最初のセルではない場合でも、コードは正しい結果を提供します。

于 2014-12-24T13:34:51.457 に答える
21

このワンストップ関数を作成して、最後の行、列、セルを決定しました。データ、フォーマットされた(グループ化/コメント化/非表示)セル、条件​​付きフォーマットなどです。

Sub LastCellMsg()
    Dim strResult As String
    Dim lngDataRow As Long
    Dim lngDataCol As Long
    Dim strDataCell As String
    Dim strDataFormatRow As String
    Dim lngDataFormatCol As Long
    Dim strDataFormatCell As String
    Dim oFormatCond As FormatCondition
    Dim lngTempRow As Long
    Dim lngTempCol As Long
    Dim lngCFRow As Long
    Dim lngCFCol As Long
    Dim strCFCell As String
    Dim lngOverallRow As Long
    Dim lngOverallCol As Long
    Dim strOverallCell As String

    With ActiveSheet

        If .ListObjects.Count > 0 Then
            MsgBox "Cannot return reliable results, as there is at least one table in the worksheet."
            Exit Sub
        End If

        strResult = "Workbook name: " & .Parent.Name & vbCrLf
        strResult = strResult & "Sheet name: " & .Name & vbCrLf

        'DATA:
        'last data row
        If Application.WorksheetFunction.CountA(.Cells) <> 0 Then
            lngDataRow = .Cells.Find(What:="*", _
             After:=.Range("A1"), _
             Lookat:=xlPart, _
             LookIn:=xlFormulas, _
             SearchOrder:=xlByRows, _
             SearchDirection:=xlPrevious, _
             MatchCase:=False).Row
        Else
            lngDataRow = 1
        End If
        'strResult = strResult & "Last data row: " & lngDataRow & vbCrLf

        'last data column
        If Application.WorksheetFunction.CountA(.Cells) <> 0 Then
            lngDataCol = .Cells.Find(What:="*", _
             After:=.Range("A1"), _
             Lookat:=xlPart, _
             LookIn:=xlFormulas, _
             SearchOrder:=xlByColumns, _
             SearchDirection:=xlPrevious, _
             MatchCase:=False).Column
        Else
            lngDataCol = 1
        End If
        'strResult = strResult & "Last data column: " & lngDataCol & vbCrLf

        'last data cell
        strDataCell = Replace(Cells(lngDataRow, lngDataCol).Address, "$", vbNullString)
        strResult = strResult & "Last data cell: " & strDataCell & vbCrLf

        'FORMATS:
        'last data/formatted/grouped/commented/hidden row
        strDataFormatRow = StrReverse(Split(StrReverse(.UsedRange.Address), "$")(0))
        'strResult = strResult & "Last data/formatted row: " & strDataFormatRow & vbCrLf

        'last data/formatted/grouped/commented/hidden column
        lngDataFormatCol = Range(StrReverse(Split(StrReverse(.UsedRange.Address), "$")(1)) & "1").Column
        'strResult = strResult & "Last data/formatted column: " & lngDataFormatCol & vbCrLf

        'last data/formatted/grouped/commented/hidden cell
        strDataFormatCell = Replace(Cells(strDataFormatRow, lngDataFormatCol).Address, "$", vbNullString)
        strResult = strResult & "Last data/formatted cell: " & strDataFormatCell & vbCrLf

        'CONDITIONAL FORMATS:
        For Each oFormatCond In .Cells.FormatConditions

            'last conditionally-formatted row
            lngTempRow = CLng(StrReverse(Split(StrReverse(oFormatCond.AppliesTo.Address), "$")(0)))
            If lngTempRow > lngCFRow Then lngCFRow = lngTempRow

            'last conditionally-formatted column
            lngTempCol = Range(StrReverse(Split(StrReverse(oFormatCond.AppliesTo.Address), "$")(1)) & "1").Column
            If lngTempCol > lngCFCol Then lngCFCol = lngTempCol
        Next
        'no results are returned for Conditional Format if there is no such
        If lngCFRow <> 0 Then
            'strResult = strResult & "Last cond-formatted row: " & lngCFRow & vbCrLf
            'strResult = strResult & "Last cond-formatted column: " & lngCFCol & vbCrLf

            'last conditionally-formatted cell
            strCFCell = Replace(Cells(lngCFRow, lngCFCol).Address, "$", vbNullString)
            strResult = strResult & "Last cond-formatted cell: " & strCFCell & vbCrLf
        End If

        'OVERALL:
        lngOverallRow = Application.WorksheetFunction.Max(lngDataRow, strDataFormatRow, lngCFRow)
        'strResult = strResult & "Last overall row: " & lngOverallRow & vbCrLf
        lngOverallCol = Application.WorksheetFunction.Max(lngDataCol, lngDataFormatCol, lngCFCol)
        'strResult = strResult & "Last overall column: " & lngOverallCol & vbCrLf
        strOverallCell = Replace(.Cells(lngOverallRow, lngOverallCol).Address, "$", vbNullString)
        strResult = strResult & "Last overall cell: " & strOverallCell & vbCrLf

        MsgBox strResult
        Debug.Print strResult

    End With

End Sub

結果は次のようになります。
最後のセルを決定する

より詳細な結果を得るには、コードの一部の行のコメントを外すことができます。
最後の列、行

1つの制限があります。シートにテーブルがある場合、結果の信頼性が低下する可能性があるため、この場合はコードの実行を避けることにしました。

If .ListObjects.Count > 0 Then
    MsgBox "Cannot return reliable results, as there is at least one table in the worksheet."
    Exit Sub
End If
于 2015-12-23T21:55:40.073 に答える
12

ソリューションを使用する際に留意すべき重要な注意事項の1つ...

LastRow = ws.Cells.Find(What:="*", After:=ws.range("a1"), SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row

LastRow...変数のLong型が次のとおりであることを確認することです。

Dim LastRow as Long

そうしないと、.XLSXブックの特定の状況でオーバーフローエラーが発生することになります。

これは、さまざまなコードの使用に立ち寄るカプセル化された関数です。

Private Function FindLastRow(ws As Worksheet) As Long
    ' --------------------------------------------------------------------------------
    ' Find the last used Row on a Worksheet
    ' --------------------------------------------------------------------------------
    If WorksheetFunction.CountA(ws.Cells) > 0 Then
        ' Search for any entry, by searching backwards by Rows.
        FindLastRow = ws.Cells.Find(What:="*", After:=ws.range("a1"), SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
    End If
End Function
于 2015-01-02T18:58:31.870 に答える
12

元の質問は最後のセルを見つける際の問題に関するものなので、この回答では、予期しない結果を得ることができるさまざまな方法をリストします「マクロを使用してExcelシートのデータを含む最後の行を見つけるにはどうすればよいですか?」に対する私の回答を参照してください。これを解決するための私の見解のために。

まず、 sancho.sによる回答とGlennFromIowaによるコメントを拡張し、さらに詳細を追加します。

[...]最初に何が使用されていると見なされるかを決定する必要があります。少なくとも6つの意味があります。セルには:

  • 1)データ、つまり数式。空白の値になる可能性があります。
  • 2)値、つまり非空白の数式または定数。
  • 3)フォーマット;
  • 4)条件付きフォーマット。
  • 5)セルに重なる形状(コメントを含む)。
  • 6)テーブル(リストオブジェクト)への関与。

どの組み合わせをテストしますか?一部(テーブルなど)はテストがより困難な場合があり、一部はまれな場合(データ範囲外の形状など)ですが、その他は状況に応じて異なる場合があります(たとえば、値が空白の数式)。

あなたが考慮したいと思うかもしれない他の事柄:

  • A)非表示の行(オートフィルターなど)、空白のセル、または空白の行はありますか?
  • B)どのようなパフォーマンスが許容されますか?
  • C)VBAマクロはワークブックまたはアプリケーション設定に何らかの影響を与える可能性がありますか?

それを念頭に置いて、「最後のセル」を取得する一般的な方法がどのように予期しない結果を生み出すかを見てみましょう。

  • 質問の.End(xlDown)コードは、Siddharth Routの回答で説明されている理由により(たとえば、空でないセルが1つある場合や、間に空白のセルがある場合)、最も簡単に壊れます( 「xlDownも同様に信頼性が低い」を検索してください) 。
  • Counting(CountAまたはCells*.Count)に基づくソリューション、.CurrentRegionまたは空白のセルまたは行が存在すると破損するソリューション
  • .End(xlUp)列の終わりから逆方向に検索するソリューションは、CTRL + UPと同様に、表示されている行でデータを検索します(空白の値を生成する数式は「データ」と見なされます)(したがって、オートフィルターを有効にして使用すると、誤った結果が生成される可能性があります⚠️ )。

    最後の行をハードコーディングするなど、標準的な落とし穴を回避するように注意する必要があります(詳細については、ここでSiddharth Routによる回答を参照し、 「列の最後の行を検索」Range("A65536").End(xlUp)セクションを探してください)( )に依存する代わりにsht.Rows.Count

  • .SpecialCells(xlLastCell)はCTRL+ENDと同等であり、「使用範囲」の一番下と右端のセルを返します。したがって、「使用範囲」に依存することに適用されるすべての警告は、このメソッドにも適用されます。さらに、「使用範囲」はワークブックの保存時とアクセス時にのみリセットされるため、保存されていない変更(一部の行が削除された後など)で古い結果⚠️が生成される可能性がありますworksheet.UsedRangedotNETによる近くの回答xlLastCellを参照してください。
  • sht.UsedRange(ここのsancho.sによる回答で詳細に説明されています)データとフォーマットの両方を考慮し(条件付きフォーマットではありません)、ワークシートの「使用範囲」をリセットします。これは、希望する場合とそうでない場合があります。

    よくある間違いは⚠️を使用することです。これは、最後の行番号ではなく、使用された範囲の行数.UsedRange.Rows.Countを返します(最初の数行が空白の場合は異なります)。詳細については、newguyの回答を参照してください。マクロを含むExcelシートのデータを含む最後の行?

  • .Find任意のデータ(数式を含む)または任意の列の非空白値を含む最後の行を検索できます。数式と値のどちらに関心があるかを選択できますが、Excelの[検索]ダイアログ️️⚠️でデフォルトがリセットされるため、ユーザーが非常に混乱する可能性があります。また、慎重に使用する必要があります。ここでSiddharth Routの回答を参照してください( 「シートの最後の行を検索する」セクション) 。
  • ループ内の個々の'をチェックするより明示的なソリューションCellsは、通常、Excel関数を再利用するよりも低速です(ただし、パフォーマンスは向上します)が、検索したいものを正確に指定できます。とVBA配列に基づく私のソリューションを参照UsedRangeして、指定された列にデータがある最後のセルを検索します。これは、非表示の行、フィルター、空白を処理し、デフォルトの検索を変更せず、非常にパフォーマンスが高くなります。

どのソリューションを選択する場合でも、注意してください

  • 行番号を格納するLong代わりに使用する( 65,000を超える行を取得しないようにするため)およびIntegerOverflow
  • 作業しているワークシートを常に指定するには(つまりDim ws As Worksheet ... ws.Range(...)、ではなくRange(...)
  • .Value()を使用するときは、セルにエラー値が含まれていると失敗するため、のVariantような暗黙のキャストは避けてください。.Value <> ""
于 2018-04-22T23:01:27.270 に答える
8

Siddarth Routの回答に加えて、Findに行番号ではなくRangeオブジェクトを返すようにすると、CountA呼び出しをスキップできると言い、返されたRangeオブジェクトをテストしてNothing(空白のワークシート)かどうかを確認します。 。

また、LastRowプロシージャのバージョンで、空白のワークシートに対してゼロを返すようにすると、空白であることがわかります。

于 2014-11-05T15:24:15.557 に答える
8

誰もこれについて言及していないのではないかと思いますが、最後に使用したセルを取得する最も簡単な方法は次のとおりです。

Function GetLastCell(sh as Worksheet) As Range
    GetLastCell = sh.Cells(1,1).SpecialCells(xlLastCell)
End Function

これは基本的に、 Cellを選択した後にCtrl+で取得したのと同じセルを返します。EndA1

注意点:Excelは、ワークシートでこれまでに使用された中で最も右下のセルを追跡します。したがって、たとえば、B3に何かを入力し、H8に何かを入力し、後でH8の内容を削除した場合でも、 Ctrl+を押すとH8セルに移動します。上記の関数は同じ動作をします。End

于 2015-04-27T15:21:54.507 に答える
3
sub last_filled_cell()
msgbox range("A65536").end(xlup).row
end sub

これは、列Aの最後のセルです。このA65536コードはExcel2003でテストされました。

于 2015-10-01T05:09:44.313 に答える
3

ただし、この質問はVBAを使用して最後の行を見つけることを目的としています。これは頻繁にアクセスされるため、ワークシート関数の配列数式を含めるとよいと思います。

{=ADDRESS(MATCH(INDEX(D:D,MAX(IF(D:D<>"",ROW(D:D)-ROW(D1)+1)),1),D:D,0),COLUMN(D:D))}

角かっこなしで数式を入力し、++を押して配列数式にする必要がShiftありCtrlますEnter

これにより、列Dで最後に使用されたセルのアドレスがわかります。


pgsystemtesterのおかげで、これにより、最後に使用されたセルの行番号がわかります。

{=MATCH(INDEX(D:D,MAX(IF(D:D<>"",ROW(D:D)-ROW(D1)+1)),1),D:D,0)}
于 2017-05-08T21:48:48.940 に答える
3

2021年末に更新

Excelの新しい計算エンジンと配列機能、およびフィルター機能を使用すると、このトピックの争いがはるかに少なくなり、以下のオプションが速度、信頼性、および単純さの最適な組み合わせを提供すると思います(これは過去にバランスを取るのが困難であることが証明されていますここにある多数の投稿が示しています)。

また、isBlank関数で定義されているようにlast used空白ではないと定義しています。

Excelの数式

まず、フィルター関数を使用すると、特定の行または列(この場合はColumn AまたはRow 1)に対して以下の数式を使用して最後のセルを取得するのがはるかに簡単になることに注意してください。

=MAX(FILTER(ROW(A:A),NOT(ISBLANK(A:A))))
=MAX(FILTER(COLUMN(1:1),NOT(ISBLANK(1:1))))

最後の行の特定の範囲のVBA関数

上記の関数を使用すると、VBA関数に変換できますが、範囲を制限することでさらに高速になり、複数の列を実行することで機能を拡張できます(ChrisNeilsenの即時フィードバックtweeking/提案に感謝します。また、各列を前の最後の行よりも高い行の範囲のみにスコープすることで、速度が大幅に向上することもわかりました。

Function FindLastRowInRange(someColumns As Range) As Long
Const zFx = "=MAX(FILTER(ROW(????),NOT(ISBLANK(????)),0))"
   
   Dim tRng As Range, i As Long, tRow As Long, nRng As Range
   With someColumns.Worksheet
      Set tRng = Intersect(someColumns.EntireColumn, .UsedRange)
      
      For i = 1 To tRng.Columns.Count
         
         Set pRng = Intersect(tRng.Columns(i), _
         Range(.Rows(FindLastRowInRange + 1), .Rows(.Rows.Count)))
         
         If Not pRng Is Nothing Then
            tRow = .Evaluate(Replace(zFx, "????", _
               pRng.Address, 1, -1))
         
            If tRow > FindLastRowInRange Then _
               FindLastRowInRange = tRow
            
         End If
      Next i
   End With
End Function

ワークシートの最後の行のVBA関数

ワークシート全体(すべての列)を検討するには、前の式を参照しているが揮発性関数である別のVBA式を使用することをお勧めします。これにより、ワークシートに変更が加えられたときに数式が確実に更新されます明らかに、これら2つの式を組み合わせることができますが、私は揮発性関数の使用を制限することを好みます。

Function FindLastRowInSheet(anywhereInSheet As Range) As Long
      Application.Volatile
      FindLastRowInSheet = FindLastRowInRange(anywhereInSheet.Worksheet.UsedRange)
End Function

他のオプションと比較した利点

  • アプローチを変更せずに、ワークシートの一部またはすべての行/列を許可します。
  • のリスクのように隠し行を見逃す可能性はありませんxlup
  • フォーマットされた/使用された範囲の問題を無視します。
  • Findユーザーの設定に干渉しません。
  • VBA計算よりも高速なワークシート機能を使用します。
  • カウントセルなし(パフォーマンスホッグ)。

うまくいけば、これで議論は終わりですが、誰かがこれに弱点を見つけたら、共有してください。

于 2019-11-28T04:11:51.183 に答える
2

CTRL+ Shift+を模倣する方法を探していたEndので、ドットネットソリューションは素晴らしいです。ただし、Excel 2010ではset、エラーを回避したい場合はを追加する必要があります。

Function GetLastCell(sh As Worksheet) As Range
  Set GetLastCell = sh.Cells(1, 1).SpecialCells(xlLastCell)
End Function

自分でこれを確認する方法:

Sub test()
  Dim ws As Worksheet, r As Range
  Set ws = ActiveWorkbook.Sheets("Sheet1")
  Set r = GetLastCell(ws)
  MsgBox r.Column & "-" & r.Row
End Sub
于 2017-05-17T15:23:25.220 に答える
0
Sub lastRow()

    Dim i As Long
        i = Cells(Rows.Count, 1).End(xlUp).Row
            MsgBox i

End Sub

sub LastRow()

'Paste & for better understanding of the working use F8 Key to run the code .

dim WS as worksheet
dim i as long

set ws = thisworkbook("SheetName")

ws.activate

ws.range("a1").select

ws.range("a1048576").select

activecell.end(xlup).select

i= activecell.row

msgbox "My Last Row Is " & i

End sub
于 2016-06-29T08:07:22.737 に答える
0

過去3年以上の間、これらは、定義された列(行の場合)および行(列の場合)ごとに最後の行と最後の列を検索するために使用している関数です。

最後の列:

Function lastCol(Optional wsName As String, Optional rowToCheck As Long = 1) As Long

    Dim ws  As Worksheet

    If wsName = vbNullString Then
        Set ws = ActiveSheet
    Else
        Set ws = Worksheets(wsName)
    End If

    lastCol = ws.Cells(rowToCheck, ws.Columns.Count).End(xlToLeft).Column

End Function

最後の行:

Function lastRow(Optional wsName As String, Optional columnToCheck As Long = 1) As Long

    Dim ws As Worksheet

    If wsName = vbNullString Then
        Set ws = ActiveSheet
    Else
        Set ws = Worksheets(wsName)
    End If

    lastRow = ws.Cells(ws.Rows.Count, columnToCheck).End(xlUp).Row

End Function

OPの場合、これは列の最後の行を取得する方法ですE

Debug.Print lastRow(columnToCheck:=Range("E4:E48").Column)

最後の行、データを含む空の行をカウントします。

ここでは、よく知られているExcelの数式を使用できます。これにより、VBAを使用せずに、Excelでワークシートの最後の行を取得できます。=IFERROR(LOOKUP(2,1/(NOT(ISBLANK(A:A))),ROW(A:A)),0)

これをVBAに入れ、Excelで何も書き込まないようにするために、後者の関数のパラメーターを使用して、次のようなことを念頭に置くことができます。

Public Function LastRowWithHidden(Optional wsName As String, Optional columnToCheck As Long = 1) As Long

    Dim ws As Worksheet

    If wsName = vbNullString Then
        Set ws = ActiveSheet
    Else
        Set ws = Worksheets(wsName)
    End If

    Dim letters As String
    letters = ColLettersGenerator(columnToCheck)
    LastRowWithHidden = ws.Evaluate("=IFERROR(LOOKUP(2,1/(NOT(ISBLANK(" & letters & "))),ROW(" & letters & " )),0)")

End Function

Function ColLettersGenerator(col As Long) As String

    Dim result As Variant
    result = Split(Cells(1, col).Address(True, False), "$")
    ColLettersGenerator = result(0) & ":" & result(0)

End Function
于 2018-06-01T19:30:44.203 に答える
0

通常の範囲またはテーブル(ListObject)の最後の行

  1. 範囲が通常の範囲またはテーブル(リストオブジェクト)の場合、最後の行を見つけるにはさまざまなメソッドを使用する必要があります。
  2. テーブルの最後の行を見つけるには、追加のパラメーター(テーブル名、最初のテーブル列に対する列の相対位置)を指定する必要があります。

範囲タイプに関係なく、最後の行に対してこのユニバーサル関数を作成しました。セル参照を指定するだけで、最後の行が返されます。範囲の特性を知る必要はありません。特に、範囲が通常の範囲である場合や、ListObjectである場合は特にそうです。テーブルで通常の範囲メソッドを使用すると、間違った結果が返される場合があります。確かに事前に計画を立てて、毎回正しい方法を使用することはできますが、ユニバーサル機能を利用できるのであれば、なぜわざわざするのでしょうか。

Sub RunMyLastRow()
Dim Result As Long
Result = MyLastRow(Worksheets(1).Range("A1"))
End Sub
    Function MyLastRow(RefrenceRange As Range) As Long
    Dim WS As Worksheet
    Dim TableName As String
    Dim ColNumber As Long
    Dim LastRow As Long
    Dim FirstColumnTable As Long
    Dim ColNumberTable As Long
    Set WS = RefrenceRange.Worksheet
    TableName = GetTableName(RefrenceRange)
    ColNumber = RefrenceRange.Column
    
    ''If the table (ListObject) does not start in column "A" we need to calculate the 
    ''first Column table and how many Columns from its beginning the Column is located.
    If TableName <> vbNullString Then
     FirstColumnTable = WS.ListObjects(TableName).ListColumns(1).Range.Column
     ColNumberTable = ColNumber - FirstColumnTable + 1
    End If 

    If TableName = vbNullString Then
    LastRow = WS.Cells(WS.Rows.Count, ColNumber).End(xlUp).Row
    Else
    LastRow = WS.ListObjects(TableName).ListColumns(ColNumberTable).Range.Find( _
               What:="*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
    End If
    MyLastRow = LastRow
    End Function
    
    ''Get Table Name by Cell Range
    Function GetTableName(RefrenceRange As Range) As String
        If RefrenceRange.ListObject Is Nothing Then
            GetTableName = vbNullString
        Else
            GetTableName = RefrenceRange.ListObject.Name
        End If
    End Function
于 2021-07-16T17:04:51.927 に答える