Excel VBA同一文字列のポイントを合計

このQ&Aのポイント
  • Excel VBAを使用して、同じ文字列のポイントを合計する方法について教えてください。
  • 具体的な処理は、VBAコードを使用して、選択されたワークシート内の予約識別子(C列)の重複をチェックし、ポイント(D列)を合計し、新しいシートに結果を表示します。
  • また、重複した識別子が見つかった場合には、最初に出現した行の識別子を一覧の最初に表示するようにしたいとのことです。
回答を見る
  • ベストアンサー

Excel VBA同一文字列のポイントを合計

ExcelのVBAのコードを教えてください。 (自分で範囲(Rangeや Cells)のValueの合計などはできるのですが、グダグダ書くとわかりにくくなるので、やりたいこと=実現したいことのみ書きます) 画像の上図(青い線より上の図)は、現状もっているExcelのファイルです。緑のタイトルがついているE列までが実データです。 似たようなデータ(表)を含むワークシートがこのファイル(Book内)に複数あるのですが、とりあえず処理対象はアクティブな(選択して見ている)ワークシートを対象とします。 作業としては、上図のように6行目にタイトルが並んでおり、そのうちのC列「予約識別子」とD列「ポイント」を集計しています(処理対象はC, D列です)。予約を入れる「クリック」という「行為」に対して予約識別子が立って、それに対してポイントが溜まる、みたいなシステムです。最終行は毎月異なるので、n行としています。n行というのは、月によって100行のときもあれば、10000行を超えることもあります。 処理行為としては、黄色い2列を新たに加えて作業に使っています。 G列に計算式でC列(予約識別子)に重複がある行に1というフラグを建て、次にフィルターでC列の同じ文字列(例えば「CD08」)をフィルターして、Subtotalでそれぞれの文字列(例えば「CD08」)のポイントの合計を算出しています(F列の最初の識別子の行に、合計ポイントを入れている[F7の1000、F9の2500、F12の16000など])。 最終的に、図の青い線より下のような別シート(新シート)をつくっています。これが成果物です。(シート名はSheet1、Sheet(1)のような、単純につくった順番がわかれば良いです。) 現在計算式とフィルターでやっている処理は、100行程度であれば人の手でもすぐに終わるのですが、10000行を越えていると、時間がかかったり、操作する人によってはヒューマンエラーで計算ミスが起こります。 これをVBAでやりたいのです。 C列(文字列String)の重複をみつけ、D列のポイント数値(これは数字Longです)を合計して、別の新しいシートに左上(A1からで良い)並べたい。 これを実現するコードを教えてください。 なお (ここから下はマストではないのですが) 集計後の識別子の並びは、重複したものがみつかっても最初に出現した行の文字列を一覧の最初に残したいと思っています。 例えば7行目にある「CD08」(青いセル)は上図の表では1行目、10行目に出現しているのですが、下図のシートでも最初に出現した行(新シートでも最初の行)に入れたい。 上図の12行目にある「E3EA」(ピンク)は、15,19,20行にもありますが、12行目を最初の出現とし、「BF0D」の次に置いています。 これはクリックをされた方が、複数の商品に対して予約行為(クリック)を行えますが、予約時刻を記録している列がすでに削除されてしまっているため、予約順(最初の一手の早押し順)を見える化しておきたいのです。

  • ketae
  • お礼率85% (293/342)

質問者が選んだベストアンサー

  • ベストアンサー
  • kagakusuki
  • ベストアンサー率51% (2610/5101)
回答No.1

