• ベストアンサー

エクセルVBA(LOOKUP関数)Win2000、Office2000

いつも関数(LOOKUP)を使って集計をしているのですが、これがVBAで一発処理できれば効率がよくなると思い、頑張ってコードを書き書きしてます。 が、どうもうまくいかきません。下に今書いているコードを書きます。やりたい内容がおわかりいただければいいのですが・・・よろしくお願いします。 Subtest() Dim ds,ss As Worksheet'(シート名) Dim Dlrow As Long'(DataSheetの最終行) Dim Slrow As Long'(DataSheetの最終行) Dim i,r,dAs Long’(行、列カウンタ) Set ds=Worksheets("DataSheet") Set ss=Worksheets("syukei") For DL row =1 To ds.Range("B65536").End(xlUp).Row 'DataSheetの行数判定 Next ForSLrow=1 To ss.Range("B65536").End(xlUp).Row '集計シートの行数判定 Next '現在セルにある関数→集計シートA3=LOOKUP(B3,DataSheet!3:H6308,DataSheet!C3:C6308) '対応する列 '検索値は全て、集計シートのB列 '検査範囲は全て、データシートのH列 ↓////※ここらへんから苦戦してます//// '集計シートのA列=データシートのC列 WithWorksheets("syukei") Fori=3ToSLrow '.Cells(i,1)="=Lookup(Cells(i,2),Worksheets(DS).cells3,8):cells(DLrow,8),worksheets(DS).cells(3.3):cells(DLrow:3)" Nexti EndWith '以降, 集計C列=データのI列のように対応する列毎に、上のコードで処理していこうと思っています。(もしかしてダサイやり方ですか?) 'J列以降は、以降集計J~AS列とデータR~BA列の+1列 'Forr=10to45→r=J~AS(10to45) 'Ford=18to53→d=R~BA(18to53) 'Fori=3toSLrow 'Cell(r,i)=Lookup・・・・・ 'nextr 'nextd 'nexti EndSub と、こんな感じで、頑張ってます。よろしくお願いいたします。

質問者が選んだベストアンサー

  • ベストアンサー
  • nishi6
  • ベストアンサー率67% (869/1280)
回答No.3

>どの辺りをいじればいいのでしょうか イレギュラーなので、1列毎に書くべきでしょう。 補足にD列がない?下はB、D列は書き込んでいません。 'データシートの値を集計表に書く For Col = 1 To 45   If Not (Col = 2 Or Col = 4) Then     Select Case Col       Case 1: pCol = 3 '集計表A列=データシートC列       Case 3: pCol = 9 '集計表C列=データシートI列       Case 5: pCol = 16 '集計表E列=データシートP列       Case 6: pCol = 17 '集計表F列=データシートQ列       Case 7: pCol = 6 '集計表G列=データシートF列       Case 8: pCol = 12 '集計表H列=データシートL列       Case 9: pCol = 13 '集計表I列=データシートM列       '集計表J列=データシートR列、8列ずれ       Case 10 To 45: pCol = Col + 8     End Select     wsS.Cells(Rw, Col) = wsD.Cells(fRw, pCol)   End If Next

rurucom
質問者

補足

nishi6さん!ありがとうございました。 やはり、1行づつで良かったのですね。試しにしてみたらうまくはいったもののほんとにこれで良いのか・・・と不安だったもので・・・ これは、いろいろと使えそうです。大変助かりました。少しだけ仕組みが分かりました。後の今回分からなかったとこは勉強していきたいと思います。本当にありがとうございました。

その他の回答 (3)

  • papayuka
  • ベストアンサー率45% (1388/3066)
回答No.4

こんにちは。 既に解決されたみたいなので、補足に対する回答だけ。。 関数なら、このようなケースの場合は LOOKUP では無く INDEXとMATCHを組み合わせて↓こんな感じでしょうか。 集計シートのA3に =INDEX(DataSheet!$A$3:$BA$6308,MATCH(B3,DataSheet!$H$3:$H$6308,0),3) ただ、この手の関数は使いすぎると猛烈に重くなるので程ほどに。

