[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]
『重複をチェックしてメッセージボックスに表示』(ゆき)
Excelで受注リストの管理をしています。
B列に「管理番号」という文字列がありますが、この番号が重複しているかどうかを1日の終わりにチェックしようとしています。
シートは下記のようになっています。
A B C ・・・・ 1 1月度受注リスト 2 3 日付 管理番号 物件 4 1/8 AA1212-01 東京商事 5 1/8 AB1212-01 大阪商店 6 1/9 AA1212-02 福岡商会 7 1/10 BB1212-01 東京商事
このリストで、シート上にボタンを設置し、ボタンクリックでB列にまったく同じ番号(文字列)があった場合に
「 下記の管理番号が重複しています AA1212-10 AB1212-20 」
というようなメッセージボックスを表示させたいのですが、同時に複数の管理番号を表示させる方法がわかりません。
今書いているコードは下記のようなものです。
Option Explicit
Sub 重複チェック()
Dim i As Long Dim j As Long Dim z As Long Dim Kanri As String Dim cnt As Long
cnt = 0
With Sheets("受注リスト")
z = .Cells(Rows.Count, 1).End(xlUp).Row
For i = 4 To z For j = i + 1 To z
If .Cells(i, 2).Value = .Cells(j, 2).Value Then Kanri = .Cells(i, 2).Value cnt = cnt + 1
MsgBox "下記の管理番号が重複しています" & vbCrLf & Kanri
Exit For End If Next j Next i
If cnt = 0 Then
MsgBox "重複している管理番号はありません" Exit Sub End If End With
End Sub
上記のコードでは、複数の重複管理番号があった場合に1つのメッセージボックスにつき 1つの管理番号しか表示できず、いくつもメッセージボックスが表示されたりします。
重複した管理番号が複数ある時にまとめて一つのメッセージボックスに表示させるにはどうしたらよいでしょうか。
管理番号の表示の仕方は
「 下記の管理番号が重複しています AA1212-10,AB1212-20 」
このように横に並べても構いません。
Excel2010です。 よろしくお願いします。
都度メッセージを表示するのではなく、検出時はメッセージを作成し 確認終了後に表示するようにすればどうでしょうか。
確認方法も Dictionary を使う方法にした例ですが、ご参考まで。 (Mook)
Option Explicit Sub 重複チェック()
Dim objDic As Object Set objDic = CreateObject("Scripting.Dictionary")
Dim msg As String msg = ""
Dim i As Long Dim z As Long With Sheets("受注リスト") z = .Cells(Rows.Count, 1).End(xlUp).Row For i = 4 To z If objDic.Exists(.Cells(i, 2).Value) = True Then msg = msg & vbNewLine & .Cells(i, 2).Value Else objDic(.Cells(i, 2).Value) = True End If Next i
If msg <> "" Then MsgBox "下記の管理番号が重複しています" & msg Else MsgBox "重複している管理番号はありません" End If End With End Sub
アップ後、よく見たら、Mookさんのと重なっているところが多かった。 まぁ、バリエーションとして。
なお、、(ゆき)さんの二重ループの構成、データ数が少なければ問題はないけど データ数が多くなれば結構時間がかかるね。この形で処理するなら、事前に並び替えを 行って、二重ループをなくすことも検討してみたらいいと思う。
Sub 重複チェック2()
Dim c As Range Dim dicA As Object Dim dicB As Object
Set dicA = CreateObject("Scripting.Dictionary") Set dicB = CreateObject("Scripting.Dictionary")
With Sheets("受注リスト")
For Each c In .Range("B4", .Range("B" & .Rows.Count).End(xlUp)) If dicA.exists(c.Value) Then dicB(c.Value) = True dicA(c.Value) = True Next
End With
If dicB.Count = 0 Then MsgBox "重複している管理番号はありません" Else MsgBox "下記の管理番号が重複しています" & vbCrLf & Join(dicB.keys, vbLf) End If
End Sub
(ぶらっと)
もうひとつバリエーション。(ROUGE) Sub Sample() Dim tbl, i As Long, x, ky, txt As String With Sheets("受注リスト") tbl = .Range("A1", .Range("A" & .Rows.Count).End(xlUp)).Resize(, 3).Value End With With CreateObject("Scripting.Dictionary") For i = 4 To UBound(tbl, 1) If .Exists(tbl(i, 2)) Then x = .Item(tbl(i, 2)) x(0) = True x(1) = x(1) & ", " & i .Item(tbl(i, 2)) = x Else .Add tbl(i, 2), Array(False, i) End If Next For Each ky In .Keys If .Item(ky)(0) Then txt = txt & vbCrLf & ky & " : " & .Item(ky)(1) & " 行目" End If Next If Len(txt) Then MsgBox "下記の管理番号が重複しています" & txt Else MsgBox "重複している管理番号はありません" End If End With End Sub
Loop無しで、
Option Explicit
Sub test() Dim x As String, y With Range("b4", Range("b" & Rows.Count).End(xlUp)) x = .Address(0, 0) y = Filter(Evaluate("transpose(index(if(countif(offset(" & x & _ ",0,0,row(1:" & .Rows.Count & "))," & x & ")=2," & x & ",""zzz""),))"), "zzz", 0) If UBound(y) > -1 Then MsgBox vbTab & "下記の管理番号が重複しています" & _ vbTab & String(2, vbLf) & vbTab & Join$(y, vbLf & vbTab) Else MsgBox "重複無し" End If End With End Sub (seiya)
皆様たくさんの案をありがとうございます!
まだ簡単なマクロしか作れなくて勉強中なので、皆様のコードをよく見て理解できるようになります!
※ちなみに、リストは入力した順で並んでいないといけないので、B列を基準にソートはできないんです… 今のところ「入力順」を示す箇所が無いのが難点なので、リストのレイアウトを考えて入力順に連番を振って、ソートできるような方法も考えてみます。
(ゆき)
[ 一覧(最新更新順) ]
YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki.
Modified by kazu.