Excel VBA質問箱 IV

当質問箱は、有志のボランティア精神のおかげで成り立っています。
問題が解決したら、必ずお礼をしましょうね。
本サイトの基本方針をまとめました。こちら をご一読ください。

投稿種別の選択が必要です。ご注意ください。
迷惑投稿防止のため、URLの入力を制限しています。ご了承ください。


1864 / 13645 ツリー ←次へ | 前へ→

【71348】ソート→集計をマクロで ゆうか 12/2/24(金) 13:35 質問[未読]
【71356】Re:ソート→集計をマクロで UO3 12/2/24(金) 19:36 回答[未読]
【71357】Re:ソート→集計をマクロで UO3 12/2/24(金) 19:39 回答[未読]
【71362】Re:ソート→集計をマクロで ゆうか 12/2/25(土) 1:03 質問[未読]
【71370】Re:ソート→集計をマクロで UO3 12/2/25(土) 14:19 発言[未読]
【71372】Re:ソート→集計をマクロで UO3 12/2/25(土) 19:01 発言[未読]
【71374】Re:ソート→集計をマクロで UO3 12/2/26(日) 1:38 発言[未読]
【71404】Re:ソート→集計をマクロで ゆうか 12/2/29(水) 15:01 質問[未読]
【71414】Re:ソート→集計をマクロで UO3 12/3/1(木) 10:17 回答[未読]
【71424】Re:ソート→集計をマクロで ゆうか 12/3/1(木) 13:12 発言[未読]
【71433】Re:ソート→集計をマクロで UO3 12/3/2(金) 11:26 発言[未読]
【71434】Re:ソート→集計をマクロで UO3 12/3/2(金) 11:43 回答[未読]
【71358】Re:ソート→集計をマクロで Hirofumi 12/2/24(金) 19:40 発言[未読]
【71361】Re:ソート→集計をマクロで ゆうか 12/2/25(土) 0:56 質問[未読]

【71348】ソート→集計をマクロで
質問  ゆうか  - 12/2/24(金) 13:35 -

引用なし
パスワード
   日別の売上を集計し、1ヵ月分の請求書を自動で作成するマクロを作成しています。
まず、日ごとにシートがあり、それを31日分【集計】sheetに貼り付けるまではマクロが出来ました。(日ごとのシートはお客様作成の為、行列がランダムだったので【集計】sheetにまとめました。)
それ以後、商品コードごとに、個数を金額を集計したいのですが、
どうしてもうまく行きません。【集計】sheetのレコードは4,500行ほどあるので
自動集計やピボットではなく、マクロで行いたいと思っています。
集計結果は【合計集計】sheetに作成したいと思っています。
自動記録などを使ったり、HPなどをみて独学でやっているので、
どなたかご指導いただけると嬉しいです。
よろしくお願い致します。

【集計】sheet
A      B      C      D      E      F

コード   種類    品名    値段    個数    金額
104    沖縄    キウイ    250    20    5,000
105    沖縄    パイン    150    6    900
102    高知    バナナ    150    6    900
102    沖縄    バナナ    150    15    2,250
101    愛媛    みかん    200    2    400
103    京都    メロン    300    10    3,000
100    青森    りんご    100    2    200
100    青森    りんご    100    3    300
100    青森    りんご    100    5    500

【合計集計】sheet
A      B      C      D      E      F

コード   種類    品名    値段    個数   金額
100    青森    りんご    100    10    1,000
101    愛媛    みかん    200    2    400
102    高知    バナナ    150    21    3,150
103    京都    メロン    300    10    3,000
104    沖縄    キウイ    250    20    5,000
105    沖縄    パイン    150    6    900
合計                           13,450

【71356】Re:ソート→集計をマクロで
回答  UO3  - 12/2/24(金) 19:36 -

引用なし
パスワード
   ▼ゆうか さん:

こんばんは。一例です。
(アップされたサンプルでは102が高知と沖縄なので、以下のコードでは別物とみなしています。)

Sub Sample()
  Dim v As Variant
  Dim z As Long
  Dim i As Long
  Dim k As Long
  Dim dic As Object
  Dim dKey As String
  Dim c As Range
  Dim w As Variant
  
  Set dic = CreateObject("Scripting.Dictionary")
  
  With Sheets("集計")
    z = .Range("A1").CurrentRegion.Rows.Count - 1
    ReDim v(1 To z, 1 To 6)
    For Each c In .Range("A2", .Range("A" & .Rows.Count).End(xlUp))
      dKey = Join(WorksheetFunction.Index(c.Resize(, 4).Value, 1, 0), vbTab)
      If Not dic.exists(dKey) Then
        dic(dKey) = dic.Count + 1
        i = dic(dKey)
        v(i, 1) = c.Value
        v(i, 2) = c.Offset(, 1).Value
        v(i, 3) = c.Offset(, 2).Value
        v(i, 4) = c.Offset(, 3).Value
      End If
      v(i, 5) = v(i, 5) + c.Offset(, 4).Value
      v(i, 6) = v(i, 6) + c.Offset(, 5).Value
    Next
  End With
  
  With Sheets("集計合計")
    .Cells.ClearContents
    .Range("A1:F1").Value = Sheets("集計").Range("A1:F1").Value
    .Range("A2").Resize(dic.Count, 6).Value = v
    .Rows(2).Resize(dic.Count).Sort key1:=.Range("A2"), Order1:=xlAscending, Header:=xlNo
    .Range("A" & dic.Count + 2).Value = "合計"
    .Range("F" & dic.Count + 2).FormulaR1C1 = "=SUM(R2C:R[-1]C)"
    .Select
  End With
  
  Set dic = Nothing
  MsgBox "合計処理が完了しました"
  