rurucom
質問者

お礼

papayukaさん!ありがとうございました。 >=INDEX(DataSheet!$A$3:$BA$6308,MATCH(B3,DataSheet!$H$3:$H$6308,0),3) OKでした。 でも、確かに重くなりました。 今回もいろいろと勉強になりました。また何かありましたらよろしくお願いします。しばらくVBAにはまりそうです。

  • nishi6
  • ベストアンサー率67% (869/1280)
回答No.2

質問を読んで、『集計シートのB列とデータシートのH列を照合して一致したデータシートの値を持ってくる。』ようですが・・・  少し問題点が・・・   1.LOOKUPを使っているが、データシートのH列はソートされている?   2.LOOKUPで一致しないデータがあると、#N/Aのエラーがでる。      さらに悪いのは、違うデータを持ってくる事がある。どうやって対応している?   3.これだけの行数と列数に対してLOOKUPを使用して大丈夫?      やるとすれば、すぐ、値に書き換えるか。      と、すると、何のためのLOOKUPか。 という事で、私ならFindメソッドを使うでしょう。データのソート、見つからない場合の対応も簡単ですし。 ただ、下のコードのデータシートから集計シートに書き出すところは自信なしです。質問を読んで、よく分からなかったところです。 集計シートのB列とデータシートのH列を照合して、一致したら、その行の処理を行っています。セル単位の処理ではないです。 LOOKUPは使っていませんので、不要なら読み飛ばして下さい。 Sub Syuukei()   Dim wsS As Worksheet '集計表   Dim wsD As Worksheet 'データシート     Set wsS = Worksheets("Syukei")     Set wsD = Worksheets("DataSheet")   Dim Rw As Long '集計表の行カウンタ   Dim Col As Integer, pCol As Integer '集計表とデータシートの列カウンタ   Dim searchArea As Range '検索する範囲   Dim fCell As Range '見つけたセル   Dim fRw As Long '見つけたセルの行   Set searchArea = wsD.Range("H3:H" & wsD.Range("H65536").End(xlUp).Row)   Rw = 3   While wsS.Cells(Rw, 2) <> ""     '集計表のB列の値でデータシートのH列を検索     Set fCell = searchArea.Find(wsS.Cells(Rw, 2), Lookat:=xlWhole)     If Not fCell Is Nothing Then       '見つかったらその行数を求める       fRw = fCell.Row       'データシートの値を集計表に書く       For Col = 1 To 45         If Col <> 2 Then           Select Case Col             '集計表A列=データシートC列             Case 1: pCol = 3             '集計表C列=データシートI列、集計表D列~I列までは同じ?             Case 3 To 9: pCol = Col + 6             '集計表J列=データシートR列、8列ずれ             Case 10 To 45: pCol = Col + 8           End Select           wsS.Cells(Rw, Col) = wsD.Cells(fRw, pCol)         End If       Next     End If     Rw = Rw + 1 '次の行   Wend   Set searchArea = Nothing End Sub ※気がついた事  For DLrow =1 To ds.Range("B65536").End(xlUp).Row  Next  DLrow は最終行+1になってしまうはずです。書くなら、  DLrow = ds.Range("B65536").End(xlUp).Row でしょう。  Dim ds,ss As Worksheet  これも書くなら  Dim ds As Worksheet  Dim ss As Worksheet  です。最初の書き方では、dsはバリアント変数です。  Dim i,r,d As Long  も  Dim i As Long,r As Long,d As Long  としたほうがいいでしょう。この辺りはHelpに説明があります。

rurucom
質問者

補足

