Excel (VBA)

Excel VBAに関するフォーラムです。
  • 解決済みのトピックにはコメントできません。
このトピックは解決済みです。
質問

 
(Windows 10全般 : Excel 2019)
エクセル シートの値に応じてデータを挿入したいです。
投稿日時: 23/04/15 12:01:05
投稿者: 渡邉 智久

こんにちは。
 
エクセルで職場の労務管理用の勤務表を作成しています。
職場のメンバー(最大20人くらい)毎に日ごとの勤務時間を勤務コード(・やY1、Y2など)を基に労働抽出し、月の労働時間を計算しようとしています。
月によって勤務コードの種類が増えたり減ったりするのですが、シートの特定の範囲内で使用しているコードを同じシート内に重複せず、一覧にすることは可能でしょうか。
 
(完成イメージです)
 
(sheet1)
4月 1日2日3日4日・・・・・
   Y1 Y2 Y1 Y2 Y3 G1 C1 → 勤務コード種類 Y1 Y2 Y3 C1 C2 G1   
   Y1 Y2 Y1 Y2 Y3 G1 C2 時間
     Y1 Y2 Y1 Y2 Y3 G1 C1      回数
 
(sheet2)
5月 1日2日3日4日・・・・・ 
  Y1 Y2 Y1 Y2 Y3 G1 C1 → 勤務コード種類 Y1 Y2 Y3 C1 C2 G1 C10 B1
   Y1 Y2 Y1 Y2 Y3 G1 C2       時間
     Y1 Y2 Y1 Y2 Y3 B1 C10      回数
 
 
        ↑列が自動で追加
                                       
可能であれば計算式を記載したセルの集まりも自動で追加したいです。
 
漠然としており申し訳ございません。
よろしくお願い致します。
 

回答
投稿日時: 23/04/15 12:55:27
投稿者: simple

出来上がりの例を数値を入れて示して下さい。時間とかはどう関係するんですか?それは対象外?
> 可能であれば計算式を記載したセルの集まりも自動で追加したいです。
もう少し具体的に説明してください。

投稿日時: 23/04/15 15:41:32
投稿者: 渡邉 智久

 simple様
 
ご連絡ありがとうございます。
データでお送りできればいいのですが、送れないのでこのメッセージでなんとかお伝えできれば
と思います。よろしくお願い致します。
 
@1か月の日ごとの勤務スケジュールをスタッフ毎に作成します。
勤務コード(Y=日勤、S=夜勤 有= 有給などあるの)
 
 
@日ごと(1か月)の勤務コード例
 
勤務コードをコピー&ペーストし、エクセルの別シートからVLOOKUPで参照し、
勤務コードを勤務時間に変換します。合計日数や合計予定時間も日ごとのセルの右側に出したいです。下のイメージでは縦になっていますが、横にだしたいです。
            
氏名    ○月□日○月□日○月□日    
    ○曜日    ○曜日    ○曜日
AAA    A2    休    A2
BBB    A2    休    A2
CCC    Y2    A2    Y2
DDD    Y2    A2    Y2
EEE    休    ・    休
FFF    休    ・    休
GGG    ・    Y2    ・
ZZZ    ・    Y2    ・
 
合計日数 予定時間
30    168:55:00
30    168:55:00
30    176:20:00
30    176:20:00
30    168:40:00
30    168:40:00
30    176:05:00
30    176:05:00
 
 
 
Aコード毎の集計(例)  
勤務コード毎の勤務回数や労働時間を集計したいのですが
ここで課題があります。
部署ごとで@Aを作りたいのですが、
勤務コードは部署によって異なります。なので、
@にコピー&ペーストした勤務コートに応じて下のようなコード毎の集計を自動ででるようにしたいのです。
例えばA課ではY1 Y2の勤務コードのパターンのみ→2個のコード詳細の計算セル
   B課ではR1、R2、R3の勤務コードのパターン→3個のコード詳細の計算セルが自動ででる。
@にコピー&ペーストしたコードの詳細の計算セルができるというものです。
 
