• ベストアンサー

VBAの記録を追加したい

エクセル2002使用です。 VBAで次のコードを使っています。 Private Sub Worksheet_Change(ByVal Target As Range) Dim Rng As Range Set Target = Intersect(Range("C:C"), Target) If Target Is Nothing Then Exit Sub For Each Rng In Target If Rng.Value <> "" Then Rng.Offset(, -2).Value = Now Else ' (*) Rng.Offset(, -2).Value = "" ' (*) End If Next Rng End Sub (C列のセルに何か入力されると、A列の同じ行にその時刻が入る。) 同じシートで、F列に何か入力されるとE列の同じ行にその時刻が入るように書き直したいのですが、どうすればいいのでしょうか? すいませんが、よろしくお願いします。

  • ken123
  • お礼率73% (299/409)

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

  • ベストアンサー
  • popesyu
  • ベストアンサー率36% (1782/4883)
回答No.2

補足読みました。同時に使いたいということでしたか。早とちりしてすいません。 で質問者さんが試されたコードのどこが問題かと言うと 。 If Target Is Nothing Then Exit Sub まずここで入力がC列以外でしたらその時点で終了しています。F列の判定が出来ません。 もうひとつは Set Target = Intersect(Range("C:C"), Target) Targetを直接書き換えていますので、続けてTargetを参照させるのが無理になります。 ということでこれはあくまでも一例ですが。 元のコードを出来るだけいじらずに修正すると --- Dim newTarget As Range Dim Rng As Range Dim retu As Integer '変更されたセルにC列が含まれているかどうか Set newTarget = Intersect(Range("C:C"), Target) 'C列がなかったらF列が入っているか判定 If newTarget Is Nothing Then Set newTarget = Intersect(Range("F:F"), Target) 'F列もなかったら終了 If newTarget Is Nothing Then Exit Sub retu = -1 'F列用の書き込み列 Else retu = -2 'C列用の書き込み列 End If ’時刻の書き込み For Each Rng In newTarget If Rng.Value <> "" Then Rng.Offset(, retu).Value = Now Else ' (*) Rng.Offset(, retu).Value = "" ' (*) End If Next Rng とかなりますが、列の判定部分はもっとスマートに出来るかと思います。

ken123
質問者

お礼

popesyuさま、ありがとうございました。 上手くいきました。 しかし、これも構文をコピーさせていただいただけで、ご指摘の通り自分では作れません。 なんとか業務に関係する30ほどの関数を扱えるレベルなのですが、VBAをなんとか習得したいと思い、今まで勉強したのと同じように本を読みながら参考にやっているのですが、なかなか今までのようにはスムーズにいかず、通信教育とかも受けてはいるのですが、何かしっくりきません。 この場であつかましい質問なのですが、VBA初心者の勉強方法の心得とかありましたら教えていただきたいのですが・・・・ ホント、申し訳ないですがよろしくお願いします。

その他の回答 (3)

  • popesyu
  • ベストアンサー率36% (1782/4883)
回答No.4

1、2番です。 まぁ解決したようですが。最後にヒントということで。 基本はデバックとヘルプだけで初めて見るコードでもどこでエラーが出ているのか、またどこが問題かがわかりますよ。 本やら通信教育はヘルプの補足にしかすぎません。 まず今回の例で具体的に説明しますと。 最初に1番の補足にあるようなコードを試せばエラーが出ますよね。 でどこでエラーが出ているかは、デバックの際にステップバイステップで一行ずつ確認しながら進めると If Target Is Nothing Then Exit Sub の行でいきなり終了されてしまっているのがすぐに把握できます。 で次のエラーはTargetの変数を上書きさせて処理させている為の問題で、この辺りの参照形式の方法などは、一般論的な変数の取り扱いの方法などは本などが役にたつかと思います。 そしてヘルプの使い方に関しては。 例えば3番さんが紹介した方法ですと範囲指定で(B、C列をまとめて貼り付けなどで)こぴぺされた場合などに正常に動きません。 で変更がおきた列を把握するのにIntersectメゾットが使われているのはそれへの対応のようですが、私はこのメゾットの存在も使い方も知りませんでしたw ヘルプを見てその使い方を確認たところ、確かにこういう回りくどい方法が必要なようなんですよね。 まぁ存在すら知らないメゾットをいきなりヘルプから調べるのは難しいのですが、サンプルなどがあればそれがヒントそのものになります。意味が不明な語句が出たらまずヘルプで確認しましょう。 以上、今回のトラブルは変数の取り扱いの処理の部分だけ、本などできちんと勉強していればそれ以外のエラーに関してはエラーが起きた箇所を把握するだけで解決できた問題かと思います。

ken123
質問者

お礼

