『条件により列も非表示したい』(ヒロ坊)
お尋ねします。
以下は、実際に設定しているもので、条件により行を非表示にするものです。
これに、列も非表示にしたいのです。
J116:L116のセルが0の場合は、その列(J列〜L列)を非表示にしたいというものです。
どうぞよろしくお願いします。
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
Const pw As String = "11100"
Dim rr As Range, r As Range
If Intersect(Target, Range("D2")) Is Nothing Then Exit Sub
ActiveSheet.Unprotect Password:=pw
Set rr = Rows("21:82")
rr.Hidden = False
For Each r In rr.Rows
If r.Range("N1").Value = 0 Then
r.Hidden = True
End If
Next
ActiveSheet.Protect Password:=pw
End Sub
< 使用 Excel:Excel2021、使用 OS:Windows11 >
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
Const pw As String = "11100"
Dim rr As Range, r As Range
If Intersect(Target, Range("D2")) Is Nothing Then Exit Sub
Application.EnableEvents = False
ActiveSheet.Unprotect Password:=pw
Set rr = Rows("21:82")
rr.Hidden = False
For Each r In rr.Rows
If r.Range("N1").Value = 0 Then
r.Hidden = True
End If
Next r
If Application.WorksheetFunction.CountIf(Range("J116:L116"), "<>0") = 0 Then
Columns("J:L").Hidden = True
Else
Columns("J:L").Hidden = False
End If
ActiveSheet.Protect Password:=pw
Application.EnableEvents = True
End Sub
(稚拙) 2026/06/19(金) 11:56:02
With Rows("21:82")
.Hidden = False
For Each r In .Rows
If r.Columns("N").Value = 0 Then r.Hidden = True
Next
End With
↑と同じ感じの処理にするとしたら↓こんな感じでしょうか?
With Columns("J:L")
.Hidden = False
For Each r In .Columns
If r.Rows("116").Value = 0 Then r.Hidden = True
Next
End With
(白茶) 2026/06/19(金) 14:09:39
■1
提示のコードの主要部分だけを抜き出して整理すると↓のようになります。
Sub 整理()
Dim r As Range
'▼行方向のチェック
Stop 'ブレークポイントの代わり
For Each r In Range("N21:N82")
If r.Value = 0 Then
r.EntireRow.Hidden = True
End If
Next
End Sub
■2
そのうえで、列方向のチェックを加えたいということですから↓のようにすべきといわれているだけです。
Sub 整理改()
Dim r As Range
'▼行方向のチェック
Stop 'ブレークポイントの代わり
For Each r In Range("N21:N82")
If r.Value = 0 Then
r.EntireRow.Hidden = True
End If
Next
'▼列方向のチェック ←【こいつを追加】
Stop 'ブレークポイントの代わり
For Each r In Range("J116:L116")
If r.Value = 0 Then
r.EntireColumn.Hidden = True
End If
Next
End Sub
■3
Withステートメントについては↓などで学習されたらよいとおもいます。
【参考】 http://officetanaka.net/excel/vba/beginner/16.htm
(もこな2) 2026/06/19(金) 16:55:59
■4
そもそもChangeイベントで対応すべき案件なのか?というところも疑問ですが以下のようにすればいいんじゃないでしょうか?
Private Sub Worksheet_Change(ByVal Target As Range)
Dim r As Range
If Not Intersect(Target, Range("D2")) Is Nothing Then
'▼シートを開いた時に1度だけやればよいので、ThisWorkbookモジュールのOpenイベントにすることを検討
With Me 'ThisWorkbookモジュールに書くならMeではダメ(ちゃんとシートを指定すること)
.Unprotect Password:="11100"
.Protect Password:="11100", UserInterfaceOnly:=True
End With
'▼行方向のチェック
With Range("N21:N82")
.EntireRow.Hidden = False
For Each r In .Cells
If r.Value = 0 Then
r.EntireRow.Hidden = True
End If
Next
End With
'▼列方向のチェック【追加分】
With Range("J116:L116")
.EntireColumn.Hidden = False
For Each r In .Cells
If r.Value = 0 Then
r.EntireColumn.Hidden = True
End If
Next
End With
End If
End Sub
(もこな2) 2026/06/20(土) 00:37:55
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Count > 1 Then Exit Sub
If Target.Address <> "$C$9" Then Exit Sub
If Target.Value <> "" And IsNumeric(Target.Value) Then
Application.EnableEvents = False
Call Posting_Output
Application.EnableEvents = True
End If
End Sub
以下のような組み合わせでよいでしょうか?
ただ、実行したところ、うまく作動しません。今一度、ご教示いただきたく、よろしくお願いします。
Private Sub Worksheet_Change(ByVal Target As Range)
Dim r As Range
If Not Intersect(Target, Range("D2")) Is Nothing Then
With Me
.Unprotect Password:="11100"
.Protect Password:="11100", UserInterfaceOnly:=True
End With
If Target.Count > 1 Then Exit Sub
If Target.Address <> "$C$9" Then Exit Sub
If Target.Value <> "" And IsNumeric(Target.Value) Then
Application.EnableEvents = False
Call Posting_Output
Application.EnableEvents = True
End If
Next
End With
With Range("J116:L116")
.EntireColumn.Hidden = False
For Each r In .Cells
If r.Value = 0 Then
r.EntireColumn.Hidden = True
End If
Next
End With
End If
End Sub
(ヒロ坊) 2026/06/22(月) 08:19:57
それでもわからなければ↓が真になるときはどういうときか考えてみましょう。
If Not Intersect(Target, Range("D2")) Is Nothing
(もこな2) 2026/06/22(月) 08:30:55
Private Sub Worksheet_Change(ByVal Target As Range)
Dim r As Range
If Not Intersect(Target, Range("D2")) Is Nothing Then
If Target.Count > 1 Then
msgbox "書き換えのあったセルが2つ以上のため処理しません"
eles
If Target.Address <> "$C$9" Then
If Target.Value <> "" And IsNumeric(Target.Value) Then
msgbox "処理対象です"
end if
eles
msgbox "書き換えのあったセル番地が【$C$9】ではないため処理しません"
end if
end if
eles
msgbox "書き換えのあったセルに【D2セル】が含まれていないため処理しません"
end if
end sub
(もこな2) 2026/06/22(月) 09:18:07
「組み合わせる」というか、二つの処理を必要に応じてそれぞれ実行したい、ということですね?
( Call Posting_Outputの内容が説明されていないので、関係があるかどうか判断不能です。
関連しているなら、きちんと内容説明してください。)
そうであれば、
今回のChangeイベントプロシージャを
Private Sub Worksheet_Change(ByVal Target As Range)
Dim r As Range
If Not Intersect(Target, Range("D2")) Is Nothing Then
'' その場合の処理 をここに書きます。ここは出来ているわけです。
End If
'(*)
End Sub
のように、Exit Subを使わずに、「条件を満たすときに、これこれの処理を行う」という方式にすれば、
今のもののあと(つまり(*)の位置)に、
今回追加したいコード片を追加するだけでよいのでは?
なお、(ヒロ坊) 2026/06/22(月) 08:19:57のコードは If と End If が対応していなかったり、Nextが突然でてきたりしています。もう少し神経使ったほうがよいでしょう。
(xyz) 2026/06/22(月) 13:37:16
■5
失礼「Else」のスペルと分岐結果の整理をミスってました。
正しく整理するとこうですね。
Private Sub Worksheet_Change(ByVal Target As Range)
Dim r As Range
If Not Intersect(Target, Range("D2")) Is Nothing Then
If Target.Count > 1 Then
MsgBox "書き換えのあったセルが2つ以上のため処理しません"
Else
If Target.Address <> "$C$9" Then
MsgBox "書き換えのあったセル番地が【$C$9】ではないため処理しません"
Else
If Target.Value <> "" And IsNumeric(Target.Value) Then
MsgBox "処理対象です"
End If
End If
End If
Else
MsgBox "書き換えのあったセルに【D2セル】が含まれていないため処理しません"
End If
End Sub
提示のコードも落ち着いて見ればわかると思いますが、【D2セル】と【C9セル】を含むセル範囲をいっぺんに書き換えれば「If Not Intersect(Target, Range("D2")) Is Nothing Then」は真になりますが、同時に「If Target.Count > 1 Then」も真になるので、指示通り「Exit Sub」してるわけです。
(C9セルのみを書き換えた場合は、D2セルが含まれていませんから最初の条件を満たしません。)
■6
したがって、セルの書き換えをマクロの発動条件にする必要があるのかというところは引き続きの疑問ですが、例えば↓のようにすべきでしょう。
Private Sub Worksheet_Change(ByVal Target As Range)
Dim r As Range
If Not Intersect(Target, Range("D2")) Is Nothing Then
'D2セル(を含むセル範囲)が書き換えられたときにやりたい処理
End If
If Not Intersect(Target, Range("C9")) Is Nothing Then
If Range("C9").Value <> "" And IsNumeric(Range("C9").Value) Then
Application.EnableEvents = False
Call Posting_Output
Application.EnableEvents = True
End If
End If
End Sub
※ChangeはTargetが複数になりえますので「Target.Value <> ""」などもよろしくないとおもいましたので修正しています。 「If Target.Count > 1 Then Exit Sub」をそのままにするならば、変えなくても大丈夫です。
(もこな2) 2026/06/22(月) 15:04:33
Private Sub Worksheet_Change(ByVal Target As Range)
Dim r As Range
If Not Intersect(Target, Range("D2")) Is Nothing Then
'D2セル(を含むセル範囲)が書き換えられたときにやりたい処理
End If
If Not Intersect(Target, Range("C9")) Is Nothing Then
If Range("C9").Value <> "" And IsNumeric(Range("C9").Value) Then
Application.EnableEvents = False
Call Posting_Output
Application.EnableEvents = True
End If
Next
End With
With Range("J116:L116")
.EntireColumn.Hidden = False
For Each r In .Cells
If r.Value = 0 Then
r.EntireColumn.Hidden = True
End If
Next
End With
End If
End Sub
(ヒロ坊) 2026/06/23(火) 07:35:43
■(もこな2) 2026/06/20(土) 00:37:55 にてご提示いただいたもの
Private Sub Worksheet_Change(ByVal Target As Range)
Dim r As Range
If Not Intersect(Target, Range("D2")) Is Nothing Then
'▼シートを開いた時に1度だけやればよいので、ThisWorkbookモジュールのOpenイベントにすることを検討
With Me 'ThisWorkbookモジュールに書くならMeではダメ(ちゃんとシートを指定すること)
.Unprotect Password:="11100"
.Protect Password:="11100", UserInterfaceOnly:=True
End With
'▼行方向のチェック ←ここから不要
With Range("N21:N82")
.EntireRow.Hidden = False
For Each r In .Cells
If r.Value = 0 Then
r.EntireRow.Hidden = True
End If
Next
End With ←ここまで不要
'▼列方向のチェック【追加分】
With Range("J116:L116")
.EntireColumn.Hidden = False
For Each r In .Cells
If r.Value = 0 Then
r.EntireColumn.Hidden = True
End If
Next
End With
End If
End Sub
■以下の動作を追加
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Count > 1 Then Exit Sub
If Target.Address <> "$C$9" Then Exit Sub
If Target.Value <> "" And IsNumeric(Target.Value) Then
Application.EnableEvents = False
Call Posting_Output
Application.EnableEvents = True
End If
End Sub
(ヒロ坊) 2026/06/23(火) 07:59:08
懸念点をいくつか。杞憂であればよいですが。 (1) > 「組み合わせる」というか、二つの処理を必要に応じてそれぞれ実行したい、ということですね? > ( Call Posting_Outputの内容が説明されていないので、関係があるかどうか判断不能です。 > 関連しているなら、きちんと内容説明してください。) と書きました。
(ヒロ坊)さん提示の、 2026/06/22(月) 08:19:57のコードを改めて見ると、 もともとあった「行に関する非表示の処理」がなくなっていますよね。 単に、変更処理の途中で一部だけ載せましたということならいいですが、 その行に関する処理の代替が Call Posting_Outputということなんですか?(名前からは想定しにくいですが) それなら、そのように説明したうえで、Posting_Outputのコード内容を提示するのが筋でしょう。
(2)また、行、列を非表示にする処理が、Posting_Outputの処理に影響があり、 Posting_Outputの処理を先に処理しないといけないなら、そのことを考慮する必要があります。
いずれにしても、正確な情報提供をしてください。でないと正確な回答は得られません。 私はここまでとします。頑張ってください。 # 早朝に書いてあったもので、本日の質問者さんのコメントは読んでいない # 段階のものです。
(xyz) 2026/06/23(火) 08:02:03
1■↓動作確認済
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Count > 1 Then Exit Sub
If Target.Address <> "$C$9" Then Exit Sub
If Target.Value <> "" And IsNumeric(Target.Value) Then
Application.EnableEvents = False
Call Posting_Output
Application.EnableEvents = True
End If
End Sub
2■↓動作確認済
Private Sub Worksheet_Change(ByVal Target As Range)
Dim r As Range
If Not Intersect(Target, Range("B9")) Is Nothing Then
With Me
.Unprotect Password:="11100"
.Protect Password:="11100", UserInterfaceOnly:=True
End With
With Range("E17:AH17")
.EntireColumn.Hidden = False
For Each r In .Cells
If r.Value = 0 Then
r.EntireColumn.Hidden = True
End If
Next
End With
End If
End Sub
(ヒロ坊) 2026/06/23(火) 08:14:57
気になるところを何点か。
★1
同じシートモジュールに【Worksheet_Change】は1つしか記述できません。
なので、私もxyzさんも↓のように分けて書く必要がありますよと言ってるわけです。
Private Sub Worksheet_Change(ByVal Target As Range)
'D2セル(を含むセル範囲)が書き換えられたときにやりたい処理
'C9セルのみが書き換えられたときにやりたい処理
End Sub
★2
ガン無視されましたが、以下はブックを開くときに1度だけ行えばよい処理です。
With Me
.Unprotect Password:="11100"
.Protect Password:="11100", UserInterfaceOnly:=True
End With
何を言われているかわからない場合は↓のように、元に戻したほうが理解しやすいとおもいます。
保護解除
〜処理〜
保護し直し
★3
>必要に応じて処理したいというものです。
こちらも無視されていますが、尚更、Changeイベントで処理する話なのか疑問があります。
■8(余談です)
今更ですが、
For Each r In Rows("21:82").Rows
If r.Range("N1").Value = 0 Then
r.Hidden = True
End If
Next
と
For Each r In Range("N21:N82")
If r.Value = 0 Then
r.EntireRow.Hidden = True
End If
Next
【r】に取り出されるもの違うのですが気づいてますよね?
前者は行全体、後者はセル単体です。
(もこな2) 2026/06/23(火) 09:06:36
■9
2026/06/23(火) 08:14:57のセル番地に合せるとこういうことになるんじゃないでしょうか?
Private Sub Worksheet_Change(ByVal Target As Range)
Dim r As Range
Stop 'ブレークポイントの代わり
'▼C9セルのみ書き換えがあった時の処理
If Not Target.Count > 1 Then
If Not Target.Address <> "$C$9" Then
If Target.Value <> "" And IsNumeric(Target.Value) Then
Application.EnableEvents = False
'Call Posting_Output
Application.EnableEvents = True
End If
End If
End If
'▼B9セルを含むセル(範囲)の書き換えがあった時の処理
If Not Intersect(Target, Range("B9")) Is Nothing Then
ActiveSheet.Unprotect Password:="11100"
With Range("E17:AH17")
.EntireColumn.Hidden = False
For Each r In .Cells
If r.Value = 0 Then
r.EntireColumn.Hidden = True
End If
Next
End With
ActiveSheet.Protect Password:="11100"
End If
End Sub
いずれにせよ、切り貼りしたものをこれでよいか?って聞くんじゃなくて、○○になるとおもって✕✕のようにしたんだけど(ステップ)実行すると、△△のようになってしまうので困っているなど、具体的にお困りの状況を説明できないでしょうか?
(もこな2) 2026/06/25(木) 20:28:34
■11
>Notも消す必要があると思い
なぜそう思ったのですか?
以下は、それぞれどういう命令だと理解してますか?
If Target.Count > 1 Then Exit Sub →〜〜のとき〜〜する
If Target.Address <> "$C$9" Then Exit Sub →〜〜のとき〜〜する
If Not Intersect(Target, Range("D2")) Is Nothing Then
★処理★
End If
→〜〜のときに処理が実行される
(もこな2) 2026/06/26(金) 08:39:52
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Range("D2")) Is Nothing Then
If Target.Count > 1 Then Exit Sub
If Target.Address <> "$C$9" Then Exit Sub
If Target.Value <> "" And IsNumeric(Target.Value) Then
★処理★
End If
End If
End Sub
上記のコードで、それぞれ以下の場合、どうなるとおもってますか?
(全体を9行と考えて答えてください)
(答えは■5にありますが、ひとまずカンニングなしで考えてみてください)
★1 D2のみ入力があった場合
→〇行目のExit Subが実行される
★2 C9のみ入力があった場合
→〇行目が偽と判定されるから〇行目に進む
★3 D2とC9に同時に入力があった場合
→〇行目のExit Subが実行される
(もこな2) 2026/06/26(金) 09:16:09
★1 D2のみ入力があった場合
→21行目のExit Subが実行される
★2 C9のみ入力があった場合
→17行目が偽と判定されるから21行目に進む
★3 D2とC9に同時に入力があった場合
→17行目のExit Subが実行される
(ヒロ坊) 2026/06/26(金) 10:04:42
01 Private Sub Worksheet_Change(ByVal Target As Range)
02 If Not Intersect(Target, Range("D2")) Is Nothing Then
03 If Target.Count > 1 Then Exit Sub
04 If Target.Address <> "$C$9" Then Exit Sub
05 If Target.Value <> "" And IsNumeric(Target.Value) Then
06 ★処理★
07 End If
08 End If
09 End Sub
上記の9行を前提に話をしているつもりなので、21行目とか17行目とか存在しない行を言われても理解できてるのかわかりません。
見切り発車ですが、解説をアップします。
★1 D2のみ入力があった場合
→「Target.Address」が"$C$9"ではありませんから4行目のExit Subが実行されて終了します。
★2 C9のみ入力があった場合
→D2セルが含まれませんから、2行目が偽と判定され8行目に進み、次の行のEnd Subで終了します。
★3 D2とC9に同時に入力があった場合
→「Target.Address」が2(1より大きい)になりますから3行目のExit Subが実行されて終了します。
このように、「2026/06/22(月) 08:19:57」で質問のあったコードは構文としては間違ってませんが、★処理★にたどり着くものが無いのです。
「2026/06/22(月) 08:30:55」でも述べましたが、これはご自身でブレークポイントを設定し、ステップ実行して確認すれば容易に気づけます。
繰り返しになりますが、提示されたコードを切り貼りするだけではなく、ちゃんとコードの意味を理解していないと修正できないと思います。
(もこな2) 2026/06/26(金) 12:34:59
Private Sub Worksheet_Change(ByVal Target As Range)
Dim r As Range
If Not Intersect(Target, Range("D2")) Is Nothing Then
With Me
.Unprotect Password:="11100"
.Protect Password:="11100", UserInterfaceOnly:=True
End With
If Target.Count > 1 Then Exit Sub
If Target.Address <> "$C$9" Then Exit Sub
If Target.Value <> "" And IsNumeric(Target.Value) Then
←この行に処理にたどり着くものが必要ということでしょうか?
Application.EnableEvents = False
Call Posting_Output
Application.EnableEvents = True
End If
Next
End With
With Range("J116:L116")
.EntireColumn.Hidden = False
For Each r In .Cells
If r.Value = 0 Then
r.EntireColumn.Hidden = True
End If
Next
End With
End If
End Sub
(ヒロ坊) 2026/06/26(金) 16:26:38
C9 が書き変えられたら1■を、B9 が書き変えらたら2■を処理する
と言うことですよね。
↑
コパイロットに聞いてみました。
Worksheet_Change 内での統合版を作成してみました。
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.CountLarge > 1 Then Exit Sub
Select Case Target.Address
'-------------------------
' 1■ C9 が変更されたとき
'-------------------------
Case "$C$9"
If Target.Value <> "" And IsNumeric(Target.Value) Then
Application.EnableEvents = False
Posting_Output
Application.EnableEvents = True
End If
'-------------------------
' 2■ B9 が変更されたとき
'-------------------------
Case "$B$9"
With Me
.Unprotect Password:="11100"
.Protect Password:="11100", UserInterfaceOnly:=True
End With
Dim r As Range
With Range("E17:AH17")
.EntireColumn.Hidden = False
For Each r In .Cells
If r.Value = 0 Then r.EntireColumn.Hidden = True
Next
End With
Case Else
Exit Sub
End Select
End Sub
これで合っているかどうかわからんけど。
(マクロ苦手) 2026/06/26(金) 18:15:09
そのうえでわからない(悩んでいる)部分はどこですか?
「2026/06/22(月) 08:19:57」と「2026/06/26(金) 16:26:38」で提示のコードは同じものかとおもいますが、そこから判定・分岐の部分だけ抜き出したものが↓です。
01 Private Sub Worksheet_Change(ByVal Target As Range)
02 If Not Intersect(Target, Range("D2")) Is Nothing Then
03 If Target.Count > 1 Then Exit Sub
04 If Target.Address <> "$C$9" Then Exit Sub
05 If Target.Value <> "" And IsNumeric(Target.Value) Then
06 ★処理★
07 End If
08 End If
09 End Sub
上記のコードで"うまく作動しません"と仰っていることについて、実際には何が起こってるかは「■13」で解説済です。
(確認方法はステップ実行するのが一番わかりやすいとおもいます。(だから■10でなんで消したのか聞いています。))
また、何を勘違いしているのか想像はついていますし、解決方法もいくつか思いついていますが、■11の答えを見てから説明しようと思っています。
大ヒント(というか答え) 「Exit Sub」してそこで終わっちゃってるのが問題でしょう。 そして、解消方法は【(xyz) 2026/06/22(月) 13:37:16】で既に指摘されています。
(もこな2) 2026/06/26(金) 18:29:09
セルの書き換えは単純な入力だけではなく、セル範囲をまとめて貼付けしたときや消去したときも含まれますから、意外と複数セルの書き換えが起こることは多いです。(もちろん、複数セルを選択している状況で入力し、Ctrl + Enterで確定したときも複数セルの書き換えになります)
したがってIntersectメソッドでの判定はそのまま採用されたほうがいいんじゃないかと思いました。
(もこな2) 2026/06/26(金) 19:03:09
逆を言えば、Target.Addressが「"$C$9"」のときは、絶対に1つのセルしか書き換わってないわけです。
なので↓のようにすれば、Select Caseでの分岐でもよいとおもいます。
Private Sub Worksheet_Change(ByVal Target As Range)
Select Case True
Case Target.Address = "$C$9"
'◆1 C9セルのみが変更されたとき
MsgBox "C9セルのみが書き換えられました"
Case Not Intersect(Range("B9"), Target) Is Nothing
'◆2 B9セルを含むセル範囲が変更されたとき
MsgBox "B9セルを含むセル範囲が書き換えられました"
Case Else
'Exit Sub ←この後の処理分岐や処理はなく、End Subするだけなので無くてもよい
End Select
End Sub
ただ、Select Caseの処理は排他(1回の実行で両方が処理されることはない)となりますが、既に述べたようにChangeイベントは、複数のセルが書き換わることが往々にしてありうるので、「■6」で提示したように、どちらの条件も満たすときは両方の処理をするという設計にしたほうがいいんじゃないかと思っています。
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Range("D2")) Is Nothing Then
'◆3 D2セルを含むセル範囲が変更されたとき
MsgBox "D2セルを含むセル範囲が書き換えられました"
End If
If Not Intersect(Target, Range("C9")) Is Nothing Then
'◆4 C9セルを含むセル範囲が変更されたとき
MsgBox "C9セルを含むセル範囲が書き換えられました" & vbLf & "C9セルの値は「" & Range("C9").Value & "」です"
End If
End Sub
(もこな2) 2026/06/26(金) 22:43:29
(ヒロ坊) 2026/06/27(土) 07:00:46
(匿名) 2026/06/27(土) 09:47:30
あと、確認がなかったので理解してると解釈してますが、【ステップ実行】や【ブレークポイント】という言葉の意味がわからないのであれば↓などを読んでみてください。
【ステップ実行】 https://www.239-programing.com/excel-vba/basic/basic023.html http://plus1excel.web.fc2.com/learning/l301/t405.html
【ブレークポイント】 https://www.239-programing.com/excel-vba/basic/basic022.html https://www.tipsfound.com/vba/01010
■18
>2026/06/26(金) 18:29:09を見返して、理解できたように思います。
そもそも、こちらが確認したかったことは以下の通りです。
■10での確認 ステップ実行するためにブレークポイントを設定する必要があるはずですがなんで消したのか?
■11での確認 ↓は、それぞれどういう命令と理解しているか。
If Target.Count > 1 Then Exit Sub
If Target.Address <> "$C$9" Then Exit Sub
If Not Intersect(Target, Range("D2")) Is Nothing Then
★処理★
End If
理解できたということなので詳しい説明は省きますが、前者2つは条件を満たしたときにそこで処理を終了するという命令になっている一方で、3番目は条件を満たしたときに「★処理★」を実行するという命令です。
出かける用事があるので、残りは後程にします。
(もこな2) 2026/06/27(土) 10:04:15
■19
おそらくですがトピ主はIF関数の記述方法を勘違いしているものと思われます。
IF関数の基本的な形は以下の通りです。
If 条件式 Then
真のときの処理内容 ←Then節といいます
Else
偽のときの処理内容 ←Else節といいます
End If
そして、Then節のみの場合は以下のようにElse節を省略することができます。
If 条件式 Then
真のときの処理内容 ←Then節のみ記述する
End If
さらに、Then節が1行のみの場合は以下のような記述も可能です。
If 条件式 Then 真のときの処理内容 ←「End If」は記述してはいけません
----------------------------------- ここまでが理解できていなければ、もう一度読み直すなり、実験するなり、質問するなりしてください。 以下は理解できたものとして話しています。 -----------------------------------
上記を踏まえると、
If Target.Address <> "$C$9" Then Exit Sub
↑は↓と同じ意味ということが理解できるかとおもいます。
If Target.Address <> "$C$9" Then
Exit Sub
End If
ですが、今回の場合は「Target.Address」が【"$C$9"じゃないとき】【じゃないとき】に"処理したい"わけですよね。
すると以下のように、Else節に処理を書けばよいと思いつくかもしれません。
If Target.Address <> "$C$9" Then
Exit Sub
Else
★処理★ ←条件が真【じゃないとき】にやりたいこと
End If
ですが、余談2の余談でも触れてますが、Exit SubしなくてもそのままEnd Subに向かって進むだけならば、どのみち処理終了しますので無くてもよいわけです。これを踏まえると↓のようにThen節に何も書かなくてもよいことになります。
If Target.Address <> "$C$9" Then
Else
★処理★ ←【条件が真】【じゃないとき】にやりたいこと
End If
ここでちょっと考えてみましょう。「【条件が真】【じゃないとき】」って別の書き方ができないでしょうか?
書くとややこしくなりますが「条件が真じゃないとき」という条件にすることもOKです。
すなわち↓でもOKということになります。
If Not 条件 Then
★処理★
End If
と、ここまで書けばわかったと思いますが↓からNotを取ってしまったらマズイですよね?
If Not 【Target.Addressが"$C$9"じゃないとき】 Then
★処理★
End If
なので、「■11」でどういう命令と理解してるのか確認したのです。
■20
ちなみに、以下は同じ意味になりますから、Notを記述したくないといったことであれば、採用されるとよいでしょう。
If Not Target.Address <> "$C$9" Then
If Target.Address = "$C$9" Then
また、Target.Addressが「"$C$9"」のときは、かならず「Target.Count」も「1」ですから、理屈が理解できているならば省略してもよいとおもいます。
(逆に実害があるわけじゃないので、数か月後の自分が理屈をわすれてしまいそうならばそのままにしたほうがよいでしょう)
------------------------------------------------------------ 長くなったのでいったん区切ります。 ------------------------------------------------------------ 「■19」について、Else IFやマルチステートメントは意図して説明していません。 説明できる回答者さんいらっしゃいましたらフォローをお願いします。
(もこな2) 2026/06/28(日) 15:36:52
Private Sub Worksheet_Change(ByVal Target As Range)
Dim r As Range
If Not Intersect(Target, Range("D2")) Is Nothing Then
If Target.Count > 1 Then Exit Sub
If Target.Address <> "$C$9" Then Exit Sub
If Target.Value <> "" And IsNumeric(Target.Value) Then
Call Posting_Output
Range("J116:L116").EntireColumn.Hidden = False
For Each r In Range("J116:L116").Cells
If r.Value = 0 Then
r.EntireColumn.Hidden = True
End If
Next
End If
End If
End Sub
そうです。「■5」でも述べていますが、「TargetがD2セルを含む」という条件と「Target.Addressが"$C$9"のもの」という条件のどちらも満たすものがないので処理に進まなかったわけです。
だから「■6」などで↓のようにすべきだという話をしていたわけです。
Private Sub Worksheet_Change(ByVal Target As Range)
Dim r As Range
If Not Intersect(Target, Range("D2")) Is Nothing Then
'D2セル(を含むセル範囲)が書き換えられたときにやりたい処理
End If
If Not Intersect(Target, Range("C9")) Is Nothing Then
'C9セル(を含むセル範囲)が書き換えられたときにやりたい処理
End If
End Sub
■22
>ステップ実行、ブレークポイントについても勉強します。
是非そのようにしてください。いずれも、デバッグ作業の超基本となる技術です。
正直に言うと、「2026/06/23(火) 07:35:43」の時点で↓のような状態でしたので、ただ切り貼りしてるだけで、ステップ実行もしていないのだろうと推測していました。
・「'D2セル(を含むセル範囲)が書き換えられたときにやりたい処理」がそのまま残っている
・構文ミスが直っていない
おそらく元のコードは引き継いだものだったり、ネットで見かけたものなどでご自身で書いたものではないのでしょが、今の担当者はあなたです。
何度も言っているように、中身がわからないまま切り貼りすれば何とかなるってものでもないので、わからない命令や用語はちゃんとしらべて、それでも不安なら「××について〇〇と理解したけどあってますか?」などのように追加質問して理解されるとよいとおもいます。
■23
話がそれますが、仕組み(理屈)が分かった今なら、「D2セルに関する処理」と「C9セルに関する処理を」分けて書くべきって指摘をされているのに↓はおかしなことを確認しているとわかりますよね?
←この行に処理にたどり着くものが必要ということでしょうか?
また、「Exit Sub」する書き方にこだわりがあるということならば、↓のように順番を変えれば対応することはではあります。
Private Sub Worksheet_Change(ByVal Target As Range)
Dim r As Range
If Not Intersect(Target, Range("D2")) Is Nothing Then
'〜〜処理〜〜
End If
If Target.Address <> "$C$9" Then Exit Sub
'〜〜処理〜〜
End Sub
よって、「2026/06/22(月) 08:19:57」の何が一番マズかったかというと、「TargetにD2セルが含まれているか」という判定をしている中に、まったく別の「C9セルに関する判定(と処理)」をいれてしまったことが問題だったわけです。(構文のミスもよくはありませんが、実行以前にコンパイルエラーでエクセル君から指摘されて気づけたはずです)
■24
閑話休題。ここまでで、大まかな部分の説明はしたかとおもいます。
細かい部分で余談的な話を追加するかもしれませんが、ひとまず私もここまでとします。
トピックは追ってますので、追加質問等あれば↓のように具体例を挙げて状況を説明いただければわかる範囲で解説します。
〇〇のとき××になるとおもい、ステップ実行で確認したところ、△△から☆☆のところに進んでしまった。 ××のところで、〇〇というエラーが発生してしまった
(もこな2) 2026/06/28(日) 17:19:48
Private Sub Worksheet_Change(ByVal Target As Range)
Dim r As Range
Debug.Print Target.Address(RowAbsolute:=False, ColumnAbsolute:=False, ReferenceStyle:=xlA1, External:=False)
'▼C9セルのみ書き換えがあった時の処理
If Target.Address = "$C$9" Then
If Target.Value <> "" And IsNumeric(Target.Value) Then
Stop 'ブレークポイントの代わり
Application.EnableEvents = False
Call Posting_Output
Application.EnableEvents = True
Else
Debug.Print "Target.Valueは「" & Target.Value & "」です"
End If
End If
'▼B9セルを含むセル(範囲)の書き換えがあった時の処理
If Not Intersect(Target, Range("B9")) Is Nothing Then
Stop 'ブレークポイントの代わり
ActiveSheet.Unprotect Password:="11100"
With Range("E17:AH17")
.EntireColumn.Hidden = False
For Each r In .Cells
If r.Value = 0 Then
r.EntireColumn.Hidden = True
End If
Next
End With
ActiveSheet.Protect Password:="11100"
End If
End Sub
もし、こちらでも思い通りの動作にならず、かつ自己解決ができない場合は、イミディエイトに何と出力されたのかを添えて質問されるとよいと思います。
(※イミディエイトが何なのかわからない場合は↓で学習してみてください。)
【イミディエイトウィンドウ】 https://www.sejuku.net/blog/46859#index_id2 https://excel-ubara.com/excelvba1/EXCELVBA486.html
また、↓も覚えておいて損はないと思います。
【ローカルウィンドウ】 https://excel-ubara.com/excelvba4/EXCEL266.html http://excelvba.pc-users.net/fol8/8_2.html
■26(余談3)
「■6」「■9」で触れてますが「Target.Value」に拘る場合は、Targetが複数セルだとマズいわけです。
もっと言うと複数のセルを対象にValueプロパティで値を取り出そうとすると問題になります。
なので、最初のコードでは↓のように「r」に【行全体】を取り出してから、【行全体】のうち"N1セルに相当するセル"という指定の仕方をしていたのです。
Set rr = Rows("21:82")
For Each r In rr.Rows
If r.Range("N1").Value = 0 Then
r.Hidden = True
End If
Next
よって、同じようにE〜AH列から「r」に【列全体】を取り出して、【列全体】のうち116行目という指定をするなら次のようになります。
Set rr = Columns("E:AH")
For Each r In rr.Columns
If r.Range("A116").Value = 0 Then
r.Hidden = True
End If
Next
この点について、私が示したコードだと、「r」に取り出すものが【セル単体】になっています。
一方で、【セル単体】は独立して表示/非表示といったことはできませんから、私の提示したものではEntireRow(EntireColumn)を使って【セル単体】.【を含む行(列)全体】というようにして操作しています。
このあたりも、提示のあったものを何も考えず切り貼りするのではなく、ご自身が理解(納得)した方法にされるとよいでしょう。
(もこな2) 2026/07/04(土) 07:58:44
[ 一覧(最新更新順) ]
YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki.
Modified by kazu.