• 締切済み

主キーを軸として複数項目を抽出し、統合するには?

Excel2003を使用しています。A列を主キーとしてデータを抽出&統合したいです。(重複レコードは削除) <元データ> (A列)ID、(B列)時刻、(C列)名称という3列で構成されるデータが3000行あります。 実際のデータ内容としては  (A列)ID123456、(B列)00:01:00、(C列)りんご 開始、です。 同一IDについては、関連データが必ず2行あります。(データ行の並び順は、ID順というわけではなく、ランダムです) ※「名称」に"開始"という文字が入っているものと、「名称」に"終了"という文字が入っているものの2種類です。 ※「時刻」はそれぞれ異なります。 ※同一IDの場合、C列の「名称」も("開始"か"終了"のテキストが入っている事を除けば)同一です。 例1) 関連データ1:(A列)ID123456、(B列)00:01:00、(C列)りんご 開始    関連データ2:(A列)ID123456、(B列)00:05:00、(C列)りんご 終了 <抽出内容> 上記のようなデータを、1つのIDにつき1行にまとめ、下記の形式の表を作成したいです。 (A列)ID、(B列)名称、(C列)開始時間、(D列)終了時間、(E列)処理時間(終了時間-開始時間で算出する) 例1)の場合、下記になります。 (A列)ID123456、(B列)りんご、(C列)00:01:00(開始時間)、(D列)00:05:00(終了時間)、(E列)00:04:00(処理時間) <希望> 関数、ピボットテーブル、フィルタオプション、VBA、いずれでも結構ですが、これを元に日々使用する自動ツールを作成するため、汎用性のある簡潔な方法が良いです。 (元データの列構成と抽出後データの列構成は固定ですが、元データ行数は可変します。1万行ぐらいまで増加する可能性あり) 宜しくお願い致します。

みんなの回答

  • bunjii
  • ベストアンサー率43% (3589/8248)
回答No.6

質問の内容から業務用のデータ処理と思われます。 大量のデータを一括処理するときはCSV形式のファイルに書き出してExcelと関係のないテキスト自動編集プログラムを専門家に作成してもらうと良いでしょう。 前処理としてExcelを使ってIDをキーとしてソートすればC++等で簡単なプログラムができると思います。 業務用の処理システムは自作できないとき有償で外注すべきです。 ボランティアの知恵を借りるのは甘え過ぎです。 仕事としては単純な作業なので操作手順をマクロに記録すれば元データを読み込むだけで自動処理できます。 元データの時刻を名前に付加されている”開始”または”終了”を手掛かりに追加された列へIF関数を使って代入できます。 開始時刻と終了時刻に振り分けられたセルから計算式のみ除去するには対象範囲を選択してクリップボードへコピーし、同じ場所へ値のみを張り付ければ良いでしょう。 次に元データの時刻をキーとしてシート全体を対象にソートし、更にIDをキーとしてソートすれば同一IDの開始時刻、終了時刻の組み合わせができますので、終了時刻の最上位セルを削除して上へシフトすれは最後の処理として開始時刻と終了時刻が空欄の行を削除します。 以上の作業は応用力のみで解決する単純作業です。

chamogoo
質問者

お礼

ありがとうございます!

全文を見る
すると、全ての回答が全文表示されます。
  • keithin
  • ベストアンサー率66% (5278/7940)
回答No.5

