[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]
『クロス集計の逆の表を作る方法』(Y)
皆様のお知恵を貸してください。
膨大なデータを縦横で整理するときには、数字の集計の場合はピボットテーブルを使えばいろいろできると思いますが、文字列をそのまま表に残したい場合どうすればいいのか、教えてください。
具体的には、例えば、元データが
入社 ポジション 氏名
2011 係長 A
2011 係長 B
2012 課長 C
2012 係長 D
2012 課長 E
というデータだったとします。このとき、完成形を
縦軸に入社、横軸にポジション、中身は氏名という風にしてつくりたいです。
イメージは、
課長 係長
2011 A
2011 B
2012 C
2012 E
2012 D
もっと言うと
課長 係長
このように変換する良い方法はありませんでしょうか?
基本的なことで恐縮ですが、ご教示いただきたいです。
よろしくお願いします。
< 使用 Excel:Excel2019、使用 OS:Windows10 >
おはようございます ^^ いろいろ、方法は有ると思いますが。。。 VBAでしたら 1.作業シートへコピー後、年度で昇順並び替え(並んでたら良いのですが念のため) 2.上から順にポジション別の配列に各ポジションに該当すればお名前を格納していく 3.年度が変わるタイミングで、連想配列等にでも年度と配列を格納、使用配列の初期化 上記を最後まで繰り返す。 4.作った連想配列から年度、各ポジションの配列を取り出し、所定のセルに書き出す とかでも出来なくはないかと。wややこしそぉ。。← 多分。。。自信ありません。。。^^; でわ。。。m(_ _)m (隠居じーさん) 2020/05/15(金) 09:09
手作業だと、こんな感じでできそうです。
1)ピボットで個数をカウント
2)ピボットを値に変換
3)個数を数式で氏名に置換
4)年毎に、氏名を上に詰める
5)不要行、列を削除
それをマクロにすると
Option Explicit
Sub test() Dim ws As Worksheet Dim tbl As Range Dim pvt As PivotTable Dim pvf As PivotField Dim a As Range Dim r As Range Dim k As Long Dim v
Set ws = ActiveSheet Set tbl = ws.Cells(1).CurrentRegion
With ws.Parent.PivotCaches.Create(xlDatabase, tbl).CreatePivotTable("") .RowAxisLayout xlTabularRow .ColumnGrand = False .RowGrand = False For Each pvf In .PivotFields pvf.Subtotals(1) = False Next .AddDataField .PivotFields("氏名"), , xlCount .AddFields Array("入社", "氏名"), "ポジション"
.TableRange1.Copy .TableRange1.PasteSpecial xlPasteValues End With
Set tbl = Cells(1).Cells(1).CurrentRegion With Intersect(tbl, tbl.Offset(2, 2)) .SpecialCells(xlCellTypeConstants).FormulaR1C1 = "=rc2" .Value = .Value End With
For Each a In Cells(1).CurrentRegion.Columns(1).SpecialCells(xlCellTypeBlanks).Areas For k = 3 To tbl.Columns.Count With a.Resize(a.Count + 1).Offset(-1, k - 1) If WorksheetFunction.CountA(.Cells) > 0 Then v = WorksheetFunction.Transpose(.Value) v = Split(WorksheetFunction.Trim(Join(v))) .ClearContents .Resize(UBound(v) + 1).Value = WorksheetFunction.Transpose(v) End If End With Next
For Each r In Intersect(tbl, a.EntireRow).Rows If WorksheetFunction.CountIf(r, "<>") < 2 Then r.Delete xlShiftUp End If Next Next
Rows(1).Delete Columns(2).Delete
End Sub
(マナ) 2020/05/15(金) 12:37
おはようございます ^^ 既に、ご案内のようですが。。。作ってみましたので。。。 汗顔の至りですが。。。m(_ _)m Option Explicit Sub OneInstanceM1() Const zProgramID As String = "zBase09.xlsm" Dim zTb As Workbook Dim i As Long Dim j As Long Dim k As Long Dim n As Long Dim zKcnt() As Long Dim zBase() As Variant Dim 課長() As Variant Dim 係長() As Variant Dim zD As Object Dim zVar As Variant Set zD = CreateObject("Scripting.Dictionary") Set zTb = Workbooks(zProgramID) zTb.Worksheets("Sheet1").Copy zTb.Worksheets(1) With zTb.ActiveSheet .Cells(1).CurrentRegion.Sort Key1:=.Columns(1), Order1:=xlAscending, Header:=xlYes zBase = .Cells(1).CurrentRegion.Offset(1).Value End With Application.DisplayAlerts = False zTb.ActiveSheet.Delete Application.DisplayAlerts = True ReDim 課長(0), 係長(0) For i = 1 To UBound(zBase, 1) - 1 If zBase(i, 2) = "課長" Then ReDim Preserve 課長(j) 課長(j) = zBase(i, 3) j = j + 1 End If If zBase(i, 2) = "係長" Then ReDim Preserve 係長(k) 係長(k) = zBase(i, 3) k = k + 1 End If If zBase(i, 1) <> zBase(i + 1, 1) Then zD(n) = Array(zBase(i, 1), 課長, 係長) n = n + 1 ReDim 課長(0), 係長(0) j = 0 k = 0 End If Next With zTb.Worksheets("Sheet2") .UsedRange.Clear i = 2: k = 1: n = 0 .Cells(1).Resize(, 3) = Array("年度", "課長", "係長") For Each zVar In zD For j = 0 To 2 If j > 0 Then ReDim Preserve zKcnt(n) zKcnt(n) = UBound(zD(zVar)(j)) n = n + 1 .Cells(i, k + j).Resize(UBound(zD(zVar)(j)) + 1, 1) = Application.Transpose(zD(zVar)(j)) If j = 2 Then i = i + WorksheetFunction.Max(zKcnt) + 1 Erase zKcnt n = 0 End If Else .Cells(i, 1) = zD(zVar)(j) End If Next Next .UsedRange.Columns.AutoFit .Activate End With Erase zBase, 課長, 係長, zKcnt Set zD = Nothing Set zTb = Nothing End Sub (隠居じーさん) 2020/05/16(土) 09:32
おはようございます。 ちょっと書いてみました。。 一応、、部長さんもいらっしゃるかなと思って↓みたいなデータがあったとしたら
入社 ポジション 氏名 2011 係長 A 2011 係長 B 2012 課長 C 2012 係長 D 2012 課長 E 2013 部長 q
こんな感じになりました。。ちょっと順番が逆ですけど。。出現順ですね(^^;
係長 課長 部長 2011 A B 2012 D C E 2013 q
Option Explicit Sub てすと() Dim MyA As Variant Dim v As Variant Dim x As Variant Dim MyP() As Variant Dim i As Long Dim n As Long Dim k As Long MyA = Sheets("Sheet1").Range("A1").CurrentRegion.Resize(, 3).Value ReDim MyP(0) For i = LBound(MyA, 1) + 1 To UBound(MyA, 1) x = Application.Match(MyA(i, 2), MyP, 0) If IsError(x) Then ReDim Preserve MyP(n) MyP(n) = MyA(i, 2) n = n + 1 End If Next ReDim v(1 To UBound(MyA, 1), 1 To UBound(MyP) + 2) k = 1 For i = LBound(MyP) To UBound(MyP) v(k, i + 2) = MyP(i) Next For i = LBound(MyA, 1) + 1 To UBound(MyA, 1) If UBound(Filter(Application.Transpose(Application.Index(v, 0, 1)), MyA(i, 1), True)) Then k = k + 1 v(k, 1) = MyA(i, 1) x = Application.Match(MyA(i, 2), MyP, 0) If Not IsError(x) Then v(k, x + 1) = MyA(i, 3) End If Else x = Application.Match(MyA(i, 2), MyP, 0) If Not IsError(x) Then If Not IsEmpty(v(k, x + 1)) Then k = k + 1 v(k, x + 1) = MyA(i, 3) End If End If Next With Sheets("Sheet2") .Cells.Clear .Range("A1").Resize(k, UBound(v, 2)).Value = v End With Erase MyA, v, MyP End Sub MyYは使ってませんでした。。。m(__)m (SoulMan) 2020/05/16(土) 10:56
[ 一覧(最新更新順) ]
YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki.
Modified by kazu.