- ベストアンサー
Excel 入力されたデータを各列に分類したい
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
その他の回答 (4)
- mimazoku_2
- ベストアンサー率20% (1905/9111)
それなら、入力用セルと表示用セルに分ければいいんでは? 項目1の前に項目0を設けて、数値や値などは項目0に入力する。 内容により、項目1以降に表示させたいセルを並べれば、見た目上お好みの表示になりますよ。
- imogasi
- ベストアンサー率27% (4737/17069)
>関数、ピボット等 VBAは使ったことがないのかもしれないが参考に。 将来Google検索で、この課題で見る人もいるだろうから、あえて掲げる。 ーー データ Sheet1 2015/1/1 A B C D 2015/1/2 A C D 2015/1/3 A B 2015/1/4 B C D 2015/1/5 C 2015/1/6 B C 2015/1/7 C D 2015/1/8 A B D 2015/1/9 D 2015/1/10 D 2015/1/11 D VBE画面で、標準モジュールを挿入して、下記をコピペ Sub test01() Rows(100).Clear '第100行目のワークエリアをクリア Worksheets("Sheet1").Columns(1).Copy Worksheets("Sheet2").Columns(1) 'Sheet1の日付列をSheet2へ転記 c = 2 'ワークエリア第100行目のB列から使う '--- rl = Worksheets("Sheet1").Range("A1000").End(xlUp).Row 'データ最終行をつかむ 'MsgBox rl '-- For i = 2 To rl '最終行まで1行ずつ繰り返し cr = Worksheets("Sheet1").Cells(i, "Z").End(xlToLeft).Column 'その行のデータのある最左列をつかむ 'MsgBox cr For j = 2 To cr '最右列まで各セルについて繰り返し x = Worksheets("Sheet1").Cells(i, j) 'MsgBox x Set p = Worksheets("Sheet1").Range("b100:Z100").Find(x) If p Is Nothing Then 'MsgBox "初め" Worksheets("Sheet1").Cells(100, c) = x 'ワーク行第100行に追加 Worksheets("Sheet2").Cells(i, c) = x c = c + 1 Else 'MsgBox p.Column Worksheets("Sheet2").Cells(i, p.Column) = x '見つけた列位置に、データをセット End If Next j Next i Rows(100).Clear p1: End Sub 結果 Sheet2 のA2以下、以右に (ーは実際は空白です。OKWAVEでは、回答表示が左寄せされるのであえて入れているもの。) 2015/1/1 A B C D 2015/1/2 A - C D 2015/1/3 A B 2015/1/4 - B C D 2015/1/5 - - C 2015/1/6 - B C 2015/1/7 - - C D 2015/1/8 A B - D 2015/1/9 - - - D 2015/1/10- - - D 2015/1/11- - - D ーー 画像で示した後、文章で(前提やデータ量的なこと、その他注意事項を)説明を入れるべきです.画像が最善とも限らないのだ。 勤務日の勤務者名の整理データのイメージでやりました。だから同一行では同じデータは出てこないと仮定。(この点他の回答者も聞いているのでは) '--- 上記VBAでは、日にち(データ行)が99日以上とか、勤務者人数が25人を超える場合は、プログラムの微修正が必要。 第100行目は一時的なワークエリアとして使用。配列等で処理も可能だが、位置を見つけるスマートな関数等がないと思うので。FindはメソッドはMatch関数でも代替可能かと。 ーー 関数の回答も出ているようだが、式の意味の理解は質問者に取ってむつかしくないかな。 こういう、配置後の行先セルが他のデータのあり様で変わるタイプの課題は、関数では経験とスキルを要するので、VBA向きなんだ。 ーー このVBAの処理ロジックは、わかりやすいと思うが。 ワーク行の100行目の列に左列から順に、新しいデータ(新出現ならそのデータ)を記録して、その後のデータでは、100行目(の各列)を見て、今回のデータのある列を割り出して、処理行(上記ではi)のその割り出した列に、データを配置(代入)している。 見つからない場合は100行目のデータ最終列の次列に追加する。 ーー 列に出す順序を、出現順でなく、もし「偉いさん」順(世の中はこうしている例が多い)なら、100行目をはじめに、社員数分だけ、手入力でして、出現列の順序を固定したうえで、上記VBAを微修正すればできるとおもう。
- kagakusuki
- ベストアンサー率51% (2610/5101)
>分類する値は、都度変更されておりマスター化する事ができません。 >(何が入ってくるか不明) という事は、元データである左の表において項目が入力されている列の数こそ4列であるものの、入力されている「AAA」や「BBB」などといった項目名の種類自体は4種類しかないとは限らず、下の添付画像の例の様に5種類以上の項目名が入力されている事もあり得るのでしょうか? 取り敢えずその様な場合にも対応可能な方法を回答致します。 今仮に、左表が存在しているシートのシート名がSheet1であり、その中で「列1」と入力されているセルがA1セルであるものとします。 又、右表が存在しているシートのシート名がSheet2であり、その中で「列1」と入力されているセルがA1セルであるものとします。 又、Sheet3のA列~D列を作業列として使用するものとします。 まず、Sheet3のA2セルに次の関数を入力して下さい。 =IF(INDEX(Sheet1!$B:$E,ROW(),COLUMNS($A:A))="","",IF(COUNTIF(Sheet1!$B$1:INDEX(Sheet1!$E:$E,ROW()-1),INDEX(Sheet1!$B:$E,ROW(),COLUMNS($A:A)))+COUNTIF(INDEX(Sheet1!$B:$B,ROW()):INDEX(Sheet1!$B:$E,ROW(),COLUMNS($A:A)),INDEX(Sheet1!$B:$E,ROW(),COLUMNS($A:A)))=1,ROW()*10+COLUMNS(Sheet1!$B:B),"")) 次に、Sheet3のA2セルをコピーして、Sheet3のB2~D2のセル範囲に貼り付けて下さい。 次に、Sheet3のA2~D2のセル範囲をコピーして、Sheet3のA列~D列の3行目以下に貼り付けて下さい。 次に、Sheet2のA2セルに次の関数を入力して下さい。 =IF(INDEX(Sheet1!$A:$A,ROW())="","",INDEX(Sheet1!$A:$A,ROW())) 次に、Sheet2のB1セルに次の関数を入力して下さい。 =IF(COLUMNS($B:B)>COUNT(Sheet3!$A:$D),"",INDEX(Sheet1!$B:$E,INT(SMALL(Sheet3!$A:$D,COLUMNS($B:B))/10),MOD(SMALL(Sheet3!$A:$D,COLUMNS($B:B)),10))) 次に、Sheet2のB2セルに次の関数を入力して下さい。 =IF(COUNTIF(INDEX(Sheet1!$B:$E,ROW(),),B$1),B$1,"") 次に、Sheet2のB1~B2のセル範囲をコピーして、Sheet2の1行目~2行目においてB列よりも右側にあるセル範囲に貼り付けて下さい。 次に、Sheet2の2行目全体をコピーして、Sheet2の3行目以下に貼り付けて下さい。 以上です。
お礼
本ロジックにつきまして、大変勉強になりました! システム化が図られており、あらゆる場合を想定した仕様ですね、 有難うございます。 ロジックをじっくり勉強し、将来の展開時には、ぜひ本仕様を活用をさせて頂きたいと思います。
- -9L9-
- ベストアンサー率44% (1088/2422)
同じシートで項目1を固定したままではデータの出元と行先が錯綜していますので無理でしょう。 別シートや項目1は固定して項目2からA、B、Cと展開するならIF関数等で簡単にできると思いますが。
お礼
できました!有難うございます。 シンプル且つ分かりやすいロジックの為、直ぐに別担当者とも共有化できました。 また、将来的には「kagakusuki 様」のロジックにチャレンジをして あらゆる場合に対応する台帳にするつもりです♪