>ですが、名称(りんご)は重複します。 別に問題ありません。回答した通りの手順で全く問題無く出来ますが、何か? #ちなみにマクロだとこんなカンジで。 sub macro1()  dim LastRow as long  range("D:I").insert shift:=xlshifttoright  range("G:I").numberformat = "hh:mm:ss"  lastrow = range("A65536").end(xlup).row  with range("D2:D" & lastrow)   .formula = "=ROW(D1)"   .value = .value  end with  range("A:D").sort key1:=range("A1"), order1:=xlascending, key2:=range("B1"), order2:=xlascending, header:=xlyes  range("E1:I1") = array("ID","商品","開始","終了","処理")  range("E2").formula = "=A2"  range("F2").formula = "=LEFT(C2,LEN(C2)-3)  range("G2").formula = "=B2"  range("H3").formula = "=B3"  range("I2").formula = "=H3-G2"  range("E2:I3").copy range("E2:I" & lastrow )  range("E2:I" & lastrow).value = range("E2:I" & lastrow).value  range("E2:I" & lastrow).specialcells(xlcelltypeblanks).delete shift:=xlshiftup  range("A:D").sort key1:=range("D1"), order1:=xlascending, header:=xlyes end sub #元データの並び順を保全する必要が無ければもっと簡単に。 sub macro1r1()  dim LastRow as long  range("E:I").insert shift:=xlshifttoright  range("G:I").numberformat = "hh:mm:ss"  lastrow = range("A65536").end(xlup).row  range("A:C").sort key1:=range("A1"), order1:=xlascending, key2:=range("B1"), order2:=xlascending, header:=xlyes  range("E1:I1") = array("ID","商品","開始","終了","処理")  range("E2").formula = "=A2"  range("F2").formula = "=LEFT(C2,LEN(C2)-3)  range("G2").formula = "=B2"  range("H3").formula = "=B3"  range("I2").formula = "=H3-G2"  range("E2:I3").copy range("E2:I" & lastrow )  range("E2:I" & lastrow).specialcells(xlcelltypeblanks).delete shift:=xlshiftup end sub

chamogoo
質問者

お礼

ありがとうございます!

全文を見る
すると、全ての回答が全文表示されます。
noname#204879
noname#204879
回答No.4

簡単化するために、「元データ」を添付図 Sheet1 に示すように4列にします。 Sheet2 において、 B2: =VLOOKUP(A2,Sheet1!A:D,3,FALSE) C2: =SUMPRODUCT((Sheet1!$A$2:$A$10000=$A2)*(Sheet1!$D$2:$D$10000=C$1),Sheet1!$B$2:$B$10000) セル C2 を[コピー]して、此れをセル D2 に[貼り付け] E2: =D2-C2 範囲 B2:E2 を下方にズズーッとドラッグ&ペースト

chamogoo
質問者

お礼

ありがとうございます!

全文を見る
すると、全ての回答が全文表示されます。
  • MackyNo1
  • ベストアンサー率53% (1521/2850)
回答No.3

