質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

Q&A

解決済

4回答

9482閲覧

【Excel VBA】入力月日の自動入力

linx_0415

総合スコア8

VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

0グッド

0クリップ

投稿2018/12/25 08:10

編集2018/12/25 09:04

『Private Sub Worksheet_Change(ByVal Target As Range)』を用いて、
E10セルに名前入力(手動)後、入力時点の月日がE11セルに入力(自動)される
(E12セルに名前入力→E13セルに月日が入力される…といった形で、同様に行方向への動作が繰り返される)
という動作を行わせたいです。

DEF
名前(手動)
日付(自動)
名前(手動)
日付(自動)
・・・

↑なんとなくですが、こんなイメージ…。
D10/D11セル、F10/F11セルは結合されています。(以下行方向に同様の状態)

ネットに散見しているコードをかき集めて、以下のようになりましたが、
動作はしないし、どれがどういう役割でどんな動きをするのかというのも
まったく理解できていません。

Private Sub Worksheet_Change(ByVal Target As Range) If Intersect(Target, Range("E:E")) Is Nothing Then Exit Sub If Target.Row <> 1 Then Exit Sub Application.EnableEvents = False Target.Offset(1, 0).Value = Now Application.EnableEvents = True End Sub

どのようなものであれば動作するのか/それぞれどのような役割があるのか等、
初心者なのでお手数おかけしますが、教えていただけますと幸甚です。

<用途>
作業のチェックリスト内
名前は入力は徹底されているが、日付の入力が徹底されないという状況の対応策
同列ではなく、E列名前/F列日付といった妥協も検討中です。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2018/12/25 08:19

質問の意図がいまいち分からないです。 「太郎」と名前を入力(この操作は手動)→年月が自動入力(この操作はプログラム) 「花子」と名前を入力(この操作は手動)→年月が自動入力(この操作はプログラム) ・・・・・ この操作を行いたいという意味でしょうか?
TanakaHiroaki

2018/12/25 08:19

当該シートモジュールにマクロを記載されていますでしょうか。 初心者がイベントプロシージャを用いて期待通りに動作するものを 作成するのは難しいかもしれません。
torisan

2018/12/25 08:29

入力欄がE1ならば動作確認とれました、とだけ。
linx_0415

2018/12/25 08:57 編集

>NETACHILさん  その意味で間違いありません。わかりづらくて申し訳ないです…。 >TanakaHiroakiさん  当該シートモジュールに記載しています。  標準モジュールに慣れた/複数動作を組み合わせて期待通りに動作するものを作成することができるようになった程度の初心者です。  難しいというのは、新しい知識を得るうえでは当たり前ですし、やっていかないと難しいまま進まないので挑戦している段階です。
TanakaHiroaki

2018/12/25 09:24 編集

>linx_0415さん 難しいという言葉で気を悪くさせて申しわけありません。私も初心者です。 Targetが複数セルの場合に想定していない動作が起こりやすいので気をつけてください。
guest

回答4

0

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つ上のセルに何か入力されているときに、
空欄を許さない

ということならば、
条件付書式設定で、セルの塗りつぶしを赤とかにして、注意を喚起する
という方法論もありかなと思います。

個人的には、「元に戻す」機能を潰してまで、
自動化に拘る案件には思えません。
(もちろん、説明されてない機能も付けて、
アプリケーションとかシステムとかと呼ばれるようなものを
これからガッツリ作るなら、それはそれでありだとは思います。)

あああああ
でもでもでも、

作業のチェックリスト内

こういうことなら、ダブルクリックで名前と日付が入るようにしたほうがいいかも。。。
入力規則のリストから名前選んで、日付が入るように。。。とかもあり?
まぁ、アイデアはいろいろ出てきますが、
まずは、ちゃんと、電話口の先の他人に伝わるように説明できるように、
やりたいこと(前提条件も含む)をちゃんとできるようになりましょう。

投稿2018/12/25 13:00

編集2018/12/25 13:45
mattuwan

