• ベストアンサー

マクロが動きません

以下のようなプログラムでC3の値が変わるたびにA10の値に1を加えていきG3,H3が両方0になったらA10の値も0にする。C5の値が変わるたびにA15の値に1を加えJ3,K3が共に0になったらC5も0にするようにしました。 しかし、動作しません。 このシートの3行目は=シート名!セル番号 という形でほかのシートのセルの値が表示されるようになっています。G3、H3、J3、K3に手動で数値を入力した場合 は動作します。 ほかのシートのセルの値を表示させたセルの値が変化しても動作させる方法はないでしょうか> Private Sub worksheet_change(ByVal target As Range) With target If .Count > 1 Then Exit Sub If IsNumeric(.Value) = False Then Exit Sub If IsEmpty(.Value) = True Then Exit Sub If Not .Row = 3 Then Exit Sub Select Case .Column Case 3 Range("A10").Value = Range("A10").Value + 1 Case 5 Range("A15").Value = Range("A15").Value + 1 End Select End With If Range("g3").Value = 0 And Rang("h3").Value = 0 Then Range("A10").Value = 0 If Range("j3").Value = 0 And Rang("k3").Value = 0 Then Range("A15").Value = 0 End Sub

  • tkoo
  • お礼率5% (15/254)

質問者が選んだベストアンサー

  • ベストアンサー
  • Musaffah
  • ベストアンサー率36% (37/101)
回答No.4

#2、#3さんの言うように、確かに深く考えずにシンプルにしたほうがいいでしょうね。 ちなみに条件付ではありますが、こんなんはどうでしょうか? 結果を表示させるワークシートを"Sheet1"、"リンク先(実際の値を入れている)ワークシートを"Sheet2"として説明します。 また、#1さんのコメントは反映させてください。 (1)リンク先のセル位置を同じにする。 つまり、"Sheet1"ワークシートのC3セルのリンク先は必ず"Sheet2!C3"セルとします。 (2)作成された関数をPublic関数にする。また関数名も独自なものにする。 Public Sub Recal(ByVal target As Range)   ・   ・ (質問者さんが作成されたコード)   ・ End Sub (3)Sheet2にchangeイベントを作成する。 こんな感じで作成します。 Private Sub Worksheet_Change(ByVal Target As Range) Call Worksheets("Sheet1").Recal(Target) End Sub これで条件付(同じセルをリンクしなければならない)ではありますが、お望みのものができると思いますよ。 どうでしょうか?

その他の回答 (4)

  • matsu_jun
  • ベストアンサー率55% (146/265)
回答No.5

