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

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

excel2003(vba)で御教授御願いします。

    A     B     C 1  番号   名前   タイプ 2  qqq111  Xさん   SA1 3  qqq222  Yさん   SA2 4  aaa111  Xさん   SB1 5  111    Xさん   SC3 6  222    Yさん   SC2 入力情報として上記のような3列からなる情報がエクセルに記入されていたとします。 A1,B1,C1にそれぞれ項目名(列名)があるとします。 番号111と222の人がC列に対して上記のようなタイプを保持しているとき 出力結果として下記の表をVBAにより自動発生させることを実現したいです。     A    B    C    D    E    F    G    H    I 1            SA1   SA2  SB1  SB2   SC1  SC2  SC3 2  番号  名前 3  111   Xさん  ○         ○                  ○ 4  222   Yさん        ○                  ○ ロジックとして、 出力結果のA列は、入力情報のA列の"数字"部分です。 頭三文字:aaa,qqqは省きます。 出力結果のB列は重複している名前を一つにして出力しています。 つまり番号列は数字部分、名前はそのままでそれぞれ重複文を 圧縮して出力します。 さらに、入力タイプ列に書かれた情報通りに○をCからI列のどれかに ○を付けます。 番号と名前は可変するとします。。 また、タイプはSA1からSC3で固定でしてこの中のいづれかに該当するとします。 動作確認を行いOKとなったソースプログラムの記述を御願い致します。 以上長くなりますが、何卒宜しく御教授お願い致します。

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

  • ベストアンサー
  • 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
質問者

お礼

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

