[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]
『シフト表から今日出勤している人と出勤時間を詰めて表示させたい』(おかもと)
よろしくお願いいたします。
シフト表と出勤簿があります。
指定した日付に出勤となっている人だけを出勤簿に表示させと思っているのですがなかなかうまくいかずお知恵を拝借したいと思います。
■シート「シフト」
Aさん Bさん Cさん 9月1日 9:00-18:00 有給 13:00-19:00 9月2日 9:00-18:00 有給 9月3日 有給 13:00-19:00
■シート「出勤簿」
日付 9月1日
出勤 Aさん Cさん
時間 9:00-18:00 13:00-19:00
※有給などでお休みの人は出勤簿から排除したい
※出退勤時間はすべて00:00-00:00形式で入力されている
以上、何卒よろしくお願いいたします。
< 使用 Excel:Excel2019、使用 OS:Windows10 >
行列番号がわかるように表を提示してください。 元表が何行×何列の表なのかも明記してください。
とりあえず・・・ ・シフト表の名前は B1:J1、日付は A2:A50 ・セルにコロン「:」が入力されていたら「出勤」とみなす
■シフト A B C D 1 Aさん Bさん Cさん 2 9/1 3 9/2 4 9/3 ・
■出勤簿 A B C D 1 9/1 2 出勤 3 時間
■出勤簿 B2 =IF($B$1="","",IFERROR(INDEX(シフト!$1:$1,AGGREGATE(15,6,COLUMN($B$1:$J$1)/ISNUMBER(FIND(":",INDEX(シフト!$B$2:$J$50,MATCH($B$1,シフト!$A$2:$A$50,0),0))),COLUMN(A1))),""))
B3 =IF(B2="","",VLOOKUP($B$1,シフト!$A$2:$J$50,MATCH(B2,シフト!$A$1:$J$1,0),FALSE))
右コピー ※B2の式、最後の方の COLUMN(A1)の「A1」は、実際のレイアウトがどうなっていようと変更しないように
以上 (笑) 2022/09/27(火) 14:41
シート「出勤簿」のB2: =IFERROR(INDEX(シフト!$B$1:$D$1,AGGREGATE(15,6,COLUMN($A$1:$C$1)/(LEN(INDEX(シフト!$B$2:$D$4,MATCH($B$1,シフト!$A$2:$A$4,0),))>=3),COLUMN(A1))),"")
シート「出勤簿」のC2: =IFERROR(INDEX(シフト!$B$2:$D$4,MATCH($B$1,シフト!$A$2:$A$4,0),MATCH(B2,シフト!$B$1:$D$1,0)),"")
両式を右にコピーします。
(メジロ) 2022/09/27(火) 14:53
Sub Sample() Dim ws1 As Worksheet Dim ws2 As Worksheet Dim var1() As Variant Dim var2() As Variant Dim lastColumn As Long Dim iRow As Variant Dim iColumn As Long Dim i As Long
'シート定義 Set ws1 = Worksheets("シフト") Set ws2 = Worksheets("出勤簿") 'ws1の1行目の最終列を取得 lastColumn = ws1.Cells(1, Columns.Count).End(xlToLeft).Column 'データを入れるための配列を定義(最大データ収納数で定義しあとで減らす) ReDim var1(lastColumn - 2) '名前用 ReDim var2(lastColumn - 2) '時間用 'ws2の出力範囲を空白にする ws2.Range("B2:B3").ClearContents 'ws2の日付と同じものをws1のA列2行目以降で探す iRow = Application.Match(ws2.Range("B1").Value, ws1.Range("A2", ws1.Cells(Rows.Count, 1).End(xlUp)), 0) '同じ日付があった場合(無い場合iRowはエラーになる) If IsNumeric(iRow) Then '2列目から最終列まで巡回 For iColumn = 2 To lastColumn 'セルの値が「*#:##-*#:##」形式になっていたら If ws1.Cells(iRow + 1, iColumn).Value Like "*#:##-*#:##" Then '1行目の値を名前用配列に入れる var1(i) = ws1.Cells(1, iColumn).Value 'iRow+1行目の値を時間用配列に入れる var2(i) = ws1.Cells(iRow + 1, iColumn).Value '配列インデックスを加算 i = i + 1 End If Next '配列インデックスが加算されていたら(配列にデータが入っていたら) If i > 0 Then '配列インデックス最大値をデータ数に合わせる ReDim Preserve var1(i - 1) '名前用 ReDim Preserve var2(i - 1) '時間用 '出力範囲にデータを入れる ws2.Range("B2").Value = Join(var1) '名前 ws2.Range("B3").Value = Join(var2) '時間 End If End If End Sub
練習課題のつもりでマクロを書いてみました。
おかもとさんの考えていたものと違っていたらすみません。
(下手の横好き) 2022/09/27(火) 15:46
笑さま、メジロさま
おかげ様で希望通りの処理ができました。AGGREGATE関数を知れたのも新しい発見でした。ありがとうございます。
下手の横好き様
提示してくださった方法により、こういった解決法もあるのだと自分の考え方が偏っていたことを知ることができましたありがとうございます。
みなさま本当にありがとうございました。
次回から行列番号と元表の行列を明記するようにいたします。
(おかもと) 2022/09/29(木) 10:15
[ 一覧(最新更新順) ]
YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki.
Modified by kazu.