エクセル2003でマクロを組んでいます。
Sheet1,Sheet2の2つのシートがあり、
片方のシートの"A4:G10"の範囲に値を書き込むと、もう片方の同じ位置に同じ値が書き込まれるようなマクロを組みたいです。
以前ここで教えていただいたものを改変して以下を作りました(ThisWorkBookモジュールです)。
Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)
Dim r As Range
Dim Num As Integer
Dim S As String, Sh_name As String
Sh_name = ActiveSheet.Name
Set r = Intersect(Target, Range("A4:G10"))
If Not (r Is Nothing) Then
Application.EnableEvents = False
For Num = 1 To 2
S = "Sheet" & Num
If S <> Sh_name Then
Worksheets(S).Range(r.Address).Value = r.Value
End If
Next
Application.EnableEvents = True
End If
End Sub
ここまでは正常に動作します。
また、
Sheet1とSheet2のモジュールに、
A列のセルに値が入力された場合、同じ行のC列のセルの色を塗るという記述をしています。
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Column = 1 Then
Cells(Target.Row, 3).Interior.ColorIndex = 5
End If
End Sub
これらを同時に生かしたいのですが、
どのように書けばいいでしょうか。
EnableEvents = False/Trueを消してしまうと、
Worksheets(S).Range(r.Address).Value = r.Valueが実行されるたびにThisWorkBookモジュールが動いているようです。
そして2回目のSet r = Intersect(Target, Range("A4:G10"))でエラーが出ます。
(エラーは出ずとも延々と(無限ではない回数)ThisWorkBookモジュールを繰り返したコードもありました。)
よろしくお願いします。
No.3ベストアンサー
- 回答日時:
補足:
>今考えうる「全て」は、値、フォントの色、セル背景色、罫線です。
もし、フォントの色、セルの背景色、罫線のイベントで取ろうとしたら、インスタンスを作らないといけないので、かなり長いコードになるし、まったく発想が違います。今の延長上ではありませんから、これ以上の方法を願うのでしたら、「作業グループ」を取ってください。
例:
Worksheets(Array("Sheet1", "Sheet2")).Select
そうでなかったら、Worksheet_Activate() などで、特定の範囲をコピーしたほうが楽です。
以前も、同じような質問が出ていましたが、同期と言っても、二つのWindowを開くなら別ですが、そうでなければ、見えないシートに対しては、開けるまでは、正確にはどうなっているかはわからないのですから。(値は、参照式があるので別ですが。)
>(3)は、ThisWorkBookモジュールで(2)を行った時にSheet2のシートモジュールが動いて欲しかったのですが、
それをするなら、もともと、Sheet イベントは不必要です。
サブルーチン・マクロを呼び出せばよいのです。
'ThisWorkbook モジュール
Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)
Application.EnableEvents = False
If StrComp(Sh.Name, "Sheet1") = 0 And Not Intersect(Target, Range("A4:G10")) Is Nothing Then
Worksheets("Sheet2").Range(Target.Address).Value = Target.Value
Call WorksheetsChange(Target.Address)
ElseIf StrComp(Sh.Name, "Sheet2") = 0 And Not Intersect(Target, Range("A4:G10")) Is Nothing Then
Worksheets("Sheet1").Range(Target.Address).Value = Target.Value
Call WorksheetsChange(Target.Address)
End If
Application.EnableEvents = True
End Sub
'標準モジュール
'プロシージャ名は、紛らわしい名前をあえてつけた
Sub WorksheetsChange(myTarget As String)
Dim Sh As Worksheet
For Each Sh In Worksheets(Array("Sheet1", "Sheet2"))
With Sh
If .Range(myTarget).Column = 1 Then
If .Range(myTarget).Cells(1).Value <> "" Then
.Range(myTarget).Offset(, 2).Interior.ColorIndex = 5
Else
.Range(myTarget).Offset(, 2).Interior.ColorIndex = xlColorIndexNone
End If
End If
End With
Next Sh
End Sub
回答ありがとうございます。
返信が遅れて申し訳ありません。
挙げていただいたコードで満足のいく結果となりました。
シートイベントは要らなかったんですね。
これから標準モジュールに、背景色以外で同期を取りたい内容を加えていこうと思います。
今回は作業グループは使わないことにしましたが、使った方が処理速度は速いでしょうか。
No.2
- 回答日時:
こんばんは。
>『Sheet1と2において指定した範囲の全ての同期を取る』です。
>今考えうる「全て」は、値、フォントの色、セル背景色、罫線です。
なるべく、最初から、そういうことは書いていただいたほうがよいですね。あまり後出しの条件が多いと、書いてきた全ての内容がひっくり返ってしまうことがあります。
最初に書かなかったけれども、最初から同期を取る目的なら、二つのシートを作業グループにしたほうが早いです。それで全てが済むはずです。最初、掲示する前に、そういうマクロを書いたけれども、趣旨が違うと思って載せませんでした。
マクロのマクロのような方法は、難しくなるだけだと思います。
>すみません、絶対の自信があるわけじゃないのですが、
>できればどうヘンなのか教えていただけないでしょうか。
>Sh_name = ActiveSheet.Name
>Set r = Intersect(Target, Range("A4:G10"))
そういうコードを回答者の中でも書く人がいますが、引数がきちんと捕らえられていないと思います。
引数、Sh は、ActiveSheet だからですし、
Intersect(Target, Range("A4:G10"))
シートの指定がない前の確実性がない時に、Intersect の戻り値を Range オブジェクトを変数に代入しているけれど、単に、範囲のチェッカーだけに使えばよいと思います。それと、引数 Target で取得しているのだから、それを使えば済むわけです。
回答ありがとうございます。
返信が遅れて申し訳ありません。
>二つのシートを作業グループにしたほうが早いです。
「シートを作業グループにする」という記述があるのですね、「マクロの記録」でしっかり記録できました。
(Arrayを使ってシート数分やってるだけみたいですけど)
これも使ってみようと思います。
>>できればどうヘンなのか教えていただけないでしょうか。
>引数がきちんと捕らえられていないと思います。
正直まだ理解できないようです、聞いておいて申し訳ありません。
Sh.nameで入力したシート名が手に入ることだけはわかりました。
No.1
- 回答日時:
こんにちは。
ご質問者さんの、その Workbook_SheetChange のコードがちょっとヘンですね。前回のご質問で、これを出していただければすぐに分かりましたが。
>Sh_name = ActiveSheet.Name
>Set r = Intersect(Target, Range("A4:G10"))
この二行がヘンです。
>Worksheets(S).Range(r.Address).Value = r.Valueが実行されるたびにThisWorkBookモジュールが動いているようです。
Workbook_SheetChange 自体は、どこのシートのどの場所でも、入力すれば呼び出します。
ThisWorkbook モジュール
Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)
Application.EnableEvents = False
If StrComp(Sh.Name, "Sheet1") = 0 And Not Intersect(Target, Range("A4:G10")) Is Nothing Then
Worksheets("Sheet2").Range(Target.Address).Value = Target.Value
ElseIf StrComp(Sh.Name, "Sheet2") = 0 And Not Intersect(Target, Range("A4:G10")) Is Nothing Then
Worksheets("Sheet1").Range(Target.Address).Value = Target.Value
End If
Application.EnableEvents = True
End Sub
なお、私なら、シートモジュールは、こんな感じに色消しも入れます。
これは、好みによります。こちらは、特に問題ありません。
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Column = 1 Then
If Target.Cells(1).Value <> "" Then
Target.Offset(, 2).Interior.ColorIndex = 5
Else
Target.Offset(, 2).Interior.ColorIndex = xlColorIndexNone
End If
End If
End Sub
この回答への補足
いつも回答ありがとうございます。
申し訳ありません、ちょっと説明不足でした。
「同時に生かしたい」と書いたのは、
・各シートにおいてA4:G10の範囲の値について同期を取る
・各シートのA列に値が入ったら同行のC列は青で塗る
の2点です。
例えばSheet1のA1に"1"と入力した時の結果として、
(1)Sheet1のC1が青で塗られる。→Sheet1のシートモジュールの結果
(2)Sheet2のA1に"1"が入力される。→ThisWorkBookモジュールの結果
(3)Sheet2のC1が青で塗られる。→(ThisWorkBookモジュールの結果による)Sheet2のシートモジュールの結果
を行いたいです。
質問した時点で、
(1)は既にできており(問題無いと言ってもらえました)、
(2)も(ヘンと言われてしまいましたが結果的には)動いていました。
(3)は、ThisWorkBookモジュールで(2)を行った時にSheet2のシートモジュールが動いて欲しかったのですが、
Application.EnableEvents = Falseでイベントを止めているので動きません。
Application.EnableEvents = Falseを消すと、ループしてしまうのでNGです。
そこで、
(3)も実現するにはどのように組んだらよいでしょうか、というのが意図していた質問でした。
もしかして不可能でしょうか。
ちなみにコード中でSheet1と2にしか対応していないのにFor文で回している理由は、
Sheetが増えた時に対応しやすいかなと思ってのことです。
今回はこのようなコードしか思いつけなかったのでこれを質問しましたが、
目的としては、
『Sheet1と2において指定した範囲の全ての同期を取る』
です。
今考えうる「全て」は、値、フォントの色、セル背景色、罫線です。
例)
Sheet1に値の入力があった→Sheet2の同じ位置に入力。
Sheet2のセルの色を青に→Sheet1の同じ位置のセルの色を青に。
他にもっと確実な方法でもあれば教えていただきたいです。
>Workbook_SheetChange のコードがちょっとヘンですね。
すみません、絶対の自信があるわけじゃないのですが、
できればどうヘンなのか教えていただけないでしょうか。
よろしくお願いします。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Visual Basic(VBA) 【Excel VBA】自動メール送信の機能追加 5 2022/09/29 12:53
- Excel(エクセル) エクセルVBAでオブジェクトが必要です 2 2022/09/10 16:37
- Visual Basic(VBA) 【変更】ファイルを閉じてダイアログで保存した時、更新したシートだけの処理の実行をする 5 2022/03/26 18:31
- Visual Basic(VBA) excel vbaでvlooupの変数がわかりません。 7 2022/05/30 09:35
- Excel(エクセル) VBAについて 3 2022/06/19 18:19
- Visual Basic(VBA) 【VBA】写真の貼り付けコードがうまく機能しません。 5 2022/09/01 18:43
- Visual Basic(VBA) [Excel VBA] このコードでは行の挿入や行の消去をすると13のエラーが出てしまう。 3 2022/12/09 00:29
- Visual Basic(VBA) excel2021で実行できないマクロ。どこを直したらいいのか 2 2022/03/28 03:40
- Visual Basic(VBA) ExcelのVBAコードについて教えてください。 2 2022/05/26 17:19
- Visual Basic(VBA) VBAのユーザーフォームのテキストボックスに入力制限をしたい 6 2022/11/15 08:28
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
至急!尿検査前日にオナニーし...
-
首吊りどこ締めるの
-
尿検査の前日は自慰控えたほう...
-
尿検査前日に自慰行為した時の...
-
検便についてです。 便は取れた...
-
白血球が多いとどんな心配があ...
-
中出しをするとお腹が痛い・・・。
-
射精をして1週間以内に尿検査を...
-
彼女のことが好きすぎて彼女の...
-
腕を見たら黄色くなってる部分...
-
勃起する時って痛いんですか? ...
-
変な話しになります。尿検査で...
-
これって喉仏ですか? 私は女性...
-
EXCELで条件付き書式で空白セル...
-
男です。昨日の午後3時くらいに...
-
今朝、毎朝の習慣でオナニーし...
-
納豆食べた後の尿の納豆臭は何故?
-
1日前の検尿
-
値が入っているときだけ計算結...
-
精子が黄色?
おすすめ情報