• 締切済み

VBA 複数条件の抽出

お世話になります。 sheet1~sheet100までのシートがあるとして、 可能とバスケ、普通とバスケがあったら、並んで バスケ バスケ 可能   普通 という文字を取り出したいです。 文言はいろいろな種類があり、野球、水泳などがあるとします。 それをVBAで行うにはどうすればいいでしょうか。 例)Sheet1 A B 可能   バスケ 可能  野球 不可能 野球 普通  水泳 普通  バスケ 可能  卓球 不可能 こういう表を作りたいです↓ 集計シート A B C D E F G~     卓球  卓球 バスケ バスケ テニス 野球 水泳     可能 不可能  可能  普通  可能 不可能 可能 sheet1   1 5 6 3 2~ sheet2 2 3 1 1 4 sheet3 4 3 3 3 1 sheet4 1 1 1 1 9 sheet5  2 3 1 1 4 よろしくお願いいたします。

みんなの回答

  • masnoske
  • ベストアンサー率35% (67/190)
回答No.3

以下のフローで考えてみました. (1) Sheet1~Sheet100から B列,A列の形式で組合せをコレクションに抽出 (2) 作業シートにコレクションを出力 (3) A列昇順・B列昇順で並べ替える (4) COUNTIFS関数で集計を作成 (5) 作業シートの行列を入れ替えたデータを結果シートに貼り付ける Sub Macro1() Dim sh As Worksheet Dim shTemp As Worksheet Dim shResult As Worksheet Dim col As Collection Dim str As String Dim rng As Range Dim i As Variant Dim j As Variant Dim arry As Variant Dim shMax As Long shMax = 100 Set shTemp = Worksheets("作業") Set shResult = Worksheets("集計") ' 組合せをコレクションに抽出する Set col = New Collection For i = 1 To shMax Set sh = Worksheets("Sheet" & i) For Each rng In sh.Range("A:A") If rng.Value = "" Then Exit For str = rng.Offset(0, 1).Value & "," & rng.Value ' On Error Resume Next col.Add str, str On Error GoTo 0 Next Next ' tempシートの準備 shTemp.Activate shTemp.Cells.Clear ' コレクションから作業シートに出力する For i = 1 To col.Count arry = Split(col(i), ",") shTemp.Cells(i, 1) = arry(0) shTemp.Cells(i, 2) = arry(1) Next ' データを昇順に並べ替える With shTemp.Sort.SortFields .Clear .Add Key:=Range("A:A") .Add Key:=Range("B:B") End With With shTemp.Sort .SetRange Range("A:B") .Header = xlGuess .Apply End With ' シート行を挿入 shTemp.Range("1:1").Insert For i = 1 To shMax shTemp.Cells(1, i + 2).Value = "Sheet" & i Next ' COUNTIF関数を設定 shTemp.Range("C2") = "=COUNTIFS(INDIRECT(C$1 & ""!B:B""),$A2,INDIRECT(C$1 & ""!A:A""),$B2)" shTemp.Range("C2").Copy Range(shTemp.Range("C2"), shTemp.Cells(shTemp.UsedRange.Rows.Count, shTemp.UsedRange.Columns.Count)).PasteSpecial xlPasteFormulas ' 作業シートの行列を入れ替えて結果シートに貼り付ける shResult.Cells.Clear shTemp.UsedRange.Copy shResult.Range("A1").PasteSpecial xlPasteValues, Transpose:=True ' 最終処理 Application.CutCopyMode = False shTemp.Range("A1").Select shResult.Activate shResult.Range("A1").Select End Sub

  • HohoPapa
  • ベストアンサー率65% (455/693)
回答No.2

