2015-11-28 16 views
8

数式の結果が実際の値で空でない数式を保持するセルの範囲の最後の行を見つけるにはどうすればよいですか?数式を保持するセルの範囲で最後の空でない行を見つけよう

セル範囲が("E1:E10")の場合、セルA1〜A10を参照する式が、=IF("A1"="","","A1")の順になるように簡略化します。しかし、A1からA6までのセルにのみ値が入力されているため、E7からE10のセルの計算式の結果は空になります。 10の値を有するLASTROWで

lastRow = ActiveSheet.Range("E" & Rows.Count).End(xlUp).Row 

結果:でそれをやろうとし

。私が望むのは、この例ではlastRowの値が6であることです。

実際のコードはこれよりも複雑ですので、数式は異なるシート上の単一のセルを参照し、動的に追加されるため、最後の列Aの列を確認するだけではありません。

答えて

6

私は@D_Besterによって提供されたよりも多くのエレガントな方法は、セルの範囲をループせずにfind()オプションを使用することであると思います。また

Sub test() 
    Dim cl As Range, i& 
    Set cl = Range("E1:E" & Cells(Rows.Count, "E").End(xlUp).Row) 
    i = cl.Find("*", , xlValues, , xlByRows, xlPrevious).Row 
    Debug.Print "Last row with data: " & i 
End Sub 

テスト

enter image description here

、より短いです上記で提供されたコードのバージョンは、

です。
Sub test2() 
    Debug.Print [E:E].Find("*", , xlValues, , xlByRows, xlPrevious).Row 
End Sub 
+2

はいこれは非常にエレガントです!ありがとう@Vasily – Rosetta

+0

素晴らしい作品と私​​が探していたものでした。 変数 'i'の宣言でアンパサンド'& 'の意味は何ですか? (アンパサンドなしで同じように動作するようです) – Pascale

+2

@Pascaleそれは 'Dim i as Long'を意味します。もしあなたが'& 'を取り除くなら' i'は 'Variant'として宣言されます。コーディングの簡単な方法です。 '%'は '整数'、 '&'は 'ロング'、 '$'は 'ストリング'、 '@'は '通貨'、 '!'は 'シングル'、 '#'は 'ダブル' Variant'を指定しました – Vasily

2

これは、(シート1 Sheet1カラムAで)式を含む最後の行を決定するのに役立つべきである:式を含むすべてのセルの範囲を決定するために使用される

lastRow = Split(Split(Sheet1.Range("A:A").SpecialCells(xlCellTypeFormulas).Address, ",")(UBound(Split(Sheet1.Range("A:A").SpecialCells(xlCellTypeFormulas).Address, ","))), "$")(2) 
SpecialCells

。この範囲は、Splitを使用して解析されます。 Uboundでは、これらのセルの最後が検索されています。結果が再び分割されて行番号が抽出されます。

+0

私はあなたのコードを適用しようとしましたが、式を持つ最初の行を返します。 (私のシートの範囲は行3から行26までで、lastRowは3を返します:MsgBoxで印刷したときに、21となることを期待したとき)調整が必要な場合、またはこれが良いアプローチであっても。「これは数式を含む最後の行を決定するのに役立つはずですが、その数式の結果が「空の文字列」ではない式を含む最後の行が必要です。申し訳ありませんが、私はあなたの答えを誤解したが、私はまったく私がstackoverflowで見つけるものに頼っているので、私は全くVBAの経験がありません。 – Pascale

+2

@Ralph Addressプロパティは255文字の文字列に制限されているため、数式を含むすべての領域を含むわけではありません。 – shg

5

空でない列の最後のセルを検索したい場合は、空白文字列( "")ではありません。

空白でないセルをループでチェックするだけで、LastRowに従います。

lastrow = ActiveSheet.Range("E" & ActiveSheet.Rows.Count).End(xlUp).Row 
Do 
    If ActiveSheet.Cells(lastrow, 5).Value <> "" Then 
     Exit Do 
    End If 
    lastrow = lastrow - 1 
Loop While lastrow > 0 

If lastrow > 0 Then 
    Debug.Print "Last row with data: " & lastrow 
Else 
    Debug.Print "No data in the column" 
End If 

Rows.countにはどのシートが指定されていないことに注意してください。これは、アクティブシートを使用することを意味します。もちろんActiveSheet.Range()もアクティブシートにあります。しかし、RangeまたはRows.Rangeまたは.Rowsに混ぜることは悪い習慣です。 ActiveSheetを変更したが、不特定の参照を変更しなかった場合、あなたを噛んでしまうような無意識のある使用法を示しています。

+0

私はあなたが示唆しているように、それらを後方にループすることについてすでに考えていましたが、それを達成するよりエレガントな方法を望んでいました。 – Pascale

+0

あなたの答えをありがとう、Rows.CountとActiveSheetの使い方を改善する方法を説明してくれてありがとう。 – Pascale

+3

私はそこにいると思います。「分割して征服する」アプローチを試してみてください。 '2^20'は1048576に等しいので、これは' Rows.Count'の値です。それはあなたの 'Do ... Loop'が' lastrow 'に到達するまでに20回以上繰り返されることはないと言いました。 – Rosetta

関連する問題