労働時間などは関数を組んで計算したいと思いますが、
したのようにコード毎に集計するようにセルが形成されないかと思っています。(↓のイメージですと縦ですが、エクセル上では横に新たに挿入となるイメージです。)
 
コード    コード詳細    
Y1    日勤
回数  合計時間(数字は表示形式を変更します。)    
7    2.236111111
7    2.236111111
7    2.236111111
7    2.236111111
8    2.555555556
8    2.555555556
8    2.555555556
8    2.555555556
 
コード    コード詳細
A2    夜勤明け2
回数  合計時間
60    19.79166667
8    2.638888889
8    2.638888889
8    2.638888889
8    2.638888889
7    2.309027778
7    2.309027778
7    2.309027778
7    2.309027778
 
 
こんな形で伝わりますでしょうか。
ご不明な点、多々あると思うのですが、教えて頂ければ幸いです。
よろしくお願い致します。
 
 
 
 
 
 

回答
投稿日時: 23/04/15 20:29:08
投稿者: simple

外出から今戻ったところです。
ところで、ご自分ではどこまでトライされているんでしょうか?
作成依頼だとちょっとまずいのですが。(利用上のお願いを読んでください)
ちなみに、Dictionaryなどは使えますか?
今後のメインテナンスも考えて余り凝ったものにしないほうがいいような気もしています。

回答
投稿日時: 23/04/16 15:16:56
投稿者: Suzu

例えば

	A	B	C	D	E	F	G・・・
1		2023	年	4	月
2		1	2	3	4	5	6・・・
3	氏名	土	日	月	火	水	木・・・
4	AAA	A2	休	A2・・・
5	BBB	A2	休	A2・・・
6	CCC	Y2	A2	Y2・・・

 
こんな表があり、
A2:7.75時間勤務
Y2:9時間勤務
 
だと したとき
B4〜AF列(ひと月 31日の時の列) に勤務コードを
貼り付け または 数式により得る様にすれば
 
 
AH列〜に
 
	AH	AI	AJ	AK・・・
1
2	A1		A2		Y1		Y2		休
3	8		7.75		7.5		9		0
  【↑勤務コード (A1,A2,Y1等)の下の行に コードに対応する勤務時間】
  
4	※1	※2	※3
5	※1'	※2'
6		:

 
 
※1(セル AH4)
=COUNTIF($B4:$AF4,AH$2)
 
※1'(セル AH5)
=COUNTIF($B5:$AF5,AH$2)
  以下行オートフィル
 
 
※2(セル AJ4)
=AH$3*AH4
 
※2(セル AJ5)
=AH$3*AH5
  以下行オートフィル
 
 
列方向は、COUNTIFの AHが、AJ、AL・・ となってゆけば良いので
AHと、AI 列の 必要な行まで 数式を入れた後
AH、AI の当該セル 2列を選択し、列方向へオートフィル
 
とすれば、合計日数 予定時間、各コード毎の 回数と勤務時間は集計できるのではないでしょうか?
 
 
 
引用:
@にコピー&ペーストした勤務コートに応じて下のようなコード毎の集計を自動ででるようにしたいのです。
例えばA課ではY1 Y2の勤務コードのパターンのみ→2個のコード詳細の計算セル
   B課ではR1、R2、R3の勤務コードのパターン→3個のコード詳細の計算セルが自動ででる。
@にコピー&ペーストしたコードの詳細の計算セルができるというものです。

この部分は
 1)A課、B課を、表内のどこで判定すれば良いか判らない
 2)2個(または3個)のコード詳細の計算セルが自動で出る の 説明の意味自体を推測しかねる
ので、回答できません。

回答
投稿日時: 23/04/16 19:11:43
投稿者: simple

(1)PowerQueryを使って、一旦縦持ちデータに変換したうえで、ピボットテーブルで集計を行う方法
(2)Dictionaryなどを使ってマクロで作成する方法
などがあると思います。
 
(1)は、どなたかから回答があればよいとおもいます。
(2)について、若干のコメントをしておきます。
 
重複を除いた勤務形態の作成だけマクロで行い、
基本的に数式処理は手動対応する方法が考えられます。
 
 