End Sub

【71357】Re:ソート→集計をマクロで
回答  UO3  - 12/2/24(金) 19:39 -

引用なし
パスワード
   ▼ゆうか さん:

ごめんなさい。コードを1行追加しました。

Sub Sample()
  Dim v As Variant
  Dim z As Long
  Dim i As Long
  Dim k As Long
  Dim dic As Object
  Dim dKey As String
  Dim c As Range
  Dim w As Variant
  
  Set dic = CreateObject("Scripting.Dictionary")
  
  With Sheets("集計")
    z = .Range("A1").CurrentRegion.Rows.Count - 1
    ReDim v(1 To z, 1 To 6)
    For Each c In .Range("A2", .Range("A" & .Rows.Count).End(xlUp))
      dKey = Join(WorksheetFunction.Index(c.Resize(, 4).Value, 1, 0), vbTab)
      If Not dic.exists(dKey) Then
        dic(dKey) = dic.Count + 1
        i = dic(dKey)
        v(i, 1) = c.Value
        v(i, 2) = c.Offset(, 1).Value
        v(i, 3) = c.Offset(, 2).Value
        v(i, 4) = c.Offset(, 3).Value
      End If
      i = dic(dKey)
      v(i, 5) = v(i, 5) + c.Offset(, 4).Value
      v(i, 6) = v(i, 6) + c.Offset(, 5).Value
    Next
  End With
  
  With Sheets("集計合計")
    .Cells.ClearContents
    .Range("A1:F1").Value = Sheets("集計").Range("A1:F1").Value
    .Range("A2").Resize(dic.Count, 6).Value = v
    .Rows(2).Resize(dic.Count).Sort key1:=.Range("A2"), Order1:=xlAscending, Header:=xlNo
    .Range("A" & dic.Count + 2).Value = "合計"
    .Range("F" & dic.Count + 2).FormulaR1C1 = "=SUM(R2C:R[-1]C)"
    .Select
  End With
  
  Set dic = Nothing
  MsgBox "合計処理が完了しました"
  
End Sub

【71358】Re:ソート→集計をマクロで
発言  Hirofumi  - 12/2/24(金) 19:40 -

引用なし
パスワード
   こんなのでは?
「コード」で整列して、1行づつ処理しています

Option Explicit

Public Sub Sample_1()

  'Listの列数(A〜F列)
  Const clngColumns As Long = 6
  'Listの中の「コード」と成る列位置(基準列からの列Offset:0列目)
  Const clngKey1 As Long = 0
  
  Dim i As Long
  Dim lngRows As Long
  Dim lngWrite As Long
  Dim rngList As Range
  Dim rngResult As Range
  Dim vntData As Variant
  Dim vntSum As Variant
  Dim vntTotal As Variant
  Dim strProm As String

  '【集計】の先頭セル位置を基準とする(先頭列の列見出しのセル位置)
  Set rngList = Worksheets("集計").Range("A1")

  '【合計集計】の結果出力の先頭セル位置を基準とする(先頭列の列見出しのセル位置)
  Set rngResult = Worksheets("合計集計").Range("A1")
  
  '画面更新を停止
  Application.ScreenUpdating = False
  
  '【集計】のListに就いて
  With rngList
    '行数の取得
    lngRows = .Offset(Rows.Count - .Row, clngKey1).End(xlUp).Row - .Row
    If lngRows <= 0 Then
      strProm = "データが有りません"
      GoTo Wayout
    End If
    'Listを「コード」順で整列
    .Offset(1).Resize(lngRows, clngColumns).Sort _
        Key1:=.Offset(1, clngKey1), Order1:=xlAscending, _
        Header:=xlNo, OrderCustom:=1, MatchCase:=False, _
        Orientation:=xlTopToBottom, SortMethod:=xlStroke
  End With
  
  '【合計集計】に就いて
  With rngResult
    'データをクリア
    If .CurrentRegion.Rows.Count > 1 Then
      Intersect(.CurrentRegion, .CurrentRegion.Offset(1)).ClearContents
    End If
  End With
  
  '合計用の配列を確保
  ReDim vntTotal(1 To clngColumns)
  vntTotal(1) = "合計"
  
  '【集計】のデータ先頭行を集計用配列に取得
  vntSum = rngList.Offset(1).Resize(, clngColumns).Value
  '【集計】のデータ2行目〜最終行+1まで繰り返し
  For i = 2 To lngRows + 1
    '1行分のデータを配列に取得
    vntData = rngList.Offset(i).Resize(, clngColumns).Value
    '「コード」が同じなら
    If vntData(1, clngKey1 + 1) = vntSum(1, clngKey1 + 1) Then
      '「個数」「金額」を集計
      vntSum(1, 5) = vntSum(1, 5) + vntData(1, 5)
      vntSum(1, 6) = vntSum(1, 6) + vntData(1, 6)
    Else
      '合計を集計
      vntTotal(5) = vntTotal(5) + vntSum(1, 5)
      vntTotal(6) = vntTotal(6) + vntSum(1, 6)
      'データを出力
      lngWrite = lngWrite + 1
      rngResult.Offset(lngWrite).Resize(, clngColumns).Value = vntSum
      '読み込んだデータを集計用変数に代入
      vntSum = vntData
    End If
  Next i
  
  '合計を出力
  lngWrite = lngWrite + 1
  rngResult.Offset(lngWrite).Resize(, clngColumns).Value = vntTotal
  
  strProm = "処理が完了しました"
   