ご丁寧なアドバイスありがとうございました。 いままであまりヘルプは参照せず本やらネットやらを参考にやってきましたが、ヘルプが結構重要なんですね。今回もヘルプを見直していたら勉強になりました。 まだ、基礎がしっかりとしていないので大変ですが、地道にがんばってみます。 このたびは本当にありがとうございました。 これからもよろしお願いします。

  • imogasi
  • ベストアンサー率27% (4737/17068)
回答No.3

ご質問の意図を誤解していたら済みません。 Private Sub Worksheet_Change(ByVal Target As Range) If Target.Column = 6 Then 'F列なら Target.Offset(, -1) = Now 'E列に End If If Target.Column = 3 Then 'C列なら Target.Offset(, -2) = Now 'A列に End If End Sub

ken123
質問者

お礼

imogasiさま、バッチリです。ありがとうございます。 すっきりしました。 すいません、差し支えなければ#2のお礼欄にも書かせていただいたのですが、VBA初心者へのアドバイスをもらえたら助かるのですが・・・ 独学なんでとまどっています。 よろしくお願いします。

  • popesyu
  • ベストアンサー率36% (1782/4883)
回答No.1

1 Set Target = Intersect(Range("C:C"), Target) Set Target = Intersect(Range("F:F"), Target) 2 Rng.Offset(, -2).Value = Now Rng.Offset(, -1).Value = Now 3 Rng.Offset(, -2).Value = "" ' (*) Rng.Offset(, -1).Value = "" ' (*) まぁ人が作ったものを修正されたいのでしょうが。1の部分ぐらいは直感で判断できないのなら、無理に修正しない方がいいのではないかなと思いますが。 修正方法とかそれ以前の部分で戸惑われませんか?

ken123
質問者

補足

popesyuさん、早速のご回答ありがとうございます。 すいまんせん。説明不足だったのですが、現在の状況はそのままで(C列を見てA列を入力)、追加でF列を見てE列にも時刻が入るようにしたいのですが・・・ 下記のような感じでいろいろ試しているのですが上手くいかず・・・ 勉強始めたばかりなのですが、構成要素の区別がつかず、つまづいています・・・よろしくお願いします。 Private Sub Worksheet_Change(ByVal Target As Range) Dim Rng As Range Set Target = Intersect(Range("C:C"), Target) If Target Is Nothing Then Exit Sub For Each Rng In Target If Rng.Value <> "" Then Rng.Offset(, -2).Value = Now Else ' (*) Rng.Offset(, -2).Value = "" ' (*) End If Next Rng Dim Rng2 As Range Set Target = Intersect(Range("F:F"), Target) If Target Is Nothing Then Exit Sub For Each Rng2 In Target If Rng2.Value <> "" Then Rng2.Offset(, -1).Value = Now Else ' (*) Rng.Offset(, -1).Value = "" ' (*) End If Next Rng2 End Sub