まずは訂正から 1) 現状のソースでは、C3とE3の変更時に反映されることになっています。   質問文が間違っているのなら良いのですが、そうでないのならば、   ソースの6行目、7行目の「.Row」と「.Column」は逆ですよ。 2) Wendy02様もご指摘のとおり、冒頭に   Application.EnableEvents = False   最後に   Application.EnableEvents = True   が入るべきです。そうでないと、ソース内部でセルの値を変更した時   再度このルーチンに入ってしまうからです(再帰処理が発生してしまう)。   今回の例では無限ループ(呼び出すたびに同じルーチンを呼び出しなおして、処理が終了しないこと)は   発生しませんが、worksheet_changeイベント利用時には、常におまじないとして入れておきましょう   実際は、念のために、以下のように記述するくせを付けるとよいかと存じます。   Private Sub Worksheet_Change(ByVal Target As Range)     On Error GoTo ERRHND  'ルーチン上エラーが発生したら下のラベル行ERRHND:以下へジャンプ     Application.EnableEvents = False  'イベント発生の抑止。これでイベント内でセルの値を変更しても再帰しない。     'ここに実際の処理を記述     'Exit Sub は利用しない、処理を中止したい場合は GoTo ERRHND と記載する     'さもないと次回から(ブックの開きなおしまで)イベントが発生しなくなります   ERRHND:     Application.EnableEvents = True  'イベント発生の復活   End Sub 3) これもWendy02様ご指摘ですが、14、15行目、Rangeの「e」が抜けています。 4) セルG3、H3、J3、K3をチェックするルーチンに届かないケースが大半になっています。   現状ソースの14、15行目を実行する条件として、   条件1) 変更した行が3行目(元のソースが間違っていないとして)である   条件2) 変更後のセルの値が数値である   条件3) 変更後のセルが空白でない   以上3条件を全て満たしている場合のみしか届かなくなっています。   最終的に他からのリンクによりG3、H3、J3、K3の値が変更されることになると、場合によっては   全くチェックがされないことになりますね。これを避けるためには、14、15行目の上にラベルを付け、   現在 Exit Sub と記述してある部分を、 GoTo (ラベル名) と記述するとよいでしょう。 さて、以上踏まえた上で、解答を。 「Workbook_SheetChangeイベントを利用すれば万事OKです」 ThisWorkbookオブジェクト内のWorkbook_SheetChangeイベントであれば、どのシートのセルが 変更されても発生するイベントですから、あとからどう数式や参照シートを変更しても 常に参照できることになります。当然このイベントには、ターゲットのシートオブジェクト およびターゲットが引数として引き渡されるので、イベント内でシート名も簡単に参照できます。 詳しい説明は、tkoo様のスキルであれば不要と思いますので、とりあえず以下にコードだけ記載します。 Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)   Application.EnableEvents = False   On Error GoTo ERRHND   If Sh.Name = "Sheet1" Then   'ここに目的のシート名が入る     With Target       If .Count > 1 Then Exit Sub       If IsNumeric(.Value) = False Then GoTo DATCHK       If IsEmpty(.Value) = True Then GoTo DATCHK       If Not .Row = 3 Then GoTo DATCHK       Select Case .Column       Case 3         Sh.Range("A10").Value = Sh.Range("A10").Value + 1       Case 5         Sh.Range("A15").Value = Sh.Range("A15").Value + 1       Case Else         GoTo DATCHK       End Select     End With   End If DATCHK:   With Sheets("Sheet1")      'ここにも目的のシート名が入る     If .Range("G3").Value = 0 And .Range("H3").Value = 0 Then .Range("A10").Value = 0     If .Range("J3").Value = 0 And .Range("K3").Value = 0 Then .Range("A15").Value = 0   End With ERRHND:   Application.EnableEvents = True End Sub

  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.3

読み落としていました。 >ほかのシートのセルの値を表示させたセルの値が変化しても動作させる方法はないでしょうか 自シートを開いている限りは、他シートからのリンクしたセルは、他シートを開いて操作しなければ、変わらないのでは?他シートは閉じている限りは、NonActiveです。 自シート開いた時点で、チェックする方法はあるけれど、それよりは、papayukaさんのご指摘のとおりだと思いますね。

  • papayuka
  • ベストアンサー率45% (1388/3066)
回答No.2

質問のポイントは、他のシートへリンクされているセル値の変更を捕らえたいって事? 難しく考えずに、リンク元になっている他シートの Worksheet_Changeで処理すれば良いだけじゃない?

  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.1

ただ、見た感じだけですけれども、基本的なことですが、イベントで、こういうコードを置く場合は、 >Range("A10").Value = Range("A10").Value + 1 ◎ Application.EnableEvents =False '*ワークシートへ記入するコード '**ワークシートへ記入するコード ◎ Application.EnableEvents =True それと、最後の部分は、タイプミス?一度は、ワークシートで行ってみたのかな? Rang("h3").Value = 0 Then Range("A10").Value = 0   ↓ Range("h3").Value Rang("k3").Value = 0 Then Range("A15").Value = 0   ↓ Range("k3").Value 後は、 Select Case .Column で、Case 3 と、Case 5 はありますが、Case Else がないようなので、そのまま、その下のコードを実行していくのですか?もし、それで良いのでしたら、たぶん、大丈夫だと思います。