関連するQ&A

  • エクセル2003に詳しい方御教授願います。

        A    B    C    D    E    F    G    H    I 1            SA1   SA2  SB1  SB2   SC1  SC2  SC3 2  番号  名前 3  111   Xさん  ○         ○                  ○ 4  222   Yさん        ○                  ○ 上記のような情報がエクセルに記入されていたとします。 A2,B2,C1,D1,E1,F1,G1,H1,I1にそれぞれ項目名(列名)があるとします。 番号111と222の人がC1~I1までの項目に対して上記のように○が付いているとき 下記のようなSQL文(5行)をA5~A9に自動発生させることを実現したいです。 update tablename set type = SA1 where user = qqq111 ; update tablename set type = SB1 where user = aaa111 ; update tablename set type = SC3 where user = 111 ; update tablename set type = SA2 where user = qqq222 ; update tablename set type = SC2 where user = 222 ; 上記5文はそれぞれ左から6項目10項目が可変です。 10項目は、 SAのどれかに○が付いている人は、qqq+番号 SBのどれかに○が付いている人は、aaa+番号 SCのどれかに○が付いている人は、番号 という法則で可変します。 エクセルはまだまだ初心者でして、vbaを使うしかないのかそれとも 何か標準の関数を使えば解決するのかすら検討できません。 以上長くなりますが、何卒宜しく御教授お願い致します。

  • 同一テーブルのカラムの結合による取得

    列A 列B 列C 111 AAA PPP 222 AAA QQQ 333 AAA null 444 AAA null と言うテーブルがあるとして、 列Cがnullのレコードとnullでないレコードを列Bで ジョインし、下記のような結果を取得したいです。 列A 列C 333 PPP 333 QQQ 444 PPP 444 QQQ 今は SELECT X.列A ,Y.列C FROM table X ,table Y WHERE X.列B = Y.列B AND X.列C IS NULL AND Y.列C IS NOT NULL で取得しています。 この同じテーブルであるtableを二つ使わずに 同様の結果を取得するSQLはありますでしょうか。

  • トランジスタの型番について

    古いアンプのトランジスタを交換しようと思います。 そこで分からない事があるのです。右と左は同じ物で付け替えが出来ますか。 後ろのアルファベットで何が変わるのですか。 2SC1775A と 2SC1775A-E 2SB648 と 2SB648-C と 2SB648A-C 2SD668 と 2SD668-C と 2SC668A-C 2SA968 と 2SA968B

  • excelで別シートのセルを選択(VBA)

    どなたか教えてください。 シートXのB1に行番号 シートXのB2に列番号 が記載されていたとして、 別シート(Y)の、上記で指定したセルを選択する(フォーカスを移動する方法)を教えてください。 シート(X)   A   B   C  1 行  25  2 列  2  シート(Y)   A   B   C  1 2   ::::::: 24 25   (ここ) 以下のように書いても、最後の行でエラーになってしまいます。  行番号 = Sheets("X").Cells(1, 2).Value  列番号 = Sheets("X").Cells(2, 2).Value  Sheets("Y").Select  Range(Cells(行番号, 列番号)).Select

  • 条件付きグループ集計

    関数で以下のようなことができるでしょうか。 ピボットテーブル, vbaは使用しない前提でお願いします。 以下のようなDataから、情報を得たいと考えます。 Data 感覚としては、A列がグループ番号, B列が当該グループの参加者の達成率のような感じです。 A B 1 50% 1 70% 1 0% 2 10% 2 35% 3 100% 3 70% 3 20% 入力: x[%] 出力 y1: B列がx[%]以上のレコードが含まれるグループ数 y2: 件数上位1グループの件数占有率 この場合、 x=100なら、出力y1=1, y2=100% x=50なら、出力y1=2, y2=50% x=10なら、出力y1=3, y2=14% となります。 Dataのc列以降に関数等を入力して加工する分には構いません。

  • Excel2003 VBA Functionの定数に関して教えて下さい

    Excel2003 VBA Functionの定数に関して教えて下さい。 例えば、 Function test(x, y) test = A * x + B * y + C End Function という数式を定義し、プログラム中で使用したいとします。 数式を見て分かる通り、xとyは変数でA, B, Cは定数です。 そして、これらA, B, Cの値を A = Cells(3,5) B = Cells(3,6) C = Cells(3,7) のようにシート上の値を使用したいのですが、 上記のようにプログラム中で宣言してもFunctionの中では値が入っていないものとみなされてしまいます。 この問題の回避のため、、 Function test(x, y) A = Cells(3,5) B = Cells(3,6) C = Cells(3,7) test = A * x + B * y + C End Function のようにFunctionの中に、定数を宣言を入れてしまうか、 Function test(x, y, A, B, C) test = A * x + B * y + C End Function のようにA, B, Cも定数ではなく、変数として扱う方法があります。 しかしながら、一つ目の方法では、こういったFunctionの数が増えてくると、 同じ定数を複数の場所で宣言することになり、後からプログラムを書き直そうとしたときに 極めて不便です。 一方で、2つめの方法では、test(x, y, A, B, C)のように、 一つのFunctionを呼び出すためにごちゃごちゃしてスペースをとり、 後から見たときに見にくくなります。 後、Constとして定義する方法もありますが、 A = Cells(3,5) のように、シート上のデータを代入する方法をとりたいと考えています。 上記以外の方法以外でもっとスマートな方法がありましたら 教えて頂けますでしょうか?

  • 図心を求める

    この図形の図心の求め方がわからないです!!! (a) y=x+2a (b) y=-x+a 面積 Sa:2a^2 Sb:a^2/2

  • EXCEL VBA 別シートで検索後、貼り付け

    excel2010 (ブック名A.xlsx)にシート名SA、シート名SBがあります。 シート名SAのC列に検索対象(C1~C50位)があり シート名SBのB列が検索範囲(流動的ですがB1~B100位の範囲)です。 検索対象は文字列で、これが検索範囲のセルにに含まれていた場合 検索範囲の隣のセルCxxに検索対象文字列をコピー&ペーストしたいです また、検索範囲の行数に値があるまで、順次処理をしていきたいです

  • EXCEL関数について質問です

    EXCELで同窓会旅行用の名簿を作っているのですが、下記のような動きをするEXCEL関数って作ることができますか? 具体的な方法を教えていただけると嬉しいのですが。。。 ・シート Sheet1に名簿一覧がある(例:A列は名前一覧、B列は部屋番号の空欄) Sheet2に部屋番号一覧がある(例:A列は部屋番号一覧、B,C,D列は名前の空欄) ・動き Sheet2のB,C,D列の名前の空欄に名前を入れていくと、 Sheet1の名簿の名前に対応した部屋番号がB列に自動で挿入される 万が一、Sheet2のB,C列(名前欄)で名前が重複してあった際には Sheet1の名簿に対応したB列に「エラー」と表示される ※Sheet1の名簿の名前(A列)は既に記入済みです。 ※Sheet2に部屋番号(A列)は既に記入済みです。 以上、お手数ですがよろしくお願いいたします。

  • Excel2003VBA offsetの考え方

    たとえば、 A1にカーソルがあってActiveCell.Offset(0,1)であればB1を表示することになると思うのですが、なぜ、このオフセットは、先に行で次が列なのでしょうか? たとえば、数学ですとグラフの座標は(x軸,y軸)となっている方がわかりやすいと思うのですが、合理的な考え方があればお教えください。

専門家に質問してみよう