前提・実現したいこと
スケジュールと出勤簿をひとつにまとめたいです。
予定表(スケジュール)は日付毎、人毎の表になっております。
日報(出勤簿)はデータです。
日報はピポッドテーブルにて集計表を作成しております。
予定表と日報の日付と氏名は実際はまったく同じではありません。
予定表の方が多かったり、日報の方が多かったりと一部もしくは全部一致します。
略号は分かりやすく「aa」のみにしておりますが本当は複数あります。
発生している問題・エラーメッセージ
図のようにシート"結合"に予定表と日報を人毎(予定表の順番で)に横に並べて表示させたいです。
予定表の氏名順と同じようにピポッドテーブルの氏名順番を変更させる方法がありましたら、教えて頂けないでしょうか
宜しくお願いいたします
該当のソースコード
Private Sub CommandButton3_Click() Dim DataS As Worksheet Dim ws As Worksheet Dim pvc As PivotCache Dim pvt As PivotTable Set ws = Sheets.Add ActiveSheet.Name = "ピボットテーブル" Set DataS = ThisWorkbook.Worksheets("日報") Set pvc = ActiveWorkbook.PivotCaches.Create( _ SourceType:=xlDatabase, _ SourceData:=DataS.Range("A:K"), _ Version:=xlPivotTableVersion15) Set pvt = pvc.CreatePivotTable( _ TableDestination:=ws.Name & "!R3C1", _ TableName:="ピボットテーブル1", _ DefaultVersion:=xlPivotTableVersion15) With pvt.PivotFields("略号") .Orientation = xlRowField .Position = 1 End With With pvt.PivotFields("日付") .Orientation = xlRowField .Position = 2 End With With pvt.PivotFields("氏名") .Orientation = xlColumnField .Position = 1 End With pvt.AddDataField pvt.PivotFields("執務時間"), "合計 / 執務時間", xlSum End Sub
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/03/17 06:37
回答4件
0
ベストアンサー
難儀されてますね。
無理難題の要求に付き合わされて、心中お察しします。
多分完成するまでにこのプロジェクトは無かったことになりそうな気がしますが。。。
予定の入力(クロス集計表形式)
(提示の形でもいいですが、めんどくさかったのでリスト形式を先に作って
サンプル用にピボットテーブルでクロス集計表を作りました。
逆も出来る機能があれば便利なんですけどね^^;自作するのもそんな大した労力は要らないですが)
これを一旦リスト形式にします。
予定のリストと実施のリストを統合します。(別途区分を追加します)
これをコピーしてリンク貼り付けします
で数式を、数式バーのような式に直します。
必要な個所にドラッグ
並べ替えは、仕様書に基づいて順番に見て行って、
一つ目は、織田なので、織田を1列目へ
二つ目は、徳川だけど、ないのでパス
三つ目は、豊臣だから、豊臣を3列目へ
四つ目は、斉藤なので、斉藤を5列目へ
と移動すればいいですよね?
移動のコードは、マクロの記録で分かると思うので、
まずは手動でドラッグして記録してみましょう。
これらの作業をマクロで自動化すればいいかなと思います。
もちろん、細かい微調整もありますが。
んと、慣れないと見難いのはわかりますが、
人に合わせてプログラムを作ることは可能ですが、
難易度が高くなります。
エクセルを使うのが前提条件なら、人がエクセルに合わせてやることもしないと、
開発に時間が掛かるばかりで運用が出来ませんよ。
ましてや、本職で無く素人が勉強しながら作るのですから数か月から1年以上かかるかも知れないのは、
覚悟するべきです。
その時間の給料が払えるなら、10万円くらいで委託できたりしないですかねぇ。。。相場は知らないですが、
(1行1000円でしたっけ?)
フリーランスとか頼めば割と安くできるし、動作確認も含め、1ヶ月もあれば完成するのでは?
投稿2020/04/07 08:12
総合スコア2163
0
結合とピボットテーブル二つ要望がありますが、
ピボットテーブルを自身で定義した順番でソートする方法です。
定義順をユーザー設定リストに登録してそれを利用すれば任意の順番に並び変えることができます。
このソースでは予定表の2行目の名前順を取得しユーザー設定リストに登録しています。
またユーザー設定リストはブックではなくシステムで管理されているので
ゴミが残るのを防止するためソート後に削除しています。
vba
1Sub CommandButton3_Click() 2 3・・・ 4 Dim pEndColumn As Long 5 Dim SortData As Variant 6・・・ 7 8 pvt.AddDataField pvt.PivotFields("執務時間"), "合計 / 執務時間", xlSum 9 10 With ThisWorkbook.Worksheets("予定表") 11 pEndColumn = .Cells(2, .Columns.Count).End(xlToLeft).Column 12 '予定2行目の氏名順をリストで取得する 13 SortData = .Range(.Cells(2, 2), .Cells(2, pEndColumn)) 14 End With 15 16 '取得したリストをユーザー設定リストに登録 17 Application.AddCustomList ListArray:=SortData 18 19 'ユーザー設定リスト登録位置を取得 20 ocNum = Application.GetCustomListNum(SortData) 21 22 '登録したユーザー設定リストでピボットテーブルをソート 23 ActiveSheet.Range("$B$4").Sort Order1:=xlAscending, Type:=xlSortLabels, _ 24 OrderCustom:=ocNum + 1, Orientation:=xlLeftToRight, SortMethod:=xlStroke 25 26 'ユーザー設定リストを削除 27 Application.DeleteCustomList ListNum:=ocNum 28 29End Sub
追記
書いてしまってからなんですが少し不安定な方法のようです。
ユーザー設定リストを削除する前にブックを保存しておくと落ちるのは防げます。
ただソートする時に保存されてしまうのでそこの動作に関してはご了承ください。
end-u様の教えてくださった方法でブック保存時の不具合の問題は解決しました。
VBA
1 Application.DisplayAlerts = False 2 3 With ThisWorkbook.Worksheets("予定表") 4 pEndColumn = .Cells(2, .Columns.Count).End(xlToLeft).Column 5 '予定2行目の氏名順をリストで取得する 6 SortData = .Range(.Cells(2, 2), .Cells(2, pEndColumn)) 7 End With 8 9 '取得したリストをユーザー設定リストに登録 10 Application.AddCustomList ListArray:=SortData 11 12 'ユーザー設定リスト登録位置を取得 13 ocNum = Application.GetCustomListNum(SortData) 14 15 '登録したユーザー設定リストでピボットテーブルをソート 16 ThisWorkbook.Worksheets("ピボットテーブル").Range("$B$4").Sort Order1:=xlAscending, Type:=xlSortLabels, _ 17 OrderCustom:=ocNum + 1, Orientation:=xlLeftToRight, SortMethod:=xlStroke 18 19 'ピボットテーブルに設定されているソート条件のクリア 20 ThisWorkbook.Worksheets("ピボットテーブル").Sort.SortFields.Clear 21 22 'ユーザー設定リストを削除 23 Application.DeleteCustomList ocNum 24 25 Application.DisplayAlerts = True
投稿2020/03/31 04:25
編集2020/04/02 01:09総合スコア2183
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/04/01 05:36
2020/04/01 07:39
2020/04/01 12:37
2020/04/02 01:09
2020/04/02 03:49
2020/04/02 03:55
0
予定表と日報の日付と氏名は実際はまったく同じではありません。
予定表の方が多かったり、日報の方が多かったりと一部もしくは全部一致します。
まずは、この状態をなんとかしましょう
でないとまとまるものもまとまりません
どちらかというと、「予定表」をベースとしたほうが後の処理がラクです
最低限、「予定表」と「日報」の氏名は揃えましょう
日付は、入力がない場合でも「予定表」に組み込む事は簡単にできますよね
その整理ができた前提での提案です
1.「日報」から氏名と日付をキーにしてピボットテーブルを作成する
2.「予定表」をコピー、加工して、1で作成したピボットテーブルを参照する数式を入れる
具体的には
1.のピボットテーブルを作成すると図1のようになります
(図1)
2.の「予定表」をコピー、加工というのは、図2のように氏名の後ろに列を挿入します
(図2)
その後 C3セルに数式を入れます =のあとに図3のように1で作成したピボットテーブルの該当データを選択すると
=GETPIVOTDATA("執務時間",Sheet1!$A$3,"日付",DATE(2020,3,1),"氏名","織田")
のように式が入ります
(図3)
=GETPIVOTDATA("執務時間",Sheet1!$A$3,"日付",$A3,"氏名",B$2)
日付は列固定で $A3
氏名は行固定で B$2
修正後の式を下方向と各氏名の後に挿入した列にコピーすると良いです
必要に応じて要所要所をマクロ化すれば良いでしょう
(追記)
ぁ一応、逆に日報ベースの別案も作ってはいましたけどね
ピボットをベースに予定表の内容がMatchするものをひっぱってくる感じ。
提示のレイアウト限定ではありますが
VBA
1Sub test() 2 Dim r As Range 3 Dim d As Range 4 Dim dd As Range 5 Dim cc As Range 6 Dim rr As Range 7 8 With Sheets("日報") 9 'PivotTableのSourceData 10 Set r = .Range("K1", .Cells(.Rows.Count, 4).End(xlUp).Offset(, -3)) 11 End With 12 13 'とりあえず新規Sheetに集計してみる 14 With ActiveWorkbook.PivotCaches.Add(SourceType:=xlDatabase, _ 15 SourceData:=r).CreatePivotTable("") 16 .PivotFields("日付").Orientation = xlRowField 17 .PivotFields("氏名").Orientation = xlColumnField 18 '"略号"の集計はダミー。後で数式セット 19 .AddDataField .PivotFields("略号"), "略号&場所", xlCount 20 .AddDataField .PivotFields("執務時間"), "執務時間計", xlSum 21 .DataPivotField.Orientation = xlColumnField 22 .ColumnGrand = False 23 .RowGrand = False 24 .RowAxisLayout xlTabularRow 25 '"略号&場所"の範囲取得 26 .PivotSelect "'略号&場所'", xlDataOnly 27 Set d = Selection 28 .TableRange2.Copy 29 'PivotTableを解除 30 .TableRange2.PasteSpecial xlPasteValues 31 End With 32 Application.CutCopyMode = False 33 34 '数式の参照先アドレスget 35 With Sheets("予定表") 36 Set r = .Range("A2").CurrentRegion 37 Set dd = .Range("B3", r(r.Count)) 38 End With 39 Set cc = dd.Resize(1).Offset(-1) 40 Set rr = dd.Resize(, 1).Offset(, -1) 41 42 '数式文字列設定 =INDEX(dd,MATCH($A4,rr,0),MATCH(B$2,cc,0))&"" 43 Dim s(2) As String 44 s(0) = "=index(" & dd.Address(, , , True) 45 s(1) = "match($A4," & rr.Address(, , , True) & ",0)" 46 s(2) = "match(B$2," & cc.Address(, , , True) & ",0))&""""" 47 d.Formula = Join(s, ",") 48 '数式の値化が必要であれば以下コメント活かす 49 'For Each r In d.Areas 50 ' r.Value = r.Value 51 'Next 52End Sub
(2020.04.02追加)
..なんか自分でも納得いかないコードですが..
すみません、「こんなアプローチもあります」的なサンプル扱いでお願いします
VBA
1Sub test2() 2 Dim r As Range 3 Dim d As Range 4 Dim dd As Range 5 Dim cc As Range 6 Dim rr As Range 7 Dim x As Long 8 Dim i As Long 9 Dim j As Long 10 Dim k As Long 11 12 '予定表の範囲を取得 13 With Sheets("予定表") 14 Set r = .Range("A2").CurrentRegion 15 Set dd = .Range("B3", r(r.Count)) 16 End With 17 Set cc = dd.Resize(1).Offset(-1) 18 Set rr = dd.Resize(, 1).Offset(, -1) 19 20 Dim pt As PivotTable 21 Dim st As String 22 Dim ws As Worksheet 23 Set ws = Sheets.Add 24 25 With Sheets("日報") 26 x = .Cells(.Rows.Count, 10).End(xlUp).Row 27 k = x + 1 '最後のデータクリアで使う 28 29 '日報から氏名、日付、略号場所キーでピボット作成 _ 30 後で日報ベースの予定|実績の実績データ追加で使う 31 Set r = .Range("A1", .Cells(x, "L")) 32 r.Columns("L").Formula = "=B1&H1" 33 st = .Range("L1").Value 34 Set pt = ActiveWorkbook.PivotCaches.Add( _ 35 SourceType:=xlDatabase, _ 36 SourceData:=r) _ 37 .CreatePivotTable(ws.Range("A1")) 38 pt.ColumnGrand = False 39 pt.RowGrand = False 40 pt.RowAxisLayout xlTabularRow 41 With pt.PivotFields("氏名") 42 .Orientation = xlRowField 43 .Subtotals(1) = False 44 End With 45 With pt.PivotFields("日付") 46 .Orientation = xlRowField 47 .Subtotals(1) = False 48 End With 49 pt.PivotFields(st).Orientation = xlRowField 50 pt.AddDataField pt.PivotFields("執務時間"), "執務時間計", xlSum 51 '予定表の氏名と日付を日報に追加 52 x = x + 1 53 For i = 1 To rr.Count 54 For j = 1 To cc.Count 55 If dd(i, j).Value <> "" Then 56 .Cells(x, "D").Value = rr(i).Value 57 .Cells(x, "J").Value = cc(j).Value 58 x = x + 1 59 End If 60 Next 61 Next 62 Set r = .Range("A1", .Cells(x - 1, "L")) 63 End With 64 'ピボット利用して「結合」シート作成 65 Dim ws2 As Worksheet 66 Set ws2 = Sheets.Add 67 With ActiveWorkbook.PivotCaches.Add( _ 68 SourceType:=xlDatabase, _ 69 SourceData:=r) _ 70 .CreatePivotTable(ws2.Range("A1")) 71 .ColumnGrand = False 72 .RowGrand = False 73 .RowAxisLayout xlTabularRow 74 .PivotFields("日付").Orientation = xlRowField 75 .PivotFields("氏名").Orientation = xlColumnField 76 .AddDataField .PivotFields("略号"), "予定|実績", xlCount 77 .AddDataField .PivotFields("執務時間"), "執務時間計", xlSum 78 .DataPivotField.Orientation = xlColumnField 79 '"予定|実績"の範囲取得 80 .PivotSelect "予定|実績", xlDataOnly 81 Set d = Selection 82 'PivotTableを解除 83 .TableRange2.Copy 84 .TableRange2.PasteSpecial xlPasteValues 85 End With 86 Application.CutCopyMode = False 87 88 '予定表から予定|実績データ追加 _ 89 数式文字列設定 =INDEX(dd,MATCH($A4,rr,0),MATCH(B$2,cc,0))&"" 90 Dim s(2) As String 91 s(0) = "=index(" & dd.Address(, , , True) 92 s(1) = "match($A4," & rr.Address(, , , True) & ",0)" 93 s(2) = "match(B$2," & cc.Address(, , , True) & ",0))&""""" 94 d.Formula = Join(s, ",") 95 96 '日報ベースの予定|実績の実績データ追加 97 Dim r1 As Range 98 Dim r2 As Range 99 Dim y 100 ws.Activate 101 Set rr = d.Areas(1).Offset(, -1) 102 For Each r1 In d.Areas 103 r1.Value = r1.Value 104 pt.PivotSelect r1(1).Offset(-2).Value, xlLabelOnly 105 For Each r2 In Selection.Offset(, 1) 106 y = Application.Match(CLng(r2.Value), rr, 0) 107 If IsNumeric(y) Then 108 r1(y).Value = CStr(r1(y).Value) & "|" & r2.Offset(, 1).Value 109 End If 110 Next 111 Next 112 '追加したダミーデータと作業用Sheetをクリア 113 r.Columns("L").ClearContents 114 Range(r(k, 1), r(r.Count)).ClearContents 115 Application.DisplayAlerts = False 116 ws.Delete 117 Application.DisplayAlerts = True 118End Sub
投稿2020/03/26 05:22
編集2020/04/03 10:39総合スコア52
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/03/27 02:12
2020/03/27 04:22
2020/03/27 05:19
2020/04/02 03:39
2020/04/02 14:25
2020/04/03 07:03
2020/04/03 10:35
2020/04/07 04:04
2020/04/07 04:57
0
したいことは、「結合」っていうシートを作ることですよね?
どこまでができていて、どこができていないのかが正直十分に理解できていません。
ピポットテーブルは質問に関する情報を何か持っていますか?
現時点で読んだ限り、まず大枠から考えると、「予定表」をベースにし、
「日報」の中の「日付」と「氏名」が該当する行の「略号」と「場所」と「執務時間」を当てはめればいいのかなと思いました。
まず、VBAとかは置いておいて、一般的なアルゴリズム的に結合したいということは、
1.まずは、「予定表」と「日報」シートから表のデータを取ってくる。
2.「日報」で、主キーを決める。主キー(複合キー)は、◎列と〇列と△列を決めればどこか一つの行に必ず決まるという項目です。(ここでは、「日付」と「氏名」のはず)
3.「日報」を1行ずつ見て、主キーの組み合わせになる場所を「予定表」から探す。
4.そこに「略号」と「場所」と「執務時間」を入れる。
これを「日報」すべての行に実施すると、求めたい表のデータは形成できると思います。
それをVBAのプログラムに落とし込めば、あとは表示するときの微調整だけで済みます。
なので、そのソースコードを作ってみましょう。
※質問内容が十分に読み取れていないかもしれません、回答内容が見当違いであればすみません
投稿2020/03/25 13:55
総合スコア346
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。