• ベストアンサー

ダイアログボックスを表示させるマクロ

こんにちは。 エクセルのマクロについて教えてください。 エクセルでA列に名前を入力する作業をしています。 入力作業中に、それまでに入力した名前と 重複した名前を入力しようとすると、 「重複しています」と ダイアログボックスを表示するマクロは どのように組めばよいのでしょうか? わかりづらい文章ですみません。 よろしくお願いします。  (A列) 1 高橋 2 田中 3 佐藤 4 太田 5 田中 ←←重複した名前を入力すると、        「 重複しています」とダイアログボックスが表示される。

  • pgn
  • お礼率96% (29/30)

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

  • ベストアンサー
  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.9

こんにちは。 しばらく時間が経ってしまいすみません。 もう少し、きれいなコードに出来ると良かったのですが、思った以上に、あまり良い考えがまとまらなかったです。今年は、とても暑い! Private Sub Worksheet_Change(ByVal Target As Range)   Dim c As Range   Dim TargetCell As Range   If Target.Column <> 1 And Cells(Target.Row, 1).HasFormula Then     If Target.DirectDependents.Column = 1 Then       Set TargetCell = Cells(Target.Row, 1)       If WorksheetFunction.CountIf(Columns(1), TargetCell.Value) > 1 Then         MsgBox "重複"         Application.EnableEvents = False         Target.ClearContents         Application.EnableEvents = True         Set TargetCell = Nothing         Exit Sub       End If     End If   Else     For Each c In Target       If Not c.HasFormula Then         If WorksheetFunction.CountIf(Range("A1", Target), c) > 1 Then           MsgBox "重複"           Application.EnableEvents = False           Target.ClearContents           Application.EnableEvents = True         End If       End If     Next c   End If End Sub

pgn
質問者

お礼

Wendy02さん、こんばんわ。 お礼が遅くなりすみませんでした。 教えていただいたコードで思ったとおりに出来ました。 これまで悩んでいたことがすっきりしました。 コードの内容をすぐには理解できませんが、 じっくり勉強させていただきます。 Wendy02さんには、私のとりとめのない質問に いつも親切にわかりやすく回答していただいて 感謝の言葉もありません。 ありがとうございました。

その他の回答 (8)

  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.8

こんばんは。 >A列に「=B&C&D」という式をいれると この数式では、数式として入りません。確認しますが、数式は、以下のようなものですね。 例えば、A4 に =B4&C4&D4 この状況では、そのような問題は発生しておりません。 Excelのバージョンは、2003以下ですか? ループして、「重複」というメッセージが何度も出るということでしょうか?今回、数式があれば、メッセージは出ないようにしてあります。 もし、チェックするなら、   MsgBox "重複"     ↓   MsgBox "重複 " & c.Address       または、 MsgBox "重複 " & c.Address & ", " & c.Formula としたら、どれが問題になっているか分かります。 もう一度、シートタブを右クリックして、[コードの表示]をクリックして確認してみていただけませんか?#7のコードそのものですか?それとも、変えていますか? もし変えているようでしたら、そのコードを教えてください。

pgn
質問者

お礼

Wendy02さん、こんばんわ。 >今回、数式があれば、メッセージは出ないようにしてあります。 すみません。私大きな間違いをしていたようです。 私が作ろうとしていたのは、 A列に数式をあらかじめ入れておき、 その数式の答え(結果)が重複していれば、 「重複」と返すコードを組もうとしていました。 (=B4&C4&D4というような数式をA列に入れておく)   ↓   A列     B列   C列  D列  あいう     あ    い   う  かきく     か    き   く  あいう     あ    い   う   ↑  「重複」と出る。 #7で回答していただいた中にも 「ループの中に、条件を入れてみました。数式ではないことと、セルが空でないこと。」 とあるのを、勘違いして認識していました。 #7のコード(そのままコピーして使わせていただいています)ですと、 数式の重複はカウントしませんが、数式の答えが重複しても、「重複」と表示しません。 (ここを悩んでいました) 私の説明不足、表現不足を痛感しております。 ご迷惑をおかけしてほんとうに申し訳ありません。 >この数式では、数式として入りません。確認しますが、数式は、以下のようなものですね。例えば、A4 に =B4&C4&D4。 すみません、これも書き損じです。「=B4&C4&D4」との意味です。 >Excelのバージョンは、2003以下ですか? Excelのバージョンは、2003です。 長く付き合わせてしまう結果になり、ほんとうに申し訳ありません。 また、毎回、回答を寄せていただき、ほんとうにありがとうございます。

  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.7

