Excel (VBA)

Excel VBAに関するフォーラムです。
  • 解決済みのトピックにはコメントできません。
このトピックは解決済みです。
質問

 
(指定なし : 指定なし)
RE: 合計と合計欄を比べる
投稿日時: 25/11/20 21:07:55
投稿者: simple

解決されたようですが、参考情報を書いておきます。
 
■表形式に変換したのち、合計用算式を埋め込む方法
 

【マクロ実行前】              【マクロ実行後】
      A列                           A列         B列
1     ●料理欄                1     ●料理欄    
2     親子丼×2              2     親子丼      2
3     天丼×2         ⇒     3     天丼        2
4     親子丼×3              4     親子丼      3
5     天丼×3                5     天丼        3
6     親子丼×3              6     親子丼      3
7     親子丼×2              7     親子丼      2
8     ●合計欄                8     ●合計欄    
                              9     親子丼     10
                             10     天丼        5
                             
                             B9セル  =SUMIF($A$2:$A$7,A9,$B$2:$B$7)
                             B10セル =SUMIF($A$2:$A$7,A10,$B$2:$B$7)

【マクロ例】
Rem 表形式に変換したのち、合計用算式を埋め込み
Sub test1()
    Dim pos&
    Dim dic     As Object
    Dim key
    Dim outputRng As Range
    Dim adres1$, adres2$, adres3$
    Dim k&
    
    '1セルから2セルに展開
    pos = Application.Match("●合計欄", Columns(1), 0)
    Range("A2", Cells(pos - 1, "A")).TextToColumns _
        Destination:=Range("A2"), DataType:=xlDelimited, _
        TextQualifier:=xlDoubleQuote, ConsecutiveDelimiter:=False, Tab:=False, _
        Semicolon:=False, Comma:=False, Space:=False, Other:=True, _
        OtherChar:="×", FieldInfo:=Array(Array(1, 1), Array(2, 1)), _
        TrailingMinusNumbers:=True

    'ユニークな料理名を取得
    Set dic = CreateObject("Scripting.Dictionary")
    For k = 2 To pos - 1
        dic(Cells(k, "A").Text) = Empty
    Next
    
    '料理名の書き込み
    Set outputRng = Cells(Rows.Count, "A").End(xlUp).Offset(1)
    outputRng.Resize(dic.Count) = Application.Transpose(dic.keys)

    '合計算式の埋め込み
    adres1 = Range("A2", Cells(pos - 1, "A")).Address
    adres2 = Range("B2", Cells(pos - 1, "B")).Address
    adres3 = outputRng.Address(False, False)
    outputRng.Offset(, 1).Resize(dic.Count).Formula = _
            "=SUMIF(" & adres1 & "," & adres3 & "," & adres2 & ")"
End Sub

【この方式のメリット】
・標準的な表形式となっている
・個数を変更すると自動で合計が更新される
・既存の料理名であれば、行の追加、削除にも対応して合計式が自動で修正される。
  (ただし、料理名が追加されたら、全体をもう一度作成しなおす必要がある)

投稿日時: 25/11/20 21:10:12
投稿者: simple

■現状のフォーマットのまま、差異があれば表示を加える方式
 

     A列
1     ●料理欄
2     親子丼×2
3     天丼×2
4     親子丼×3
5     天丼×3
6     親子丼×3
7     親子丼×2
8     ●合計欄
9     親子丼×9 天丼×5
10    親子丼は 10 が正しい  ←マクロ実行後、差異があれば赤字で追記する

【マクロ例】
Sub test2()
    Dim pos&
    Dim k&, s$
    Dim ary     As Variant
    Dim rng     As Range
    Dim elem    As Variant
    Dim dic     As Object

    pos = Application.Match("●合計欄", Columns(1), 0)
    Set dic = CreateObject("Scripting.Dictionary")
    
    '料理名、個数の読み込み。合計数の計算
    For k = 2 To pos - 1
        s = Cells(k, "A")
        ary = Split(s, "×")
        dic(ary(0)) = dic(ary(0)) + CLng(ary(1))
    Next

    '合計欄のセル位置
    Set rng = Cells(Rows.Count, "A").End(xlUp)

    '合計数の検証
    For Each elem In Split(rng, " ")
        ary = Split(elem, "×")
        If CLng(ary(1)) <> dic(ary(0)) Then
            Set rng = rng.Offset(1)
            rng.Value = ary(0) & "は " & dic(ary(0)) & " が正しい"
            rng.Font.Color = vbRed
        End If
    Next
End Sub

【備考】
あくまでも既存の料理ごと合計のチェックなので、料理欄に新規料理名が追加されていても感知しない。
(むろん、マクロを修正すれば、双方向のチェックは可能。検討してみてください)
 
余り念入りにみていないので、見落としはあるかもしれません。

投稿日時: 25/11/21 22:40:01
投稿者: simple

閉じます。