総合スコア2136

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

自己解決

今回は別途担当者欄を用意し、作業完了時は日付のみ入力/作業予定者と違う者が作業を実行した場合は、担当者欄の名前を変更…という措置をとることにしました。

今までVBAの勉強をしていた時は、(もちろんいくつも試した結果)

①やりたいことをざっくりGoogle検索
②上がってきたコードを実際に自分で実行
③実際の動作を見て理解
④不要なコードを削除。必要なコードを残し、簡易的に書き換え。
⑤どのような動作になるのか、コメントを記入し見返せるようにする

という形でやっていたため、今回の質問に至りました。
※今回は実際に動作させてみても、何が動いているのかわからなかった
※コードを細かく検索してみても、適切な情報に出会えなかった

ロジカル的に物事を考えてまとめて伝えるのが苦手なタイプ(直観的タイプ)なので、
こういった掲示板で質問をしてどうにかする、、、というのが向いてなかったのかもしれません。
皆様にはご迷惑をおかけしました。

ただ、今回はそもそも初心者問わず、実装するのことが難しそうな事象だったということを知ることができました。
勉強自体は各々の適切な形(理解しやすい・飲み込みやすい)があると思いますので、ご了承いただけますと幸甚です。
またもっと簡単なもので(明確にセル範囲が決まっているものとか)Private Subなどに挑戦してみたいと思います。

投稿2018/12/26 00:55

編集2018/12/26 01:00
linx_0415

総合スコア8

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

TanakaHiroaki

2018/12/26 14:00

解決済みとのことですが、あえてコメントしました。 以下の方法で、どのような動きをしているのか理解することができるはずです。 ・コードの実行を、ステップ実行(F8を押す)で1行ずつ確認 ・Debug.Print で変数をイミディエイトウィンドウに出力 VBAの学習を地道に積み重ねると大きなリターンが得られますよ。
guest

0

<アドバイス>
Worksheetのイベントプロシージャを使用する場合、Targetが複数セルの場合に想定していない動作が起こりやすいので気をつけてください。
今回の事例では、むしろWorkbookのイベントプロシージャを使用し、ファイル閉じるボタンが押された場合に、該当シートの該当列に名前があり、かつ関連するセルの日付が空欄であることを検出し、現在日時を自動入力するマクロのほうが少し簡単に実現すると思います。

mattuwanさん

私がlinx_0415さんにコメントした「難しいかもしれません。」を具体的かつ適切に表現していただき、ありがとうございます。
新しい知識を得るために「ネットで寄せ集めたコードでマクロを組む」は、誰もが陥りやすい遠回りな手段であり、作業の流れを整理してからコーディングすることの大切さを丁寧に記載いただき、大変感服いたしました。

投稿2018/12/25 13:23

編集2018/12/25 13:38
TanakaHiroaki

総合スコア1063

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

「E10セルに名前入力後、自動で入力時点の年月がE11セルに入力される」という事であれば、内容が変化するセルは E10 だという事になります。

であれば、Worksheet_Change(range("E10")) というような使われ方なのでしょう。
そうすると引数Target は、 Range("E10")という値を持つことになります。Target.Rowの値は10になります。

そうすると下記の行で、Target.Row <> 1 が成り立つからSubの実行が終わります。

If Target.Row <> 1 Then Exit Sub

以上が、「動作はしない」理由だと考えられます。

=== 感想 ===
Excelは、任意のセルの値を書き換えられます。
なので、次にどのセルが変更されるかが事前にわかりません。

E10の次にE22が書き換えられるというような事も起こり得ますから、
どんな時にも対応できるようにするには、E2が書き換えられた時、E4が書き換えられた時、、、、、と延々と準備をしておかなければなりません。

もうすこし、どのような使われ方を想定して、何が必須なのかといった事を検討したうえで、プログラムの構成を考えたほうが良いのではないでしょうか。

投稿2018/12/25 08:54

coco_bauer

総合スコア6915

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問