>シート名はSheet1、Sheet(1)のような、単純につくった順番がわかれば良いです。 という条件を満たす際に、もし古い集計結果のシートが削除されるなどといった理由で、例えば Sheet(1)、Sheet(3)、Sheet(4) などの様に途中に抜け(上記の場合はSheet(2))があったり、 Sheet(3)、Sheet(4)、Sheet(2)、Sheet(1) の様に、順不同に並んでいたりする恐れがある事も考慮しなければならなかったため、シートを作成した順番通りに番号が付く様にする事が結構面倒でしたが、何とか御要望通りになる様にする事が出来ました。  尚、新しく作成されるシートのシート名は、取り敢えず 「Activeシートのシート名」+「_集計 (」+「そのシートが作成された順番」+「)」 という形式になる様にしております。 Sub QNo9232496_Excel_VBA同一文字列のポイントを合計() Const OrigItemRow = 6 '元データのシートにおけるタイトル行 Const OrigFirstColumns = "C:E" '元データのシートにおけるコピーする列範囲 Const GroupOrigColumn = "C" '元データのシートにおける「予約識別子」の列 Const NumericOrigColumn = "D" '元データのシートにおける「ポイント数」の列 Const PasteCell = "A1" '集計結果のシートの中の貼り付け先のセル Const GroupPasteColumn = "A" '集計結果のシートにおける「予約識別子」の列 Const NumericPasteColumn = "B" '集計結果のシートにおける「ポイント数」の列 Const AddString = "_集計(" '元データのシートのシート名を基にして、集計結果のシートのシート名を作る際に付け加える文字列 Dim OrigSheet As Worksheet, OutputSheet As Worksheet, OrigRange As Range, _ buf As Variant, m As Long, n As Long, i As Long Set OrigSheet = ActiveSheet With OrigSheet n = .Cells(Rows.Count, Range(OrigFirstColumns).Column).End(xlUp).Row If n <= OrigItemRow Then MsgBox "処理すべきデータが見当たりませんません。" & vbCrLf _ & "マクロを終了します。", vbExclamation, "データ無し" Exit Sub End If m = 1 For i = 1 To Sheets.Count buf = Sheets(i).Name If buf Like .Name & AddString & "*#)" Then buf = Mid(buf, InStrRev(buf, AddString) + Len(AddString)) buf = Left(buf, Len(buf) - 1) If IsNumeric(buf) Then If m - buf <= 0 Then m = Int(buf) + 1 End If End If Next i Application.ScreenUpdating = False Application.Calculation = xlManual Set OutputSheet = Sheets.Add(after:=Sheets(Sheets.Count)) OutputSheet.Name = .Name & AddString & m & ")" Set OrigRange = Intersect(.Range(OrigFirstColumns), .Range(OrigItemRow & ":" & n)) .Select End With Application.CutCopyMode = False OrigRange.Copy With OutputSheet With .Range(PasteCell) .PasteSpecial Paste:=xlPasteAll .PasteSpecial Paste:=xlPasteColumnWidths Application.CutCopyMode = False .Resize(OrigRange.Rows.Count, OrigRange.Columns.Count).RemoveDuplicates _ Columns:=Range(PasteCell & ":" & GroupPasteColumn & 1).Columns.Count, Header:=xlYes End With With .Range(NumericPasteColumn & Range(PasteCell).Row + 1 & ":" & NumericPasteColumn _ & .Cells(Rows.Count, Range(PasteCell).Column).End(xlUp).Row) .FormulaR1C1 = "=SUMIF('" & OrigSheet.Name & "'!C" & Columns(GroupOrigColumn).Column _ & ",RC" & Columns(GroupPasteColumn).Column & ",'" & OrigSheet.Name & "'!C" _ & Columns(NumericOrigColumn).Column & ")" .Parent.Calculate .Value = .Value End With End With With Application .Calculation = xlCalculationAutomatic .ScreenUpdating = True End With End Sub

ketae
質問者

お礼

いつもありがとうございます。そしてお世話になります。 望む結果になりました。勉強しないとちょっと分からない部分もありますが、おいおいまた別質問を建てたいと思います。 シートは連番でいいと書いたのは、集計したらすぐにCSVファイルに書き出して保存し、この集計データを別のホストシステムで扱う担当者に渡すフローが別にあるため、計算した結果を同じBook内にワークシートのまま保存することがないためでした。 説明不足で申し訳ありません。