こんばんは。 >ダイアログボックスが表示され続けてしまいます。 >これを解消しようと試みいたのですが、うまくいきませんでした。 それは気が付きませんでした。本当ですね。 >これは、For Each ~ In 範囲 あたりのコードが関係してくるのでしょうか? だとは思うのですが、無限ループが発生していますね。何がどうなのか、私も、さっぱり見当が付かなくなりそうな気がします。 ループの中に、条件を入れてみました。 数式ではないことと、セルが空でないこと。 If Not c.HasFormula And c.Value <> "" Then イベントを一旦解除する、という命令を入れてみました。 (どこでイベントが発生しているかは、不明ですが、無限ループは解除されます。) Application.EnableEvents = False しかし、まだ問題点があるのは、数式の値の重複は許しています。そのためには、私が考えるのは、特殊な方法で、Target の範囲(A列)を広げないで作りますが、先々の問題は、まず、これで、当面の問題が解決するか様子をみてください。見た目は簡単ですが、なかなか、ここまで来ると、パズルのように難しいです。 Private Sub Worksheet_Change(ByVal Target As Range) Dim c As Range   If Target.Column = 1 Then  'A列   Application.EnableEvents = False   For Each c In Target     If Not c.HasFormula And c.Value <> "" Then     If WorksheetFunction.CountIf(Range("A1", Target), c) > 1 Then       MsgBox "重複"       c.ClearContents     End If     End If   Next c   End If   Application.EnableEvents = True End Sub

pgn
質問者

お礼

Wendy02さん、こんばんわ。 お礼が遅くなってすみませんでした。 この2日間、いろいろと試行錯誤していました。 セル(A列)に関数を入れていると、思うようにうまくいきません。 (たとえば、A列に「=B&C&D」という式をいれると  無限ループはでないものの、数回ループしてしまいます。) とっくに私の限界を超えているのですが、 原因が分からないところが、頭を悩ませます。 細かな質問に何度も何度も 丁寧な回答を寄せていただきありがとうございました。 初心者にもわかりやすく、たいへん感謝しています。 ありがとうございました。

  • WWolf
  • ベストアンサー率26% (51/192)
回答No.6

#1です。遅くなりすいません。 早速ですが、参考に記述したコードはシートのコードですので、他のシートからとってくる場合は If inp = Cells(i, 1).Value Then ↓ If inp = worksheets("飛ばす元のシート名").Cells(i, 1).Value Then で解決すると思いますが、他のブックではブック名も必要です。 参考にして頑張って下さい。

pgn
質問者

お礼

WWolfさん、こんばんわ。 追加の質問にもお答えくださってありがとうございます。 教えていただいたコードを参考にマクロを組み直してみます。

  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.5

こんばんは。 > マクロの本を読んでもよくわかりませんでした。 そうですね。今回のような内容は、VBAの本には載っていませんね。 マクロの本は、入門用か最高度かで、中間値というか、実践的な内容が書かれている本が少ないようです。(最高度のものは、かなり減ってきているようですし、VB6の本も手に入らないので、今から、現在のVBAを覚えようとする人は、本当に大変です。この5年先をみて、VB.Net 型に移行を考えてもよいと思います。VB.Net は、現在、無料で手に入るはずです。VBAは、VB.Net スタイルになるといわれています。しかし、現在のVBAが、その時になくなることはないと思います。) 今回の内容は、だいたい、1年間ぐらいVBAの掲示板を、はしごして読んでいると知識として入ります。 本題に入ります。 最初から説明しないといけませんよね。 まず、Worksheet_Change というのは、セルを開けてEnter するときが引き金になります。(VBAを勉強すると、この内容が、後々疑問に感ずることが来るかもしれません。) 次に、 Private Sub Worksheet_Change(ByVal Target As Range)                        ↑          このTarget というのは、Range オブジェクトです。 Rangeオブジェクトというのは、Cells オブジェクトと違って、1個でも2個でも、列でも、行の範囲も入ります。それを、処理する方法は、いくつかありますが、For Each ~ In 範囲 で、処理するのが一番簡単だと思います。 エラーで、 「型が一致しません」 というのは、 (1) inp = Target.Value 'ここでは、Target.Value が、inpに複数の値でも入りますが、 If inp = Cells(i, 1).Value Then   'Cells(i,1) と一対一にならないことがあるのです。 'Target.Value には、複数の値が入っているからです。 (2) Application.WorksheetFunction.CountIf(Range("A1", Target), Target) こちらの場合は、第二引数(後ろ)の Target は、値が、複数が入らないようになっているのです。こういう関数の仕様は、公になっていないので、やってみなければ分からないことが多いです。ただ、今回は、第二引数は、1つの値しか入らないと思ってよいです。そうすると、二つ以上入れたら、エラーが返ってしまいます。 そこで、ひとつずつ、取る手段として、For Each ~ In 範囲 を使い、一つずつ、関数に入れてあげます。 まだまだ、ここの周辺には、難しい部分や公開されていない話が残っていますから、折に触れて質問してみると良いかと思います。