nishi6さん!お久しぶりです。 私には??????ですが・・・すばらしい!です。とにかくできました。 >私ならFindメソッドを使うでしょう。 →この辺を勉強してみます。 ///取り急ぎ補足ですが・・・/// >'集計表C列=データシートI列、集計表D列~I列までは同じ? →いいえ。実は違います。 集計C列=データのI列 集計E列=データのP列 集計F列=データのQ列 集計G列=データのF列 集計H列=データのL列 集計I列=データのM列 です。どの辺をいじればいいのでしょうか? Caseで1行づつ書くしかないのでしょうか?というかそれで良いのでしょうか? >1.LOOKUPを使っているが、データシートのH列はソートされている? → 空いているセルはありませんが、昇順降順にはなっていません。他の列でソートしているので・・・ >2.LOOKUPで一致しないデータがあると、#N/Aのエラーがでる。   さらに悪いのは、違うデータを持ってくる事がある。どうやって対応している? → 対応に困っています。実際にデータがあるはずなのに持ってこない(#N/A)    >3.これだけの行数と列数に対してLOOKUPを使用して大丈夫?      やるとすれば、すぐ、値に書き換えるか。  と、すると、何のためのLOOKUPか。 → おっしゃる通りです。私の知識不足です。LOOKUPしか思いつきませんでした。

  • papayuka
  • ベストアンサー率45% (1388/3066)
回答No.1

こんにちは。 頑張っていらっしゃいますね。 データ構造が解からないので外しているかもしれません。 元ブックをコピーして、テスト環境で試して下さい。 Sub ATest() Const sN = "DataSheet" Dim dRange As Range, sRange As Range  With Worksheets(sN)    Set dRange = .Range("H3:H" & .Range("H65536").End(xlUp).Row)  End With  With Worksheets("syukei")    Set sRange = .Range("B3:B" & .Range("B65536").End(xlUp).Row)  End With  sRange.Offset(0, -1) = "=LOOKUP(B3," & sN & "!" & dRange.Address & _           "," & sN & "!" & dRange.Offset(0, -5).Address & ")"  Set dRange = Nothing: Set sRange = Nothing End Sub

rurucom
質問者

補足

papayukaさん!早速の回答ありがとうございます。この前も大変お世話になりました。 早速テストしました。回答の内容はGOODです。とりあえず私には?????で結果オーライ状態です。Dim dRange As Range, sRange As Range .Rangeの使い方など、Offsetの使い方、Addressなど、よく分かりません。これから勉強していきます。 それとは別に、ひとつ問題がありました。結果が、#N/Aのエラーです。 直接関数を入れてみても#N/Aなので、コードの問題ではないようです。考えられる問題点としては、どのようなことがあるでしょうか? 検索値、検査値、対応値の降順昇順ソートとか?・・・・・ 現在全てランダムに並んでいます。どれかをソートすればどれかがランダムになるので・・・ 現在の検索値、検査値は4桁から6桁の数字です。対応値は、文字列(漢字、かな、カナ) とりあえず状況的にこんな感じなんですが、よろしくお願いします。