Wayout:

  '画面更新を再開
  Application.ScreenUpdating = True
  
  Set rngList = Nothing
  Set rngResult = Nothing
   
  MsgBox strProm, vbInformation
     
End Sub

【71361】Re:ソート→集計をマクロで
質問  ゆうか  - 12/2/25(土) 0:56 -

引用なし
パスワード
   コメントを丁寧につけて、書いていただいてありがとうございます。
何度も何度もやってみました。
ただ、私の理解が乏しく、編集するのが困難だったため、
先にコメントいただいた方のを使用させていただきました。
プラスアルファ自動記録を使ってみたのですが、
どうもごちゃごちゃしてしまって。
最終行を取得して、罫線を引いたり、リストの先頭行を中央揃えなど、
行を取得し・・・というのがなぜかエラーになってしまったので、
結果、自動記録しかないという結論に至りました。
見ていただいて、ご意見ご指導をいただけると嬉しいです!!
Sub Sample()
  Dim v As Variant
  Dim z As Long
  Dim i As Long
  Dim k As Long
  Dim dic As Object
  Dim dKey As String
  Dim c As Range
  Dim w As Variant
 
  Set dic = CreateObject("Scripting.Dictionary")
 
  With Sheets("集計")
    z = .Range("A1").CurrentRegion.Rows.Count - 1
    ReDim v(1 To z, 1 To 6)
    For Each c In .Range("A2", .Range("A" & .Rows.Count).End(xlUp))
      dKey = Join(WorksheetFunction.Index(c.Resize(, 4).Value, 1, 0), vbTab)
      If Not dic.exists(dKey) Then
        dic(dKey) = dic.Count + 1
        i = dic(dKey)
        v(i, 1) = c.Value
        v(i, 2) = c.Offset(, 1).Value
        v(i, 3) = c.Offset(, 2).Value
        v(i, 4) = c.Offset(, 3).Value
      End If
      i = dic(dKey)
      v(i, 5) = v(i, 5) + c.Offset(, 4).Value
      v(i, 6) = v(i, 6) + c.Offset(, 5).Value
    Next
  End With
 
  With Sheets("集計合計")
    .Cells.ClearContents
    .Range("A1:F1").Value = Sheets("集計").Range("A1:F1").Value
    .Range("A2").Resize(dic.Count, 6).Value = v
    .Rows(2).Resize(dic.Count).sort key1:=.Range("A2"), Order1:=xlAscending, Header:=xlNo
    .Range("A" & dic.Count + 2).Value = "合計"
    .Range("F" & dic.Count + 2).FormulaR1C1 = "=SUM(R2C:R[-1]C)"
    .Select
  End With
  Columns("A:F").EntireColumn.AutoFit
  Application.ScreenUpdating = True
 
  Set dic = Nothing
  MsgBox "合計処理が完了しました"
 
End Sub
Sub 罫線()              'リストの最終行まで罫線を引く

  Range(Selection, Selection.End(xlToRight)).Select
  Range(Selection, Selection.End(xlDown)).Select
  Selection.Borders(xlDiagonalDown).LineStyle = xlNone
  Selection.Borders(xlDiagonalUp).LineStyle = xlNone
  With Selection.Borders(xlEdgeLeft)
    .LineStyle = xlContinuous
    .Weight = xlThin
    .ColorIndex = xlAutomatic
  End With
  With Selection.Borders(xlEdgeTop)
    .LineStyle = xlContinuous
    .Weight = xlThin
    .ColorIndex = xlAutomatic
  End With
  With Selection.Borders(xlEdgeBottom)
    .LineStyle = xlContinuous
    .Weight = xlThin
    .ColorIndex = xlAutomatic
  End With
  With Selection.Borders(xlEdgeRight)
    .LineStyle = xlContinuous
    .Weight = xlThin
    .ColorIndex = xlAutomatic
  End With
  With Selection.Borders(xlInsideVertical)
    .LineStyle = xlContinuous
    .Weight = xlThin
    .ColorIndex = xlAutomatic
  End With
  With Selection.Borders(xlInsideHorizontal)
    .LineStyle = xlContinuous
    .Weight = xlThin
    .ColorIndex = xlAutomatic
  End With
  
  Range("A1").Select
  Selection.End(xlDown).Select
  Range("A47:E47").Select      '最終行の"合計"が入るセルとその右隣の5つのセルを選択し、範囲内で中央揃えを使用とした結果です。
  With Selection
    .HorizontalAlignment = xlCenterAcrossSelection
    .VerticalAlignment = xlCenter
    .WrapText = False
    .Orientation = 0
    .AddIndent = False
    .IndentLevel = 0
    .ShrinkToFit = False
    .ReadingOrder = xlContext
    .MergeCells = False
  End With
  Range("A47").Select
  Selection.End(xlUp).Select
  Rows("1:1").Select
  With Selection
    .HorizontalAlignment = xlCenter
    .VerticalAlignment = xlCenter
    .WrapText = False
    .Orientation = 0
    .AddIndent = False
    .IndentLevel = 0
    .ShrinkToFit = False
    .ReadingOrder = xlContext
    .MergeCells = False
  End With
  Range("A1").Select