ピボットテーブルを利用するなら以下のような手順になります。 まず準備として、C列を選択して「データ」「区切り位置」で「カンマやスペース・・・」にチェックが入っていることを確認して「次へ」で区切り文字の「その他」の欄にスペースを入力して「完了」します(添付画像上参照)。 このデータでピボットテーブルを作成し、行フィールドに「ID」と「品名」、列フィールドに「開始/終了」、データフィールドに「時刻」をドラッグし、データフィールドで右クリックし「フィールドの設定から「合計」を選択し、セルの書式を時刻にします。 さらにピボットテーブル上で右クリックし「オプション」から「列の合計」「行の合計」のチェックを外します。 またIDごとの合計欄にカーソルを置いて右クリックから「表示しない」を選択します(これで添付画像下のようなレイアウトになります。 E列の処理時間は「=IF(D13="","",D13-C13)」のような数式を入力しておきます。 ちなみに「合計/時刻」や「開始/終了」などの文字は、そのセルでスペースを入力して見えなくしたほうがきれいなレイアウトになると思います。 また罫線をデータ範囲だけに入れたい場合は、条件付き書式などを利用することもできます。

chamogoo
質問者

お礼

出来ました!ありがとうございます。

全文を見る
すると、全ての回答が全文表示されます。
  • tom04
  • ベストアンサー率49% (2537/5117)
回答No.2

こんばんは! VBAになってしまいますが、一例です。 IDと名称は常に対応していて、重複はない!という前提です。 ↓の画像のようにSheet1のデータをSheet2に表示するようにしてみました。 両Sheetとも1行目の項目は入力済みで、Sheet1のデータは2行目以降にあるとします。 Alt+F11キー → メニュー → 挿入 → 標準モジュール → VBE画面に ↓のコードをコピー&ペーストしてマクロを実行してみてください。 (Alt+F8キー → マクロ → マクロ実行です) Sub Sample1() 'この行から Dim i As Long, k As Long, endRow As Long, c As Range, wS1 As Worksheet, wS2 As Worksheet Set wS1 = Worksheets("Sheet1") Set wS2 = Worksheets("Sheet2") Application.ScreenUpdating = False endRow = wS2.Cells(Rows.Count, "A").End(xlUp).Row If endRow > 1 Then Rows(2 & ":" & endRow).ClearContents End If For i = 2 To wS1.Cells(Rows.Count, "A").End(xlUp).Row If WorksheetFunction.CountIf(wS2.Range("A:A"), wS1.Cells(i, "A")) = 0 Then With wS2.Cells(Rows.Count, "A").End(xlUp).Offset(1) .Value = wS1.Cells(i, "A") If InStr(wS1.Cells(i, "C"), "開始") > 0 Then .Offset(, 1) = Trim(Replace(wS1.Cells(i, "C"), "開始", "")) .Offset(, 2) = wS1.Cells(i, "B") Else .Offset(, 1) = Trim(Replace(wS1.Cells(i, "C"), "終了", "")) .Offset(, 3) = wS1.Cells(i, "B") End If End With Else Set c = wS2.Range("A:A").Find(what:=wS1.Cells(i, "A"), LookIn:=xlValues, lookat:=xlWhole) If Not c Is Nothing Then k = c.Row If InStr(wS1.Cells(i, "C"), "開始") > 0 Then wS2.Cells(k, "C") = wS1.Cells(i, "B") Else wS2.Cells(k, "D") = wS1.Cells(i, "B") End If End If End If Next i For i = 2 To wS2.Cells(Rows.Count, "A").End(xlUp).Row If WorksheetFunction.Count(Range(wS2.Cells(i, "C"), wS2.Cells(i, "D"))) = 2 Then With wS2.Cells(i, "E") .Value = .Offset(, -1) - .Offset(, -2) End With End If Next i wS2.Range("C:E").NumberFormatLocal = "[h]:mm:ss" Application.ScreenUpdating = True End Sub 'この行まで こんな感じではどうでしょうか?m(_ _)m

chamogoo
質問者

補足

早々にありがとうございます! 前提についてですが、元ソースで、同一IDのレコードは常に2つ("開始"と"終了")です。 ですが、名称(りんご)は重複します。 ID123456が"りんご"で、ID222222も"りんご"、ID333333は"バナナ"という具合です。

全文を見る
すると、全ての回答が全文表示されます。
  • keithin
  • ベストアンサー率66% (5278/7940)
回答No.1

ふつーに考えて、ID123456は必ず商品りんごに対応しているのですね。 ピボットテーブルレポートを使うなら、C列の「りんご開始」「りんご終了」のそれぞれ「りんご」が邪魔です。D列に関数を追加する(マクロで追加させるのでも勿論可)なり、C列を直接マクロで修正するなりして「開始」と「終了」だけにしてしまいます。 ○IDを列に配置する ○時間をデータに配置する ○「開始」「終了」だけにしたD列若しくはC列を行に配置する ○行に集計アイテムとして「=終了-開始」を追加する とりあえず以上で、最低限必要な集計は出来ます。 ●以下はオプションです 更に元データとしてE列に、IDに対応した(若しくはC列から生成した)「商品名」(りんごだけ記載)を追記し列に配置する 「商品名▼」を右クリックしてフィールドの設定の「詳細」から「トップテン表示」を選び、使用するフィールドを「合計/時刻」にする エクセル2007以降を利用する環境があれば、 1.必要に応じてマクロを併用し、「重複の削除」を使って一意のID一覧を作成する 2.SUMIFS関数を使ってID・開始、ID・終了の時刻をそれぞれ参照する 3.引き算して時間を求める 4.VLOOKUP関数などでIDから「りんご××」を取り出してきて、××部分を(もちろん関数を使って)除去して「りんご」だけを算出する ぐらいでも良いです。 1万行を想定するなら、「関数を使って一意のIDリストを並べさせる」みたいなことは考えてはいけません。またExcel2003以前では、関数(例えばSUMPRODUCT関数等)を使って回答後半の方法を試みるのもお勧めしません。 いずれもやればできますが、実際はよほど丁寧に作業列を追加する等して準備しないと使い物になりませんので。

chamogoo
質問者

補足

ありがとうございます! 元データで、同一IDのレコードは常に2つ("開始"と"終了")です。 ですが、名称(りんご)は重複します。 ID123456が"りんご"で、ID222222も"りんご"、ID333333は"バナナ"という具合です。 つまり、"開始"と"終了"という2つのレコードを、IDを主キーとして1つに統合する作業です。 従って、元データが3000行であれば、抽出後のデータは1500行になります。 残念ながら、Excel2007の環境はありません…

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • Excel 複数の項目合致するデータを抽出したい

    是非、よろしくお願いいたします。 以下の状況です。 sheet1には A、B、C、Dという4列があります。データは1000行くらいです。 sheet2には A、B、C、Eという4列があります。データは2000行くらいです。 この状況で、sheet1のD列の右に新しい列を作り、 「sheet1の(例えば)A1、B1、C1と合致する行のsheet2のE列データ」を、 sheet2のABC列範囲を検索して抽出したいのです。 項目が一つであればvlookup関数でできるものを「複数項目に合致」のため上手くいきません。 この3列のデータを結合して一つにしてみましたが、結合後のデータが16桁以上のため末尾が「0」になってしまい、正確に検索できません。 何か上記を可能にする方法はないでしょうか? よろしくお願いいたします。

  • excelの複数シートを検索対象にして重複行を抽出する方法

    ある値が重複する行を抽出したいのですが 抽出元データが600,000行近くあり、1sheetに入らず9シート程に分けました。 countifを使おうとしたのですが検索範囲に複数シート指定が出来ず(3D-参照の対象関数ではないようです)、 =COUNTIF('sheet1:sheet9'!$C:$C,C1)としてみたのですが、重複行があっても全て#VALUE!となってしまうので機能できていないようです。 具体的には sheet1~8に下記のようなデータがあり、C列が重複する行を抽出したい。 A列:id、B列:名前、C列:メアド、D列:xx 宜しくお願い致します。

  • エクセルで項目抽出

    エクセルで下記のような表から項目を抽出したいのですが うまくいきません A列 りんご みかん りんご ぶどう みかん と入力されていて任意のセルに、A列に入力されている項目から 重複分を除き抽出したいです 具体的には任意セルに「りんご、みかん、ぶどう」と抽出したいのです。 オートフィル機能を使いやってみましたが、 A列に後からデータを追加すると追加データまでは拾えませんでした。 よろしくお願いいたします

  • ある項目の種別だけ抽出する方法

    Excel2010です。 銀行明細書の項目毎の整理を行いたいのですが A列に日付、 B列に金額、 C列に電気代や水道代、ガス代といった項目の名称 が入っています。 C列から検索して、 電気代の行のみを全て抽出して 日付、金額をまとめるようなことをしたいのですが どうすれば良いですか? VBAが必要でしたら その方法を教えてください。

  • EXCEL、複数の条件からデータを抽出

    EXCELを使って複数の条件からデータを抽出したいです。 条件は 利用した施設、開始時間、終了時間の3つから条件にあう金額を抽出したいです。 VLOOKUPでは一つの条件からでしか抽出が出来ないので困っています。 A列に利用した施設、G列に開始時間、H列に終了時間が並んでいます。K列に金額を抽出したいです。 それぞれの時間、施設ごとの料金表をつくってそこから抽出しようと思っています。使用出来る関数やそれ以外にもやり方などあればご教授頂ければと思います。宜しくお願い致します。

  • Excel2003 複数の条件を満たすデータを抽出する関数を教えて下さ

    Excel2003 複数の条件を満たすデータを抽出する関数を教えて下さい! 下のデータで、A列でB、B列で赤を選んだ人は「みかん」という「みかん」を抽出する関数を教えて頂けませんでしょうか? データシートとは別に集計シートを作成しています。 お忙しい中恐れ入りますが、ご教示下さいますようお願い申し上げます。。。 ●データ A B C 1 A 赤 みかん 2 B 赤 りんご 3 C 白 いちご 4 B 青 いちご 5 D 赤 みかん 6 A 青 みかん 7 C 黄 りんご 8 E 赤 バナナ

  • EXECL・複数タブからのデータ抽出

    同一Book内での処理です。 今現在の処理内容です タブAには抽出されるデータがあります。 セルA1・・・抽出キー セルB1・・・抽出データ1 セルC1・・・抽出データ2 タブBには抽出キー・抽出結果を表示するようにしています。 セルA1・・・抽出キー1 セルB1・・・抽出キー2 セルC1・・・抽出キーを合成 <=CONCATENATE(A1,"→",B1)> セルD1・・・データ抽出 <=VLOOKUP(C1,タブA!$A:$C,2,FALSE)> したいことは タブAのデータと同一内容のデータが複数タブに存在するときのデータ抽出する場合はどうすればよいのでしょうか? タブA(リンゴ)には抽出されるデータがあります。 セルA1・・・抽出キー セルB1・・・抽出データ1 セルC1・・・抽出データ2 タブB(みかん)には抽出されるデータがあります。 セルA1・・・抽出キー セルB1・・・抽出データ1 セルC1・・・抽出データ2 タブCではセルA1の内容によって抽出するデータのタブを選択しデータを抽出したい セルA1・・・抽出キー1 セルB1・・・抽出キー2 セルC1・・・抽出キーを合成 <=CONCATENATE(A1,"→",B1)> セルD1・・・データ抽出 <=ここの計算式が知りたい タブCのセルA1の抽出キーに(リンゴ)と入力されていればタブA(リンゴ)のシートよりデータ抽出 タブCのセルA1の抽出キーに(みかん)と入力されていればタブB(みかん)のシートよりデータ抽出 単にいえば、データ抽出するタブを指定して<VLOOKUP関数>を利用できるのか? できないなら実現できる手法を教えていただきたいです。 説明が難しいですが、内容がわかっていただけたでしょうか? 達人からの回答よろしくお願いいたします

  • 行抽出・関数・複数条件

    以下の質問をみて、一つの条件のものを作ることは出来ました。 しかし、AND()やCOUNTIFS()などを用いながら自分なりに複数条件の行抽出をしてみようとトライしてみたのですが、きちんとした行を返してくれません。 どなたか、以下の質問を少し変えて、 ************************************************************** <A列> <B列> <C列> 7/1 りんご 100円 7/2 ぶどう 200円 7/2 すいか 300円 7/3 みかん 100円 このような表があって、100円とりんごを含む行をそのままの形で、 別のセル(同じシート内)に抜き出したいのですが。 7/1 りんご 100円 ************************************************************** といった表示をする関数を書いていただけないでしょうか。 よろしくお願いします。 http://okwave.jp/qa/q3200952.html

  • エクセルで項目を抽出したい

    皆様のお知恵をお貸しください。 日々作業者が行っている日報の項目を一覧表より抽出したいのです。 シート1には受付日(A列) 品番(B列) 数量(C列) 納期(D列)・・・ などが記入されています。日々増えていき月あたり100件程度です シート2には作業者の日報に書かれている品番(A列)、作業時間(B列)、作業者名(C列)作業日時(D列)を手入力していきます。 月当たり1000ほどの入力になります。 複数の作業者が同じ仕事をすること、日をまたぐこともあり重複しています。 求めたいことはシート3のA列にシート2で書かれた品名をシート1の品名の中から抽出し自動で書き出したいのです。 今はピボットを使いシート2のデータを表にして、そこの項目をLOOKUP関数を用いて導きだしていますが、その都度ピボットを更新させないといけないので煩わしいと思い、できれば関数で抽出をしたいのです。欲を言えば品番の若い順に自動で抽出できればいいのですが、まずはシート2に書かれた順でもかまいません。 記入例 シート1には A列    B列    C列    D列 10/1   10001    30    10/12 10/2   10002    1     10/5 10/2 10003 3 11/5 ・       ・        ・ シート2には  A列    B列     C列    D列 10001    2.5     ○○   10/2  9058    4      ○○   10/2 10003 1 ○○   10/3 10001 1 ××   10/3  10003 6 ××   10/3 10002 2 △△   10/5 シート3には(希望としては)  A列     9058 10001 10002 10003 . . . よろしくお願いします。     

  • エクセル、複数あるデータを順番にピックアップする方法

    すみません、教えてください。 下記のようなデータの中から、たとえばC行の中から”りんご”に当てはまるデータを検索し、その列のA行とB行を抽出したいとすると、どのような方法がありますでしょうか。 別の空のシートに抽出したいのですが、よくわかりません。 よろしくご教授ください。お願い致します。 【元データ】     列A   列B   列C   列D   … 列1  八百丸  渋谷区  りんご  100 列2  八百吉  港 区  みかん  80 列3  八百屋  新宿区  か き  100 列4  八百正  新宿区  りんご  200 【求めたい検索結果】 八百丸 渋谷区 八百正 新宿区

このQ&Aのポイント
  • バッハ以下の来賓が天皇陛下の開会宣言中に起立していたのかはわかりません。
  • 過去の開会宣言では、元首が特別高い段に進み出ている場合を除き、全員が起立していました。
  • バッハ以下が座っていた場合、国際常識に照らして考えると、バッハにはなかった可能性があります。
回答を見る

専門家に質問してみよう