- ベストアンサー
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列の同じ行にその時刻が入るように書き直したいのですが、どうすればいいのでしょうか? すいませんが、よろしくお願いします。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
補足読みました。同時に使いたいということでしたか。早とちりしてすいません。 で質問者さんが試されたコードのどこが問題かと言うと 。 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 とかなりますが、列の判定部分はもっとスマートに出来るかと思います。
その他の回答 (3)
- popesyu
- ベストアンサー率36% (1782/4883)
1、2番です。 まぁ解決したようですが。最後にヒントということで。 基本はデバックとヘルプだけで初めて見るコードでもどこでエラーが出ているのか、またどこが問題かがわかりますよ。 本やら通信教育はヘルプの補足にしかすぎません。 まず今回の例で具体的に説明しますと。 最初に1番の補足にあるようなコードを試せばエラーが出ますよね。 でどこでエラーが出ているかは、デバックの際にステップバイステップで一行ずつ確認しながら進めると If Target Is Nothing Then Exit Sub の行でいきなり終了されてしまっているのがすぐに把握できます。 で次のエラーはTargetの変数を上書きさせて処理させている為の問題で、この辺りの参照形式の方法などは、一般論的な変数の取り扱いの方法などは本などが役にたつかと思います。 そしてヘルプの使い方に関しては。 例えば3番さんが紹介した方法ですと範囲指定で(B、C列をまとめて貼り付けなどで)こぴぺされた場合などに正常に動きません。 で変更がおきた列を把握するのにIntersectメゾットが使われているのはそれへの対応のようですが、私はこのメゾットの存在も使い方も知りませんでしたw ヘルプを見てその使い方を確認たところ、確かにこういう回りくどい方法が必要なようなんですよね。 まぁ存在すら知らないメゾットをいきなりヘルプから調べるのは難しいのですが、サンプルなどがあればそれがヒントそのものになります。意味が不明な語句が出たらまずヘルプで確認しましょう。 以上、今回のトラブルは変数の取り扱いの処理の部分だけ、本などできちんと勉強していればそれ以外のエラーに関してはエラーが起きた箇所を把握するだけで解決できた問題かと思います。
お礼
ご丁寧なアドバイスありがとうございました。 いままであまりヘルプは参照せず本やらネットやらを参考にやってきましたが、ヘルプが結構重要なんですね。今回もヘルプを見直していたら勉強になりました。 まだ、基礎がしっかりとしていないので大変ですが、地道にがんばってみます。 このたびは本当にありがとうございました。 これからもよろしお願いします。
- imogasi
- ベストアンサー率27% (4737/17069)
ご質問の意図を誤解していたら済みません。 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
お礼
imogasiさま、バッチリです。ありがとうございます。 すっきりしました。 すいません、差し支えなければ#2のお礼欄にも書かせていただいたのですが、VBA初心者へのアドバイスをもらえたら助かるのですが・・・ 独学なんでとまどっています。 よろしくお願いします。
- popesyu
- ベストアンサー率36% (1782/4883)
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の部分ぐらいは直感で判断できないのなら、無理に修正しない方がいいのではないかなと思いますが。 修正方法とかそれ以前の部分で戸惑われませんか?
補足
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
お礼
popesyuさま、ありがとうございました。 上手くいきました。 しかし、これも構文をコピーさせていただいただけで、ご指摘の通り自分では作れません。 なんとか業務に関係する30ほどの関数を扱えるレベルなのですが、VBAをなんとか習得したいと思い、今まで勉強したのと同じように本を読みながら参考にやっているのですが、なかなか今までのようにはスムーズにいかず、通信教育とかも受けてはいるのですが、何かしっくりきません。 この場であつかましい質問なのですが、VBA初心者の勉強方法の心得とかありましたら教えていただきたいのですが・・・・ ホント、申し訳ないですがよろしくお願いします。