End Sub

【71362】Re:ソート→集計をマクロで
質問  ゆうか  - 12/2/25(土) 1:03 -

引用なし
パスワード
   そうそうに、ありがとうございました。
記述が分かりやすく、結果確認が出来ました。
ありがとうございます。
出来上がったリストに書式を設定したかったのですが、
罫線、選択範囲内で中央揃え等、最終行を取得する記述がうまく動かず、
結果、自動記録でやってみました。
良い方法があれば教えてください。

本当にありがとうございます。
ゆうか


Sub Sample()
  Dim v As Variant
  Dim z As Long
  Dim i As Long
  Dim k As Long
  Dim dic As Object
  Dim dKey As String
  Dim c As Range
  Dim w As Variant
 
  Set dic = CreateObject("Scripting.Dictionary")
 
  With Sheets("集計")
    z = .Range("A1").CurrentRegion.Rows.Count - 1
    ReDim v(1 To z, 1 To 6)
    For Each c In .Range("A2", .Range("A" & .Rows.Count).End(xlUp))
      dKey = Join(WorksheetFunction.Index(c.Resize(, 4).Value, 1, 0), vbTab)
      If Not dic.exists(dKey) Then
        dic(dKey) = dic.Count + 1
        i = dic(dKey)
        v(i, 1) = c.Value
        v(i, 2) = c.Offset(, 1).Value
        v(i, 3) = c.Offset(, 2).Value
        v(i, 4) = c.Offset(, 3).Value
      End If
      i = dic(dKey)
      v(i, 5) = v(i, 5) + c.Offset(, 4).Value
      v(i, 6) = v(i, 6) + c.Offset(, 5).Value
    Next
  End With
 
  With Sheets("集計合計")
    .Cells.ClearContents
    .Range("A1:F1").Value = Sheets("集計").Range("A1:F1").Value
    .Range("A2").Resize(dic.Count, 6).Value = v
    .Rows(2).Resize(dic.Count).sort key1:=.Range("A2"), Order1:=xlAscending, Header:=xlNo
    .Range("A" & dic.Count + 2).Value = "合計"
    .Range("F" & dic.Count + 2).FormulaR1C1 = "=SUM(R2C:R[-1]C)"
    .Select
  End With
  Columns("A:F").EntireColumn.AutoFit
  Application.ScreenUpdating = True
 
  Set dic = Nothing
  MsgBox "合計処理が完了しました"
 
End Sub
Sub 罫線()              'リストの最終行まで罫線を引く

  Range(Selection, Selection.End(xlToRight)).Select
  Range(Selection, Selection.End(xlDown)).Select
  Selection.Borders(xlDiagonalDown).LineStyle = xlNone
  Selection.Borders(xlDiagonalUp).LineStyle = xlNone
  With Selection.Borders(xlEdgeLeft)
    .LineStyle = xlContinuous
    .Weight = xlThin
    .ColorIndex = xlAutomatic
  End With
  With Selection.Borders(xlEdgeTop)
    .LineStyle = xlContinuous
    .Weight = xlThin
    .ColorIndex = xlAutomatic
  End With
  With Selection.Borders(xlEdgeBottom)
    .LineStyle = xlContinuous
    .Weight = xlThin
    .ColorIndex = xlAutomatic
  End With
  With Selection.Borders(xlEdgeRight)
    .LineStyle = xlContinuous
    .Weight = xlThin
    .ColorIndex = xlAutomatic
  End With
  With Selection.Borders(xlInsideVertical)
    .LineStyle = xlContinuous
    .Weight = xlThin
    .ColorIndex = xlAutomatic
  End With
  With Selection.Borders(xlInsideHorizontal)
    .LineStyle = xlContinuous
    .Weight = xlThin
    .ColorIndex = xlAutomatic
  End With
  
  Range("A1").Select
  Selection.End(xlDown).Select
  Range("A47:E47").Select      '最終行の"合計"が入るセルとその右隣の5つのセルを選択し、範囲内で中央揃えを使用とした結果です。
  With Selection
    .HorizontalAlignment = xlCenterAcrossSelection
    .VerticalAlignment = xlCenter
    .WrapText = False
    .Orientation = 0
    .AddIndent = False
    .IndentLevel = 0
    .ShrinkToFit = False
    .ReadingOrder = xlContext
    .MergeCells = False
  End With
  Range("A47").Select
  Selection.End(xlUp).Select
  Rows("1:1").Select
  With Selection
    .HorizontalAlignment = xlCenter
    .VerticalAlignment = xlCenter
    .WrapText = False
    .Orientation = 0
    .AddIndent = False
    .IndentLevel = 0
    .ShrinkToFit = False
    .ReadingOrder = xlContext
    .MergeCells = False
  End With
  Range("A1").Select