<<ワークシート>> レイアウトは以下のとおりです。

       A列        B列         C列         D列
 1行目         4月1日      4月2日       4月3日   
 2     AAA         A2          休          A2
 3     BBB         A2          休          A2
 4     CCC         Y2          A2          Y2
 5     DDD         Y2          A2          Y2
 6     EEE         休          ・          休
 7     FFF         休          ・          休
 8     GGG         ・          Y2          ・
 9     ZZZ         ・          Y2          ・
10                                         
11                                         
12     形態別回数  A2          Y2          ・  ■B12:D12にマクロで勤務形態を
13     AAA         2           0           0     書き込む
14     BBB         1           2           0   ・B13 以下には、=COUNTIF($B3:$AF3,B$12) 
15     CCC         1           2           0     のような式を予め設定
16     DDD         0           0           1
17     EEE         0           0           1
18     FFF         0           1           2
19     GGG         0           1           2
20     ZZZ         0           0           0
21                                         
22                                         
23                 8           9           10  ・B23には、=VLOOKUP(B24,対応表,2,FALSE)
24     形態別時間  A2          Y2          ・     などを設定 
25     AAA         16          0           0   ■B11:D11にマクロで勤務形態を書き込む  
26     BBB         8           18          0   ・B25 以下には、=B13*B$23 を予め設定 
27     CCC         8           18          0
28     DDD         0           0           10
29     EEE         0           0           10
30     FFF         0           9           20
31     GGG         0           9           20
32     ZZZ         0           0           0

 
(a)マクロで、
  ・回数のカウント
  ・時間への換算
  ・横計、縦計などの計算
  をすべて設定することもできるでしょう。
(b)メンテナンス負荷も考慮して、
  左上隅の一つのセルにだけ予め数式を埋め込んでおいて、
   あとはマクロで必要な数だけコピーしたり、
  縦計、横計の計算式をマクロで入れる方法もあるでしょう。
メインテンス負荷、とか仕様がどの程度変わり得るか、あなたのコード作成スキルとか考慮して、
(a)(b)どちらのタイプがよいか、そちらで検討してみて下さい。
 
各課によって異なる勤務形態を重複を除いてとりだし、
・形態別回数の行と
・形態別時間の行に
書き込むためのマクロは以下のとおりです。
参考にしてください。
 
Sub test()
    Dim dic       As Object
    Dim rng       As Range
    Dim body      As Range
    Dim r         As Range
    Dim rng1      As Range
    Dim rng2      As Range
    Dim s         As String

    Set dic = CreateObject("Scripting.Dictionary")
    Set rng = [A1].CurrentRegion
    Set body = Intersect(rng, rng.Offset(1, 1))

    For Each r In body
        s = r.Value
        If s <> "休" Then
            dic(s) = Empty
        End If
    Next

    '形態別回数の行に、勤務形態を書き込み、ソート
    Set rng1 = Columns("A").Find("形態別回数", LookAt:=xlWhole)
    Set rng1 = rng1.Offset(0, 1).Resize(1, dic.Count)
    rng1.Value = dic.keys               ' 勤務形態を書き込む
    rng1.Sort key1:=rng1(1), order1:=xlAscending, Orientation:=xlSortColumns

    '形態別時間の行に、勤務形態を書き込み、ソート
    Set rng2 = Columns("A").Find("形態別時間", LookAt:=xlWhole)
    Set rng2 = rng2.Offset(0, 1).Resize(1, dic.Count)
    rng2.Value = dic.keys
    rng2.Sort key1:=rng2(1), order1:=xlAscending, Orientation:=xlSortColumns
End Sub

投稿日時: 23/04/17 19:32:51
投稿者: 渡邉 智久

simple様 suzu様
 
コメント頂きありがとうございます。
 
詳しくコード教えていただきまして、本当にありがとうございます。
勤務表の作成にあたり行いたかったことができそうです。
とても助かりました。
 
 
simple様
 
ご指摘頂いたように作成のお願いのような形になってしまい、申し訳ございませんでした。
今後気をつけます。
教えて頂いたマクロのコード、とても勉強になりました。
 
 
本当にありがとうございました。