ログインしてさらにmixiを楽しもう

コメントを投稿して情報交換!
更新通知を受け取って、最新情報をゲット!

EXCEL VBAコミュの範囲の中に数字を一つだけ表示

  • mixiチェック
  • このエントリーをはてなブックマークに追加
初めまして。
只今エクセルVBA勉強中真っ只中のナデシコと言います。

現在作っているものでわからないところがあるので、
わかる方、教えてください。

A1:A5の範囲の中に1を一つだけ入力でき、
且つ、
B1:B5の範囲の中に1を一つだけ入力でき、
且つ、
C1:C5の範囲の中に1を一つだけ入力できる。

というコードを組みたいのですが、
一つ目のコードだけは以下のようにしました。

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
  Dim clvl As Variant
  If Application.Intersect(Target, Range("A1:A5")) Is Nothing Then Exit Sub
  If Target.Offset(-1, 0) <> "" Then
    clvl = Target.Offset(-1, 0)
    Range("A1:A5").ClearContents
    Target.Offset(-1, 0) = clvl
  End If
End Sub


実はこれのコードは私が組んだものではなく、
他の人にやってもらったものなので、
私にはまだ理解できないところが多々あります。

このコードを利用して、且つ、Select Caseを使ったコードを
書くには、どうすればよいのでしょうか?

いろいろと考えてみましたが、全く分からず困っています涙

コメント(13)

追記します。

「A1:A5の範囲の中に1を一つだけ入力でき、」
の詳細ですが、

例えばA1に<1>が入力されている状態でA2に<1>を入力するとA1の<1>は消えるようにする
(その他の条件も同様に)

ということを行うためのプログラムを考えています。

よろしくお願いします。。。
ちとこのコードでは充分でないですね…。
(1). A1セルを選択した時にエラーが出てしまう
(2). A1〜A4のいずれかに値を入れた状態で、A5セルに値を入れて
   Enterを押すと元のセルとA5両方に値が入ってしまう
(3). 値の確定をEnterキーでなくTabキーで行った場合に対応できない

SelectionChangeイベントでなく、Changeイベントで行うのが
いいのではないかと思います。
動くコードは作りましたが、まず上記のコードでやっている事を
理解されてからのほうがわかりやすいかと…どうしましょう?
とりあえず、、、

Private Sub Worksheet_Change
  Dim clvl As Variant
  If Application.Intersect(Target, Range("A1:A5")) Is Nothing Then Exit Sub
  If Target.Offset(-1, 0) <> "" Then
    clvl = Target.Offset(-1, 0)
    Range("A1:A5").ClearContents
    Target.Offset(-1, 0) = clvl
  End If
End Sub


イベントプロシージャを直してみました。

Select Caseを使いたいのは、Select Caseを勉強しているので・・・という理由からですあせあせ


やむさん、
私は根本的には動くプログラムを作るよりも、
「内容を理解」していきたいので、
説明頂けるなら、是非exclamation ×2お願い致しますexclamation ×2
えぇと、まずSelectionChangeで書いていた場合で説明しますね。
Changeイベントに書いた場合、Targetの意味合いが変わりますので。


Dim clvl As Variantの部分は宣言なのでいいとして…

If Application.Intersect(Target, Range("A1:A5")) Is Nothing Then Exit Sub

Intersect(範囲1,範囲2)は、範囲1と範囲2の共通部分を取得するものです。
この場合、共通部分=Nothing…つまりA1〜A5のどことも重ならない場合は
処理を抜けています(Exit Sub)。

If Target.Offset(-1, 0) <> "" Then

・セルの値をかえたあとEnterキーで確定する
という事を前提としてコードが組まれているようです。
その前提で説明すると、
Target(今いるセル)の1行上のセル(直前にいたセル)の値を見て、
何か入力されていたらIf文の中を実行という流れです。

clvl = Target.Offset(-1, 0)

これで直前のセルの値を変数に格納しておいて、

Range("A1:A5").ClearContents

A1〜A5セルの内容をクリアして、

Target.Offset(-1, 0) = clvl

あらためて直前のセルに値を格納しなおしています。
次にエラーが起きた理由を…長文ですみませんあせあせ(飛び散る汗)

(1). A1セルを選択した時にエラーが出てしまう

