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

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

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

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

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

検索

検索は、あるデータの集まりの中から 目的のデータを見つけ出すことです。

Q&A

解決済

3回答

6293閲覧

WorksheetFunctionでINDEXとMATCHを使って、ある文字列を別シートで検索後、同じ行、別の列の値を返したい

vba_begginer

総合スコア6

VBA

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

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

検索

検索は、あるデータの集まりの中から 目的のデータを見つけ出すことです。

0グッド

0クリップ

投稿2018/04/10 07:00

編集2018/04/10 07:25

前提・実現したいこと

現在、VBAであるデータベースから検索した値を表示させる検索ツールを作っています。
WorksheetFunctionでINDEXとMATCHを使って、ある文字列を別シートで検索後、別の列の指定のセル値(文字列)を返すようなコードを作っています。
散々試行錯誤した結果、以下のエラーメッセージが出てしまいました。

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

ある条件検索に基づいた、指定列の文字列が返せません。

WorksheetFunctionクラスのINDEXプロパティを取得できません

該当のソースコード

VBA

1 2Sub 検索テスト() 3 With Application 4 .ScreenUpdating = False 5 .EnableEvents = False 6 .Calculation = xlCalculationManual 7 End With 8 9 Dim 検索ブック, データベース As Workbook 10 Dim 検索シート, データシート As Worksheet 11 12 Workbooks.Open _ 13 "データベース.xlsx" _ 14 , UpdateLinks:=0 15 16 Set 検索ブック = Workbooks("検索システム.xlsm") 17 Set データベース = Workbooks("データベース.xlsx") 18 Set 検索シート = 検索ブック.Worksheets("検索シート") 19 Set データシート = データベース.Worksheets("データシート") 20 21 Dim i, j As Long 22 Dim 検索値 As Range 23 Set 検索値 = Range(検索シート.Cells(8, 7), 検索シート.Cells(7000, 7)) 24 25  For i = 8 To 7000 26 For j = 2 To 5670 27 On Error Resume Next 28 If 検索シート.Cells(i, 7).Value = データシート.Cells(j, 2).Value _ 29 And 検索シート.Cells(i, 8) = データシート.Cells(j, 26) Then 30 検索シート.Cells(i, 9).Value = Application.WorksheetFunction. _ 31 Index(データシート.Cells(j, 27), Application.WorksheetFunction. _ 32 Match(検索シート.Cells(i, 7), Range(データシート.Cells(2, 2), データシート.Cells(5670, 2)), 0)) 33 End If 34 Next j 35 Next i 36 37 データベース.Close False 38 検索ブック.Worksheets(1).Activate 39 40 With Application 41 .ScreenUpdating = True 42 .EnableEvents = True 43 .Calculation = xlCalculationAutomatic 44 End With 45End Sub 46

試したこと

変数をi,jに分けて、ループ処理のパターンを2種類にしてみました。

補足情報(FW/ツールのバージョンなど)

Excel 2010を使用しています。

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

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

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

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

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

ExcelVBAer

2018/04/10 07:07

