下記のようなコードの場合、A3を変更した場合には
"3"を取得することができました。一方でセルの範囲でA2:A5にまとめて
"Hello"をペーストした場合、"2"しか取得できません。
これをすべて取得して順番にFor each等で行ごとに処理することはかのなのでしょうか?
vba
1Private Sub Worksheet_Change(ByVal Target As Range) 2 If Intersect(Target, Range("A1").EntireColumn) Is Nothing Then 3 Exit Sub 4 5 Else 6 Debug.print Target.Row 7 End If 8End Sub
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。

回答3件
0
ベストアンサー
ご推察通り、For each で可能です。
vba
1Private Sub Worksheet_Change(ByVal Target As Range) 2 If Intersect(Target, Range("A1").EntireColumn) Is Nothing Then 3 Exit Sub 4 Else 5 Dim r As Range 6 For Each r In Target 7 Debug.Print r.Row 8 Next 9 End If 10End Sub
投稿2019/07/18 05:57
総合スコア34347
0
すでに解決済みのようですが、、、
下記のようなコードの場合、A3を変更した場合には
"3"を取得することができました。一方でセルの範囲でA2:A5にまとめて
"Hello"をペーストした場合、"2"しか取得できません。
これをすべて取得して順番にFor each等で行ごとに処理することはかのなのでしょうか?
ホントに解決なんですか?
ExcelVBA
1Private Sub Worksheet_Change(ByVal Target As Range) 2 If Intersect(Target, Range("A1").EntireColumn) Is Nothing Then 3 Exit Sub 4 5 Else 6 Debug.Print Target.EntireRow.Address(false,false) 7 End If 8End Sub
こういう答えを期待してたのでは?
あるいは、こうかな?
ExcelVBA
1Private Sub Worksheet_Change(ByVal Target As Range) 2 Dim c As Range 3 4 Set Target = Intersect(Target, Me.Columns("A")) 5 6 If Not Target Is Nothing Then 7 For Each c In Target 8 Debug.Print c.Address 9 Next 10 End If 11End Sub
行番号を全部取得する必要があるかどうか判断する材料がないので、
行番号が全部取得できたとして何に使いたいかを、
説明してほしいなと思います。
というか、ほんとにやりたいことを説明してくれないと、
なにか勘違いされてるような気がします。
投稿2019/07/19 12:58
総合スコア2167
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
hatena19さんの回答への補足です。
ExcelのRangeが示すセルの状態は時と場合により異なり、その状態によって各種挙動が変わることがあります。
Worksheet_Changeの引数のTarget
の場合は、「セル範囲(単一セル・単一領域範囲・複数領域範囲)」を示し、
For Eachを行うと、Target
内のセル1個1個がZ字の順番で取り出されます。
どういうことかというと、行を挿入した場合は新規に挿入された行のセル全てが、Target
に入ります。
そのため、Target
を対象にFor Eachを行うと、その行の1列目のセルから最後の列のセルまでが1個ずつ列挙されます。
対策案はいくつかありますが、汎用的な方法としてはRowsプロパティを使う方法があります。
任意のRangeに対してRowsプロパティを参照すると、参照している範囲自体は変わりませんが、そのRangeを「行毎に区切った範囲」を示すRangeの集合が返されます。
そのため、Target.Rows
に対してFor Eachを行うと、確実に1行ずつのRangeを得られます。
ただし、このRangeは「行毎に区切った範囲」を示しているためやや挙動が特殊になります。
そのため、Cellsプロパティで再度「セル範囲」に戻したほうが扱いやすいです。
他の案として、今回の質問の場合ではA列さえ取得できればいいようにも見えます。
そのため、Intersectで取得した範囲(変更されたセルの内、A列と重なる範囲)を対象にFor Eachしても良いかもしれません。
vba
1Private Sub Worksheet_Change(ByVal Target As Range) 2'https://teratail.com/questions/ 3 4 'Intersect(Target, Range("A1").EntireColumn) 5 'を無駄に堅牢に書いているだけ 6 Dim columnACells As Excel.Range 7 Set columnACells = Target.Application.Intersect( _ 8 Target, _ 9 Target.Worksheet.Range("A1").EntireColumn, _ 10 Target.Worksheet.UsedRange _ 11 ) 12 If columnACells Is Nothing Then 13 Exit Sub 14 End If 15 16 Dim r As Excel.Range 17 For Each r In columnACells 18 Debug.Print r.Row, r.Address 19 Next r 20 21 '参考:汎用的な方法 22 If False Then 23 For Each r In Target.Rows 24 Debug.Print r.Address, 'Targetの各行 25 Debug.Print r.Item(1).Address, '上の行と同じ結果(rが行を示す範囲なため) 26 Debug.Print r.Cells.Item(1).Address '変更された各行の先頭のセルのアドレス 27 Next r 28 End If 29End Sub
投稿2019/07/18 11:06
編集2019/07/18 22:12総合スコア2166
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/07/18 06:14
2019/07/18 09:56 編集
2019/07/18 10:30
2019/07/18 13:53