もとのコードだと
「値を入力してEnterキーを押したときに実行されるイベント」
という認識でコードを書いていると思うんですが、このイベントは
セルの位置が変わった時のイベントなので、たとえばセルをクリック
しただけでもイベントが実行されます。
ここで、A1セルをクリックすると
Target.Offset(-1, 0)…A1セルの1つ上のセル
これは存在しないのでエラーになってしまいます。

(2). A1〜A4のいずれかに値を入れた状態で、A5セルに値を入れて
   Enterを押すと元のセルとA5両方に値が入ってしまう

A5セルに値を入れてEnterキーを押すと、移動先のセルはA6セルです。
そうすると、A1〜A5の範囲に入っていないという判定になるので
その後の処理が行われない→値がダブって入ってしまいます。

(3). 値の確定をEnterキーでなくTabキーで行った場合に対応できない

Tabキーで確定すると下ではなく横に移動するのにコードでは
あくまで今いる位置の1行上を見るので、正しく判定できません。
んで、動くコードはこちらです。
今回の場合Select Caseを使わないほうが単純だったりするのですが、
例として使用してみました。

Changeイベントの場合、Targetは値が変更されたセル範囲を指します。
(たとえばA1セルに値を入れてEnterを押したとき、SelectionChangeだと
TargetはA2セルですがChangeイベントだとTargetはA1セルになります)

Private Sub Worksheet_Change(ByVal Target As Range)
 Dim clvl As Variant
 If Application.Intersect(Target, Range("A1:C5")) Is Nothing Then Exit Sub
 clvl = Target.Value
 Application.EnableEvents = False
 Select Case Target.Column
  Case 1: 'A列の場合
   Range("A1:A5").ClearContents
  Case 2: 'B列の場合
   Range("B1:B5").ClearContents
  Case 3: 'C列の場合
   Range("C1:C5").ClearContents
 End Select
 Target.Value = clvl
 Application.EnableEvents = True
End Sub
どーんと書いてしまいましたが、わかりにくいところがありましたら
そう言ってくださいませ手(パー)
レス遅くなってすみません。

やむさん・・・ありがとうございます。
完璧です。
理想通りに動きました。
本当にありがとうございます。

enterだけでなく、Tabでもきちんと動きます。

ちなみにやむさんは、9レス目(?)のコードを書くのに、
時間はどのくらいかかりますか?

こういうものって、頭の中でサラサラッと出来るものなんでしょうか?

私はまだまだ修行中の身なので、
サラサラどころか全然です涙
>ナデシコさん
慣れてしまえばある程度パターンが決まってきちゃうので、
考えてから書くまでそんなにはかかりませんよー。
今回のは元のコードがあったのをいじっただけなので、1分弱です。

Application.EnableEventsの意味はgoogleか何かで調べておいて
くださいなー。
VBAはgoogleで検索すればいくらでもサンプルが転がってるので、
わからなければ検索するようにすると効率がいいかと思います。

と、ついでにSelect Caseを使わないパターンものせておきますね。
Cellsプロパティはかなり使う頻度が高いかと思います。


Private Sub Worksheet_Change(ByVal Target As Range)
 Dim clvl As Variant
 If Application.Intersect(Target, Range("A1:C5")) Is Nothing Then Exit Sub
 clvl = Target.Value
 Application.EnableEvents = False
 Range(Cells(1, Target.Column), Cells(5, Target.Column)).ClearContents
 Target.Value = clvl
 Application.EnableEvents = True
End Sub
1分弱exclamation & questionですかexclamation & question

はぁ〜〜〜〜〜〜・・・ふらふら
すごいですねぇ〜〜〜〜〜。
私も早くそのくらいにならなくては・・・。

ついでといいつつ、立派なプログラムをありがとうございます。
本当に勉強になりました。

また何か質問することがあるかもしれませんが、
その時はどうぞまた、よろしくお願いします。


P.S.その時までには今よりは少し、成長しておきますあせあせ(飛び散る汗)

ログインすると、みんなのコメントがもっと見れるよ

mixiユーザー
ログインしてコメントしよう!

EXCEL VBA 更新情報

EXCEL VBAのメンバーはこんなコミュニティにも参加しています

星印の数は、共通して参加しているメンバーが多いほど増えます。