関連するQ&A

  • 複数のシートの合計

    3つシートがあります。 各シート、A列にA01,A02・・・B05・・・などの番号が入力されています。平均300行くらいです。 ただし、各シートの番号は全く同じではなく、例えばsheet1と3にはF45があってもsheet2にはない、といった感じです。 そして、このA列に対してB、C、D列にはカテゴリわけされて数字が入っています。 たとえばりんご、みかん、バナナとあり、A01のりんごは5、みかんは0、バナナは5個といった感じです。 このシートを1つに重複せずにまとめたいのです。 例えばsheet1-3のA02のりんごの合計は5、E06のバナナの合計は1といった感じです。 一度A列を別シートに全て貼り付け、フィルタオプションで重複を除き、その後、VLOOKUPで各シート抽出し、その合計を出す、とやっていたのですが、#N/Aが出てしまい、値に直そうにもフィルタがかかっていてさらに別シートに貼り付けなおして・・・とやっているのですが、あまりにも時間がかかり(同じようなファイルが50個近くある)、もっと効率のいい方法があったら教えてほしいです。

  • Excelで文字列をまとめたい

    こんにちは いつもお世話になります。 このカテへの投稿は初めてですが、今頼まれて簡単な集計表を作ろうとしています。 あるシートを入力専用のシートにし、たとえばA列に日付、B列には品名、C列には数量を入れるとします。 これを1ヶ月続けたあと、品名でまとめた集計表を作ります。 100行くらいのデータのうち、種類としては10数種類であり、その数は毎月変動します。(行数も) 集計表に重複せずに整理するため、今まではB列だけを別にコピーし、手動でソートして重複しているデータを削除していました。 これをなんとかもっと簡単に行う方法はないものでしょうか? 残りの数字の部分はSUMIF関数を使って合計させていますので簡単なのですが、前処理にいい方法が思いつきません。 ぼちぼち頭の柔軟性に疑問符がつき始めた小生になにかいいヒントをいただけましたら幸いです。 よろしくお願いいたします。

  • エクセル 合計条件が行と列の時の計算式

    エクセルで、データがはいっている”データシート”と 合計を表示させたい”合計シート”があり、 合計シートに同じ番号の品名でおなじ日付のものを合計して 表示させたいと思っています。 データシートには、以下のように品名が同じものが複数はいっています     A列 B列 C列 D列・・・・Z列これからさらにデータが増えていきます 1行目品名 4/1 4/4 4/5 2行目Z100 10  20  30 3行目Z300 40  50  60 4行目Z100 11  22  33 5行目Z200 70  80  90  ・  ・ 200行くらいデータがありこれからさらにデータが増えていきます。 合計シートもデータシートと同じような形で データシートのA列の 同じ番号&同じ日付 の数字をそれぞれセルB2からZ200まで合計した 数字を表示させたいです。     A列 B列 C列 D列・・・・Z列 1行目    4/1 4/4 4/5 2行目Z100 21  42  63 3行目Z300 40  50  60 4行目Z200 70  80  90  ・  ・ 200行目 合計シートのB2セルに入力したのですが、#VALUEエラーがでてしまい ました。 =SUMPRODUCT((データシート'!$A$2:$A$500=合計シート!$A2)*(データシート'!$B$1:$Z$1,合計シート!$B1)) SUMIFでも試してみたのですが、エラーがでてしましました。 説明が分かりにくく申し訳ないですが、どなたか分かる方いらしたら 教えてください。よろしくお願いします。

  • エクセルで二つの条件での合計値

    こんにちわ。 関数でいろいろやってみているのですが、どうしてもうまくいきません。 シート1に一覧表があります。A列にコード番号(約500番)、B列に名前、C列に種類わけ(10種類・リストにしています)、D列に数字が入っています。これが約5000行あります。 これをシート2に、コード番号(A列)及び種類(C列)が一致するものの数字(D列)の合計を出した、自動更新される集計表を作りたいのです。 しかも、C列の種類わけしているものの中から、2つずつペアリングしての数字(D列)の合計を出したいのです。 ピボットテーブルやオートフィルターでひとつずつ出していってもいいのですが、次々と追加で行が増えていくので、その都度集計表を更新していくのもタイヘンだと思い、自動的に更新されるといいなと思っています。 説明不足なことがありましたら、返答します。 相当困っています。 どなたか助けてください。 よろしくお願いします。

  • EXCELの合計

    A列に色々な顧客名がB列に数値が入っています。 現在顧客別にソートを掛けて合計を集計していますが 別シートに自動的に顧客別のシートをつくりそこに自動的に数値合計が 反映できる事は可能でしょうか(同じシート内でも可)。 C列に顧客と数値合計が飛ぶようにしたのですがソートを掛けると 行全体が動くので上手くいきません・・・

  • EXCEL VBAで思ったように動いてくれないのですが。

    度々すみません。お世話になります。Win98-EXCEL2000での処理です。 やりたいことは、A~Eまでのファイルを変数で開き、各ファイルの総シート数の1/2のシート数のシート(1)~シート(?)までを処理し、1つ目のファイルのシート処理が終わった段階で合計をして、別シートに合計のみを転記、次のファイルの処理へ移動したいのです。 WithやLoopの使い方や、SETやNextはどこで書いていいのかがよく解っていないので、何をどこでどう書いてよいのか教えてください。多分意味不明だと思うので、補足しますのでお願いします。今の処理だとSheetYOの合計処理がすっ飛ばされているような気がします。 Sub TEST() 各種変数宣言 For iii = 1 To 4 If iii = 1 Then f = "A_log" ElseIf ・・・残りB~Eまで入力 Exit For End If Next iii Workbooks.Open Filename:=f & ".xls" c = Worksheets.Count / 2  With sheetSET Set sheetSET = Workbooks(f & ".xls").Sheets(iiii) Set sheetYO = マクロを書いているファイルです。 Do Until iiii = c For iiii = 1 To c   If iiii = 1 Then      オートフィルタ処理 Sheets(iiii).AutoFilter.Copy sheetYOにコピー処理 Else 上記と同じオートフィルタ処理 Sheets(iiii).AutoFilter.Range.Offset(1, 0).Copy 上記の最終行+1にコピー処理 Exit For End If Next iiii Loop End With With sheetYO    別シートに合計のみを転記 End With Workbooks(f & ".xls").Close False End Sub

  • VBA初心者です。シート1の文字列をシート2のリストにコピーしたい。

    VBA初心者です。 ExcelのVBAでシート1の文字列をシート2のリストに追加したいのですが すでにリストに登録されているものは(重複するもの)追加しないようにしたいのですがうまくいきません。 シート1のA列に「商品名」B列に「色番号」が入力されています。 A   B 1ペン 123 2ペン 233 3ペン 123 4ペン 222 ※A列とB列はセットです。 このようになっていたとして、それぞれに変数A・Bを用意して シート2の商品リストに入れていくのですが 1行目と3行目のように重複するものは(すでにリストに入っているもの) 1つ目だけをリストに加え、2回目以降のものはリストに加えたくありません。 条件をIF文で書いているのですが、重複するものの判定がうまくいかず 困っています。 シート1には毎回違う納品書がくるのでフィルタ等で重複を 探すことはできません。

  • Excelで特定の文字のある列の数値を合計する関数

    Excelで、特定の文字列を含む列の数値の合計を、自動で集計してくれる関数はあるでしょうか。 複数シート(シートA、シートB)で構成されるExcelファイルで、シートAにはすべての取扱い商品が記載されています。現在は、シートBに入力されている商品ごとの販売個数の合計をシートB上でsumにより求め、その数値をシートAの該当箇所に、手で入力しています。シートAに記載されている商品が多いため、この手作業を関数で代替したいのです。 ただし、シートBに、次のような条件があります。 シートBの1行目(A1,B1,C1,D1...)には、見出しとして"氏名" "りんご" "バナナ" "いちご"...などがあり、2行目以降は、販売者の名前と、その人が販売した商品の個数が入力されています。掲載人数は40人(行数で41行)ほどです。 ところが、誰も"りんご"を販売していなければ、その列自体がなくなります。シートBには販売された商品しか記載されておらず、たとえばB1は、必ずしも"りんご"ではありません。 シートAからBを参照し、シートBの1行目に、もし"りんご"の文字があれば、そのりんごの列の2行目以降にある販売数の合計を、"バナナ"があれば同じくバナナの販売数の合計を、じかにシートAのそれぞれの合計欄に表示させたいのです。 なお、シートBの行と列を入れ換えたシートB'を作るのは、避けたいと思っています。理由は、販売者の名前でも、全商品の販売個数をシートAにsumif関数で集計していること。また、シートは1週間ごとに、今後30枚程度まで増え、その各週合計もシートAに集計する予定のため、シートは各週1枚だけにしたいのです。 このような条件のもと、Excelの関数で集計する方法があれば、教えてくださいますか。

  • エクセルで条件指定した行の合計値の出しかた

    A列 B列 C列 100  1   1 200  2   2 300  3   3 400  4   4 500  4   5 600  2   2 700  3   1 800  4   4 下記の条件にあてはまる行のA列の合計値をそれぞれ出したい。 ・B列が2以上、C列が2以下である。 ・B列が2以上、C列が3以上5以下である。 上記のデータ例が不定期にブロック分けされていて、オートフィルタが使いずらい状況です。 各合計値を出力するセルを指定して、関数等で処理する方法があったら、教えて下さい。

  • エクセル2007での質問です。A~I列にデータが入っています(1行には

    エクセル2007での質問です。A~I列にデータが入っています(1行には見出し、よって2行目からデータが入っています)。C列には名前(色々なデータが入っているので、C列には同じ名前人の名前が何行か入っています)。G列には、10~25の数字が入っています。 1行目にフィルタをかけます。C列で、Aさんの名前でフィルタをかけます(C列は、人によって行数が違います)。こしてフィルタをかけるた時に、G列の10~25あるうちの 13のみの合計を(これも13は、何行かあります)。 このAさんのみフィルタかけ、そのG行のうちの13の合計額を、A1000に出したいのですが、どうしたらいいですか?(A1000に出したいってことは、999までデータが入っています)。 どう関数を入れたらいいか教えてください。

専門家に質問してみよう