End Sub
Sub リストの項目行中央揃え()
  Rows("1:1").Select
  With Selection
    .HorizontalAlignment = xlGeneral
    .VerticalAlignment = xlCenter
    .WrapText = False
    .Orientation = 0
    .AddIndent = False
    .IndentLevel = 0
    .ShrinkToFit = False
    .ReadingOrder = xlContext
    .MergeCells = False
  End With
End Sub

【71370】Re:ソート→集計をマクロで
発言  UO3  - 12/2/25(土) 14:19 -

引用なし
パスワード
   ▼ゆうか さん:

>出来上がったリストに書式を設定したかったのですが、
>罫線、選択範囲内で中央揃え等、最終行を取得する記述がうまく動かず、
>結果、自動記録でやってみました。

もとのプロシジャの中にくみこむほうがいいと思いますが、コード案をアップする前に、中央そろえについて

1.1行目、タイトル行の縦方向、横方向の希望設定をそれぞれおしえてきださい。
2.最終の合計行の、縦方向、横方向の希望設定をそれぞれおしえてきださい。
3.2行目からのデータ部分の、縦方向、横方向の希望設定をそれぞれおしえてきださい。

【71372】Re:ソート→集計をマクロで
発言  UO3  - 12/2/25(土) 19:01 -

引用なし
パスワード
   ▼ゆうか さん:

上で質問したように、表の各ブロックごとに、どのような書式設定がお好みなのかはわからないので
「適当」に。

ブロックごとに分けてあるので、あとはいかようにでも、直してくださいね。

Sub Sample()
  Dim v As Variant
  Dim z As Long
  Dim i As Long
  Dim k As Long
  Dim dic As Object
  Dim dKey As String
  Dim c As Range
  Dim w As Variant

  Set dic = CreateObject("Scripting.Dictionary")

'  Application.ScreenUpdating = False

  With Sheets("集計")
    z = .Range("A1").CurrentRegion.Rows.Count - 1
    ReDim v(1 To z, 1 To 6)
    For Each c In .Range("A2", .Range("A" & .Rows.Count).End(xlUp))
      dKey = Join(WorksheetFunction.Index(c.Resize(, 4).Value, 1, 0), vbTab)
      If Not dic.exists(dKey) Then
        dic(dKey) = dic.Count + 1
        i = dic(dKey)
        v(i, 1) = c.Value
        v(i, 2) = c.Offset(, 1).Value
        v(i, 3) = c.Offset(, 2).Value
        v(i, 4) = c.Offset(, 3).Value
      End If
      i = dic(dKey)
      v(i, 5) = v(i, 5) + c.Offset(, 4).Value
      v(i, 6) = v(i, 6) + c.Offset(, 5).Value
    Next
  End With

  With Sheets("集計合計")
    .Cells.ClearContents
    .Range("A1:F1").Value = Sheets("集計").Range("A1:F1").Value
    .Range("A2").Resize(dic.Count, 6).Value = v
    .Rows(2).Resize(dic.Count).Sort key1:=.Range("A2"), Order1:=xlAscending, Header:=xlNo
    .Range("A" & dic.Count + 2).Value = "合計"
    .Range("F" & dic.Count + 2).FormulaR1C1 = "=SUM(R2C:R[-1]C)"
    
    '============ 罫線他の書式設定 開始
    
    .Cells.Borders.LineStyle = xlNone 'まず、すでにひかれている罫線があればそれを削除
    
    '1行目 タイトル行 ★これはあらかじめ書式設定しておけば、コード処理は不要
    With .Range("A1:F1")
      .HorizontalAlignment = xlCenter
      .VerticalAlignment = xlCenter
    End With
    '合計行
    With .Range("A" & dic.Count + 2)
      .Resize(, 5).HorizontalAlignment = xlCenterAcrossSelection '好みではなかったら xlCenterに。
      .Offset(, 5).HorizontalAlignment = xlCenter
      .Resize(, 6).VerticalAlignment = xlCenter
    End With
    'データ領域
    With .Range("A2", .Range("F" & dic.Count + 1))
      .HorizontalAlignment = xlCenter
      .VerticalAlignment = xlCenter
    End With
    '罫線
    With .Range("A1").CurrentRegion.Borders
        .LineStyle = xlContinuous
        .Weight = xlThin
    End With
    
    .Columns("A:F").EntireColumn.AutoFit '★これは、あらかじめ書式設定しておけばコード処理は不要
    
    '============ 罫線他の書式設定 終了
    .Select
  End With
  
  Application.ScreenUpdating = True

  Set dic = Nothing
  MsgBox "合計処理が完了しました"

