この人頭いいなと思ったエピソード

sheet1の、”B3”に年、”D3”に月、”F3”に日、そして”F5”に担当者名が入力されます。
他にも様々な項目がsheet1にあり、それらを日計として別のsheet2に転記します。
(sheet1に設置した入力ボタンを押すと、sheet2に転記されます)

sheet2には、各担当者が日計を入力し、下記のように日々新しいデータが蓄積されていきます。
(sheet2は、A列に年、B列に月、C列に日、D列に担当者名となっています)
 
 年  月  日  担当 ・・・その他項目色々・・・
2022  10  5  A
2022  10  5  B
2022  10  5  C
2022  10  9  A
2022  10  9  C

現状ですと、新たにsheet1からsheet2への登録の際、
同一年月日かつ同一担当のデータが既にある場合でもsheet2の最終行に追加されてしまいます。

同じ年月日で同じ担当のデータがある場合、
「同じデータがあります」等、何らかのメッセージボックスで警告したいのですが、
複数の一致データ(年、月、日、担当者)の検索方法がよくわかりません。
お知恵を頂けると幸いです。

質問者からの補足コメント

  • うーん・・・

    回答有難うございます。

    同一標準モジュールの冒頭にコードを記載しました。
    (Private Function check_dup() As Boolean〜End Functionまで)

    そして、下記のようにプロシージャに組み込みました。

    sub 日計転記()
    If check_dup() = True Then
    MsgBox ("重複してます")
    Else
    MsgBox ("重複してません")
    ※ここに新たな日計データを追加する文を記載。
    End If
    endsub

    これで実行すると、重複していない時には、メッセージが出て、日計にデータが追加されます。
    (希望した通りの動作です)

    ただ、sheet2に重複データが有っても、”重複してません”とメッセージが表示され、データも追加されます。上記のような関数の呼び出し方ではマズイのでしょうか?

    No.3の回答に寄せられた補足コメントです。 補足日時:2022/10/08 13:27
  • ご親切にありがとうございます!

    ①sheet2のレイアウトは私が提示した画像と同じでしょうか。
    年、月、日、担当のセルには、値が設定されtますか?
    それとも関数式が設定されていますか?
    ②sheet1のB3,D3,F3,F5は値でしょうか。それとも、関数式でしょうか。

    同じレイアウトだと思います。
    sheet1も2も、該当セルに関数はなく、sheet1に入力した値をsheet2に転記する仕様です。


    ③重複する場合の下記項目の具体的な値を提示していただくことは可能でしょうか。
    sheet1のB3,D,F3,F5
    sheet2の重複する行のA列、B列、C列、D列の値
    できれば、画像で提示していただければありがたいです。

    B3は、今年は2022
    D3は、当該月(今は10)
    F3は、入力該当日(1〜31)
    F5は、漢字で2〜3文字(鈴木とか佐藤とか)

    画像を添付いたします。

    「VBAで重複データを確認したい」の補足画像2
    No.4の回答に寄せられた補足コメントです。 補足日時:2022/10/08 13:58
  • 度々のご回答、恐縮に存じます。
    フィルターは、sheet1も2も使っておりません。
    該当部分のソースを添付します。
    (sheet1と2については、実際のシート名に変更してございます)

    「VBAで重複データを確認したい」の補足画像3
      補足日時:2022/10/08 14:08
  • 度々のご回答、恐縮に存じます。
    フィルターは、sheet1も2も使っておりません。
    該当部分のソースを添付します。
    (sheet1と2については、実際のシート名に変更してございます)

    Private Function check_dup() As Booleanの中も、下記のように修正済みです。
    Set sh1 = Worksheets("個別日計入力")
    Set sh2 = Worksheets("店舗日別明細")

    「VBAで重複データを確認したい」の補足画像4
    No.5の回答に寄せられた補足コメントです。 補足日時:2022/10/08 14:12
  • うーん・・・

    何が問題なのか調べようと、色々と動作テストをしております。

    If check_dup() = True Thenの、True を False にすると、「重複しています」が表示されます。
    ということは、sheet2に重複データが有る時も無い時も、check_dup()の戻り値がFalseになっているということでしょうか?

    重複か否かは、下記のような理解でいますが、それでよろしいでしょうか?

    年月日および、担当が同一ものが有る・・・重複あり
    年月日は同一のものが有るが、同担当のものはまだ無い・・・重複なし

      補足日時:2022/10/08 14:18
  • HAPPY

    出来ました!
    ありがとうございます!!

    sheet1の”月”を判断するセルが、”C3”になっていました。
    正しくは、”D3”なので、そこを修正したら意図したように動きました!

    何度もお手数をおかけしましたが、おかげさまで作業が前に進められます!!
    最初のソースコードを付けてくださった回答をベストアンサーにしようと思います。

      補足日時:2022/10/08 14:29

A 回答 (5件)

No1の方のアドバイスに従い、WorksheetFunction.CountIfsを使用してチェックを行う関数を作成しました。


Public Sub 重複判定()は確認用のプロシージャです。
実際には不要です。
あなたのマクロに、Private Function check_dup() As Boolean
を組み込んで使ってください。
重複があれば、Trueを返します。(重複無はFalseを返します)
Sheet1,Sheet2のレイアウトは添付図のようになっている前提です。
レイアウトが異なる場合は、その旨、補足してください。
添付図では青色の行が重複するので、「重複してます」が表示されます。

