- ベストアンサー
【EXCEL】シフト表から休みの日だけを抽出する方法をご教授ください。
いつも大変お世話になっています。 申し訳ありません。どなたかお力をお貸しください。 1ヶ月のシフト表から休みの日を抽出したいのです。 休みの日の記号は常に【X】です。(=Xを抽出したいのです) 出勤日の記号は英数字で、最大5桁まであります。 【拡大図】 A B C D E F 1 No 氏名 2009/4/1 2009/4/2 2009/4/3 2009/4/4 2 123 山田 A B B B 3 124 佐藤 A B B X 4 125 田中 X X A A 5 128 清水 C B X A 6 025 上田 C B X A 【縮小図】 A B C DEFGHIHIJKLMNOPORSTU 1 NO 氏名 日日日日日日日日日・・・・・・ 2 123 山田 ABBBAXXAAAAAXXBBBBBXXAAAAAXXAA 3 124 佐藤 ABBXXAAAAAXXBBBBBXXAAAAAXXAABB 4 125 田中 BXXAAAAAXXBBBBBXXAAAAAXXAABBAA 5 128 清水 CBXABBBBXXXBBBBCCCCXAAAAAXXXAA 6 025 上田 CBXABBXBAAABBXBCXCCXAAAAAXXXAA 【やりたいこと】 ※No(=社員No)、氏名、休みの日を別シートに表示したいのです。 ※オートフィルタを使って、日毎に手動でやることは避けたいです。 A B C 1 No 氏名 休日 2 123 山田 2009/4/6 3 123 山田 2009/4/7 4 123 山田 2009/4/13 5 123 山田 2009/4/14 6 123 山田 2009/4/20 7 123 山田 2009/4/21 8 123 山田 2009/4/27 9 123 山田 2009/4/28 10 124 佐藤 2009/4/4 11 124 佐藤 2009/4/5 12 124 佐藤 2009/4/11 13 124 佐藤 2009/4/12 ・ ・ ・ ・ 申し訳ありませんが、 どなたかご教示をお願いします。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
関数での答えを求めているレベルと思うが、こういう(形式で) ーーー 日 氏名 データ の3元になっている表を且つ(氏名・行単位で)重複が有る休日(データではX)を抜き出すのはむつかしい。 すんなりとやるにはVBAが簡単。 氏名ー日ーデータ(Xの行あり) ・・・ の形式なら、例えば「imogasi方式」(Googleで照会のこと)のようなやり方で何とかできる。 前者から後者の形式に関数で表を構築替えも難しい。 関数は第2番目、第3番目・・の該当列を見つける関数が無いからだ。 関数の回答が出るかどうか? ーーーーーーーーーーーーー 質問者には現在は無縁だろうが、読者のこともありVBAで上げておく。 例データ Sheet1 A-G列 1 No 氏名 2009/4/1 2009/4/2 2009/4/3 2009/4/4 2 123 山田 A B B B 3 124 佐藤 A B B x 4 125 田中 x x A A 5 128 清水 C B x A 6 25 上田 C B x A ーー 結果 Sheet2 A2:C6 C列は表示形式を日付にしておくこと。 124 佐藤 2009/4/4 125 田中 2009/4/1 125 田中 2009/4/2 128 清水 2009/4/3 25 上田 2009/4/3 ーーーー コード 標準モジュールに Sub test01() Dim sh1, sh2 As Worksheet Set sh1 = Worksheets("Sheet1"): Set sh2 = Worksheets("Sheet2") d = sh1.Range("B65536").End(xlUp).Row '最下行 k = 2 'Sheet2で第2行から書き出し For Each cl In sh1.Range("d2:G" & d) 'D2:Gx範囲の全セル検査 If cl = "x" Then 'xならSheet2へ書き出し sh2.Cells(k, "A") = sh1.Cells(cl.Row, "B") sh2.Cells(k, "B") = sh1.Cells(cl.Row, "C") sh2.Cells(k, "C") = sh1.Cells(1, cl.Column) k = k + 1 End If Next End Sub で実行。 If cl = "x" Then のxは表のセルのxと半角全角など合わせること。
その他の回答 (2)
貴方の【やりたいこと】のレイアウトが異なっても構わなければ、次のような方法もあります。 Sheet1 A B C D E … AF AG 1 No 氏名 09/04/01 09/04/02 09/04/03 … 09/04/30 2 123 山田 A B B … C 3 124 佐藤 A B B … A 4 125 田中 X X A … A 5 128 清水 C B X … B 6 025 上田 C B X … C Sheet2 A B C D E 1 123 124 125 128 025 2 山田 佐藤 田中 清水 上田 3 09/04/18 09/04/04 09/04/01 09/04/03 09/04/03 4 09/04/29 09/04/08 09/04/02 09/04/05 09/04/08 5 09/04/10 09/04/20 09/04/13 6 09/04/18 09/04/26 09/04/20 7 09/04/27 8 Sheet2!A2: =VLOOKUP(A1,Sheet1!$A:$B,2,FALSE) Sheet2!A3: {=SMALL(IF(OFFSET(INDIRECT(ADDRESS(MATCH(A$1,Sheet1!$A:$A,0),1,,,"Sheet1")),,2,,31)="X",(OFFSET(INDIRECT(ADDRESS(MATCH(A$1,Sheet1!$A:$A,0),1,,,"Sheet1")),,2,,31)="X")*(Sheet1!$C$1:$AG$1),""),ROW(A1))} ← 配列数式 Sheet2 において、3行目以降のデータがないセルは、そのままでは、エラー #NUM! が表示されるので、此れを非表示にするために、次の[条件付き書式](Sheet2!A3 の場合)を設定します。 数式が =ISERROR(A3) フォント色 白
お礼
お忙しいところご回答ありがとうございました。 今回はVBAを御提案くださった方がいらっしゃったため、 VBAで対応しました。 今後ともよろしくお願いします。
- ookami1969
- ベストアンサー率14% (137/953)
まず、現状 作成されている「スケジュール表」と あなたがやりたい事では 「軸」が違うから面倒なのです。 名前が横軸、日付が縦軸になっていればフィルターでの抽出も簡単になりますよね。 「元々の表はイジれない」ということであれば、別のシートにコピペで「行列を入れ替えて貼り付け」をすれば やりたい事が やりやすくなります。 (またはピポッドでもOK) 従業員の人数によっては、その人数分のボタンを用意して そこにマクロを登録しておいて ボタンを押すだけで 「誰だれさんの休みの日」を一発で抽出出来るようになります。 それが無理なら「休みの日を抽出」だけでもマクロ登録しておいて「人」だけ手動で抽出するのが良いでしょう。 どちらにせよ上記の方法は「軸を変更する」という事が前提ですが。 興味があり、この方法を選択するということであれば再度回答します。
お礼
レスをありがとうございました。 VBAを御提案くださった方がいらっしゃったため、 今回は再度のご回答は結構です。 お忙しいところ大変ありがとうございました。
お礼
早速のご回答ありがとうございました。 お礼が大変遅くなりましたが、 imogasi 様 のアドバイスに従い行ったところ できました。(一部ソースは修正しましたが) VBAを真剣に学ぶ決意をしたところです。 関数ではできないことが(対応が難しいことが) 簡単にできるような気がします。 大変ありがとうございました。