End Sub

【71374】Re:ソート→集計をマクロで
発言  UO3  - 12/2/26(日) 1:38 -

引用なし
パスワード
   UO3様

ありがとうございます。
お昼間の質問を見落としていたにも関わらず、ありがとうございます。
タイトル行にあらかじめ書式を設定してやってみました。
書式を別シートに用意して、貼り付けるマクロを作ってみたりと
かなり遠回りしておりましたが。
今から、教えていただいたコードを読み、早速やってみます。
結果はまた書き込ませていただきます。

ゆうか

【71404】Re:ソート→集計をマクロで
質問  ゆうか  - 12/2/29(水) 15:01 -

引用なし
パスワード
   UO3様

いつもご親切にありがとうございます。
書式設定は難なく進められました。
新たに表の作成位置をC10からにしようとコードを触ったところ
タイトル行(C10:H10)がおかしな位置に移動してしまって
いくらコードを眺めても何が違っているのか分からずとまってしまいました。
一度見ていただけますか?
よろしくお願いします。

Sub sort()
Application.ScreenUpdating = False
  With Worksheets("DB")
    .Range("f4").AutoFilter _
      Field:=5, Criteria1:=">=1"
      .Range("f4").CurrentRegion.SpecialCells(xlCellTypeVisible).Copy _
      Worksheets("集計").Range("a1")
      .AutoFilterMode = False
  End With
  Worksheets("集計").Activate
  Columns("A:F").EntireColumn.AutoFit
Application.ScreenUpdating = True
End Sub
Sub 請求書作成()
  Dim v As Variant
  Dim z As Long
  Dim i As Long
  Dim k As Long
  Dim dic As Object
  Dim dKey As String
  Dim c As Range
  Dim w As Variant
 
  Set dic = CreateObject("Scripting.Dictionary")
 
  With Sheets("集計")
    z = .Range("A1").CurrentRegion.Rows.Count - 1
    ReDim v(1 To z, 1 To 6)
    For Each c In .Range("A2", .Range("A" & .Rows.Count).End(xlUp))
      dKey = Join(WorksheetFunction.Index(c.Resize(, 4).Value, 1, 0), vbTab)
      If Not dic.exists(dKey) Then
        dic(dKey) = dic.Count + 1
        i = dic(dKey)
        v(i, 1) = c.Value
        v(i, 2) = c.Offset(, 1).Value
        v(i, 3) = c.Offset(, 2).Value
        v(i, 4) = c.Offset(, 3).Value
      End If
      i = dic(dKey)
      v(i, 5) = v(i, 5) + c.Offset(, 4).Value
      v(i, 6) = v(i, 6) + c.Offset(, 5).Value
    Next
  End With
 
  With Sheets("請求書")
    .Cells.ClearContents
    .Range("C10:H10").Value = Sheets("集計").Range("A1:F1").Value
    .Range("C11").Resize(dic.Count, 6).Value = v
    .Rows(2).Resize(dic.Count).sort key1:=.Range("C11"), Order1:=xlAscending, Header:=xlNo
    .Range("C" & dic.Count + 2).Value = "合計"
    .Range("H" & dic.Count + 2).FormulaR1C1 = "=SUM(R2C:R[-1]C)"
  
    '============ 罫線他の書式設定 開始
  
    .Cells.Borders.LineStyle = xlNone 'すでにひかれている罫線があればそれを削除
  
    '1行目 タイトル行 ★あらかじめ書式設定しておけば、コード処理は不要
    With .Range("C10:H10")
      .HorizontalAlignment = xlCenter
      .VerticalAlignment = xlCenter
    End With
    '合計行
    With .Range("C" & dic.Count + 2)
      .Resize(, 5).HorizontalAlignment = xlCenterAcrossSelection
      .Offset(, 5).HorizontalAlignment = xlRight
      .Resize(, 6).VerticalAlignment = xlCenter
    End With
    'データ領域
    With .Range("C2", .Range("E" & dic.Count + 1))
      .HorizontalAlignment = xlCenter
      .VerticalAlignment = xlCenter
    End With
    With .Range("F2", .Range("H" & dic.Count + 1))
      .HorizontalAlignment = xlRight
      .VerticalAlignment = xlCenter
    End With

    '罫線
    With .Range("C1").CurrentRegion.Borders
        .LineStyle = xlContinuous
        .Weight = xlThin
    End With
  
    .Columns("C:H").EntireColumn.AutoFit '★これは、あらかじめ書式設定しておけばコード処理は不要
  
    '============ 罫線他の書式設定 終了
    .Select
    End With
 
    Application.ScreenUpdating = True

    Set dic = Nothing
    MsgBox "合計処理完了"

    End Sub

【71414】Re:ソート→集計をマクロで
回答  UO3  - 12/3/1(木) 10:17 -

引用なし
パスワード
   ▼ゆうか さん:
こんにちは

