- ベストアンサー
Excel VBA 配列を使って高速化する方法
- Excel VBAを使用して用語の読みを自動で振るシートを作成する際、配列を使って高速化する方法を教えてください。
- 現在、用語を一行ずつ入力しているため、時間がかかっています。配列を使用することで一度に書き込むことができればと思っています。
- 具体的な手順は以下の通りです。 1. シート1に用語をペーストする。 2. ペーストされた用語をシート2の用語DBにコピーする。 3. シート2をピボットにし、個数が2以上の用語と読みを返す。 4. ループで最初にヒットした用語に戻るまで繰り返す。
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
>シート2には,用語と読みが一緒になったDBがあります(用語と読みは1対1です). その場合、Do..Loopは必要ないです。 : >Set Foundcell01 = Rng01.Find(What:=Str01, searchorder:=xlByRows, LookIn:=xlValues, lookat:=xlWhole) >If Not Foundcell01 Is Nothing Then > Set firstcell = Foundcell01 > Foundcell01.Select > Do > Selection.Offset(0, 1).Value = Str02 > Selection.Offset(0, 2).Value = "●" > Loop Until ActiveCell.Address = firstcell.Address >End If : 以下のように書きます。 Set Foundcell01 = Rng01.Find(What:=Str01, searchorder:=xlByRows, LookIn:=xlValues, lookat:=xlWhole) If Not Foundcell01 Is Nothing Then Foundcell01.Offset(0, 1).Value = Str02 Foundcell01.Offset(0, 2).Value = "●" End If ただし、用語の個数をピボットでチェックして、 登録済み用語のみをFindメソッドで検索してシート1に『当て』にいく.. ような処理は効率悪いです。 >..速度の面でピボットのほうが断然早いため,改修したという経緯がございます. 前回提示したSub sample()を実行してみたらどうなりますか? 比較してみてください。 もっと速度を上げたい場合はdictionaryオブジェクトを使う事になります。 http://okwave.jp/qa/q6327928.html?order=asc
その他の回答 (1)
- end-u
- ベストアンサー率79% (496/625)
: >Set Foundcell01 = Rng01.Find(What:=Str01, searchorder:=xlByRows, LookIn:=xlValues, lookat:=xlWhole) >Do >Selection.Offset(0, 1).Value = Str02 >Selection.Offset(0, 2).Value = "●" >Loop Until ActiveCell.Address = firstcell.Address >End If >End If : ここはまともに動きませんよね。 ですのでコードを見てもやりたい事がわかりません。 「用語」と「読み」は1対1ではなくて1対複数なのですか? だからDo Loopを使っているのだとしても、書き込み位置がどう変化しているのか不明なので 具体的なアドバイスのしようがないです。 >3までの手順に修正の必要はないのですが,.. ピボットテーブルを使う意図がわかりません。 もし「用語」と「読み」が1対1ならVlookup関数を使えばすむ話のようですが.. Sub sample() Dim r1 As Range Dim r2 As Range Dim r As Range With Worksheets(1) Set r1 = .Range("B8", .Cells(.Rows.Count, 2).End(xlUp)).Offset(0, 1) End With With Worksheets(2) Set r2 = .Range(.Cells(.Rows.Count, 3).End(xlUp), "D1") End With r1.Value = Application.VLookup(r1.Offset(0, -1), r2, 2, 0) r1.Offset(0, 1).Value = "●" On Error Resume Next Set r = r1.SpecialCells(xlCellTypeConstants, xlErrors) On Error GoTo 0 If Not r Is Nothing Then r.ClearContents r.Offset(0, 1).ClearContents End If End Sub
お礼
ご回答ありがとうございます. また,こちらの記述や説明に不足があり,失礼いたしました. Do の上の以下の3行分の記述が抜けておりました. 申し訳ありません. If Not Foundcell01 Is Nothing Then Set firstcell = Foundcell01 Foundcell01.Select こちらの行いたいことを再度ご説明させていただきます. シート1には,読みを振りたい用語をB8を起始として数千から数万ペーストします. 【例】 東京 北海道 青森 ・ ・ シート2には,用語と読みが一緒になったDBがあります(用語と読みは1対1です). 用語 読み 東京 とうきょう 神奈川 かながわ 千葉 ちば 埼玉 さいたま シート1にペーストされた用語は,シート2の最下行にペーストされます 用語 読み 東京 とうきょう 神奈川 かながわ 千葉 ちば 埼玉 さいたま 東京 北海道 青森 このデータをシート3のピボットで個数を調べ,個数が2以上だった場合に読みと用語を返します. 返された用語をシート1で検索して,読みを転記しています(この転記がDo Loopでない方法で一括で行えないでしょうかというのが今回の質問になります). また,上の例ですと東京には読みが振られますが,北海道と青森には読みが振られません. 北海道と青森に関しては,Leftを使って用語を分解して上記手順のピボットでの完全一致を行い読みをふり,Leftで抽出した以外の部分(残り部分)にも同様の方法で読みを振ることを行います. それでも読みが振られない場合は,正規表現を利用して,漢字とそれ以外に分割して,漢字部分をピボットに送り,完全一致で検索して読みを振ります. それでも読みが振られないものに対しては,GetPhoneticで読みを生成しております. ピボットを使う前はvlookupで記述していたのですが,速度の面でピボットのほうが断然早いため,改修したという経緯がございます. なにとぞよろしくお願いいたします.
お礼
ご教示ありがとうございます. dictionaryオブジェクトを初めて知りました. すごい方法があるのですね. まさに現在開発中のものにぴったりです. ピボットがもっとも高速だと思い込んでいた知識の浅さに恥じ入るばかりです. 先般お示しいただきましてvlookupと一緒にじっくり取り組んで,現在のコードに実装したいと存じます. この度はお世話になりました.