関連するQ&A

  • エクセルのマクロ

    セルの値が変わったら動くマクロですが、2つ書くとエラーが出ます。 どのように直したらいいでしょうか? Private Sub Worksheet_Change(ByVal Target As Range) Select Case Target.Address If Intersect(Target, Range("EK22")) Is Nothing Then Exit Sub Else Range("EK24:EM28").Select Selection.ClearContents End If End Sub Private Sub Worksheet_Change(ByVal Target As Range) If Intersect(Target, Range("EK24")) Is Nothing Then Exit Sub Else Range("EK27:EM28").Select Selection.ClearContents End If End Sub

  • マクロで困ってます!

    マクロでセル検索かけたらそのセルに設定していたハイパーリンクが外れてしまいます。 どうすればいいでしょうか・・?お力を貸してください! バージョンは2007です! コードは下記になります! 同一ブック内の「データ」というシートにあるものを「検索更新」というシートで検索をかけるというものです。 宜しくお願いします!! Sub 検索2() myLAST = Range("B" & ActiveSheet.Rows.Count).End(xlUp).Row + 1 If myLAST < 5 Then myLAST = 5 Range("A5:F" & myLAST).ClearContents Set myC = Sheets(1).Columns(3) _ .Find(What:=Range("E2").Value, _ LookIn:=xlValues, LookAt:=xlPart) ' If myC Is Nothing Then Exit Sub myCa = myC.Address Do myLAST = Range("B" & ActiveSheet.Rows.Count).End(xlUp).Row + 1 Range("A" & myLAST) = myC.Row Range("B" & myLAST) = myC.Offset(0, -1) Range("C" & myLAST) = myC.Offset(0, 0) Range("D" & myLAST) = myC.Offset(0, 1) Range("E" & myLAST) = myC.Offset(0, 2) Range("F" & myLAST) = myC.Offset(0, 3) Set myC = Sheets(1).Columns(3).FindNext(myC) If myC Is Nothing _ Or myCa = myC.Address Then Exit Do Loop Set myC = Nothing End Sub Sub 更新() myLAST = Range("A" & ActiveSheet.Rows.Count).End(xlUp).Row If myLAST < 5 Then myLAST = 5 For Each myC In Range("A5:A" & myLAST) If myC.Value = "" Then Exit Sub With Sheets(1) .Range("B" & myC.Value) = myC.Offset(0, 1) .Range("C" & myC.Value) = myC.Offset(0, 2) .Range("D" & myC.Value) = myC.Offset(0, 3) .Range("E" & myC.Value) = myC.Offset(0, 4) .Range("F" & myC.Value) = myC.Offset(0, 5) End With Range("A" & myC.Row & ":F" & myC.Row).ClearContents Next MsgBox "更新しました" End Sub

  • エクセルのマクロについて

    エクセル2003を使用しています。もしよかったら教えてください。 【例】 エクセルシートを2つ使うことを前提として、 Sheet1にはA1:F50の6列範囲セルに対して1~60の範囲内の数字が決められた背景色とフォント色に従い元々ランダムに入っております。 次に新たにSheet2を作り、そのE1:J50の6列範囲セルに値を他からコピーしてきた数字がランダムに入っています。 上記Sheet1セル範囲とSheet2セル範囲を比較して、それぞれのセル範囲内の数字がそれぞれ一致した場合、Sheet2のセル群をSheet1のセルの背景色とフォントカラーを同一に変更するマクロがわかりませんでした。 また1~60範囲外数値であれば処理しません。 調べても、数値入力した時点で他のセルの背景・フォント色を同一に変更する方法しか無かったので、For Eachを使い、試してみたのが下記のマクロです。 Private Sub Worksheet_Change(ByVal Target As Range) Dim v, c As Range '//変更されたセル範囲・値をチェックして、関係なければ処理をしない If Target.Count > 1 Then Exit Sub If Intersect(Range("E1:J50"), Target) Is Nothing Then Exit Sub v = Target.Value If Not IsNumeric(v) Or v < 1 Or v > 60 Then Exit Sub '//参照するシートの範囲について順にチェック '//値が同じだったら、フォントカラーと背景色を同じにして終了 For Each c In Worksheets("sheet1").Range("A1:F50") If c.Value = v Then Target.Interior.ColorIndex = c.Interior.ColorIndex Target.Font.ColorIndex = c.Font.ColorIndex Exit For End If Next c End Sub これで実行するとSheet2に数値を新たに入力してうまくいきます。 ただ、Sheet2へ他からコピーしてきた数値のセル背景・フォント色を変更することができないです。 上記の作業を次から次へと新規で対応しなければならず、数値の入力に疲れてきております。 うまくいくマクロありますでしょうか?

  • マクロにおける条件文の作成の件

    以下の様に条件付きの計算式を作成しました。CommandButton3を押しても 計算しなかったり、TextBox3.Value > TextBox1 ではないときでもエラー メッセージが出ます。どこに欠点があるのか教えて下さい。 Private Sub CommandButton3_Click() Dim row As Integer If TextBox1.Value = Empty Then MsgBox ("Aが空欄です") Exit Sub End If If TextBox2.Value = Empty Then MsgBox ("Bが空欄です") Exit Sub End If If TextBox3.Value = Empty Then MsgBox ("Cが空欄です") Exit Sub End If If TextBox4.Value = Empty Then MsgBox ("Dが空欄です") Exit Sub End If If TextBox3.Value > TextBox1.Value Then MsgBox ("Cの値をAの値より小さくしましょう!") Exit Sub End If If TextBox4.Value > TextBox2.Value Then MsgBox ("Dの値をBの値より小さくしましょう!") Exit Sub End If TextBox5 = Round(TextBox1 * TextBox2 - (TextBox1 - TextBox3) * (TextBox2 - TextBox4) / 2, 0) End Sub

  • VBA CHANGEイベントに複数イベントを

    いつもお世話になっています。 色々しらべて試してみたんですが、うまくいかないんで教えてください。 CHANGEイベントに複数のイベントを書き込みたいんですが。 今現在、問題なく動いている以下のイベントがあります。 (1) Private Sub Worksheet_Change(ByVal Target As Range) Dim rang3 As Range Dim rang4 As Range Dim ■■ As String Dim LastRow1 As Long LastRow1 = Worksheets("○○").Cells(Rows.Count, "b").End(xlUp).Row Set rang4 = Worksheets("○○").Range("b:I" & LastRow) Set rang3 = Range("h4") If Intersect(Target, rang3) Is Nothing Then Exit Sub On Error Resume Next ■■ = WorksheetFunction.VLookup(Target.Value, rang4, 2, 0) If Err.Number > 0 Then MsgBox Target.Value & "はありません。基本情報台帳に入力してください。" Range("h4").Select Else Application.EnableEvents = False Range("I4").Value = Application.WorksheetFunction.VLookup(Target, Worksheets("△△").Range("b:I"), 2, False) Range("j4").Value = Application.WorksheetFunction.VLookup(Target, Worksheets("△△").Range("b:I"), 3, False) Range("k4").Value = Application.WorksheetFunction.VLookup(Target, Worksheets("△△").Range("b:I"), 7, False) Range("l4").Value = Application.WorksheetFunction.VLookup(Target, Worksheets("△△").Range("b:I"), 8, False) Range("m4").Value = Application.WorksheetFunction.VLookup(Target, Worksheets("△△").Range("b:I"), 5, False) Application.EnableEvents = True Range("K4").Select End If End Sub このシートにもう一つ、イベントを入れたいのですが。 (2) If Target.Count > 1 Then Exit Sub If Intersect(Target, Range("E4")) Is Nothing Then Exit Sub Else If Range("e4").Value = "1" Then Target.Offset(0, 19).Value = "☆" End If どこに入れればいいのかわかりません。 (3) また、(2)のイベントの他に、 (1)のVLOOLUPが実行され、尚且つ(2)のイベントのE4が値が1だった場合、Y4にH4の値を入れたいのですが・・・。 (2)のみなら動くことは確認できましたが、(1)のexit sub の直前に入れたり、end ifの前に入れたりしましたが、片方は動くが、もうひとつが動かないです。 (3)については、まったくわかりません。 マクロについて、自分でネットで勉強した程度なので、基本がわかっていないからなのでしょうが・・・。 どなたか、教えてください。 お願いします。

  • InputBoxの値で検索して転記するマクロ

    1.InputBoxを3回表示させます。 2.ユーザーに入力してもらいます。 入力できるのは半角英数字のみでそれ以外は エラーメッセージを出したいです。 3.1回目は18桁か22桁以外の場合、 2回目と3回目は4桁以外の場合はMsgBoxを表示して 再入力を促します。 4.InputBoxに入力された値の3個を連結した値で Sheet2のA列を検索して 合致したらその行のG列の値を見ます。 5.G列に"済"とあったら MsgBoxを表示して 中止するか継続するか判断します。 6.継続した場合 その該当行の各列の値をSheet1にそれぞれ転記します。 Sheet2の該当行のB列→Sheet1のセルB3 Sheet2の該当行のC列→Sheet1のセルC3 Sheet2の該当行のD列→Sheet1のセルD3 Sheet2の該当行のE列→Sheet1のセルE3 Sheet2の該当行のF列→Sheet1のセルF3 7.かつSheet2の該当行のG列に 済 と転記します。 すでに済が記入されている場合は上書です。 以下のように作成しましたがエラーで動かなくて動作確認が出来ません。 どう直せばいいのか教えてください。 イレギュラー時の対応処理が必要だとも思うのですが動作しない為 思いつきません。 記述が滅茶苦茶なのですがこれが限界です。申し訳ありません。 Sub 表示板作成() Dim 検索値1 Dim 検索値2 Dim 検索値3 Dim 検索値4 Dim 判定値 Dim 判断 Dim 記録 Dim 確認 検索値4 = 検索値1&検索値2&検索値3 Do 検索値1 = Application.InputBox("型番を入力してください") If Len(検索値) < 18 Then MsgBox "18桁未満です。再入力しますか?" Loop Else Exit Do '検索値2と3も上記と同じ記述をここへ入れる '(現在省略) End If 判定値 = Application.WorksheetFunction.VLookup(検索値4.Value, Worksheets("Sheet2").Range("A2:G10000"), 7, 0) If 判定値 = "済" Then 判断 = MsgBox("発行済みです。再度データ取得しますか?", vbYesNo) Else Select Case 判断 Case vbNo Exit Sub Case vbYes Range("B3").Value = Application.WorksheetFunction.VLookup(検索値4.Value, Worksheets("Sheet2").Range("A2:G10000"), 2, 0) Range("B4").Value = Application.WorksheetFunction.VLookup(検索値4.Value, Worksheets("Sheet2").Range("A2:G10000"), 3, 0) Range("B5").Value = Application.WorksheetFunction.VLookup(検索値4.Value, Worksheets("Sheet2").Range("A2:G10000"), 4, 0) Range("B6").Value = Application.WorksheetFunction.VLookup(検索値4.Value, Worksheets("Sheet2").Range("A2:G10000"), 5, 0) Range("B7").Value = Application.WorksheetFunction.VLookup(検索値4.Value, Worksheets("Sheet2").Range("A2:G10000"), 6, 0) End Select End If 記録 = Application.WorksheetFunction.VLookup(検索値4.Value, Worksheets("Sheet2").Range("A2:G10000"), 7, 0) 記録.Value = "済" 確認 = MsgBox("これは●●用です。いいですか?", vbYesNo) Select Case 確認 Case vbNo Exit Sub Case vbYes Call 印刷 End Select End Sub

  • 印刷後のVBAの実行 (3)

    Private Sub Workbook_BeforePrint(Cancel As Boolean) If ActiveSheet.Name = "Sheet1" Then If Range("D6").Value = "" Then Cancel = True MsgBox ("名前を入力してください") Range("D6").Select Exit Sub End If Else If ActiveSheet.Name = "Sheet2" Then If Range("C11").Value = "" Then Cancel = True MsgBox ("受付時間を入力してください") Range("C11").Select Exit Sub End If Else Exit Sub End If End If If Worksheets("Sheet1").Range("D5") = "不要" Then GoTo P1 ActiveSheet.Range("A70:Y70").Copy If Worksheets("Sheet3").Range("A1").Value = "" Then Worksheets("Sheet3").Range("A1").PasteSpecial Paste:=xlPasteValues Else Worksheets("Sheet3").Range("A65536").End(xlUp).Offset(1, 0).PasteSpecial _ Paste:=xlPasteValues End If Application.CutCopyMode = False P1: ActiveSheet.Range("A1").Select End Sub sheet1のD5に「不要」と入っていたら 24~33行目の作業がキャンセルになりますが sheet2のD5にも「不要」と入っていたら、同じ様にキャンセルできる様に出来ますでしょうか? ご回答お願いします

  • マクロでシート名を変更を変更したい

    A1セルの値をシート名にするマクロは以下のとおりだと思います。 Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range) If Target.Address = "$A$1" Then Sh.Name = Target.Range("A1").Value End Sub では、E6セルの値をシート名にすることは可能でしょうか? よろしくお願いします。

  • 印刷後のVBAの実行 (2)

    Private Sub Workbook_BeforePrint(Cancel As Boolean)   If ActiveSheet.Name = "Sheet1" Then     If Range("D6").Value = "" Then       Cancel = True       MsgBox ("名前を入力してください")       Range("D6").Select       Exit Sub     End If   Else     If ActiveSheet.Name = "Sheet2" Then       If Range("C11").Value = "" Then         Cancel = True         MsgBox ("受付時間を入力してください")         Range("C11").Select         Exit Sub       End If     Else              Exit Sub     End If   End If   ActiveSheet.Range("A70:Y70").Copy   If Worksheets("Sheet3").Range("A1").Value = "" Then     Worksheets("Sheet3").Range("A1").PasteSpecial Paste:=xlPasteValues   Else     Worksheets("Sheet3").Range("A65536").End(xlUp).Offset(1, 0).PasteSpecial _       Paste:=xlPasteValues   End If   Application.CutCopyMode = False   ActiveSheet.Range("A1").Select End Sub 先日、上記のコードを回答者の方から教えてもらい、とても助かっていますが sheet1のD5に「不要」という文字が入っていた場合、 sheet3への貼り付け(23~30行目の作業)をキャンセルして、最後にsheet1のA1を選択するようにはどの様にしたらいいでしょうか?

  • エクセル マクロについて

    エクセルでネットの情報(為替の値動き)を自動更新で取得しています。自動更新前の情報を同一シート(同一シートが無理な場合は別シートでもいいのですが…)にコピペし一覧にするマクロはありますか? Private Sub Worksheet_Change(ByVal Target As Range) If Target.Column = 1 Then         'A1のセルの値が変化したら・・・ n = Cells(Rows.Count, "B").End(xlUp).Row + 1  ’B列の最終行を探しその次の行に・・・ Range("B" & n).Value = Range("A1").Value    ’A1の値を貼り付けていく End If End Sub これだと手動セルを上書きした時しか動いてくれませんでした。検索もしたのですが見当たらなくて困っています。お力を貸してください。

専門家に質問してみよう