>タイトル行(C10:H10)がおかしな位置に移動してしまって

ではなく、「合計行が」ではないですか?
それと、罫線がひかれなくなっていません?

少しわかりにくかったかもしれませんが、たとえば集約したデータ件数が7件だったとします。
この7という数字は、Dictionaryデータの件数としてdic.Countというところに格納されています。

もともとがA1から始まっていましたので、データが7件だとするとデータ領域は A2:A8 ですよね。
なので、A2:F & dic.count+1 でしたし、"合計"という文字をセットする場所は A9 ですから
A & dic.count+2 という場所の指定になっていました。

今回、開始はC列、10行目ということですから、このあたりを全て変更しておく必要があります。
訂正箇所のみを連絡してもいいのですが、かえってわかりにくくなりますので、コードを全て。
訂正箇所には★印をつけてあります。

ところで、.Columns("C:H").EntireColumn.AutoFit
これは、あらかじめ"請求書"シートのC〜H列の列幅を"集約"シートのA〜F列とと同じにしておけば
コードはいらないと思いますが?

Sub 請求書作成()
  Dim v As Variant
  Dim z As Long
  Dim i As Long
  Dim k As Long
  Dim dic As Object
  Dim dKey As String
  Dim c As Range
  Dim w As Variant

  Set dic = CreateObject("Scripting.Dictionary")

  With Sheets("集計")
    z = .Range("A1").CurrentRegion.Rows.Count - 1
    ReDim v(1 To z, 1 To 6)
    For Each c In .Range("A2", .Range("A" & .Rows.Count).End(xlUp))
      dKey = Join(WorksheetFunction.Index(c.Resize(, 4).Value, 1, 0), vbTab)
      If Not dic.exists(dKey) Then
        dic(dKey) = dic.Count + 1
        i = dic(dKey)
        v(i, 1) = c.Value
        v(i, 2) = c.Offset(, 1).Value
        v(i, 3) = c.Offset(, 2).Value
        v(i, 4) = c.Offset(, 3).Value
      End If
      i = dic(dKey)
      v(i, 5) = v(i, 5) + c.Offset(, 4).Value
      v(i, 6) = v(i, 6) + c.Offset(, 5).Value
    Next
  End With

  With Sheets("請求書")
    .Cells.ClearContents
    .Range("C10:H10").Value = Sheets("集計").Range("A1:F1").Value
    .Range("C11").Resize(dic.Count, 6).Value = v
    .Rows(2).Resize(dic.Count).sort key1:=.Range("C11"), Order1:=xlAscending, Header:=xlNo
    .Range("C10").Offset(dic.Count + 1).Value = "合計"   '★訂正
    .Range("H10").Offset(dic.Count + 1).FormulaR1C1 = "=SUM(R2C:R[-1]C)" '★訂正

    '============ 罫線他の書式設定 開始
 
    .Cells.Borders.LineStyle = xlNone 'すでにひかれている罫線があればそれを削除
 
    '1行目 タイトル行 ★あらかじめ書式設定しておけば、コード処理は不要
    With .Range("C10:H10")
      .HorizontalAlignment = xlCenter
      .VerticalAlignment = xlCenter
    End With
    '合計行
    With .Range("C10").Offset(dic.Count + 1)  '★訂正

      .Resize(, 5).HorizontalAlignment = xlCenterAcrossSelection
      .Offset(, 5).HorizontalAlignment = xlRight
      .Resize(, 6).VerticalAlignment = xlCenter
    End With
    'データ領域
    With .Range("C11").Resize(dic.Count, 3)  '★訂正
      .HorizontalAlignment = xlCenter
      .VerticalAlignment = xlCenter
    End With
    With .Range("F11").Resize(dic.Count, 3)  '★訂正
      .HorizontalAlignment = xlRight
      .VerticalAlignment = xlCenter
    End With

    '罫線
    With .Range("C10").CurrentRegion.Borders  '★訂正
        .LineStyle = xlContinuous
        .Weight = xlThin
    End With
 
    .Columns("C:H").EntireColumn.AutoFit '★これは、あらかじめ書式設定しておけばコード処理は不要
 
    '============ 罫線他の書式設定 終了
    .Select
    End With

    Application.ScreenUpdating = True

    Set dic = Nothing
    MsgBox "合計処理完了"

End Sub

【71424】Re:ソート→集計をマクロで
発言  ゆうか  - 12/3/1(木) 13:12 -

引用なし
パスワード
   ▼UO3 さん

こんにちは。
お忙しい中いつもありがとうございます。

1行ずつおって実行し、注釈をつけていただいたものを見ながらやっています。
ありがとうございます。
答えだけを頂くのみならず、説明月で初心者の私には嬉しいないようです。

今新しいコードで実行してみたら、タイトル用の書式が10行目に、
タイトル行のデータが55行目に、そして、合計行が最終行にきて、
罫線はひかれていませんでした。
とりあえず、今はやってみただけなので、何が違うか今から1行ずつ探してみるつもりです。

ちなみに請求書の1行目から9行目にはデータが入っているので
請求書云々・・・。それが消えないようにするコードもどこをさわればよいか
検証中です。

