• 締切済み

VBA ふたつおきに加算した時の合計の表示

EXCELのVBAで下記のような表に対し、合計を求めるコードを作成しました。    A     B    C     D   E   ~O P 1            表題 2           小見出し 4              4月   5月   6月 ~3月 計 5       予約   100   200   100    6 佐藤   手数    30   20    20   7       金額   130   220   120 8       予約   150   100   100 9 斉藤   手数   30    20    20 10      金額   180   120   120 11      予約   100   100   100 12加藤   手数    20   30    20 13      金額   120   130   120    ・    ・    ・   合計         430   470    360  ←それぞれの金額だけを合計した値 ※人が増えたり減ったりしますので行数が3行づつ変化します。  入力する人が限定されないため、セルへの計算式入力(消されてしまう可能性があるため)と、  EXCELの機能(フィルター)などを使用して計算する方法がとれません。 この、合計の部分を求めるため、 Dim stRow As Long Dim lastRow As Long stRow = 5 lastRow = Range("F" & stRow).End(xlDown).Row For i = 4 To lastRow For J = 4 To 15 Cells(lastRow + 1, J).Select Cells(lastRow + 1, J).Value = Application.WorksheetFunction.SumIf(Range(Cells(stRow, "F"), _ Cells(lastRow, "F")), "金額", Range(Cells(stRow, J), Cells(lastRow, J))) Next Next これで、合計の欄にそれぞれの月の合計が出るようにはなったのですが、 入力値に変更を加えて再度計算をしたときに、 『一番最後のセルのしたに合計値を出す』としたため、 下に計算結果が(それも、すでに出ていた合計値を加算して)表示されてしまいます。 これを必ず合計の行に出していくには、合計の行が変化するため、 どのようなコードで書けば良いのかがわかりません。 よろしくお願いします。

みんなの回答

  • mu2011
  • ベストアンサー率38% (1910/4994)
回答No.3

一例です。 合計行をデータ行の直後ではなく、データ最終行+2行目(空行を挟む)に設定しては駄目でしょうか。

  • keithin
  • ベストアンサー率66% (5278/7940)
回答No.2

方法1:素直に一般的な方法 合計の行には素直にSUMIFの式を最初から入れておきます。 ただし素直で一般的じゃない方法をひとつ加えて,今仮に5行目から13行まで3行組のデータと,14行目に「合計」の行があるとすると C14: =SUMIF($B$5:$B14,"金額",C$5:C14) と式を入れて右にコピーしておきます。(念のため:数式は間違いでも循環参照でもありません) 3行組の行を行挿入したり行削除したり合計行を移動しても,問題なく計算できます。 (ついでに言うと,3行ずつデータ行を挿入する操作の方を「データ行追加」とか「データ行削除」のようなマクロで行った方が安全は安全です) 数式を守るためには,シートを保護しておきます。 シートの保護が出来ない,シートの保護の方法が判らなくて出来ないとき,やってみたけど「具体的にこういう問題が起きていて使えなかった」ときは,ご利用のエクセルのバージョンと具体的な状況を添えて別途ご相談を投稿して解決してください。 方法2:どうしてもマクロを使いたい場合。ただしあまり安全ではない。 「合計」の行が,どこにあるかはともかくどこかの一番下の行に「必ずある」という前提にするのなら,マクロでその行に所定の数値を計算して入れ直すだけです。 sub macro1()  dim lastRow as long  lastrow = range("A65536").end(xlup).row ’「合計」行  with cells(lastrow, "C").resize(1, 12)   .formular1c1 = "=SUMIF(R5C2:R[-1]C2,""金額"",R5C:R[-1]C)"   .value = .value  end with end sub #ただし一番下の行には「合計」とA列に記入されているとする #余談 ご質問で掲示されたマクロのiのfor nextループは,何の役も果たさずに無意味に行数を回しているだけです。

  • imogasi
  • ベストアンサー率27% (4737/17068)
回答No.1

合計もデータとして、最終行に影響してしまうから、始に合計行を探知し(End(xlDown).RowやXlupを使う、後者をお奨め) 、その行を削除して、質問のコードとと同じ処理をしたらどうなのですか? 簡単な話ではない?

ponpokotonton
質問者

お礼

発想を変えれば良いということですね。 確かに、最初に合計の行を探して削除してしまえばそこが一番下のセルとはならない。 頭が凝り固まっていました。 ありがとうございました。

