🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

マクロ

定義された処理手続きに応じて、どのような一連の処理を行うのかを特定させるルールをマクロと呼びます。

Q&A

解決済

4回答

1408閲覧

データを表かするにあたり

ichigo15

総合スコア14

VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

マクロ

定義された処理手続きに応じて、どのような一連の処理を行うのかを特定させるルールをマクロと呼びます。

0グッド

1クリップ

投稿2019/12/18 05:51

編集2019/12/20 03:30

前提・実現したいこと

シート名「結果」にA~K列までデータがあります。
これをシート名「仕様書」の順番に基づいて「表」に表として表示させたいです。

どこが原因か教えていただけますでしょうか。
よろしくお願いいたします。

発生している問題・エラーメッセージ

①シート名「表」に表が作成されずシート名「結果(2)」として作成されてしまう
②シート名「仕様書」の順番に基づいて並び替えられない。

該当のソースコード

①のコード

Sub

1 Dim i As Long 2 Dim j As Long 3 Dim k As Long 4 Dim Cnt As Long 5 Dim lr As Long 6 Dim Aary() As Variant 7 Dim Mary() As Variant 8 Dim Dm As Object 9 Dim Mm As Object 10 Dim Var As Variant 11 Dim Base As Variant 12 13 14 15 Set Dm = CreateObject("Scripting.Dictionary") 16 Set Mm = CreateObject("Scripting.Dictionary") 17 With Worksheets("結果") 18 lr = .Cells(.Rows.Count, 4).End(xlUp).Row 19 Base = Intersect(.Range("D:K"), .Range(.Rows(2), .Rows(lr))) 20 .Copy Worksheets(1) 21 End With 22 For i = 1 To UBound(Base, 1) 23 Dm(Base(i, 1)) = Empty 24 Mm(Base(i, 7)) = Empty 25 Next 26 Mary = Mm.keys 27 ReDim Aary(1 To Dm.Count, 1 To Mm.Count + 1) 28 For i = 1 To UBound(Base, 1) 29 For Each Var In Dm 30 Cnt = Cnt + 1 31 If Var = Base(i, 1) Then 32 Aary(Cnt, 1) = Var 33 For k = 0 To UBound(Mary) 34 If Base(i, 7) = Mary(k) Then 35 Aary(Cnt, k + 2) = Aary(Cnt, k + 2) & Base(i, 5) & Base(i, 8) & " " 36 End If 37 Next 38 End If 39 Next 40 Cnt = 0 41 Next 42 With ActiveSheet 43 .UsedRange.Clear 44 .Cells(1, 2).Resize(, UBound(Mary) + 1) = Mary 45 .Cells(2, 1).Resize(UBound(Aary, 1), UBound(Aary, 2)) = Aary 46 .UsedRange.EntireColumn.AutoFit 47 .UsedRange.Borders.LineStyle = xlContinuous 48 .Range("A:A").SpecialCells(2).NumberFormatLocal = "yyyy/mm/dd" 49 End With 50 Set Dm = Nothing 51 Set Mm = Nothing 52 Erase Base, Aary, Mary 53End Sub``` 54 55

②のコード

Sub

1 2Dim 仕様書, Rx As Long 3 4 With Sheets("仕様書") 5 仕様書 = .Range("B4:D" & .Cells(.Rows.Count, "B").End(xlUp).Row).Value 6 End With 7 8 With Sheets("表") 9 For Rx = LBound(仕様書) To UBound(仕様書) 10 .Columns(仕様書(Rx, 1) + 2).Copy Destination:=Sheets("表").Columns(仕様書(Rx, 3) + 2) 11 Next 12 End With 13 14End Sub

該当のイメージ図

◆結果

イメージ説明

◆表

イメージ説明

◆仕様書

イメージ説明

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

meg_

2019/12/18 06:22

1行ずつ実行していけば原因が分かるかと思いますが、デバッグしてみましたか?
ichigo15

2019/12/18 06:41

デバックはしてみましたが知識が低いため黄色のラインが移動しても よく分かりません。 こつ等はありますでしょうか。
meg_

2019/12/18 08:11

①については結果シートをコードのどこかで「シートのコピー」をしているはずです。デバッグしながら、ブックにシートが増えていないか観察してください。
tatsu99

2019/12/18 12:16

結果、仕様書、表の3つのシートのレイアウトを画像で提示していただけませんでしょうか。
Y.H.

2019/12/19 06:24

> シート名「表」 シート名「結果」をコピーしただけで、コードのどこにもシート名を「表」に変更していないですね。
tatsu99

2019/12/19 11:33

シート名:仕様書の画像が提示されていません。(仕様書の代わりに結果の画像が提示されています)
tatsu99

2019/12/19 11:34

表のシート名が「売上表」になっていますが、どちらが正しいのですか?
ichigo15

2019/12/20 00:09

イメージ図の投稿が上手くいかず申し訳ございません。 追加しましたのでご確認ください。 デバックでシートが増えている箇所を探してみます。 それとシート名は「表」が正しいです。 こちらが原因かもしれませんので修正して試してみます。 ありがとうございます。
ichigo15

2019/12/20 06:29

デバックでシートが増えている箇所を見つけましたので修正してみましたが 上手くいきませんでした。 Base = Intersect(.Range("D:K"), .Range(.Rows(2), .Rows(lr))) .Copy Worksheets(1)       ↓ こちらに修正 Base = Intersect(.Range("D:K"), .Range(.Rows(2), .Rows(lr))) .Copy Worksheets("表")
guest

回答4

0

ベストアンサー

とりあえず①の回答のみです。
.Copy Worksheets(1)
を行うと新規のワークシートにコピーされます。
表にコピーするには(コピーしたように見せるには)
1.表があるなら削除
2.結果を新規シートにコピー
3.新規シートを表にリネーム
する必要があります。以下のようにしてください。

VBA

1Public Sub 結果を表へ出力() 2 Dim i As Long 3 Dim j As Long 4 Dim k As Long 5 Dim Cnt As Long 6 Dim lr As Long 7 Dim Aary() As Variant 8 Dim Mary() As Variant 9 Dim Dm As Object 10 Dim Mm As Object 11 Dim Var As Variant 12 Dim Base As Variant 13 '表が存在するなら削除する 14 If ExistsWorkSheet("表") = True Then 15 Application.DisplayAlerts = False 16 Worksheets("表").Delete 17 Application.DisplayAlerts = True 18 End If 19 20 Set Dm = CreateObject("Scripting.Dictionary") 21 Set Mm = CreateObject("Scripting.Dictionary") 22 With Worksheets("結果") 23 lr = .Cells(.Rows.Count, 4).End(xlUp).Row 24 Base = Intersect(.Range("D:K"), .Range(.Rows(2), .Rows(lr))) 25 .Copy after:=Worksheets(Worksheets.Count) 26 End With 27 Worksheets(Worksheets.Count).name = "表" 28 For i = 1 To UBound(Base, 1) 29 Dm(Base(i, 1)) = Empty 30 Mm(Base(i, 7)) = Empty 31 Next 32 Mary = Mm.keys 33 ReDim Aary(1 To Dm.Count, 1 To Mm.Count + 1) 34 For i = 1 To UBound(Base, 1) 35 For Each Var In Dm 36 Cnt = Cnt + 1 37 If Var = Base(i, 1) Then 38 Aary(Cnt, 1) = Var 39 For k = 0 To UBound(Mary) 40 If Base(i, 7) = Mary(k) Then 41 Aary(Cnt, k + 2) = Aary(Cnt, k + 2) & Base(i, 5) & Base(i, 8) & " " 42 End If 43 Next 44 End If 45 Next 46 Cnt = 0 47 Next 48 Worksheets("表").Activate 49 With ActiveSheet 50 .UsedRange.Clear 51 .Cells(1, 2).Resize(, UBound(Mary) + 1) = Mary 52 .Cells(2, 1).Resize(UBound(Aary, 1), UBound(Aary, 2)) = Aary 53 .UsedRange.EntireColumn.AutoFit 54 .UsedRange.Borders.LineStyle = xlContinuous 55 .Range("A:A").SpecialCells(2).NumberFormatLocal = "yyyy/mm/dd" 56 End With 57 Set Dm = Nothing 58 Set Mm = Nothing 59 Erase Base, Aary, Mary 60End Sub 61'ワークシートの存在チェック 62Public Function ExistsWorkSheet(ByVal sheetName As String) As Boolean 63 Dim ws As Worksheet 64 ExistsWorkSheet = False 65 For Each ws In Worksheets 66 If UCase(ws.name) = UCase(sheetName) Then 67 ExistsWorkSheet = True 68 Exit Function 69 End If 70 Next ws 71End Function

投稿2019/12/20 08:34

編集2019/12/23 02:49
tatsu99

総合スコア5493

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ichigo15

2019/12/23 02:43

If ExistsWorkSheet("表") = True Then のExistsWorkSheetでエラーが出てしまいました エラー:コンパイルエラー     subまたはFunctionが定義されてません
tatsu99

2019/12/23 02:50

失礼しました。ExistsWorkSheetの関数がもれていましたので、追記しました。
ichigo15

2019/12/24 04:55

ありがとうございます。 希望する結果となりました。 まだ理解できていない部分がありますが引続き勉強いたします。
guest

0

表が正しく出力されていることが前提です。
仕様書のNoの順に氏名を並べ替えます。
No順に並べ替えるために一旦作業シート上でNo及び氏名をソートしています。
そのあとで作業シートを削除します。

VBA

1Public Sub 仕様書の名前順に並べ替え() 2 Dim ws As Worksheet 3 Dim ms As Worksheet 4 Dim mscp As Worksheet 5 Dim dicM As Object '仕様書 氏名 6 Dim dicW As Object '表 氏名 7 Dim maxrowM As Long 8 Dim maxrowW As Long 9 Dim maxcolW As Long 10 Dim wrow As Long 11 Dim wcol As Long 12 Dim set_col As Long 13 Dim set_row As Long 14 Dim key As Variant 15 Dim Warr As Variant 16 Set ws = Worksheets("表") 17 Set ms = Worksheets("仕様書") 18 Set dicM = CreateObject("Scripting.Dictionary") 19 Set dicW = CreateObject("Scripting.Dictionary") 20 maxrowM = ms.Cells(Rows.Count, "C").End(xlUp).Row '仕様書 C列最終行を求める 21 maxrowW = ws.Cells(Rows.Count, "A").End(xlUp).Row '表 A列最終行を求める 22 maxcolW = ws.Cells(1, Columns.Count).End(xlToLeft).Column '表 1行目の最終列を求める 23 If maxrowM < 4 Then Exit Sub 24 If maxrowW < 2 Then Exit Sub 25 If maxcolW < 2 Then Exit Sub 26 '仕様書の名前登録 27 For wrow = 4 To maxrowM 28 key = ms.Cells(wrow, "C").Value 29 dicM(key) = True 30 Next 31 '表の名前登録及びチェック 32 For wcol = 2 To maxcolW 33 key = ws.Cells(1, wcol).Value 34 If dicM.exists(key) = False Then 35 MsgBox ("仕様書に" & key & "なし") 36 Exit Sub 37 End If 38 dicW(key) = wcol 39 Next 40 '表を配列に格納 41 Warr = ws.Range(ws.Cells(1, 1), ws.Cells(maxrowW, maxcolW)).Value 42 43 '仕様書をソートするので作業シートへコピー 44 ms.Copy after:=Worksheets(Worksheets.Count) 45 Set mscp = Worksheets(Worksheets.Count) 46 mscp.Range("B4:" & "C" & maxrowM).Sort key1:=Range("B4"), order1:=xlAscending 47 48 '仕様書のNo順に並べ直す 49 set_col = 2 50 For wrow = 4 To maxrowM 51 key = mscp.Cells(wrow, "C").Value 52 If dicW.exists(key) = True Then 53 For set_row = 1 To maxrowW 54 ws.Cells(set_row, set_col).Value = Warr(set_row, dicW(key)) 55 Next 56 set_col = set_col + 1 57 End If 58 Next 59 'コピーしたシートを削除 60 Application.DisplayAlerts = False 61 mscp.Delete 62 Application.DisplayAlerts = True 63 MsgBox ("並べ替え完了") 64End Sub 65 66

投稿2019/12/23 03:35

tatsu99

総合スコア5493

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

<結果>シート

日付 項目 場所 氏名 金額 2019/10/1 ああ a AA 10000 2019/10/1 いい b BB 15000 2019/11/15 うう a AA 20000 2019/11/15 うう a AA 25000 2019/12/20 ええ e CC 30000 2019/12/25 おお f BB 10000 2019/12/25 おお g BB 15000 2019/12/25 ああ a AA 50000 2019/12/29 いい g DD 20000

<仕様書>シート

No. 名前 1 BB 2 DD 3 CC 4 AA

各シートがこんな感じで、
マクロを実行した結果が以下のように
なればいいのでしょうか?

<表>シート

合計 / 金額 列ラベル 行ラベル BB DD CC AA 総計 2019/10/1 15000 10000 25000 2019/11/15 45000 45000 2019/12/20 30000 30000 2019/12/25 25000 50000 75000 2019/12/29 20000 20000 総計 40000 20000 30000 105000 195000

マクロのコード

ExcelVBA

1Option Explicit 2 3Sub ListToCrossTable() 4 Dim rngList As Range 5 Dim rngTable As Range 6 Dim rngName As Range 7 Dim c As Range 8 Dim i As Long 9 Dim sixName As String 10 Dim sixDate As String 11 Dim sixAmount As String 12 Dim pvtCache As PivotCache 13 Dim pvtTable As PivotTable 14 15 '準備(前提条件の定義) 16 With ThisWorkbook 17 Set rngList = .Worksheets("結果").Range("A1").CurrentRegion 18 Set rngTable = .Worksheets("表").Range("A1") 19 With .Worksheets("仕様書").Range("A1").CurrentRegion 20 Set rngName = Intersect(.Cells, .Offset(1, 1)) 21 End With 22 Set pvtCache = .PivotCaches.Create(xlDatabase, rngList) 23 End With 24 Set pvtTable = pvtCache.CreatePivotTable(rngTable) 25 With rngList.Rows(1).Cells 26 sixName = .Item(4).Value 27 sixDate = .Item(1).Value 28 sixAmount = .Item(5).Value 29 End With 30 31 'クロス集計表作成 32 With pvtTable 33 .PivotFields(sixName).Orientation = xlColumnField 34 .PivotFields(sixDate).Orientation = xlRowField 35 .AddDataField pvtTable.PivotFields(sixAmount), , xlSum 36 End With 37 38 '並べ替え 39 For Each c In rngName 40 i = i + 1 41 pvtTable.PivotFields(sixName).PivotItems(c.Value).Position = i 42 Next 43End Sub 44

※各シートとも表の左上がA1セルとしてコードを書いています。
※エラー回避処理は一切考慮しておりません。

投稿2019/12/20 11:46

mattuwan

総合スコア2163

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ichigo15

2019/12/23 02:26

少し違っております。 <表>シートは金額のみではなく場所と金額をだします それと、合計は日付ごとではなく人毎です
guest

0

②についてですが、「表」シート同士でコピーしてもぐじゃぐじゃになるだけです。
一旦、表の内容をどこかにコピーし、それを表にコピーし直さないとだめです。

仕様書についてですが
Q1:仕様書の最大行数はC列の最後のデータがあるところで決めて良いですか。
マクロをみるとD列の最後のデータがあるところにしているように見える。

Q2:優先順位は、C列の上からの並び順で決めて良いですか。
添付図
添付図の左側図は、優先順位がAA,BB,CCの順ですが、これを優先順位CC,BB,AAに変える場合は、
添付図の中の図のように変えると考えてよいですか。(赤線の部分を変更)
それとも添付図の右側のように変えることも想定されているのですか。(青線の部分を変更)

優先順位を決めるとき、B列のNoの値も考慮し、その順序のしたいのか、
それとも、B列のNoの値には関係なく、C列の上からの並び順で決めて良いかという質問です。

投稿2019/12/20 08:52

tatsu99

総合スコア5493

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ichigo15

2019/12/23 02:38

仕様が分かりづらく申し訳ございません。 優先順位を決めるときはB列の番号で決めます。 従って添付図の中の図のように変えると考えてます(赤線の部分を変更)
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問