取り急ぎお礼だけで失礼します。

ゆうか

【71433】Re:ソート→集計をマクロで
発言  UO3  - 12/3/2(金) 11:26 -

引用なし
パスワード
   ▼ゆうか さん:

こんにちは

>ちなみに請求書の1行目から9行目にはデータが入っているので

なぁるほど、考えてみればそうですよね。ものが請求書なので、いろいろと
プリセットの項目があるんですよね。
これが「不具合」の原因です。

シートのクリアを行っているのは、With Sheets("請求書") の後の
.Cells.ClearContents です。
以下、提案です。

・やはり、請求書シートのC列〜H列の列幅は、AutoFit を行わず、あらかじめ
 見栄えのよろしい幅で、あらかじめ設定しておくことを強くお勧めします。
 たとえば、セットされる各行の文字列桁数で、できあがりが、妙に狭い幅になるケースが
 あって、かえって、みにくくなることもあるのでは?
 それと1行目〜9行目の、どの列にプリセットの文字列がはいっているのかわかりませんが
 将来、そのC列〜H列のどこかに長い適用なんかが記載された場合、その長さでAutoFitされると
 見た目が悪くなることが考えられます。

後ほど、改訂版をアップしますので、しばしお待ちください。

【71434】Re:ソート→集計をマクロで
回答  UO3  - 12/3/2(金) 11:43 -

引用なし
パスワード
   ▼ゆうか さん:

これで、いかがでしょうか。

Sub 請求書作成()
  Dim v As Variant
  Dim z As Long
  Dim i As Long
  Dim k As Long
  Dim dic As Object
  Dim dKey As String
  Dim c As Range
  Dim w As Variant
  Dim y As Long                       '★追加
  Set dic = CreateObject("Scripting.Dictionary")

  With Sheets("集計")
    z = .Range("A1").CurrentRegion.Rows.Count - 1
    ReDim v(1 To z, 1 To 6)
    For Each c In .Range("A2", .Range("A" & .Rows.Count).End(xlUp))
      dKey = Join(WorksheetFunction.Index(c.Resize(, 4).Value, 1, 0), vbTab)
      If Not dic.exists(dKey) Then
        dic(dKey) = dic.Count + 1
        i = dic(dKey)
        v(i, 1) = c.Value
        v(i, 2) = c.Offset(, 1).Value
        v(i, 3) = c.Offset(, 2).Value
        v(i, 4) = c.Offset(, 3).Value
      End If
      i = dic(dKey)
      v(i, 5) = v(i, 5) + c.Offset(, 4).Value
      v(i, 6) = v(i, 6) + c.Offset(, 5).Value
    Next
  End With

  With Sheets("請求書")
    '請求書シートの使用済みの最終行 取得
    y = .UsedRange.Cells(.UsedRange.Cells.Count).Row  '★追加
    If y > 9 Then .Rows("10:" & y).ClearContents    '★変更
    
    .Range("C10:H10").Value = Sheets("集計").Range("A1:F1").Value
    .Range("C11").Resize(dic.Count, 6).Value = v
    '★以下の行、レイアウト変更字、修正もれていました。
    .Rows(11).Resize(dic.Count).sort key1:=.Range("C11"), Order1:=xlAscending, Header:=xlNo
    .Range("C10").Offset(dic.Count + 1).Value = "合計"
    .Range("H10").Offset(dic.Count + 1).FormulaR1C1 = "=SUM(R2C:R[-1]C)"

    '============ 罫線他の書式設定 開始
 
    .Cells.Borders.LineStyle = xlNone 'すでにひかれている罫線があればそれを削除
 
    '1行目 タイトル行 ★あらかじめ書式設定しておけば、コード処理は不要
    With .Range("C10:H10")
      .HorizontalAlignment = xlCenter
      .VerticalAlignment = xlCenter
    End With
    '合計行
    With .Range("C10").Offset(dic.Count + 1)

      .Resize(, 5).HorizontalAlignment = xlCenterAcrossSelection
      .Offset(, 5).HorizontalAlignment = xlRight
      .Resize(, 6).VerticalAlignment = xlCenter
    End With
    'データ領域
    With .Range("C11").Resize(dic.Count, 3)
      .HorizontalAlignment = xlCenter
      .VerticalAlignment = xlCenter
    End With
    With .Range("F11").Resize(dic.Count, 3)
      .HorizontalAlignment = xlRight
      .VerticalAlignment = xlCenter
    End With

    '罫線
    With .Range("C10:H10").Resize(dic.Count + 2).Borders  '★変更
        .LineStyle = xlContinuous
        .Weight = xlThin
    End With
    '★これは、あらかじめ書式設定しておけばコード処理は不要
    '.Columns("C:H").EntireColumn.AutoFit
 
    '============ 罫線他の書式設定 終了
    .Select
    End With

    Application.ScreenUpdating = True

    Set dic = Nothing
    MsgBox "合計処理完了"

End Sub

1864 / 13645 ツリー ←次へ | 前へ→
ページ:  ┃  記事番号:
2610219
(SS)C-BOARD v3.8 is Free