関連するQ&A

  • 【VBA】掛け算の入力

    添付のピクチャのH2セルから都度変動する最終行迄、 B2*C2、B3*C3、、、と計算をしたいのですが、 下記のコードでは数式が入力されません。 ご指導宜しくお願いします。 Dim LastRow As Long Dim n As Long LastRow = Cells(Rows.Count, "B").End(xlUp).Row Sheets("数式を入力するシート").Select For n = 2 To LastRow Range("H" & n).Formula = "=B&n*C&n" next n

  • EXCEL VBA4行毎に枠で囲みたい

    お世話になります。 添付の様な表1があります。 これを表2のようにA1から順に4行毎に枠で囲みたいのです。 下記のようなコードを見よう見まねで書いてみましたがうまく動きません。 ごなたかご教授いただけませんでしょうか? よろしくお願い致します。 Dim i As Long Dim j As Long Dim lngYCnt As Long Dim intXCnt As Long Dim LastRow As Long ingYCnt = Worksheets("Sheet1").UsedRange.Rows.Count intXCnt = Worksheets("Sheet1").UsedRange.Columns.Count LastRow = Cells(Rows.Count, 1).End(xlUp).Row With Selection For i = 5 To LastRow Range("A" & i & ":F" & j).Select Selection.BorderAround Weight:=xlMedium j = j + 5 i = i + 5 Next End With どなたかご教授いただけませんでしょうか? よろしくお願い致します。 環境 EXCEL2003 WINDOWS XP SP3

  • エクセルVBAで困っています。

     エクセルでSheet1でSheet2に各銀行の出納帳を作りそこから各項目ごとに別Sheetに振り分けたいと思っています。  ある方にエクセルVBAで作って頂いたのですが、最初作って頂いた時の項目は会費、会議費、事務費の3つでした。その項目を9つに増やしたいと思っています。又、全てのSheetで1行目には銀行名や項目名を入れたいので2行目から日付、内容・・・といったように入力したいです。そうした場合、どこをどう変更したらよいのか分かりません。自分がわかる範囲で(適当ですが)挑んでみたのですが、私自体VBAについて全く無知のため何が何だかサッパリです。どなたか教えて頂くことはできないでしょうか。ちなみに文字数に制限があったため改行やスペースなどは入れていません。見難いとは思いますがよろしくお願いします。どうか皆様のお知恵を貸して頂けると幸いです。 Option Explicit Sub Teller() '【考え方】Sheet1とSheet2を入力と考える。 'マクロを実行したときに、Sheet1,2を元に、項目別に振り分ける。 Const BankName1 As String = "○銀行" Const BankName2 As String = "(チェック)銀行" Const tempSheet As String = "一時シート" Dim classify(9) As String Dim title(5) As String Dim i As Long Dim j As Long Dim lastRow1 As Long Dim lastRow2 As Long Dim findUpper As Long Dim findLower As Long Dim keyword As String Dim ws As Worksheet Dim Bank1 As Worksheet Dim Bank2 As Worksheet Dim Temp As Worksheet Set Bank1 = Worksheets(BankName1) Set Bank2 = Worksheets(BankName2) '【振り分ける項目名】 classify(1) = "会費" classify(2) = "会議費" classify(3) = "事務費" classify(4) = "事業費" classify(5) = "研修費" classify(6) = "報償費" classify(7) = "慶弔費" classify(8) = "予備費" classify(9) = "積立金" '【1行目に記載する見出し】 title(1) = "日付" title(2) = "内容" title(3) = "収入" title(4) = "支出" title(5) = "残高" '画面更新を停止 Application.ScreenUpdating = False '最終行取得 Bank1.Select lastRow1 = Cells(Rows.Count, 1).End(xlUp).Row Bank2.Select lastRow2 = Cells(Rows.Count, 1).End(xlUp).Row 'シートを作る For i = 1 To 3 Call MakeNewSheet_As_ThisName(classify(i)) For j = 1 To 5 Cells(1, j) = title(j) Next j Next i Call MakeNewSheet_As_ThisName(tempSheet) Cells.ClearContents Set Temp = Worksheets(tempSheet) '一時シートに、銀行1のデータと銀行2のデータをコピーする。 Bank1.Select Bank1.Range(Cells(3, 1), Cells(lastRow1, 5)).Copy Temp.Select Temp.Range(Cells(1, 1), Cells(lastRow1 - 2, 5)).PasteSpecial Bank2.Select Range(Cells(3, 1), Cells(lastRow2, 5)).Copy Temp.Select Cells(lastRow1 - 1, 1).PasteSpecial 'ソートする。 '第一優先キー:B列。[項目]昇順。 '第二優先キー:A列。[日付]昇順。 Range("A1:E" & (lastRow1 + lastRow2 - 4)).Select With ActiveWorkbook.Worksheets(tempSheet).Sort .SortFields.Clear .SortFields.Add Key:=Range("B1:B" & (lastRow1 + lastRow2 - 4)), Order:=xlAscending '第一キー .SortFields.Add Key:=Range("A1:A" & (lastRow1 + lastRow2 - 4)), Order:=xlAscending '第二キー .SetRange Range("A1:E" & (lastRow1 + lastRow2 - 4)) .Apply End With For i = 1 To 3 keyword = classify(i) findUpper = 0 findLower = 0 '上から探す For j = 1 To lastRow1 + lastRow2 - 4 Step 1 If Cells(j, 2) = keyword Then findUpper = j Exit For End If Next j If findUpper > 0 Then '下から探す For j = lastRow1 + lastRow2 - 4 To 1 Step -1 If Cells(j, 2) = keyword Then findLower = j Exit For End If Next j 'コピー Range(Cells(findUpper, 1), Cells(findLower, 5)).Copy Sheets(keyword).Select Range("A2").Select ActiveSheet.Paste Range("B2:B" & 2 + (findLower - findUpper)).Delete Shift:=xlToLeft Sheets(tempSheet).Select End If Next i '一時シートの削除 Application.DisplayAlerts = False Temp.Delete Application.DisplayAlerts = True 'アクティブセルをA1にしておく For Each ws In Worksheets Sheets(ws.Name).Select 'シート選択 Application.CutCopyMode = False Range("A1").Select Next ws Bank1.Select '画面更新を行う Application.ScreenUpdating = True MsgBox "実行しました" End Sub Sub MakeNewSheet_As_ThisName(ByVal GivenName As String) 'シートの有無を確認し、無ければ作る Dim exist_flag As Boolean Dim ws As Worksheet exist_flag = False For Each ws In Worksheets If UCase(ws.Name) = UCase(GivenName) Then 'シートが存在する場合 exist_flag = True Exit For End If Next ws 'シートを作成 If GivenName = "" Then MsgBox "空白名のシートは作れません。" ElseIf exist_flag = False Then Sheets.Add After:=Sheets(Sheets.Count) ActiveSheet.Name = GivenName End If Sheets(GivenName).Select 'シート選択 End Sub

  • エクセル vba セル合計

    添付表について下記の様な処理をしたいのですが途中からVBAの書き方が(セル合計)がわからず困っております。  *日別の原価計(K列のセル値)の小計(K列の最終入力行の下※k112)に計算する。 自分ではこの様を処理を考えております。 (1)商品名(G列)最終入力行の1行下を選ぶ(G112) (2) (1)の同行にある(k112)を合計算出セルとして選ぶ (3)商品名(G列)最終入力行(g112)からその列上の空欄行の1セル下(g66)を見て(要はg 112からEnd(xlUp))、その行と同じ範囲のK列(k112ーk66)を合計をする範囲として選ぶ (4) (2)の合計する範囲を(3)で算出する。 VBA素人の私では(1)~(3)までを下記の通り書きました。 Sub 原価合計求める() Dim lastrowshu As Long Dim lastrowgen As Long Dim fastrowgen As Long lastrowshu = Cells(Rows.Count, 7).End(xlUp).Row + 1 '帳票シートの商品名(G列)最終入力行+1を取得する。 lastrowgen = Cells(Rows.Count, 7).End(xlUp).Row '商品名行の最終入力 fastrowgen = Cells(lastrowgen, 7).End(xlUp).Row '商品名最終入力行から一番上 Cells(lastrowshu, 11).Select ここまでを実行すると添付ファイルでいうk112セルをselectするまではうまくいきましたが、 これ以降の(4)の合計の書き方がわかりません。 どなたか御教授願います。 あるいはもっといい方法があれば同時にご指導頂けますと幸いです。

  • VBA sumifで計算できません

    集計シートに入力シートから抽出した重複しない検索データの合計値を入力シートでSUMIFで書いてみましたが  「オブジェクトはこのプロパティまたはメソッドをサポートしていません。」とエラーになります。 何がいけないのか調べてみましたがVBA初心者でわからず困っています。 教えてください。よろしくお願いします。 Dim 集計データ数 As Long Dim 入力シートデータ数 As Long Dim データ行 As Long 集計データ数 = Cells(Rows.Count, 38).End(xlUp).Row 入力シートデータ数 = Worksheets("入力").Cells(Rows.Count,29).End(xlUp).Row For データ行 = 11 To 集計データ数 Cells(データ行, 11).Value = Application.WorksheetFunction.SumIf(Worksheets("入力").Range(Cells(11, 29), Cells(入力シートデータ数, 29)),Cells(データ行, 2), Worksheets("入力").Range(Cells(11, 21), Cells(データ行, 21))) Next データ行 End Sub

  • エクセル マクロで行の合計を数値で入力したい

    マクロ初心者です。 F列からAJ列までの合計をAK列に数値で入力しようとしています。 ただし、FからAJ列の各セルに全てデータは入っていません。 したがってFからAJ列のいずれかにデータが入っている最終行を 見つけて合計を算入しようとしているのですが下記の通りやっても うまくいきません。教えてください。 エクセルのバージョンは2002です。 Sub () 'データが入っている最終行まで合計額を数字で入力 LastRow = Cells(65536, COL).End(xlUp).Row For i = LastRow To 6 Step -1 Set myRange = Range(Cells(i, 6), Cells(i, 36)) Cells(i, 37).Value = WorksheetFunction.Sum(myRange) Next i End Sub

  • VBAで文字列のカウントがうまくいかない・・・です

    Dim cnt As Long Dim i As Long Dim lastRow As Long For i = 1 to 20 step 2 lastRow = Cells(65536, i).End(xlUP).Row cnt = WorksheetFunction.CountIf(ActiveSheet.Range(Cells(10, i),Cells(lastRow, i), "お世話になっております")cnt = cnt + cnt Next Excelのセルを1列ずつ飛ばして列に「お世話になっております」が含まれたら件数をカウントしています。 そのカウント数が何故かリセットされてしまいます。 カウント数を足していきたいのですが・・・考え方自体が違うのでしょうか?

  • ExcelのVBAで質問です。

    以下のようなシートがあります。 A列  B列  C列  D列  E列  F列  G列  H列 NO  名前  確認 日付1 日付2  確認 日付1 日付2 6行目からデータを入れる予定です。 C列には○印を入力します。 C列~E列までデータが入った行は、 F列~H列まで同じ処理をします。 (セルの背景色を変えます。) 以後同じことを列方向で繰り返します。 以下のようなVBAを組みましたが、 ○の個数を数える部分でエラーがでます。 Private Sub Worksheet_Change(ByVal Target As Range) Dim staff As String Dim kakunin As String Dim date1 As Date Dim date2 As Date Dim i As Long Dim j As Long Dim cnt As Long '100件分ループ For i = 6 To 105 '○の数をカウント cnt = WorksheetFunction.CountIf(ActiveSheet.Range(Cells(i, 2), Cells(i, 256)), "○") 'jとは確認の列番号のこと j = 3 * cnt staff = Cells(i, 2) kakunin = Cells(i, j) date1 = Cells(i, j + 1) date2 = Cells(i, j + 2) 'スタッフ名が入力されたら If staff = "" Then Range(Cells(i, j), Cells(i, j + 50)).Interior.ColorIndex = 15 Else Cells(i, j).Interior.ColorIndex = xlNone '○が入力されたら If kakunin = "○" Then Range(Cells(i, j + 1), Cells(i, j + 2)).Interior.ColorIndex = xlNone Else Range(Cells(i, j + 1), Cells(i, j + 2)).Interior.ColorIndex = 15 End If If Cells(i, j + 1) <> "" And Cells(i, j + 2) <> "" Then Cells(i, j + 3).Interior.ColorIndex = xlNone End If End If Next i End Sub ご教授いただけたら、幸いです。 よろしくお願いいたします。

  • VBA 検索をかけ合計数とGrp番号を抽出    

    現在、関数ではなく VBAでマクロを勉強しているのですが、 下記のコードでエラーが発生してしまいます。 是非、ご教授願えませんでしょうか。 Sheet3を作業用のSheetとして使用しています。  Sub Sample1() Dim i As Long, k As Long, lastRow As Long, wS2 As Worksheet, wS3 As Worksheet Set wS2 = Worksheets("Sheet2") Set wS3 = Worksheets("Sheet3") Application.ScreenUpdating = False With Worksheets("Sheet1") lastRow = .Cells(Rows.Count, "A").End(xlUp).Row .Range("A:A").AdvancedFilter Action:=xlFilterCopy, copytorange:=wS3.Range("A1"), unique:=True For i = 2 To wS3.Cells(Rows.Count, "B").End(xlUp).Row .Range("B1").AutoFilter field:=1, Criteria1:=wS3.Cells(i, "B") Range(.Cells(3, "B"), .Cells(lastRow, "B")).SpecialCells(xlCellTypeVisible).Copy wS2.Cells(3, (i - 1) * 2) For k = wS2.Cells(Rows.Count, (i - 1) * 2).End(xlUp).Row To 2 Step -1 wS2.Cells(k, (i - 1) * 2 - 1) = WorksheetFunction.CountIfs(.Range("A:A"), wS3.Cells(i, "A"), _ .Range("C:C"), wS2.Cells(k, (i - 1) * 2)) For j = 2 To wS3.Cells(Rows.Count, "E").End(xlUp).Row .Range("E1").AutoFilter field:=1, Criteria1:=wS3.Cells(j, "E") Range(.Cells(3, "E"), .Cells(lastRow, "E")).SpecialCells(xlCellTypeVisible).Copy wS2.Cells(3, (j - 1) * 2) For l = wS2.Cells(Rows.Count, (j - 1) * 2).End(xlUp).Row To 2 Step -1 wS2.Cells(j, (j - 1) * 2 - 1) = WorksheetFunction.CountIfs(.Range("A:A"), wS3.Cells(j, "A"), _ .Range("E:E"), wS2.Cells(k, (j - 1) * 2)) If WorksheetFunction.CountIf(wS2.Columns((j - 1) * 2), wS2.Cells(k, (j - 1) * 2)) > 1 Then wS2.Cells(l, (j - 1) * 2 - 1).Resize(, 2).Delete shift:=xlUp End If Next k Next i wS2.Range("A1").CurrentRegion.Borders.LineStyle = xlContinuous .AutoFilterMode = False End With Application.ScreenUpdating = True End Sub 実際に抽出結果を出したい概要は下記に用になります。 検索したいsheet1には セルBにはUsername番号などがあります。      A        B       C     D     E     F     G 1           Username      Grp番号    2           yamada10x      Grp1             3           yamada4x       Grp1    4           yamada10x      Grp1 5           yamada10x      Grp1 6           yamada4x       Grp2 7           yamada10x      Grp2 8           yamada4x       Grp2 9           yamada10x      Grp3 . . 50           yamada4x      Grp40 Sheet2にはセルBとCにyamada10xの合計数とgrp番号、セルEとFにはyamada4xの合計数とgrp番号などがあります。      A        B          C       D        E           F      1 2       yamada10xの合計数 Grp番号       yamada4xの合計数  Grp番号   3                                   4                                  5               . . 10                                          sheet1で検索したユーザ名・Grp番号などを行数3のセルC・FにはGrp番号を抽出 行数3のセルB・EにはGrp番号ごとのyamada10xとyamada4xの合計数をsheet2に 抽出させたいという形になります。       A        B          C       D        E          F      1 2       yamada10xの合計数  Grp番号       yamada4xの合計数 Grp番号   3               3         Grp1            1        Grp1 4               1         Grp2            2        Grp2 5               1         Grp3 . . 10                                         1       Grp40 わかりにくい図と説明で申し訳ございません。 お手数をおかけしますが、ご教授の方をお願いできますでしょうか。 よろしくお願い致します。

  • VBA RemoveDuplicatesが動かない

    以下のマクロを実行しても動きません。 RemoveDuplicatesの行でエラーとなります。 メッセージ:アプリケーション定義またはオブジェクト定義のエラーです。 何が間違ってるのでしょう? エクセル2013 Windows8 E列の重複を削除するマクロです。不要なWithを使っているのは、別マクロから切り出したものだからです。 Sub test() Dim Colref As Long, LastRow As Long With Worksheets("Sheet1") Colref = 5 LastRow = Cells(Rows.Count, Colref).End(xlUp).Row Range(.Cells(1, Colref), .Cells(LastRow, Colref)).RemoveDuplicates Columns:=CVar(Colref), Header:=xlNo End With End Sub

専門家に質問してみよう