関連するQ&A

  • エクセルVBAでLOOKUP関数がうまくできません

    エクセルVBAでLOOKUP関数がうまくできません。 入力シートと判別用のシートがあり入力シートで入力した品名を検索値 として判別用シートで数値に置き換えた値をLOOKUPで検索したいのですが WorksheetFunctionクラスのVLOOKUPプロパティを取得できませんと 実行時エラーが出ます。検索しましたが修正方法がわかりません。 構文のどこが原因なのか教えてください。 VBA初心者です。よろしくお願いします。 sub test() Dim データ行 As Long Dim データ数 As Long データ行 = Cells(Rows.Count,8).End(xlUp).Row For データ数 = 11 To データ行 Cells(データ数 ,32) = Application.WorksheetFunction.VLookup(cells(データ数,8),Worksheets("判別シート").Range("B11:E110"),5,False) Next データ数 End sub

  • ExcelのVBAの配列に関する質問です。

    ExcelのVBAの配列に関する質問です。 sheet1のデータをsheet2に表示するVBAを作成しています。。 sheet1のデータは7行目からスタートし、sheet2のデータは26行目からスタートしています。。 sheet1とsheet2の列は同じ並びではないため、それぞれのシートの列番号をCellsを用いて指定しています。 Sub test1() Dim endrow As Long endrow = Worksheets("sheet1").Range("A65536").End(xlUp).Row Dim i As Long Dim j As Long For i = 7 To endrow j = i + 19 Worksheets("sheet2").Cells(j, 1) = Worksheets("sheet1").Cells(i, 2) Worksheets("sheet2").Cells(j, 8) = Worksheets("sheet1").Cells(i, 28) Worksheets("sheet2").Cells(j, 9) = Worksheets("sheet1").Cells(i, 31) Worksheets("sheet2").Cells(j, 10) = Worksheets("sheet1").Cells(i, 32) ・ ・ ・ ※長いので省略 Next i End Sub 上記のtest1は正常に動くのですが、データ量が多いため、処理に時間がかかってしまいます。 高速化できないかと、以下のように変更しました。 Sub test2() Dim dataRange1 As Variant Dim dataRange2 As Variant dataRange1 = Worksheets("sheet1").Range("A1:GI10006") dataRange2 = Worksheets("sheet2").Range("A1:DZ10018") Dim endrow As Long endrow = Worksheets("sheet1").Range("A65536").End(xlUp).Row Dim i As Long Dim j As Long For i = 7 To endrow j = i + 19 dataRange2(j, 1) = dataRange1(i, 2) dataRange2(j, 8) = dataRange1(i, 28) dataRange2(j, 9) = dataRange1(i, 31) dataRange2(j, 10) = dataRange1(i, 32) ・ ・ ・ ※長いので省略 Next i End Sub test2は、エラーメッセージ等は表示されませんが、sheet2にデータが表示されません。 ちなみに、以下のようにsheet1のみ配列化した場合は、正常に表示されました。 Worksheets("sheet2").Cells(j, 1) = dataRange1(i, 2) Worksheets("sheet2").Cells(j, 8) = dataRange1(i, 28) Worksheets("sheet2").Cells(j, 9) = dataRange1(i, 31) Worksheets("sheet2").Cells(j, 10) = dataRange1(i, 32) test2は、どこが間違っているのでしょうか? ご教示ください。 よろしくお願いいたします。

  • エクセルVBA(掛け算)

    いつもおせわになります。 現在、下記のようなコードを書いてますがどうもうまくいきません。よろしくお願いいたします。 M列 = K列 × N列を6行目から最終行目で入れたくて下記のようなコードを書きました。 ところが・・・N列にはデータのない場合があるので、If~を入れてみました。ここまではうまくいったのですが、 O列 = K列 × P列のように数式を入れたい列が他にもあり、又同じコードを下記のように書いたら、P列にデータがないところで止まってしまいます。 '///////////////////////////////////////////// Dim wsS As Worksheet Dim r As Long Dim Srow As Long Set wsS = Worksheets("syukei") Srow = wsS.Range("D65536").End(xlUp).Row With Worksheets("syukei") For r = 6 To Srow If Cells(r, 12) = Noting Then r = r End If Cells(r, 13) = Cells(r, 11) * Cells(r, 12) Next End With With Worksheets("syukei") '↓////////ここらへんで止まる////////// For r = 6 To Srow If Cells(r, 14) = Noting Then r = r End If Cells(r, 15) = Cells(r, 11) * Cells(r, 14) Next End With End Sub 掛け算を入れたい行は、下記のようになっています。 M列=K列×L列 O列=K列×N列 Q列=K列×P列 S列=K列×R列 U列=K列×T列 W列=K列×V列 Y列=K列×X列 よろしくお願いいたします。

  • エクセルVBAについて

    前回質問させていただきました件の追加機能になります。以前質問させていただきましたマクロが下記のものです。 Sub TESTa() Dim A As Long Dim B As Long Dim C As Long Dim D As Long Dim E As Long Dim F As Long '表の行数を調べる A = Worksheets("sheet1").Range("C65536").End(xlUp).Row - 1 For C = 1 To A For B = 4 To 7 'Sheet1のデータをSheet2に複写する Worksheets("Sheet2").Cells(B - 3 + D, 15) = Worksheets("Sheet1").Cells(C + 1, 1) Worksheets("Sheet2").Cells(B - 3 + D, 6) = Worksheets("Sheet1").Cells(C + 1, B) Worksheets("Sheet2").Cells(B - 3 + D, 14) = Worksheets("Sheet1").Cells(C + 1, 3) Worksheets("Sheet2").Cells(B - 3 + D, 10) = Worksheets("Sheet1").Cells(1, B) Worksheets("Sheet2").Cells(B - 3 + D, 13) = Worksheets("Sheet1").Cells(C + 1, 2) Next D = C * 4 Next 'Sheet2の表の行数を調べる Sheets("Sheet2").Select E = Worksheets("sheet2").Range("F65536").End(xlUp).Row '0欄の確認 For F = E To 1 Step -1 If Worksheets("Sheet2").Cells(F, 6) = 0 Then '0の場合は行を削除する Cells(F, 1).EntireRow.Delete End If Next End Sub カウントするとデータ個数がSheet1で約120件になりSheet2においては、4倍になりますので約480件になります。 そこで Sheet1において12件ごとに、Sheet2,3,4...としたいのです。 Sh1 NO.1~12がSheet2 Sh1 NO.13~24がSheet3 ... 10枚のシートにしたいのですが、このマクロにどのような命令を加えればよろしいでしょうか? お手数ですがよろしくお願いいたします。

  • Excel VBA; 複数のループ処理

    ↓のようなコードがあります。 Dim i As Long, MaxRow1 As Long, MaxRow2 As Long MaxRow1 = Worksheets("Sheet1").Cells(Rows.Count, 1).End(xlUp).Row MaxRow2 = Worksheets("Sheet2").Cells(Rows.Count, 1).End(xlUp).Row For i = 1 To MaxRow1 Worksheets("Sheet1").Cells(i, 1).Value = i . Next i For i = 1 To MaxRow2 Worksheets("Sheet2").Cells(i, 1).Value = i . Next i これらを最大行の多いシートに合わせて、パフォーマンスを良くしたいと思います。 同様の処理をシート1、シート2で実施しているので纏めて記述したいです。 シート1、シート2に対する処理をサブルーチンにする方法しかありませんか? どなたかお願いします。 If MaxRow1 >= MaxRow2 Then For i = 1 To MaxRow1 Else For i = 1 To MaxRow2 End If Worksheets("Sheet1").Cells(i, 1).Value = i Worksheets("Sheet2").Cells(i, 1).Value = i . Next i

  • エクセル関数をVBAでやりたい

    IFERROR(INDEX(***,MATCH(***)),"")この式を下記マクロに組み込むことは、可能でしょうか? Sub Macro1() ' Dim line3 As Integer Dim line5 As Integer line5 = 2  '初期値を2行目に設定してます Do While Worksheets("Sheet5").Cells(line5, 1).Value > 0 'sheet5の通し番号をsheet3のH列から検索して、その行数をline3に代入する。   line3 = Worksheets("Sheet3").Range("H:H").Find(what:=Worksheets("Sheet5").Cells(line5, 8)).Row 'A,B列内容のコピー   Worksheets("Sheet5").Range("A" & line5, "B" & line5).Copy Worksheets("Sheet3").Cells(line3, 1) 'D~G列内容のコピー   Worksheets("Sheet5").Range("D" & line5, "G" & line5).Copy Worksheets("Sheet3").Cells(line3, 4)   line5 = line5 + 1    '次の行へ Loop   ( http://soudan1.biglobe.ne.jp/qa8921867.html )

  • エクセル2019 VBAについて

    エクセル2019でVBAを使いコピーペーストの勉強中です、次の箇所(Dim i As integr)で、ユーザー定義型は定義されていませんと指摘されて止まってしまします、Sheet("データ")には3行のデータは入っています、VBA初心者のため、この後が、なかなか前に進めません、どうかよろしくおねがいします。 ********************************** Sub 練習() Dim s1 As Worksheet: Set s1 = Worksheets("請求書") Dim s2 As Worksheet: Set s2 = Worksheets("データ") Dim r1 As Integer: r1 = 18 Dim r2 As Integer: r2 = 2 { Dim i As integr } For i = 0 To 2 s1.Range(s1.Cells(r1 + i, 1), s1.Cells(r1 + i, 3)).Value = s2.Range(s2.Cells(r2 + i, 2), s2.Cells(r2 + i, 4)).Value s1.Cells(r1 + i, 4).Value = s1.sells(r1 + i, 2).Value * s1.Cells(r1 + i, 3).Value Next End Sub ***************************************

  • 全くの初心者ですVBA

    どこが悪いかわかりません。 教えてください。 Sub テスト() Dim kekka As String Dim i As Integer tokuten = Worksheets("Sheet1").Cells(i, 1).Value For i = 1 To Worksheets("Sheet1").Range("A1").End(xlDown).Row.Count If tokuten >= 80 Then kekka = "合格" Else kekka = "不合格" kekka = Cells(i, 2) End If Next i End Sub シート1の A列に数値で得点が入っています。

  • Excel VBAで検索する

    Excel VBAで、Sheet1に貼り付けたテキスト内から Sheet2に記載した(1列ごとの)キーワードを検索し キーワードが含まれている行をSheet3に貼り付ける処理をしているのですが、始めたばかりなので上手くいきません。 下記がソースです。 Dim moji As String Dim word As String Dim result As Integer For i = 3 To 103 For j = 2 To 21 moji = ThisWorkbook.Worksheets("Sheet1").Cells (i, 1).Value word = ThisWorkbook.Worksheets("Sheet2").Cells (j, 2).Value result = InStr(moji, word) If doResult <> 0 Then For k = 1 To 100 ThisWorkbook.Worksheets("Sheet3").Cells (k, 1).Value= moji Next k End If Next j Next i このソースでは上手くいかないのですが、どこがダメなのか分からないので、解決の糸口がつかめません。 アドバイスなどお願いします。

  • EXCELのVBAでDcount関数がうまく動きません。

    EXCELのVBAでDcount関数を使おうとして、下記コードを作成しましたが、Dcount関数の部分が期待どおり動かず、該当なしとして、0を返してきます。 デバックで途中でマクロを止めて(Dcount関数の前)、セルに直接Dcount関数を入力すると、期待どおりの値を返してきます。 Dcount関数の記述の何が問題なのか、ご教示いただければ幸いです。 Sub 期間集計() Dim myrow, Krow As Double Dim First, Last As Date Dim i, Count As Integer Dim Data As Integer Dim Keria As String 'Worksheets("期間別").Activate Worksheets("期間別").Range("A1:BB65536").Delete Worksheets("入力").Activate With Worksheets("入力") '入力表の最終行の行数をmyrowに代入 myrow = .Range("A65536").End(xlUp).Offset(1).Row '出力前に入力データを日付順にソート .Range("A3").Sort _ Key1:=.Columns("A"), _ Header:=xlGuess First = Worksheets("集計").Range("G3") Last = Worksheets("集計").Range("H3") .Range("BH3:BH5").ClearContents .Range("BH3") = "日付" .Range("bi3") = "日付" .Range("BH4") = ">=" & First .Range("BI4") = "<=" & Last .Range(.Cells(2, 1), Cells(myrow, 47)).AdvancedFilter Action:=xlFilterCopy, _ Criteriarange:=.Range("BH3:BI4"), Copytorange:=Worksheets("期間別").Range("C11"), Unique:=False Krow = Worksheets("期間別").Range("C65536").End(xlUp).Row Keria = "C11:" & "AW" & Krow End With Worksheets("集計").Activate With Worksheets("集計") .Range(.Cells(13, 10), .Cells(24, 10)).ClearContents For i = 1 To 12 Count = 12 + i .Range(.Cells(Count, 16), .Cells(Count, 61)).Copy .Range(.Cells(11, 16), .Cells(11, 61)).PasteSpecial Paste:=xlValues .Range(.Cells(10, 16), .Cells(11, 61)).Copy With Worksheets("期間別") .Range(.Cells(11, 53), .Cells(12, 98)).PasteSpecial Paste:=xlValues Data = WorksheetFunction.DCount(.Range(Keria), .Range("C11"), .Range("BA11:CT12")) End With .Cells(Count, 10) = Data Next i End With

専門家に質問してみよう