VBAを「</>」ボタンでセットされる[```]の間に記載できませんか?
vba_begginer

2018/04/10 07:26

出来ました。見にくくなっていてすみませんでした。
ExcelVBAer

2018/04/10 07:27

すごく見やすくなりました。
vba_begginer

2018/04/10 07:28

ありがとうございます。
guest

回答3

0

下記の「Range」にシートが付いてないのが原因の可能性があります。
「データシート.Range(」と記載した方が無難です。

Application.WorksheetFunction.Index(データシート.Cells(j, 27), Application.WorksheetFunction.Match(検索シート.Cells(i, 7), Range(データシート.Cells(2, 2), データシート.Cells(5670, 2)), 0))

こういう風に何回もシートオブジェクトが出てくると見にくいので、
With データシート 等として、「データシート」を省略する等すると見やすくなります。

投稿2018/04/10 07:11

ExcelVBAer

総合スコア1175

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

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

vba_begginer

2018/04/11 00:28

ご教示誠に有り難うございます。 無事エラーメッセージはでなくなり、且つ、withステートメントを使ったことでコードが見やすくなりました。 ただ、動きがものすごく遅いです。findメソッドやvlookupを使わず高速化する目的で上記コードを作りましたが、浅はかだったようです。。。高速化する案があればご教示いただけますと幸いです。
ExcelVBAer

2018/04/11 03:00

Screenupdate や Calculation とか、基本的な事はご自分で調べてくださいね。 自分なら、シート上のデータを配列に格納して検索しますかねぇ。 ただ、配列に格納すると、配列の要素数が1から始まるので、 ご自分で都合いいように調整してください。
vba_begginer

2018/04/11 04:11

ScreenupdateやCalculationあたりは大丈夫です。 配列への格納は、確かに使えそうです。一度やってみます。 初心者にも分かりやすいご回答、誠に有り難うございます!
TanakaHiroaki

2018/04/19 07:39

シート上のデータに重複がない場合、当該列をインデックス、別の列の値(文字列)をキーとする連想配列を用いれば、高速に処理できる可能性があります。
guest

0

自己解決

以下のように修正しました。

VBA

1With データシート 2 Dim y As Long, 該当行 As Long, 該当列 As Long 3 Dim 検索値 As String 4 For y = 8 To 7000 5  該当行 = Application.WorksheetFunction.Match(検索シート.Cells(y, 7), .Range(.Cells(2, 2), .Cells(5670, 2)), 0) 6 7 If 該当行 <> 0 Then 8 On Error Resume Next 9 該当列 = .Range(.Cells(該当行 + 1, 26), .Cells(該当行 + 1, 71)).Find(what:=検索シート.Cells(y, 8), lookat:=xlWhole).Column 10   ’該当行(↓)を検索した後に、該当の行から検索語を1列ずつ検索し(→)、値を返す。 11 End If 12 Next y 13End With

投稿2018/04/17 00:32

編集2018/04/17 06:26
vba_begginer

総合スコア6

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

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

ExcelVBAer

2018/04/17 00:54

よくできました。 処理はちゃんと個別に分けるべきです。 じゃないと、ちょっとした小石でこけてしまいますから。 で、コードを載せる際は、『</>』ボタンを使ってください。 インデントが無いコードは見るに堪えませんので。 あと、該当列 = .Range().Find.().Column としてますが、 これ、Findが失敗した時、該当列 の中身はどうなるでしょう? 該当列 に 0意外の値が入った状態で確認しておいた方がいいと思いますよ。
vba_begginer

2018/04/17 04:03

ご教示、誠に有り難うございます。 『</>』ボタンの使い方をご教示いただけますと幸いです。基本的なことですみません。 On Error Resume Nextを使っても該当列にエラーが生じる可能性があるということでしょうか。 一度確認してみます。
ExcelVBAer

2018/04/17 05:44 編集

On Error Resume Next ている際に、 エラーが生じていた場合にはもちろんデバッグにはなりません。 しかし、その場合の挙動( 該当列 の値がどうなるか)について、 確認できていないのであれば、知っておかないと致命的なエラーになるでしょうね。 『</>』ボタンは、回答する際に該当ボタンを押せば分かりますよ。 ```ここに言語を入力 コード ``` ※回答に対するコメントでは使えません。
vba_begginer

2018/04/17 06:27

できました!有り難うございました。 エラーの可能性があるとのことですので、確認しておきます。 いろいろとご教示、誠に有り難うございます。
guest

0

以下のように変えてみて欲しい。

On Error Resume Next
検索シート.Cells(i, 9).Value = Application.WorksheetFunction.Index(データシート.Cells(j, 27)....
On Error GoTo 0

高速化もできるかと思うけど?

投稿2018/04/16 22:40

Nitta

総合スコア96

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

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

vba_begginer

2018/04/17 00:21

ご教示誠に有り難うございます。On Error Resume Nextを入れてみました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問