pgn
質問者

お礼

Wendy02さん、こんばんわ。 たいへんわかりやすく詳しい解説をしていただいて ありがとうございます。 (やっぱり、初心者には難しいですね。) 自分の限界を超えていることは知りつつも、もうひとつだけお聞かせください。 コピーペーストの場合は、教えていただいたコードが機能したのですが、 コピーペーストではなくて、 関数のイコールで違うセルからデータを飛ばしてくるようにすると (A列のセルにあらかじめ「=B◯」と入れておいたりすると)、 ダイアログボックスが表示され続けてしまいます。 これを解消しようと試みいたのですが、うまくいきませんでした。 これは、For Each ~ In 範囲 あたりのコードが 関係してくるのでしょうか? 質問ばかりですみません。

  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.4

こんにちは。 #2 のimogasiさんのコードをお借りして、このように換えればよいです。 ワークシート関数で使うのがベストですね。VBAのコードの処理するよりも、スピードが、10倍以上速いです。中でも、CountIf は、関数自体に、エラーを吐き出す可能性が低いので、これがよいと思います。 一般的には、入力規則の範疇ですが、コピー&ペーストでは、その範囲に対して入力規則が働きませんね。 Private Sub Worksheet_Change(ByVal Target As Range) Dim c As Range   If Target.Column = 1 Then   For Each c In Target     If WorksheetFunction.CountIf(Range("A1", Target), c) > 1 Then       MsgBox "重複"       Target.ClearContents     End If   Next c   End If End Sub

pgn
質問者

お礼

Wendy02さん、こんにちは。 回答していただきありがとうございました。 >コピー&ペーストでは、その範囲に対して入力規則が働きませんね。 この点で悩んでいましたが、 教えていただいたマクロで、すっきり解決しました。 もしよろしければ、なぜこのマクロでは、 コピー&ペーストしたセルに対しても、 メッセージボックスが立ち上がってくるのか 教えていただければと思います。 (情けない話ですが、  マクロの本を読んでもよくわかりませんでした。) わがままな内容ですいません。

回答No.3

入力規則を使うのが一番シンプルです。 A1セルを選択し、データ - 入力規則で設定タブ、入力値の種類をユーザー設定にし、数式に =COUNTIF(A:A,A1)=1 を入れます。 意味はA列にA1の値が1つだけなら入力を許可するということです。 また、メッセージボックスの内容を変更するなら、エラーメッセージタブのエラーメッセージに 重複しています など入れればOKです。 入れ終わったらA1をコピーし、A2から下に貼り付ければ完了です。 A列に罫線などあるのなら、「入力規則」の形式を指定して貼り付ければ大丈夫です。

pgn
質問者

お礼

pacific231さん、こんばんわ。 入力規則でも出来るんですね。 入力規則はリストくらいしか使ったことがなかったので、 勉強になりました。 回答していただきありがとうございました。

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

下記の方法が考えられます。 (1)IF文で全行繰り返し聞く(判別) (2)Findメソッド利用法 (3)Countif関数利用法 (4)入力規則でもできるかも (3)を掲げます 極く行数が少なくて済むのが特徴。 今打ち込んだ名前の行にカーソル復帰は省略。 Private Sub Worksheet_Change(ByVal Target As Range) If Target.Column = 1 Then If Application.WorksheetFunction.CountIf(Range("a1", Target), Target) > 1 Then MsgBox "重複"   Target = "" End If End If End Sub

pgn
質問者

お礼

imogasiさん、こんばんわ。 回答していただきありがとうございました。 Countif関数を使うのは、目から鱗でした。 わがままな質問をさせてください。 別のシートからA列へ名前をとばしてくるマクロで、A列に名前(文字列)を入れると、 If Application.WorksheetFunction.CountIf(Range("a1", Target), Target) > 1 Then のところで「型が一致しません」と デバックがおきます。 これを解消する方法はあるのでしょうか? 当初の質問に付加した内容を質問してすみません。

  • WWolf
  • ベストアンサー率26% (51/192)
回答No.1

