[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]
『Changeイベント』(riy)
Private Sub Worksheet_Change(ByVal Target As Range)
If Intersect(Target, Range("m2:m231")) Is Nothing Then Exit Sub
If Target.Formula = "" Then Application.EnableEvents = False Target.FormulaR1C1 = "=IF(RC[-9]="""","""",VLOOKUP(RC[-9],データ!C[-12]:C[-11],2,0))" Application.EnableEvents = True End If
End Sub
m2〜m231のどれかのセルのデータが消去されたら、 そのセルに関数を書き込むというものですが ちっとも動きません。無反応です。 校正をして欲しいです。 宜しくお願い致します。
m2〜m231のどれかのセルを右クリックして「数値と値のクリア」をしてもダメですか?
ダメなら、イミディエイトウィンドウに「Application.EnableEvents = True」をコピペして Enter してから試すとか。
(ウッシ)
有難うございます。 この質問を書き込んでから、ファイルを一回閉じ、再度開きましたら コードが動くようになっていました。 全く同じコードで触っていないのに、不思議不思議 何が起こったのか? 解決はしましたけど、気持ち悪いです。 ウッシさんにはお手数掛けまして申し訳ありませんでした。 (riy)
解決したようですが、ちょっと気になったので・・・。
>Private Sub Worksheet_Change(ByVal Target As Range) > If Intersect(Target, Range("m2:m231")) Is Nothing Then Exit Sub > If Target.Formula = "" Then > Application.EnableEvents = False > Target.FormulaR1C1 = "=IF(RC[-9]="""","""",VLOOKUP(RC[-9],データ!C[-12]:C[-11],2,0))" > Application.EnableEvents = True > End If >End Sub
このコードだとセルm2〜m3を選択し、この状態でDeleteキーを押すとエラーになりますよ (型が一致しない というエラーです) どのように修正すればよいかは、仕様によります。 検討してみてください。
あれっ、回答投稿されてるウッシさん って、以前、VBA質問箱でも回答されていた方ですか?
だとしたら、お久しぶりですね!!
ichinose
ichinose さん、こんばんは VBA質問箱ではそれほど回答した記憶は無いんですけど・・・ ExcelVBA あまり使わないとどんどん忘れてしまうし、Excel の 2007 バージョンも使えないままなのに、2010 まで出てしまって。 このままではマズいので少し回答しながら ichinose さん始め他の方の回答で勉強しようかなって思ってます。 (ウッシ)
ichinoseさんへ 有難うございます。 >このコードだとセルm2〜m3を選択し、この状態でDeleteキーを押すとエラーになりますよ >(型が一致しない というエラーです) >どのように修正すればよいかは、仕様によります。 昨日 テストしていて、おっしゃるような場面で「型が一致しません」とエラーになったので
If Target.Count > 1 Then Exit Sub を付け加えました。そういう事での指摘と解釈して宜しいですか? (riy)
>If Target.Count > 1 Then Exit Sub >を付け加えました。そういう事での指摘と解釈して宜しいですか? これは、riyさんが決めた仕様によります。
>Private Sub Worksheet_Change(ByVal Target As Range) If Target.Count > 1 Then Exit Sub > If Intersect(Target, Range("m2:m231")) Is Nothing Then Exit Sub > If Target.Formula = "" Then > Application.EnableEvents = False > Target.FormulaR1C1 = "=IF(RC[-9]="""","""",VLOOKUP(RC[-9],データ!C[-12]:C[-11],2,0))" > Application.EnableEvents = True > End If >End Sub
このようにしたということですよね?
確かにこのようにすれば、エラーにはなりませんね!! そもそもの仕様は、 「セル範囲m2:m231内でセルの変更があった場合、 そのセル="" であったなら、数式を埋め込む」ということですね!!
>If Target.Count > 1 Then Exit Sub
これを付加することでエラーはなくなりますが・・・、 セル範囲m2:m3を選択した状態でDeleteキーを押すと m2:m3は、クリアされた状態で処理が完了してしまいます。 セル範囲m2:m231がこのような状態でもかまわないなら これでもよいですよね!!
そままのクリアされた状態では困るなあ せめて入力前の状態に戻して エラーメッセージでもださなきゃ というなら
Option Explicit Private Sub Worksheet_Change(ByVal Target As Range) Application.EnableEvents = False If Target.Count > 1 Then Application.Undo MsgBox "単一セルの変更だけ可能です" Else If Not Application.Intersect(Target, Range("m2:m231")) Is Nothing Then If Target.Formula = "" Then Target.FormulaR1C1 = "=IF(RC[-9]="""","""",VLOOKUP(RC[-9],データ!C[-12]:C[-11],2,0))" End If End If End If Application.EnableEvents = True End Sub
こんなコードが考えられます。
いやいや、これだとExcelの複数セルへの同時入力という便利な機能が制限されてしまう 複数セル範囲を選択してDeleteキーを押してもセル範囲m2:m231の範囲には、 決められた数式を配置させたい ということなら・・・・、
Option Explicit Private Sub Worksheet_Change(ByVal Target As Range) Dim rng As Range Dim crng As Range Set rng = Application.Intersect(Target, Range("m2:m231")) If Not rng Is Nothing Then Application.EnableEvents = False For Each crng In rng If crng.Formula = "" Then crng.FormulaR1C1 = "=IF(RC[-9]="""","""",VLOOKUP(RC[-9],データ!C[-12]:C[-11],2,0))"
End If Next Application.EnableEvents = True End If End Sub
こんなコードが考えられます。
私は、もう何年もシートイベントを使ったコードは書いていませんが、 これを使っていた頃は、殆ど最後に提示したような仕様にしていました。
検討してみてください。
ichinose
感動しました。 昨日テストをしながら、なんとなく感じていた不満がこれでした。 不満解消を具体的に模索するには至らずに、でも何となくもやもや状態でした。 これです! すばらしいコード有難うございます。 (riy)
すみません。 もうひとつ質問させて下さい。 Private Sub Worksheet_Change(ByVal Target As Range) Dim rng As Range Dim crng As Range Set rng = Application.Intersect(Target, Range()) If Not rng Is Nothing Then Application.EnableEvents = False For Each crng In rng If crng.Formula = "" Then crng.FormulaR1C1 = "=IF(RC[-9]="""","""",VLOOKUP(RC[-9],データ!C[-12]:C[-11],2,0))"
End If Next Application.EnableEvents = True End If End Sub m10の値を手動で定数に変更してあります。 m2〜m3も手動で定数に変更してあります。 m2〜m3を選択して値をデリートするとm2〜m3に数式が埋め込まれます。 m10は変化しません。
m10は変化してほしくないので、このコードで問題ないのですが、 m10の値は定数で数式ではないので、m10に数式が埋め込まれない理由がわかりません。 For Each crng In rng If crng.Formula = "" Then ↑だとm10も変化しそうに一見思えるのですが?
理解して使いたいので、ご教示願えないでしょうか 宜しくお願いいたします。 (riy)
>m2〜m3を選択して値をデリートするとm2〜m3に数式が埋め込まれます。 >m10は変化しません。
Set rng = Application.Intersect(Target, Range("m2:m231"))
このコードでrngは、どのセル範囲を取得している と思いますか? m2とm3を選択して デリートしているのですから、Targetは、m2:m3を取得します。 更に Application.Intersect(Target, Range("m2:m231"))では、 target(m2:m3)とRange("m2:m231")の共有セル範囲を返します。つまり、 rngは、m2:m3 というセル範囲を取得しているわけです。
よって、 For Each crng In rng If crng.Formula = "" Then
セル m2とm3 に対してループ処理をしているので m10はループ対象外なんです。
>m10の値は定数で数式ではないので、m10に数式が埋め込まれない理由がわかりません。 数式が埋め込まれていなければ、Formulaは、""ではありませんよ。Value値と等しいはずですよ つまり、定数が入力されていれば,その定数値を返します。
ということで、私が投稿を拝見した限り、二つの誤解があるかと思います。 再度、調べてみてください。
ichinose
ばっかな私でも今度こそ理解できました。 丁寧な解説有難うございます。 感謝感謝です。 (riy)
[ 一覧(最新更新順) ]
YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki.
Modified by kazu.