Option Explicit
Public Sub 重複判定()
If check_dup() = True Then
MsgBox ("重複してます")
Else
MsgBox ("重複してません")
End If
End Sub

Private Function check_dup() As Boolean
Dim sh1 As Worksheet
Dim sh2 As Worksheet
Dim yyyy As Long
Dim mm As Long
Dim dd As Long
Dim name As String
Dim count As Long
Dim rgY As Range
Dim rgM As Range
Dim rgD As Range
Dim rgNM As Range
Dim maxrow As Long
Set sh1 = Worksheets("Sheet1")
Set sh2 = Worksheets("Sheet2")
yyyy = sh1.Range("B3").Value
mm = sh1.Range("C3").Value
dd = sh1.Range("F3").Value
name = sh1.Range("F5").Value
maxrow = sh2.Cells(Rows.count, "A").End(xlUp).Row
Set rgY = sh2.Range("A2:A" & maxrow)
Set rgM = sh2.Range("B2:B" & maxrow)
Set rgD = sh2.Range("C2:C" & maxrow)
Set rgNM = sh2.Range("D2:D" & maxrow)
count = WorksheetFunction.CountIfs(rgY, yyyy, rgM, mm, rgD, dd, rgNM, name)
If count > 0 Then
check_dup = True
Else
check_dup = False
End If
End Function
「VBAで重複データを確認したい」の回答画像3
この回答への補足あり
    • good
    • 0
この回答へのお礼

ご丁寧にコードまで記載いただき、ありがとうございます。
とりあえず、エラーなく実行できました。ただ、重複が有っても、重複無しとしてメッセージが出て、データも追加されてしまいます。
Private Functionはまだ使ったことがないので、呼び出し方に間違いが有るのかも知れません。また、そもそも、Private Functionを記載する位置が悪いのかも・・・そのへんをもう少し調べつつ取り組んでみます。

お礼日時:2022/10/08 13:40

No4です。


追伸
sheet2にフィルターがかかった状態でマクロを実行していませんでしょうか。フィルターがかかっていると、正しく動作しません。
フィルターを解除した後、マクロを実行してください。
この回答への補足あり
    • good
    • 0

No3です。


>ただ、sheet2に重複データが有っても、”重複してません”とメッセージが表示され、データも追加されます。上記のような関数の呼び出し方ではマズイのでしょうか?

呼び出し方はあっています。
sheet2に重複データがあっても、check_dupが重複と認識できていないようです。
sheet1,sheet2のデータがこちらの想定と違っている可能性が考えられます。
①sheet2のレイアウトは私が提示した画像と同じでしょうか。
年、月、日、担当のセルには、値が設定されtますか?
それとも関数式が設定されていますか?

②sheet1のB3,D3,F3,F5は値でしょうか。それとも、関数式でしょうか。

③重複する場合の下記項目の具体的な値を提示していただくことは可能でしょうか。
sheet1のB3,D,F3,F5
sheet2の重複する行のA列、B列、C列、D列の値
できれば、画像で提示していただければありがたいです。
この回答への補足あり
    • good
    • 0

No1です。



>worksheetfunction.matchでやってみましたが、~
Machは基本的に一つの条件を検索するための関数なので、今回のご質問内容に対して、わざわざMachを使う理由がわかりません。
ヒットしても、さらに他の条件をチェックする必要がありますし、二番目のヒット、三番目のヒットを探す必要が生じます。

>しかも不思議なことに、重複データが有る時には正しく~~
不思議ではありません。
シート関数でも、検索値が存在しない場合にはエラー表示になります。
ワークシート関数の場合、エラー値を返してくれればまだ扱いやすいのですが、エラーを発生させます。
ですので、エラー処理を加えれば、判定できないことはないでしょうけれど、上記の問題をどうするおつもりなのでしょうか?

もしも、ワークシート関数を利用するのなら、そのような面倒も無く、かつ、複数条件をまとめてチェックできるものをご紹介しておいたはずなのですけれど・・・???
    • good
    • 1
この回答へのお礼

回答有難うございます。
WorksheetFunction.CountIfsでの方法を例示頂きましたので、そちらで取り組んでみました。
ただ、関数の呼び出し方が悪いのか、記載する位置が悪いのか、いまだ思うように動いておりません。
これまで、Private Functionなどは使ったことが無いので、そのあたりをもう少し学習してみます。

お礼日時:2022/10/08 13:38

こんにちは



>複数の一致データ(年、月、日、担当者)の検索方法がよくわかりません。

ループで回して各行をチェックする方式なら
 IF A列が一致 And B列が一致 And C列が一致 And D列が一致 Then
みたいな形式でチェックすれば、判別可能と思います。

一気にチェックするのであれば、
WorksheetFunction.CountIfs
を利用して、(A列の範囲,A列の検索値,B列の範囲,B列の検索値・・・)として1以上の値が返れば重複していると判定できるのではないでしょうか?
https://learn.microsoft.com/ja-jp/office/vba/api …
    • good
    • 1
この回答へのお礼

A列が一致、B列が一致・・・の様に順番にチェックするため、worksheetfunction.matchでやってみましたが、worksheetfunctionクラスのmatchプロパティを取得できませんとエラーが出ます。しかも不思議なことに、重複データが有る時には正しく(?)追加データが入力されます・・・。

if 条件1 and 条件2 and 条件3 and 条件4 then

(メッセージボックスで警告)

else

(重複がない時に実行したいプログラム)

end if

としてあるのですが・・・

お礼日時:2022/10/07 17:49

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています


おすすめ情報