こんばんは 下記のサンプルは宣言は省略しています。 下記のサンプルの場合後から既存のデータを修正した場合など 考慮しておりません。 参考程度にお使い下さい。 Private Sub Worksheet_Change(ByVal Target As Range) LR = Range("A65536").End(xlUp).Row If LR <> 1 Then inp = Target.Value For i = 1 To LR - 1 If inp = Cells(i, 1).Value Then MsgBox i & "行目と重複しています" Target.Select End If Next End If End Sub 頑張って下さい。

pgn
質問者

お礼

WWolfさん、こんばんわ。 回答していただきありがとうございました。 ◯行目まで表示させるのは、たいへん役に立ちます。 この場をお借りして、欲張りな質問をさせてください。 別のシートからA列へ名前をとばしてくるマクロで、A列に名前(文字列)を入れると、 If inp = Cells(i, 1).Value Then のところで「型が一致しません」と デバックがおきます。 (マクロ初心者なので、・・。) これを解消する方法はあるのでしょうか? 当初の質問に付加した内容を質問してすみません。

関連するQ&A

  • Excelのマクロを教えてください。

    Excelのマクロを教えてください。 Sheet1 F列(商品) F2テレビ、F3DVD、F4携帯電話、サプライ、、、F32まで商品あり。 I列~N列の1段目(人*増える場合あり) I1佐藤、J1高橋、K1田中、L1中村、、、 I2~N32まで、1、2、3と個数が入力されています。 A列~E列とG列とH列は今回の処理に不要なデータがいます。 これをSheet2に A列に人、B列に商品、C列に数 例) A1 佐藤、B1 テレビ、C1 1 A2 佐藤、B2 DVD 、C2 3 A3 高橋、B3 携帯電話、C3 2 のように、書き出すマクロを教えていただけませんか? 別にマクロでなくても、Excel2007までの機能でできることであればそれでもいいです。 丸投げして申し訳ありません。

  • excel マクロ <フィルタ>

    excelのマクロで分からないことがあるので質問させてもらいます。 たとえば↓の写真のようなデータがあったとして、アルファベットさん(Aさん~Nさん)だけを表示するマクロを作る時は、フィルタをして、番号1~14にチェックをつけて・・・ってことをすると思います。そこに、ボタンをつけたいと思っています。 ボタン(チェックボックス)A、ボタン(チェックボックス)B、ボタン(チェックボックス)C、ボタンD、ボタンEをつけたいと思います。 ボタンAを押すと(チェックをつけると)→アルファベットさん(Aさん~Nさん)だけを表示 ボタンBを押すと(チェックをつけると)→山田、田中、鈴木だけを表示 ボタンCを押すと(チェックをつけると)→斉藤、佐藤、高橋、渡辺、伊藤だけを表示 で A、Bにチェックをつけるとアルファベットさんと山田、田中、鈴木を表示 B、Cにチェックをつけると山田、田中、鈴木、斉藤、佐藤、高橋、渡辺、伊藤を表示 ボタンDを押して、フィルタを解除。 ボタンEを押して、フィルタされた範囲を印刷。 ・・・・・という風に・・・ 【ボタンか、チェックボックスって書いたのは、どちらを使ったらいいのかわからないからであって、ほかにもフォームの種類がありますから、最適なのがありましたら教えてください。】 まとめると、データをボタンで絞り込んで(解除もできる)、ボタンで印刷したい。ということです。 結構、初心者なので、質問の内容がよくわからないかもしれませんけど、わかりやすく教えてください。 お願いします。

  • EXCEL メッセージボックスの表示について

    マクロを使ってA列に"1"というデータが入力されたら、 エンターキーを押した(入力確定した)時点でメッセージボックスが表示されるようにしたいのですが、 この表示のさせ方がわかりません。 これができると作業が大分楽になりますので、 わかる方いらっしゃいましたらよろしくお願いいたします。

  • 教えてください!!!

    以前にも同じような質問をしましたが・・・ エクセルでのことですが、 たとえばあるセルに『田中』と入力されると その隣に『鈴木』そのまた隣に『高橋』という感じに自動で決まった名前を入るようにしたいのですが、どなたか教えてください・・・ できればマクロ?表示コード?で教えてください。 追記 『田中』の時は『鈴木』『高橋』『井上』 『松本』の時は『中村』『佐藤』『山本』という感じになるようにしたいのですが。

  • Excelの表から、重複しないデータを抽出する方法は?

    Excelで、例えば次の表があるとします。   12/01 田中 6   12/01 高橋 3   12/02 太川 9   12/08 田中 2   12/11 井上 1   12/11 太田 2  (これは12月の各人の件数とでも思ってください) この表から、重複する名前を除いて、   田中   高橋   太川   井上  (並び順はどうでもよい) というデータを取り出すにはどうしたらよいでしょうか?

  • シートの合計

    よろしくお願いします。 エクセルでシート1~3迄あります。各シ-トのA列は名前、B列に数字が入っています。名前はA列のどの行にあるかわかりません。 同じ名前をシート4のA1に入力したらその名前の合計を出したい。  シート1    シート2   シート3       シート4   A   B    A   B   A    B     A    B 山田 10   木村  5  佐々木 18   木村  55  鈴木 20   田中 21  伊藤  33    ↑ 木村 50   山下 70  加藤  57  (入力する) 田中 15   高橋 90  佐藤  61 高橋 60   山田 10  鈴木  12             ・   ・   ・          

  • エクセルの列を表示・非表示させるマクロ

    エクセル2007を使っています。 Sheet1は,多数の人がデータを入力するシートです。 A列~F列までは,タイトル列ですが, 例えば井上さんはG列~K列に入力し,太田さんはL列~M列に入力し,・・・・という感じです。 それぞれの人が使用するとき,使いやすいように自分以外の列を非表示にする人が多いのです。 それは別にかまわないのですが,使用後に元に戻してくれない人が多くて困っています。 (会社には,パソコンのことをまったく知らないオバチャン達がいて,毎回「私のデータが無くなってる」と大騒ぎされるのです。) そこで,Sheet1から他のシートに移動するとき,自動的にすべての列が再表示されるようになればいいなと思い,質問しました。 さらに,この質問をしながら思いついたことですが, 例えばSheet2にコマンドボタンを多数作成して,それぞれの人の名前を割り当てたシートを用意したら便利ですよね。 つまり,先ほどの太田さんが自分のボタンを押したとすると, Sheet1に移動し,無関係な列(G~K列と,N~GU列〔最終列です〕)を非表示にするようなマクロがあれば,さらに便利だと思うのです。 分かりにくい文章で申し訳ありませんが, (1) コマンドボタンに割り当てて,Sheet1に移動し,不必要な列を非表示にするマクロ (2) シートが移動すると,すべての列を再表示しておくマクロ 以上 2点を教えていただきたいのですが, よろしくお願いします。

  • EXCELマクロVBAについて

    Excel2007、XPを使用しています。 AからE列に下記のような情報が入力されています。 A / B / C / D / E ID / 名前 / 住所 / 電話 / 注文日 11111 / 田中 / 東京都 / 00000000000 / 2012/08/10 11111 / 田中 / 東京都 / 00000000000 / 2012/08/09 11111 / 田中 / 東京都 / 00000000000 / 2012/08/18 11112 / 佐藤 / 京都府 / 00000000000 / 2012/08/10 11113 / 鈴木 / 北海道 / 00000000000 / 2012/08/11 11113 / 鈴木 / 北海道 / 00000000000 / 2012/08/15 A列のIDでくくったとして、 E列の注文日が最大のみの行を表示させたいです。 A / B / C / D / E ID / 名前 / 住所 / 電話 / 注文日 11111 / 田中 / 東京都 / 00000000000 / 2012/08/18 11112 / 佐藤 / 京都府 / 00000000000 / 2012/08/10 11113 / 鈴木 / 北海道 / 00000000000 / 2012/08/15 このようなことはマクロで可能なのでしょうか? 恐れ入りますがご教授お願い致します。

  • ダイアログボックスの入力項が多く困っています。

    ダイアログボックスの入力項が多く、マクロ実行時にいちいち入力していたら時間がかかるため、そこを改善したいのです。 入力項に入れる数字をあらかじめwordなどでドキュメント化しておいてexcelのマクロ実行時に読み込むようにしたいのですが、そんなことは可能ですか?

  • EXCEL2000 マクロダイアログボックス

    よろしくお願いします。 先日EXCEL2000にてツール→マクロ→新しいマクロの記録からマクロを作成しました。その作っているときに表示されていたはずの”相対参照ボタンや記録終了”のダイアログボックス「みたいものがあると思います…」が、先日思わず×を押して閉じてしまいました。 それからです、ツール→マクロ→新しいマクロを開いても、もう二度と出てこなくなりました。 さていったいこのツールはどこへ行ったのでしょうか? どこかを押せば出てくるとは思うのですが、分かりません。 ひとつアドバイスをよろしくお願いいたします。

専門家に質問してみよう