VBA
1'セルの内容が変わった時に、実行(変数Targetにはその対象セル範囲が代入される)
2Private Sub Worksheet_Change(ByVal Target As Range)
3
4 '対象セル範囲とE列のセル範囲とが重なっているセルが無い場合、プログラムから抜ける
5 '(つまり、対象セル範囲内にE列のセルが含まれていれば次に進む)
6 If Intersect(Target, Range("E:E")) Is Nothing Then Exit Sub
7
8 '対象セルの行番号が1以外ならプログラムを抜ける
9 '(つまり対象セル範囲にE1セルが含まれなければ、終わり)
10 If Target.Row <> 1 Then Exit Sub
11
12 'イベント処理を無効化
13 '(つまり、今からセルに値を入れるので、
14 '値を入れたら、また、Worksheet_Changeイベントが発生するので、
15 '無限にイベントが次々と発生するのを抑制する)
16 Application.EnableEvents = False
17
18 '現在の日時を対象セルに入力する。
19 Target.Offset(1, 0).Value = Now
20
21 'イベント処理の有効化
22 Application.EnableEvents = True
23 'プログラム終わり
24End Sub
んと、昔、僕が指摘を受けた言葉をそのまま、書きます。
「ネットで寄せ集めたコードでマクロが組めたら奇跡だ。」
多分、上で日本語で書いたコメントの意味が分からないなら、
基礎から勉強すべきだと思います。
あと、コードにする前にちゃんと日本語で作業の流れを説明すべきです。
E10セルに名前入力(手動)後、入力時点の月日がE11セルに入力(自動)される
(E12セルに名前入力→E13セルに月日が入力される…といった形で、同様に行方向への動作が繰り返される)
という動作を行わせたいです。
まず、前提条件を整理しましょう。
1)マクロを実行するのはE列のみ
2)マクロを実行するのは10行目以降
3)マクロを実行するのは偶数行のみ
4)コピペで複数セルをコピーしてきた場合はどうしましょ?
こういう事でしょうか?
次に作業の流れを考えます。
0)セルに値が実行されたら、プログラム実行
1)対象セルにE列が含まれなければ99番へ
2) 対象セルがE列だけでないなら、98番へ
3) 対象セルの先頭の行番号が10行目以降でないなら99番へ
4) 対象セルの先頭の行番号が偶数でないならプ99番へ
(上記の条件に当てはまらなければ以降の5番・6番が実行される)
5) 対象セル範囲の真下に今日の日付を入力
6) プログラムから抜ける
98) 入力をキャンセル
99) 何もしない(プログラム終わりの目印)
100)プログラム終わり
このような感じでしょうか?
※注
適当に書いてますので、そちらが本当にやりたいことかは吟味してません。
多分、この程度の処理でも、慣れた人でも、一発で完璧なコード(プログラム)を
書ける人は少ないでしょう。
それでも、最初にある程度日本語で、整理してから、
VBA語に翻訳した方がいいと思います。
その上で、何度も実験して(動作確認して)、見落としている前提条件を探していくことになります。
コードの意味が分からないなら(あるいは説明で使っている用語の意味が分からないなら)、
一単語、一単語、ネットで検索してみてはいかがでしょうか?
また、書籍を購入してみるのもありでしょう。
まずは取っ掛かりとして参考コードを書いておきます。
VBA
1Private Sub Worksheet_Change(ByVal Target As Range)
2 'もし、対象セル範囲のセルの数が1個でなければ処理を抜ける
3 If Target.CountLarge <> 1 Then Exit Sub
4
5 '※上記の行で以降の対象セル範囲(Target)が、
6 '1個のセルの場合に限定されているので、「範囲」とは表現しない
7 'が、本質的には1個のセルでもセル範囲ではある
8
9 'もし、対象セルがE列を含まなければ処理を抜ける
10 If Intersect(Target, Me.Range("E:E")) Is Nothing Then Exit Sub
11 'もし、対象セルが10行目以降でなければ処理を抜ける
12 If Target.Row < 10 Then Exit Sub
13 'もし、対象セルが偶数行でなければ処理を抜ける
14 If Target.Row Mod 2 <> 0 Then Exit Sub
15
16 '対象セルの1つ下に、今の日付を入力
17 Target.Offset(1).Value = Date
18End Sub
プログラミング的なテクニックの一つとして、
やりたいことをやらない時の条件をチェックしていって、
どの条件にも該当しなければ、やりたいことをする、
ように書けば、
分かりやすいコードになるのではないかと思います。
あああ^^;
上記のサンプルでは、イベントの無効化をするのを忘れてますね^^;
まぁ、If文で、奇数の行への入力は無視するようにしているので、
無限にイベントが発生することはないとは思いますが。。。。^^;
参考まで。
追記
自分では手入力で一つ一つのセルにしか入力しないと思っていても、
エクセルには複数セルを一度に書き換える方法がいくつかある(コピペ等)ので、
特に他人に使って貰えるようにするには、その辺も考慮する必要があります。
(数式で対象セルの内容が変わった時はイベントは発生しない?)
が、まぁ、この辺もエラーが出たり希望の結果がでないのも経験なので、
まずはやってみるところから始めてみればいいと思います。
その上で、困ったらこういう言う掲示板でアドバイスを求めて行けばいいと思います。
うろ覚えの言及もしてますが、この辺は何度も動かしながら確認することになると思います^^;
あと、
Changeイベントは、値を書き換えなくても、一旦、
編集モード入って(セル内にカーソルが出てきた状態)後、
Enterキー押下等編集モードを抜けたときに発生したと思います。(あやふやでごめんなさい)
その辺のエクセル君の癖も考慮してマクロを作る必要があります。
それから、割と忘れられがちですが、
こういうマクロは、
「標準機能についてないから、自分用(あるいは配布用に)にエクセルをカスタマイズする。」
ということです。
便利ではありますが、副作用もありますので、重々承知のうえ、取り組まれることをお勧めします。
(一番の不便は「元に戻る」の履歴がクリアされて、「元に戻る」で元に戻せなくなる)
最後になりましたが、**単に「今日の日付を簡単に入力したい」**という事であれば、
「Ctrl」キーを押しながら、「;」キーを押下でセルに今日の日付が入ります。
そちらの操作を覚えるくらいで十分かと思います。(※これなら、元に戻せる)
(それはそれで職人技っぽい難しさがあるかも知れませんが。)
他にも多々ショートカットキーで出来ることがありますので、
そういうのも調べられたら、エクセル君を使うことが楽しくなるかも知れません♪
でわ ^^)ノシ
うううう。
<用途>
作業のチェックリスト内
名前は入力は徹底されているが、日付の入力が徹底されないという状況の対応策
同列ではなく、E列名前/F列日付といった妥協も検討中です。
見逃してました。
こういうことなら、
E列で、
奇数行で、
1つ上のセルに何か入力されているときに、
空欄を許さない
ということならば、
条件付書式設定で、セルの塗りつぶしを赤とかにして、注意を喚起する
という方法論もありかなと思います。
個人的には、「元に戻す」機能を潰してまで、
自動化に拘る案件には思えません。
(もちろん、説明されてない機能も付けて、
アプリケーションとかシステムとかと呼ばれるようなものを
これからガッツリ作るなら、それはそれでありだとは思います。)
あああああ
でもでもでも、
作業のチェックリスト内
こういうことなら、ダブルクリックで名前と日付が入るようにしたほうがいいかも。。。
入力規則のリストから名前選んで、日付が入るように。。。とかもあり?
まぁ、アイデアはいろいろ出てきますが、
まずは、ちゃんと、電話口の先の他人に伝わるように説明できるように、
やりたいこと(前提条件も含む)をちゃんとできるようになりましょう。