• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:excel2003(vba)で御教授御願いします。)

Excel2003(VBA)でタイプ別表を自動発生させる方法

このQ&Aのポイント
  • Excel2003(VBA)を使用して、入力情報に基づいてタイプ別の表を自動生成する方法を解説します。
  • 入力情報は3列で構成され、A列には番号、B列には名前、C列にはタイプが記入されています。
  • この情報を元に、出力結果の表を生成し、タイプに該当する箇所に○を付けることができます。

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

  • ベストアンサー
  • cj_mover
  • ベストアンサー率76% (292/381)
回答No.2

[番号]は[名前]に対する一意なID、ということなのだとして。 Option Explicit ' ' 参照設定:  Microsoft Scripting Runtime ' ' 参照設定した場合は【a/2択】に代えて【b/2択】をイキ ' ' シート名、セル範囲の指定は、適切に。 Sub Re8111840()   Const タイプ = "SA1,SA2,SB1,SB2,SC1,SC2,SC3"   Dim mtxS() ' 元データ 二次元配列   Dim mtxP() ' 出力用二次元配列   Dim arrT() As String ' タイプ配列   Dim oDictType As Object ' 【a/2択】 '  Dim oDictType As Scripting.Dictionary ' 【b/2択】   Dim oDictID As Object ' 【a/2択】 '  Dim oDictID As Scripting.Dictionary ' 【b/2択】   Dim tnR As Long ' レコード数   Dim tnF As Long ' 出力先フィールド数   Dim cnt As Long ' 出力先レコード数   Dim nID As Long ' 文字列を除いた番号   Dim i As Long ' ' タイプTable作成   arrT = Split(タイプ, ",")   tnF = UBound(arrT) + 3   Set oDictType = CreateObject("Scripting.Dictionary") ' 【a/2択】 '  Set oDictType = New Scripting.Dictionary ' 【b/2択】   For i = 3 To tnF     oDictType(arrT(i - 3)) = i   Next i ' ' 元データを二次元配列で取得   With Sheets("Sheet1")     mtxS() = .Range("A2:C" & .Cells(2, 1).End(xlDown).Row).Value   End With   tnR = UBound(mtxS) ' ' 出力用配列サイズを不足がないサイズで大き目に再定義   ReDim mtxP(1 To tnR, 1 To tnF)   Set oDictID = CreateObject("Scripting.Dictionary") ' 【a/2択】 '  Set oDictID = New Scripting.Dictionary ' 【b/2択】 ' ' oDictIDはIDに応じた出力用配列(mtxP)の行位置(Y座標)を ' ' oDictTypeは元データ3列目[タイプ]に応じた出力用配列(mtxP)の列位置(X座標)を   For i = 1 To tnR     nID = PickUpNum(mtxS(i, 1))     If nID Then       If oDictID.Exists(nID) Then         mtxP(oDictID(nID), oDictType(mtxS(i, 3))) = "○"       Else         cnt = cnt + 1         oDictID(nID) = cnt         mtxP(cnt, 1) = nID         mtxP(cnt, 2) = mtxS(i, 2)         mtxP(cnt, oDictType(mtxS(i, 3))) = "○"       End If            End If   Next i   Set oDictType = Nothing:  Set oDictID = Nothing   Erase mtxS()   With Sheets("Sheet2")     .Cells(3, 1).Resize(cnt, tnF).Value = mtxP()     .Range("A2:B2").Value = Array("番号", "名前")     .Cells(1, 3).Resize(, tnF - 2).Value = arrT   End With   Erase arrT, mtxP() End Sub Private Function PickUpNum(ByVal S As String) As Long   Dim i As Long   For i = 1 To Len(S)     If IsNumeric(Mid$(S, i)) Then       PickUpNum = Val(Mid$(S, i))       Exit For     End If   Next i End Function

その他の回答 (1)

  • tom04
  • ベストアンサー率49% (2537/5117)
回答No.1

こんにちは! 一例です。 Sheet1のデータをSheet2に表示するようにしてみました。 Sheet2の1行目の項目、2行目の「番号」・「名前」は入力済みだとします。 標準モジュールに↓のコードをコピー&ペーストしてマクロを実行してみてください。 Sub Sample1() Dim i As Long, j As Long, k As Long, c As Range, wS1 As Worksheet, wS2 As Worksheet, myFlg As Boolean Set wS1 = Worksheets("Sheet1") Set wS2 = Worksheets("Sheet2") Application.ScreenUpdating = False i = wS2.Cells(Rows.Count, 1).End(xlUp).Row If i > 2 Then Range(wS2.Cells(3, "A"), wS2.Cells(i, "I")).ClearContents End If For i = 2 To wS1.Cells(Rows.Count, 1).End(xlUp).Row myFlg = False For k = 1 To Len(wS1.Cells(i, 1)) If Mid(wS1.Cells(i, 1), k, 1) Like "[a-z A-Z]" Then myFlg = True Exit For End If Next k If myFlg = False Then Set c = wS2.Range("A:A").Find(what:=wS1.Cells(i, 1), LookIn:=xlValues, lookat:=xlWhole) If c Is Nothing Then wS1.Cells(i, 1).Resize(1, 2).Copy wS2.Cells(Rows.Count, 1).End(xlUp).Offset(1) End If End If Next i For k = 3 To wS2.Cells(Rows.Count, 1).End(xlUp).Row For i = 2 To wS1.Cells(Rows.Count, 1).End(xlUp).Row If InStr(wS1.Cells(i, 1), wS2.Cells(k, 1)) > 0 Then j = WorksheetFunction.Match(wS1.Cells(i, 3), wS2.Range("1:1"), False) wS2.Cells(k, j) = "○" End If Next i Next k Application.ScreenUpdating = True End Sub ※ Sheet1のC列データは同番号が含まれている人に重複はない!とします。 こんなんではどうでしょうか?m(_ _)m

torajiro123
質問者

お礼

ありがとうございます。 ご丁寧な回答感謝します。