ゴリゴリとコードを書いて、地道に数えるしかないだろうと思います。 ・作業シートに、100枚あるらしいシートから   シート名、A列語句、B列語句を集める ・A列語句、B列語句順に並べ ・2つの語句ごとの出力先列番号を4列目に採番 ・シーツ名順に並べ ・各レコードが何枚目のシートのデータかを5列目に採番 ・作業シートを先頭から読み取り、 ・集計シートに求める集計結果を出力する といった手順で(ちょっと手抜きですが)コードを書いてみました。 Sub sample()  Dim wsWork As Worksheet  Dim wsSyuk As Worksheet  Dim wshCnt As Long  Dim RowCnt As Long  Dim PutCnt As Long  Dim RetuNum As Long  Dim SheetNum As Long    Set wsWork = ThisWorkbook.Sheets("作業")  Set wsSyuk = ThisWorkbook.Sheets("集計")    wsWork.Cells.Clear  wsSyuk.Cells.Clear  PutCnt = 0    For wshCnt = 1 To ThisWorkbook.Sheets.Count   With ThisWorkbook    If ((.Sheets(wshCnt).Name <> "集計") And (.Sheets(wshCnt).Name <> "作業")) Then     RowCnt = 1     Do      If .Sheets(wshCnt).Cells(RowCnt, 1).Value = "" Then Exit Do      PutCnt = PutCnt + 1      wsWork.Cells(PutCnt, 1).Value = .Sheets(wshCnt).Name      wsWork.Cells(PutCnt, 2).Value = .Sheets(wshCnt).Cells(RowCnt, 2).Value      wsWork.Cells(PutCnt, 3).Value = .Sheets(wshCnt).Cells(RowCnt, 1).Value      RowCnt = RowCnt + 1     Loop    End If   End With  Next wshCnt    With wsWork   .Select   .Cells.Select   .Sort.SortFields.Clear   .Sort.SortFields.Add2 Key:=Range("B:B"), _     SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal   .Sort.SortFields.Add2 Key:=Range("C:C"), _     SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal   With .Sort    .SetRange Range("A:C")    .Header = xlGuess    .MatchCase = False    .Orientation = xlTopToBottom    .SortMethod = xlPinYin    .Apply   End With     RowCnt = 2   RetuNum = 1   .Cells(1, 4).Value = RetuNum   Do    If .Cells(RowCnt, 1).Value = "" Then Exit Do    If ((.Cells(RowCnt, 2).Value <> .Cells(RowCnt - 1, 2).Value) Or _      (.Cells(RowCnt, 3).Value <> .Cells(RowCnt - 1, 3).Value)) Then     RetuNum = RetuNum + 1    End If    .Cells(RowCnt, 4).Value = RetuNum    RowCnt = RowCnt + 1   Loop     .Cells.Select   .Sort.SortFields.Clear   .Sort.SortFields.Add2 Key:=Range("A:A"), _     SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal   With .Sort    .SetRange Range("A:D")    .Header = xlGuess    .MatchCase = False    .Orientation = xlTopToBottom    .SortMethod = xlPinYin    .Apply   End With     RowCnt = 2   SheetNum = 1   .Cells(1, 5).Value = SheetNum   Do    If .Cells(RowCnt, 1).Value = "" Then Exit Do    If .Cells(RowCnt, 1).Value <> .Cells(RowCnt - 1, 1).Value Then     SheetNum = SheetNum + 1    End If    .Cells(RowCnt, 5).Value = SheetNum    RowCnt = RowCnt + 1   Loop    End With    RowCnt = 1  Do   If wsWork.Cells(RowCnt, 1).Value = "" Then Exit Do   wsSyuk.Cells(wsWork.Cells(RowCnt, 5).Value + 2, 1).Value = _    wsWork.Cells(RowCnt, 1).Value   wsSyuk.Cells(1, wsWork.Cells(RowCnt, 4).Value + 1).Value = _    wsWork.Cells(RowCnt, 2).Value   wsSyuk.Cells(2, wsWork.Cells(RowCnt, 4).Value + 1).Value = _    wsWork.Cells(RowCnt, 3).Value       wsSyuk.Cells(wsWork.Cells(RowCnt, 5).Value + 2, wsWork.Cells(RowCnt, 4).Value + 1).Value = _   wsSyuk.Cells(wsWork.Cells(RowCnt, 5).Value + 2, wsWork.Cells(RowCnt, 4).Value + 1).Value + 1       RowCnt = RowCnt + 1  Loop End Sub

  • imogasi
  • ベストアンサー率27% (4737/17069)
回答No.1

大きく分けると下記の3つの処理ブロックになろう。 (1)件数カウントの最終作業は、 For Each Sh In Worksheets If Sh.Name <> "集計シート Then 分類カウント処理==>集計シートにカウント計数を書き込み Next で繰り返し処理を行えば、済む。例え100にワークシートがあろうとも。 (2)B列に出てくる、語句と    A列に出てくる、語句の 1つずつの組み合わせを漏らさず、重複せず、組み合わせを100シートについて、 リストする。これがむつかしい(泥臭い作業になりそう) 各行について、A列語句+B列語句を、中間作業列(例C列)で作らせてもらえれば エクセルのフィルタの「重複するレコードは無視する」が、使える。ので楽 だが、どうかな。 この組み合わせを、集計シートの「第2行と第3行」の各列にセットする。 (3)各シートで、集計シートの第2行と第3行の語句の2つを、条件として、 エクセル関数(VBA)のCountifs関数を使って数えればよい。 それを集計シートのSheet(n)の該当行かつ、該当列にセットする。 ==== (1)(3)は多くの人が思いつくだろう。 しかし(2)はA,B列2列の組み合わせ語句で、出現しているものを 掴むのは、やや面倒。ぴったりの機能がエクセルにはないと思う。 1列データなら、前述エクセルのフィルタの「重複するレコードは無視する」が、使える、 と思う(VBAで行う)。 == ピボットテーブルなど思いは及ぶが、自信なし。 ACCESSならSQLが使えるので、やや処理がスッキリするかもしれないと夢想。 ====、 質問の書き方(模擬実例の挙げ方)が、正確さに欠けるように思うし、丸投げで、質問者は自分でどこまで」考えたか見えず、データ例も作るのは大変で、シート数も2-3ではないので、コードを作成して、挙げる気がしないよ。 いつもは、第I回答がすぐ出るのに、まだなのは、その辺もあるのでは。-

関連するQ&A