質問1 多分for ~ next 構文の中でE列の数字を修正した時にそこで別イベントが発生して ということなんだと思いますが、それが原因でしょうか。 1~5入力時も同じようなことをやっているので何が違うんだろうといのがよくわかりません。 結果的に、select case 構文内にExit for を追加して抜け出ることができたんですが・・・。
質問2 中断できずに強制終了してしまったので、仕事中に発生すると少しいやだなと思った んですが、フラグ制御についてよくわかってない段階でfor ~ next 構文を使うのは あまりよくないんでしょうか。一般論というか作法的に。 とはいっても実務的には使いそうですので注意点等あったらお願いします。
Private Sub Worksheet_Change(ByVal Target As Range)
Dim c As Long
Dim sRow, sClm, tRow As Long
sRow = 10
sClm = 4
'行と列の制限によるExit
tRow = Target.Row
If tRow < sRow Then
Exit Sub
End If
If Target.Column < sClm Then
Exit Sub
End If
'新規入力の場合B、C列に時刻入力
If Range("B" & tRow).Value <> Now Then
Range("B" & tRow).Value = Now
Range("C" & tRow).Value = Now
Else
Range("C" & tRow).Value = Now
End If
'[4]
'D列に数値の1~5のどれかの値を入力すると、値が入力された行のA列~G列の背景色は、セルD2~E6の対応する値の色になる。
'ただし、それ以外の値を入力したときは、色はなくなる。
'[5]
'D列に数値の1~5のどれかの値を入力すると、セルD2~E6に記載されている、その数値に対応した文字列がE列に記入される。
'ただし、それ以外の値を入力した場合は、E列の値はなくなる。
For c = 2 To 6
Select Case Range("D" & tRow).Value
Case Is > 5
Range(Range("A" & tRow), Range("G" & tRow)).Interior.Color = xlNone
Range("E" & tRow).ClearContents
Case Is < 1
Range(Range("A" & tRow), Range("G" & tRow)).Interior.Color = xlNone
Range("E" & tRow).ClearContents
End Select
If Range("D" & c).Value = Range("D" & tRow).Value Then
Range(Range("A" & tRow), Range("G" & tRow)).Interior.Color = _
Range("D" & c).Interior.Color
Range("D" & tRow).Offset(, 1).Value = _
Range("D" & c).Offset(, 1).Value
End If
Next
End Sub
Private Sub Worksheet_Change(ByVal Target As Range)
Dim c As Long
' Dim sRow, sClm, tRow As Long
Dim sRow As Long, sClm As Long, tRow As Long 'VBのバージョンによりますが、6.xでは必要。 ogawa
sRow = 10
sClm = 4
'行と列の制限によるExit
tRow = Target.Row
If tRow < sRow Then
Exit Sub
End If
If Target.Column < sClm Then
Exit Sub
End If
'新規入力の場合B、C列に時刻入力
If Range("B" & tRow).Value <> Now Then
Range("B" & tRow).Value = Now '←[a]ここでも worksheet_change が再帰的に呼び出されますね。 ogawa
Range("C" & tRow).Value = Now '←[b]ここでも worksheet_change が再帰的に呼び出されますね。 ogawa
Else
Range("C" & tRow).Value = Now
End If
'[a],[b]だけでも永久ループする可能性大です(処理に時間がかかれば。一瞬なら大丈夫かもしれませんが)。フラグ立てて回避しないと。 ogawa
'[4]
'D列に数値の1~5のどれかの値を入力すると、値が入力された行のA列~G列の背景色は、セルD2~E6の対応する値の色になる。
'ただし、それ以外の値を入力したときは、色はなくなる。
'[5]
'D列に数値の1~5のどれかの値を入力すると、セルD2~E6に記載されている、その数値に対応した文字列がE列に記入される。
'ただし、それ以外の値を入力した場合は、E列の値はなくなる。
For c = 2 To 6
Select Case Range("D" & tRow).Value
Case Is > 5
Range(Range("A" & tRow), Range("G" & tRow)).Interior.Color = xlNone
Range("E" & tRow).ClearContents '←[C]ここでも worksheet_change が再帰的に呼び出されますね。 ogawa
Case Is < 1
Range(Range("A" & tRow), Range("G" & tRow)).Interior.Color = xlNone
Range("E" & tRow).ClearContents '←[C]ここでも worksheet_change が再帰的に呼び出されますね。 ogawa
End Select
If Range("D" & c).Value = Range("D" & tRow).Value Then
Range(Range("A" & tRow), Range("G" & tRow)).Interior.Color = _
Range("D" & c).Interior.Color
Range("D" & tRow).Offset(, 1).Value = _
Range("D" & c).Offset(, 1).Value
End If
Next
End Sub
2015/01/07 10:08
ゲストさんのコメント
(コメントID: 2143)
以下は、フラグを使った例です。両者をステップイン実行して試してみると良いかと思います。
Dim b As Boolean
Private Sub Worksheet_Change(ByVal Target As Range)
If b = True Then
Exit Sub
End If
Dim c As Long
' Dim sRow, sClm, tRow As Long
Dim sRow As Long, sClm As Long, tRow As Long 'VBのバージョンによりますが、6.xでは必要。 ogawa
sRow = 10
sClm = 4
'行と列の制限によるExit
tRow = Target.Row
If tRow < sRow Then
Exit Sub
End If
If Target.Column < sClm Then
Exit Sub
End If
'新規入力の場合B、C列に時刻入力
If Range("B" & tRow).Value <> Now Then
b = True
Range("B" & tRow).Value = Now '←[a]ここでも worksheet_change が再帰的に呼び出されますね。 ogawa
Range("C" & tRow).Value = Now '←[b]ここでも worksheet_change が再帰的に呼び出されますね。 ogawa
b = False
Else
b = True
Range("C" & tRow).Value = Now
b = False
End If
'[a],[b]だけでも永久ループする可能性大です(処理に時間がかかれば。一瞬なら大丈夫かもしれませんが)。フラグ立てて回避しないと。 ogawa
'[4]
'D列に数値の1~5のどれかの値を入力すると、値が入力された行のA列~G列の背景色は、セルD2~E6の対応する値の色になる。
'ただし、それ以外の値を入力したときは、色はなくなる。
'[5]
'D列に数値の1~5のどれかの値を入力すると、セルD2~E6に記載されている、その数値に対応した文字列がE列に記入される。
'ただし、それ以外の値を入力した場合は、E列の値はなくなる。
For c = 2 To 6
Select Case Range("D" & tRow).Value
Case Is > 5
Range(Range("A" & tRow), Range("G" & tRow)).Interior.Color = xlNone
b = True
Range("E" & tRow).ClearContents '←[C]ここでも worksheet_change が再帰的に呼び出されますね。 ogawa
b = False
Case Is < 1
Range(Range("A" & tRow), Range("G" & tRow)).Interior.Color = xlNone
b = True
Range("E" & tRow).ClearContents '←[C]ここでも worksheet_change が再帰的に呼び出されますね。 ogawa
b = False
End Select
If Range("D" & c).Value = Range("D" & tRow).Value Then
Range(Range("A" & tRow), Range("G" & tRow)).Interior.Color = _
Range("D" & c).Interior.Color
b = True
Range("D" & tRow).Offset(, 1).Value = _
Range("D" & c).Offset(, 1).Value
b = False
End If
Next
End Sub
>小川様 >演習問題の作成途中でハマった点について質問です。 >D列(Priority1)に1~5以外の数字を入れると、マクロ実行中のまま応答しなくなり、 >タスクマネジャーから強制終了しました。 > >質問1 > 多分for ~ next 構文の中でE列の数字を修正した時にそこで別イベントが発生して > ということなんだと思いますが、それが原因でしょうか。 > 1~5入力時も同じようなことをやっているので何が違うんだろうといのがよくわかりません。 > 結果的に、select case 構文内にExit for を追加して抜け出ることができたんですが・・・。 > >質問2 > 中断できずに強制終了してしまったので、仕事中に発生すると少しいやだなと思った > んですが、フラグ制御についてよくわかってない段階でfor ~ next 構文を使うのは > あまりよくないんでしょうか。一般論というか作法的に。 > とはいっても実務的には使いそうですので注意点等あったらお願いします。 > >
>Private Sub Worksheet_Change(ByVal Target As Range)
>
> Dim c As Long
> Dim sRow, sClm, tRow As Long
> sRow = 10
> sClm = 4
> '行と列の制限によるExit
> tRow = Target.Row
> If tRow < sRow Then
> Exit Sub
> End If
>
> If Target.Column < sClm Then
> Exit Sub
> End If
>
> '新規入力の場合B、C列に時刻入力
> If Range("B" & tRow).Value <> Now Then
> Range("B" & tRow).Value = Now
> Range("C" & tRow).Value = Now
> Else
> Range("C" & tRow).Value = Now
> End If
>
>
> '[4]
> 'D列に数値の1~5のどれかの値を入力すると、値が入力された行のA列~G列の背景色は、セルD2~E6の対応する値の色になる。
> 'ただし、それ以外の値を入力したときは、色はなくなる。
> '[5]
> 'D列に数値の1~5のどれかの値を入力すると、セルD2~E6に記載されている、その数値に対応した文字列がE列に記入される。
> 'ただし、それ以外の値を入力した場合は、E列の値はなくなる。
>
> For c = 2 To 6
>
> Select Case Range("D" & tRow).Value
> Case Is > 5
> Range(Range("A" & tRow), Range("G" & tRow)).Interior.Color = xlNone
> Range("E" & tRow).ClearContents
> Case Is < 1
> Range(Range("A" & tRow), Range("G" & tRow)).Interior.Color = xlNone
> Range("E" & tRow).ClearContents
> End Select
>
> If Range("D" & c).Value = Range("D" & tRow).Value Then
> Range(Range("A" & tRow), Range("G" & tRow)).Interior.Color = _
> Range("D" & c).Interior.Color
>
> Range("D" & tRow).Offset(, 1).Value = _
> Range("D" & c).Offset(, 1).Value
> End If
> Next
>
>End Sub
>
受講生さんの投稿
(投稿ID: 1002)
演習問題の作成途中でハマった点について質問です。
D列(Priority1)に1~5以外の数字を入れると、マクロ実行中のまま応答しなくなり、
タスクマネジャーから強制終了しました。
質問1
多分for ~ next 構文の中でE列の数字を修正した時にそこで別イベントが発生して
ということなんだと思いますが、それが原因でしょうか。
1~5入力時も同じようなことをやっているので何が違うんだろうといのがよくわかりません。
結果的に、select case 構文内にExit for を追加して抜け出ることができたんですが・・・。
質問2
中断できずに強制終了してしまったので、仕事中に発生すると少しいやだなと思った
んですが、フラグ制御についてよくわかってない段階でfor ~ next 構文を使うのは
あまりよくないんでしょうか。一般論というか作法的に。
とはいっても実務的には使いそうですので注意点等あったらお願いします。
ゲストさんのコメント
(コメントID: 2142)
丁寧にステップイン実行してみました。
やはり、以下の [c] で worksheet_change が再帰的に呼び出されることがくり返されていますね。フラグ立ててください。
ゲストさんのコメント
(コメントID: 2143)
ゲストさんのコメント
(コメントID: 2144)
ファイルは、以下から取得してください。
https://www.dropbox.com/s/jy0x6gm6lp3zhgs/fukudasanmacro.xlsm?dl=0
>小川様
>演習問題の作成途中でハマった点について質問です。
>D列(Priority1)に1~5以外の数字を入れると、マクロ実行中のまま応答しなくなり、
>タスクマネジャーから強制終了しました。
>
>質問1
> 多分for ~ next 構文の中でE列の数字を修正した時にそこで別イベントが発生して
> ということなんだと思いますが、それが原因でしょうか。
> 1~5入力時も同じようなことをやっているので何が違うんだろうといのがよくわかりません。
> 結果的に、select case 構文内にExit for を追加して抜け出ることができたんですが・・・。
>
>質問2
> 中断できずに強制終了してしまったので、仕事中に発生すると少しいやだなと思った
> んですが、フラグ制御についてよくわかってない段階でfor ~ next 構文を使うのは
> あまりよくないんでしょうか。一般論というか作法的に。
> とはいっても実務的には使いそうですので注意点等あったらお願いします。
>
>
>
>
受講生さんのコメント
(コメントID: 2145)
Subプロシージャを再帰的に呼び出してループしているのも
落ち着いてステップインでみればよくわかりました。
あと、Sheet2のサンプルの美しさもよくわかりました。
ありがとうございました。
ゲストさんのコメント
(コメントID: 2148)
>Subプロシージャを再帰的に呼び出してループしているのも
>落ち着いてステップインでみればよくわかりました。
よかったです。
困ったときはステップインです。
フラグによる制御についても、もうOKでしょうか?(このお返事の様子だとたぶんOKぽいですが)
>丁寧に説明していただいてありがとうございました。
>
>Subプロシージャを再帰的に呼び出してループしているのも
>落ち着いてステップインでみればよくわかりました。
>
>あと、Sheet2のサンプルの美しさもよくわかりました。
>ありがとうございました。
>
>
>