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

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

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

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

Q&A

解決済

4回答

2992閲覧

エクセルVBA、リストA・Bを比較し、新規の値であった場合、新と入力したい

usaginote1020

総合スコア8

VBA

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

0グッド

0クリップ

投稿2020/11/30 06:58

編集2020/11/30 07:46

前提・実現したいこと

エクセルVBAで、ワークシートws.allのA2~A10000の値が、
ワークシートws.listのA2~A1000にない新規の値であった場合、ワークシートws.allのB列に「新」と入力するマクロを作りたい

発生している問題・エラーメッセージ

リストにある場合、「すでに有り」と入力するマクロは作ることができたが、ない場合「新」とすることに苦労している

該当のソースコード

For i = 2 To 10000 For j = 2 To 1000 If ws_all.Cells(i, 1).Value = ws_list.Cells(j, 1).Value Then ws_all.Cells(i, 2) = "すでに有り" Exit For Else End If Next j End If Next i

試したこと

リストが数十万行であり、ほとんどがリストBにあるためExit for でループを抜けることで
実行時間が短縮できるかと思っていますが、新と入力することが出来ず悩んでいます

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

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

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

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

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

meg_

2020/11/30 07:13

・コードは「コードの挿入」で記入してください。 ・「リスト」とは配列のことですか?
usaginote1020

2020/11/30 07:30

ご指摘ありがとうございます。質問を修正致しました。
hatena19

2020/11/30 07:43

「ワークシートws.allのA4~D10000の値が」は 「ワークシートws.allのA4~A10000の値が」の間違いではないですか。
usaginote1020

2020/11/30 07:44

失礼しました。ご指摘の通りです。修正いたします
tatsu99

2020/11/30 08:06 編集

それぞれのA2~A1000には、空白のセルがありますか。(歯抜けのセル) それとも、全てデータが設定されてますか。
usaginote1020

2020/11/30 08:05

いずれも空白セルはありません
guest

回答4

0

もしも、VBAにこだわらないのであれば、ワークシートws.allのB2に以下の式を入れてください。
あとはA列のあるところまでB列にコピペしてください。

Excel

1=IF(IFERROR(MATCH(A2,list!$A$2:$A$1000,0),"新規")="新規","新規","既存")

A列のデータが数の場合、10万件なら1秒程度で計算が終わりました。

投稿2020/11/30 22:29

編集2020/11/30 22:31
ppaul

総合スコア24670

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

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

0

以下のようにしてください。
ws_allは"Sheet1"
ws_listは"Sheet2"
にしています。あなたの環境にあわせてください。

VBA

1Option Explicit 2 3Public Sub 比較() 4 Dim maxrow1 As Long 5 Dim maxrow2 As Long 6 Dim wrow As Long 7 Dim ws_all As Worksheet 8 Dim ws_list As Worksheet 9 Dim dicT As Object 10 Set ws_all = Worksheets("Sheet1") 11 Set ws_list = Worksheets("Sheet2") 12 maxrow1 = ws_all.Cells(Rows.Count, 1).End(xlUp).Row 'sheetの最大行取得 13 maxrow2 = ws_list.Cells(Rows.Count, 1).End(xlUp).Row 'sheetの最大行取得 14 Set dicT = CreateObject("Scripting.Dictionary") ' 連想配列の定義 15 For wrow = 2 To maxrow2 16 dicT(ws_list.Cells(wrow, 1).Value) = True 17 Next 18 For wrow = 2 To maxrow1 19 If dicT.exists(ws_all.Cells(wrow, 1).Value) = True Then 20 ws_all.Cells(wrow, 2).Value = "すでに有り" 21 Else 22 ws_all.Cells(wrow, 2).Value = "新" 23 End If 24 Next 25End Sub 26

投稿2020/11/30 08:21

tatsu99

総合スコア5493

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

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

0

ベストアンサー

シート上のリスト(セル範囲)を比較するのを高速化したいということでしょうか。
セルを一つずつ参照するのは重い処理になるので、リスト(セル範囲)を配列に格納して配列で比較するといいでしょう。

Office TANAKA - VBA高速化テクニック[配列を使う]

コード例

vba

1Sub Sample() 2 Dim ary_all() 3 ary_all = WorkSheets("all").Range("A2:A10000").Value 4 5 Dim ary_list() 6 ary_list = WorkSheets("list").Range("A2:A1000").Value 7 8 Dim ary_res() As String 9 ReDim ary_res(1 To UBound(ary_all), 1 To 1) 10 11 Dim i As Long, j As Long, bNew As Boolean 12 For i = 1 To UBound(ary_all) 13 bNew = True 14 For j = 1 To UBound(ary_list) 15 If ary_all(i, 1) = ary_list(j, 1) Then 16 bNew = False 17 Exit For 18 End If 19 Next j 20 If bNew Then ary_res(i, 1) = "新" 21 Next i 22 23 WorkSheets("all").Range("B2:B1000").Value = ary_res 24 25End Sub

あるいは、関数で存在チェックしてもいいでしょう。

指定したデータがリスト内に存在するかどうかを確認する:Excel 一般|即効テクニック|Excel VBAを学ぶならmoug

VBAで関数を設定して、値に変換するという方法のコード例

vba

1Sub Sample2() 2 With WorkSheets("all").Range("B2:B9") 3 .Formula = "=IF(COUNTIF(list!$A$2:$A$8,all!A2),"""",""new"")" 4 .Value = .Value 5 End With 6End Sub

投稿2020/11/30 07:39

編集2020/11/30 08:21
hatena19

総合スコア34075

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

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

0

なにか変数を用意しておき、最初に0を入れておきます
そして、その判定のところで、すでに有り、となるところでその変数に1を代入するようにして、
そこのExitForを抜いておきます

そうしておくと、そのfor文の実行が終わったときにその変数が0であった場合、新規、と判断できます

投稿2020/11/30 07:36

y_waiwai

総合スコア88042

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問