関連するQ&A

  • VBA 範囲選択時エラー

    Private Sub Worksheet_SelectionChangeのVBAでA列B列C列でワンクリックで文字が入力できるように設定致しました。 その後、A列からC列を範囲選択してDeleteするとデバック 「実行時エラー  型が一致しません」と出てしまいます。業務上、そのセルのデータは一気に消したいので困っております。どなたか分かる方よろしくお願い致します。 Private Sub Worksheet_SelectionChange(ByVal Target As Range) Dim rng As Range, rng_1 As Range, rng_2 As Range Application.EnableEvents = False Set rng_1 = Range("H17:H100") Set rng_2 = Range("I17:I100") Set rng_3 = Range("J17:J100") Set rng_4 = Range("K17:K100") Application.EnableEvents = True Set rng = Intersect(Target, rng_1) If Not rng Is Nothing Then Cancel = True If Target.Value = "" Then Target.Value = "(1)" Else Target.Value = "(1)" End If Else Set rng = Intersect(Target, rng_2) If Not rng Is Nothing Then Cancel = True If Target.Value = "(2)" Then Target.Value = Empty Else Target.Value = "(2)" End If Else Set rng = Intersect(Target, rng_3) If Not rng Is Nothing Then Cancel = True If Target.Value = "(3)" Then Target.Value = Empty Else Target.Value = "(3)" End If Else Set rng = Intersect(Target, rng_4) If Not rng Is Nothing Then Cancel = True If Target.Value = "(4)" Then Target.Value = Empty Else Target.Value = "(4)" End If End If End If End If End If End Sub

  • VBAにお詳しい方!教えてくださいませ。

    エクセルで、E列に文字を入力した際にB列に、J列からM列に文字を入力した際にC列に入力した日付を自動的に入力されるようなマクロを教えてください。 自分で探した限りでは Private Sub Worksheet_Change(ByVal Target As Range) Dim r, rng As Range Set rng = Intersect(Target, Columns("E:E"))   If Not rng Is Nothing Then     For Each r In rng       If r.Value = "" Then         r.Offset(, -3).ClearContents       Else         r.Offset(, -3).Value = Date       End If     Next r   End If End Sub までしか出来ませんでした。 しかも複数条件を指定する方法もわかりません・・・・。 ぜひともお詳しい方、ご伝授くださいませ

  • エクセル VBA の質問です。

    A2~A20までのセルに文字を入力した段階で、それぞれB2~B20に入力日時を入れるVBAを以下のように組んでいます。 しかし、同様の条件を同一シートのE2~E20・F2~F20にも入力・自動表示できるようにしなければならなくなり、困っています。 どのように記述を変えればよいのか、教えていただけたらと思います。 宜しく御願いいたします。 Sub Worksheet_change(ByVal Target As Range) Dim Rng As Range Dim c As Range Set Rng = Range("A2:A20") If Intersect(Target,Rng) Is Nothing Then Exit Sub For Each c In Intersect(Target,Rng) If Not IsEmpty(c) Then c.Offset(, 1).Value = Now Else c.Offset(, 1).ClearContents End If Next Rng.Offset(, 1).EntireColumn.AutoFit End Sub 申し訳ありませんが、何卒、宜しく御願いいたします。

  • エクセルVBAで表から行の削除

    添付画像のような表があります。 表はB列の名前でソートされています。 D列の比率をみて、100でないものは、必ず同じ名前で複数行にわかれ合計で100になります。この例では名前CとEとHがそうです。 同じ名前が複数行にわかれている場合、最大の比率の行を残し、他の行(例では、埼玉、栃木、長野、新潟の行)を削除したいのです。 複数行にわかれるのが名前CやEのように2行なら、以下のコードで出来ました。 しかし、めったにはありませんが名前Hのような3行以上に分かれるものには対応できません。 どうすればよいでしょうか? Sub test01()   Dim c As Range   Dim Rng As Range   Set Rng = Range(Cells(2, "D"), Cells(Rows.Count, "D").End(xlUp))   For Each c In Rng '2地区の分担の場合、分担比率高い方を残す。(3地区以上は未対応)2012/08/29     If c.Value <> 100 And c.Offset(1).Value <> 100 Then       If c.Offset(, -2).Value = c.Offset(1, -2).Value Then         If c.Value >= c.Offset(1).Value Then           c.Offset(1).Value = False         Else           c.Value = False         End If       End If     End If   Next   If Application.WorksheetFunction.CountIf(Rng, False) > 0 Then     Rng.SpecialCells(xlCellTypeConstants, xlLogical).EntireRow.Delete   End If End Sub

  • エクセル 数値結果の値によって日付を入れたい

    シート2の2列目にOKが入ると、シート1のC列にOKが入り、更新された日がB列に表示されるようにしたいです。 C列に手入力でOKと入力すればB列に日付が表示されるのですが、C列をVLOOKで呼ぶようにしたら表示されなくなってしまいました。 どのように修正していいのか分かりません。 お教えいただければと思います。よろしくお願いいたします。 Private Sub Worksheet_Change(ByVal Target As Range) Dim Rng As Range Dim TgRng As Range Set TgRng = Intersect(Range("C1:C2000"), Target) If Not TgRng Is Nothing Then Application.EnableEvents = False For Each Rng In TgRng If Rng.Value = "OK" Then Rng.Offset(, -1).Value = Date End If Next Application.EnableEvents = True End If Set TgRng = Nothing End Sub

  • VBAについて

    以下のプログラムは、1年間の価格合計を求めるプログラムです。 これを実行するとうまくいくこともありますが、エラーが起きることもあります。 どうやら下記コードが原因のようなのですが、間違いがわかりません。 Target.Offset(0, 1).Value = run * (13 - month) どこが間違っているのでしょうか。 また最終的に、A行かB行のどちらかが更新されたときにこのプログラムを 実行させたいのですが、方法がわかりません。 無知な質問ではありますが、どなたか教えてください。 --------------------------------------------------------- Private Sub Worksheet_Change(ByVal Target As Range) Dim month As Integer Dim run As Integer If Intersect(Target, Range("A25:A35")) Is Nothing Then Exit Sub Else If Target.Offset(0, -2).Value <> "" Then month = Target.Offset(0, -2).Value month = month - 3 If month = -2 Then month = 10 ElseIf month = -1 Then month = 11 ElseIf month = 0 Then month = 12 End If run = Target.Offset(0, 0).Value Target.Offset(0, 1).Value = run * (13 - month) End If End If End Sub

  • 複数セル参照で塗りつぶしを変更する

    WIN:XP Off:2003 お願いします。 添付した図は入出金表です。 列Hに数値が入力されると列Eのセルが青く塗りつぶされます。 Private Sub Worksheet_Change(ByVal Target As Range) Dim Rng As Range Dim aCell As Range Set Rng = Intersect(Target, Range("H:H")) If Rng Is Nothing Then Exit Sub For Each aCell In Rng If aCell.Value > 0 Then aCell.Offset(0, -3).Interior.ColorIndex = 17 Else aCell.Offset(0, -3).Interior.ColorIndex = xlNone End If Next aCell Set Rng = Nothing End Sub ここまでは出来たのですが、列Iに入力された時に列Eが赤に塗りつぶされるにはどうしたらいいでしょうか? 同じ行のHとIに同時に数値が入る事はありません。 どうかお願い致します。

  • [VBA]型が一致しません

    EXCELWORKSHEET上で下記の処理をすると「型が一致しません」との エラーがでます。どうにも原因と対応策がわからず悩んでいます。 デバッグの良い方法ありませんでしょうか? <現象> *列2上のセルを選択して、DELETEキーを押す。⇒エラーなし。 *しかし、列2上のセルとその他のセルを同時選択した上で、DELETEキーを押すと「型が一致しません。」のエラー。 頭の「If Target.Column Like 2 And Len(Target.Value) > 0 Then 」が悪さしているのはわかるのですが・・・。 Private Sub WORKSHEET_CHANGE(ByVal Target As Range) If Target.Column Like 2 And Len(Target.Value) > 0 Then Range("c" & Target.Row).Value = Now If Target.Column Like 2 And Len(Target.Value) > 0 Then 'B列の場合だけ確認 Dim rng As Range Set rng = ActiveSheet.Range("B:B").Find(What:=Target, LookIn:=xlValues, LookAt:=xlWhole, MatchCase:=True, MatchByte:=True) If Not rng Is Nothing Then '発見した。 If rng.Address <> Target.Address Then '入力中セル以外で発見 Select Case MsgBox("過去に受け入れたLOTです。再度受入れますか?", vbYesNo) Case vbYes Range("B2").Activate Selection.End(xlDown).Select ActiveCell.Offset(0, 1).Activate ActiveCell.Value = Now ActiveCell.Offset(0, 1).Activate ActiveCell.Value = UserForm2.TextBox2.Value UserForm2.TextBox1.Value = "" UserForm2.TextBox2.Value = "" UserForm2.TextBox1.SetFocus Range("B2").Activate Selection.End(xlDown).Select Selection.Offset(1, 0).Select Case vbNo Range("B2").Activate Selection.End(xlDown).Select ActiveCell.ClearContents ActiveCell.Offset(0, 1).Activate ActiveCell.ClearContents UserForm2.TextBox1.Value = "" UserForm2.TextBox2.Value = "" UserForm2.TextBox1.SetFocus End Select End If End If End If End If End Sub

  • エクセルVBA

    A列を基準にBC列が空白ならAの数値を入れて、A>BならB列を更新、A<CならC列を更新 A列が数値以外ならその行をスキップ、という処理をしたいのですが Option Explicit Dim A As Range, B As Range, C As Range Dim i As Long Sub test() For i = 1 To 10 Set A = Cells(i, 1) Set B = A.Offset(0, 1) Set C = A.Offset(0, 2) If IsNumeric(A) Then Else Exit Sub End If If B.Value = "" Then B.Value = A.Value If C.Value = "" Then C.Value = A.Value If A.Value > B.Value Then B.Value = A.Value If A.Value < C.Value Then C.Value = A.Value Next i End Sub とすると数値以外の行の時点で停止してしまいます。 その行を飛ばして次の行に進むにはどうしたらいいのでしょうか?

  • Excel VBA の件で質問です

    照合システムを作ろうとネットを閲覧していたら次のコードが見つかりました。 Private Sub Worksheet_Change(ByVal Target As Range) Dim rr As Range If Not Intersect(Target, Range("C1:D10")) Is Nothing Then For Each rr In Intersect(Target.EntireRow, Range("C:C")) If Not IsEmpty(rr) And Not IsEmpty(rr.Offset(, 1)) Then Application.EnableEvents = False If rr.Value <> rr.Offset(, 1).Value Then Beep rr.Offset(, 2).Value = "NG" Else rr.Offset(, 2).Value = "OK" End If Application.EnableEvents = True End If Next End If End Sub このコードでいくと、C列とD列が同じであればE列にOK、間違っていればNGなのですが、C1とC2が同じであればE1にOK、間違っていればNG。次にC3とC4が同じであればE3にOK、間違っていればNG。…というふうにしたいのですが、どうすれば良いのでしょうか?

専門家に質問してみよう