質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%

Q&A

解決済

3回答

28119閲覧

当番表をつくりたい

gasuko

総合スコア27

0グッド

0クリップ

投稿2016/09/05 00:32

編集2016/09/06 05:33

まずA,B,C,D,E,F,G,H,I,Jさんがいます。
A~Jさんのシフトはみんなバラバラです。

当番の順番は必ずA→B→C→D→E→F→G→H→I→Jの順ですが、例えばBさんが、有給をとって休みだった場合は、次のCさんが当番になるようにしたいです。

シフトがでたら自動で上記の内容が出るようにしたいのですが、エクセルでやるにしてもどのようにしたらいいのか、そもそもエクセルが適切なのかも不明な為、投稿させていただきました。

当方、PHPの学習中でもあるのですが、配列でやるのかなー?とかも考えたのですが、学習が関数どまりのため、これも解決できそうにありません。。。

適切であろう言語とおおまかな手順がわかる方、アドバイスをいただけますと幸いです。よろしくお願いいたします。

イメージ説明

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

cesolution

2016/09/05 00:44

どの言語でも可能だと思いますが、もう少し具体的に内容を書かれた方が良いかと思います。例えば、上記の例で、シフトは紙で出てくるのでしょうか?それともエクセルで出てくるのでしょうか?また、当番の人が自分が当番かどうかを確認するのは、やはりエクセルでしょうか?
gasuko

2016/09/05 00:54

失礼いたしました。当番になった人に通知する、または確認できるようにするのはすごく難しそうなので、とりあえずエクセルでシフト表を作成している人間が、シフトを出したタイミングで当番の順番も管理できるようにしたいという感じです。なので基本はエクセルで一人が確認できれば良いという感じです。
guest

回答3

0

ベストアンサー

ご連絡ありがとうございます。
エクセルにシフト表があるということで、エクセルで完結させるのであれば、例えば1例として以下のような方法が考えられます。
Sheet1に以下のような形でシフトが入っているとします。
0が休み、1が出勤です。

イメージ説明

この時、Aさん~Iさんに当番順に番号を振ります。具体的には、Aさんが0番~Iさんが8番になります。
シフト表の下に、当番用の欄を作り、当番をシフトに従って、マクロの関数で自動で表示するようにします。
マクロは例えば以下のように設定できます。(Selectの部分が冗長なので、見直しは必要かと思いますが)
今回シフトを回すのが9人ですので、前回当番だった人(左となりの列の人)の当番番号に1を足した人が出勤しているかどうかを知らべます。
もし出勤していなければさらに当番番号に1を足し、、、ということを繰り返しています。
少し説明を端折り気味ですが、上記のように設定していけば、以下のように自動的に当番の人を表示させることができます。

VBA

1Function testx(x) 2Dim WS As Worksheet 3Set WS = Worksheets("Sheet1") 4Dim i As Integer 5Dim y As Integer 6 7Select Case x 8Case "A" 9 x = 0 10Case "B" 11 x = 1 12Case "C" 13 x = 2 14Case "D" 15 x = 3 16Case "E" 17 x = 4 18Case "F" 19 x = 5 20Case "G" 21 x = 6 22Case "H" 23 x = 7 24Case "I" 25 x = 8 26End Select 27 28 29 For i = 1 To 8 30 If WS.Cells(3 + ((x + i) Mod 9), Selection.Column) = 1 Then 31 y = (x + i) Mod 9 32 Exit For 33 End If 34 Next 35 36Select Case y 37Case 0 38 testx = "A" 39Case 1 40 testx = "B" 41Case 2 42 testx = "C" 43Case 3 44 testx = "D" 45Case 4 46 testx = "E" 47Case 5 48 testx = "F" 49Case 6 50 testx = "G" 51Case 7 52 testx = "H" 53Case 8 54 testx = "I" 55End Select 56 57End Function 58

投稿2016/09/05 02:20

cesolution

総合スコア217

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

gasuko

2016/09/05 02:46

こんなに詳しく教えていただけまして本当に感激です。 ご提示いただいた表に似たは作っていたのですが、それ以降の手順がわかりませんでしたので、このようにアドバイスをいただけて感謝しております。 書いていただいた内容をググりながら解読し、実際に使用できる状態にできるように頑張ろうと思います。この度は本当にありがとうございました!!
gasuko

2016/09/05 07:11

教えていただいたまま入力しましたが、エラーになってしまいました。VBAは奥が深いです・・・( ;∀;)
cesolution

2016/09/05 07:20

gasuko様 ご連絡ありがとうございます。 エラーになってしまったということで、2点ほど確認していただきたいのですが、 ①C14のデータ(上図でいうと"A"となっている部分)だけは手打ちで入力が必要になりますので、ご注意ください。その後、D14、E14、、、はそれぞれC14、D14を参照していく形になります。 ②ワークシートはSheet1を使用しているでしょうか? もし異なっている場合は、3行目の"Sheet1"の部分をご変更ください。 宜しくお願いいたします。
gasuko

2016/09/05 07:26

こちらこそコメントありがとうございます。 C14の部分には手入力でAと入力してあります。また使用しているシートはsheet1です。 VBEで入力した内容は、 <code> Sub 当番() Function testx(x) Dim WS As Worksheet Set WS = Worksheets("Sheet1") Dim i As Integer Dim y As Integer Select Case x Case "A" x = 0 Case "B" x = 1 Case "C" x = 2 Case "D" x = 3 Case "E" x = 4 Case "F" x = 5 Case "G" x = 6 Case "H" x = 7 Case "I" x = 8 End Select For i = 1 To 8 If WS.Cells(3 + ((x + i) Mod 9), Selection.Column) = 1 Then y = (x + i) Mod 9 Exit For End If Next Select Case y Case 0 testx = "A" Case 1 testx = "B" Case 2 testx = "C" Case 3 testx = "D" Case 4 testx = "E" Case 5 testx = "F" Case 6 testx = "G" Case 7 testx = "H" Case 8 testx = "I" End Select End Function End Sub </code> です。
cesolution

2016/09/05 07:34

ご連絡ありがとうございます。Sub 当番()~End Subは不要ですので、削除していただければと思います。
gasuko

2016/09/05 07:36

削除してしまうと実行ボタンが押せなくなってしまうのですが、やり方が悪いのでしょうか・・・?
gasuko

2016/09/05 07:40

実行 > sub/ユーザーフォームの実行 を押すとマクロ名を入力するような画面になるので、そこで「当番」と入力すると先ほどのコードに追加されてしまうようです。
cesolution

2016/09/05 07:42

説明不足だったため、分かりにくくすみませんでした。(自分でもちょっと不親切かとは思ったのですが) 実行ボタンは押す必要はございません。Function ~ End Functionで、関数として登録していますので、このまま、エクセルシート側から呼び出すことができます。 今回作成した関数は、testx(前回の当番の人の名前)という形で呼び出すことができます。 この関数を使うことで、関数を設定したセルと同じ列を調べ、出勤している人の中から、当番になるべき人を返すようにしております。
gasuko

2016/09/05 07:59

初歩的なことすら理解せずに質問してしまい、こちらこそ申し訳ありません。 関数を作っておいて呼び出すという方法がある事を知れてとても勉強になりました。ありがとうございます。上記の通りやってみましたらだいぶいい感じに出来たのですが、cesolution様と出力結果が異なるようで、私の結果は出勤していない人が当番になってしまうようです。
cesolution

2016/09/05 08:07

恐らくですが、再計算が上手くされていないのではないかと思いますが。C14から右に向かって順番に、式入力→Enterを押していってみていただけますか?
gasuko

2016/09/05 08:19

ひとつひとつ関数の呼び出しを行ったらcesolution様と同じ出力結果になりました。 この表の中の出勤、休みを0か1で管理していますが、これに変更を加えても当番の結果には影響しなかったのですが、急きょ休みになった人がいた場合、処理はどのように行うのが良いのでしょうか?質問ばかりになってしまい申し訳ございません。
guest

0

gasuko様
遠回りさせてしまいまして申し訳ございません。ごちゃごちゃしてきてしまいましたので、別回答いたします。
ご指摘の通り、自動で反映されなくては意味がないので、以下修正案です。
シートは上記と同様です。
ワークシートのSheet1のマクロに、以下のようにシフト表で変更があった場合に、VBAで変更を行います。

VBA

1Private Sub Worksheet_Change(ByVal Target As Range) 2 3Dim WS As Worksheet 4Set WS = Worksheets("Sheet1") 5Dim i As Integer 6 7 If (Target.Row >= 3 And Target.Row <= 11) And (Target.Column >= 3 And Target.Column <= 8) Then 8 9 For i = 1 To 5 10 WS.Cells(14, 3 + i) = testx(Cells(14, 2 + i), i + 3) 11 Debug.Print (testx(Cells(14, 2 + i), i + 3)) 12 Next i 13 14 End If 15 16End Sub

If (Target.Row >= 3 And Target.Row <= 11) And (Target.Column >= 3 And Target.Column <= 8) の部分は、C3~I11までの間のセルで変更があった際に動作するマクロという意味です。
続いて、関数のマクロも次のように変更いたします。
現在セルの列を取得するのではなく、セルの列数は、関数側に受け渡すように変更しております。

VBA

1Sub run() 2Dim WS As Worksheet 3Set WS = Worksheets("Sheet3") 4 5 For i = 1 To 5 6 WS.Cells(14, 3 + i) = testx(WS.Cells(14, 3 + i - 1)) 7 Next 8 9End Sub 10Function testx(x, j) 11Dim WS As Worksheet 12Set WS = Worksheets("Sheet3") 13Dim i As Integer 14Dim y As Integer 15 16Select Case x 17Case "A" 18 x = 0 19Case "B" 20 x = 1 21Case "C" 22 x = 2 23Case "D" 24 x = 3 25Case "E" 26 x = 4 27Case "F" 28 x = 5 29Case "G" 30 x = 6 31Case "H" 32 x = 7 33Case "I" 34 x = 8 35End Select 36 37 38 For i = 1 To 8 39 If WS.Cells(3 + ((x + i) Mod 9), j) = 1 Then 40 y = (x + i) Mod 9 41 Exit For 42 End If 43 Next 44 45Select Case y 46Case 0 47 testx = "A" 48Case 1 49 testx = "B" 50Case 2 51 testx = "C" 52Case 3 53 testx = "D" 54Case 4 55 testx = "E" 56Case 5 57 testx = "F" 58Case 6 59 testx = "G" 60Case 7 61 testx = "H" 62Case 8 63 testx = "I" 64End Select 65 66End Function 67 68

これで、C14にAだけ入れておけば、後は動くと思うのですが、ご確認いただけますでしょうか。

投稿2016/09/05 09:10

cesolution

総合スコア217

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

gasuko

2016/09/06 02:48

Private Sub Worksheet_Change(ByVal Target As Range) Dim WS As Worksheet Set WS = Worksheets("Sheet1") Dim i As Integer If (Target.Row >= 3 And Target.Row <= 11) And (Target.Column >= 3 And Target.Column <= 8) Then For i = 1 To 5 WS.Cells(14, 3 + i) = testx(Cells(14, 2 + i), i + 3) Debug.Print (testx(Cells(14, 2 + i), i + 3)) Next i End If End Sub の下に Sub run() Dim WS As Worksheet Set WS = Worksheets("Sheet3") For i = 1 To 5 WS.Cells(14, 3 + i) = testx(WS.Cells(14, 3 + i - 1)) Next End Sub Function testx(x, j) Dim WS As Worksheet Set WS = Worksheets("Sheet3") Dim i As Integer Dim y As Integer Select Case x Case "A" x = 0 Case "B" x = 1 Case "C" x = 2 Case "D" x = 3 Case "E" x = 4 Case "F" x = 5 Case "G" x = 6 Case "H" x = 7 Case "I" x = 8 End Select For i = 1 To 8 If WS.Cells(3 + ((x + i) Mod 9), j) = 1 Then y = (x + i) Mod 9 Exit For End If Next Select Case y Case 0 testx = "A" Case 1 testx = "B" Case 2 testx = "C" Case 3 testx = "D" Case 4 testx = "E" Case 5 testx = "F" Case 6 testx = "G" Case 7 testx = "H" Case 8 testx = "I" End Select End Function を記述してC14にAを入力すれば自動で当番が出力されるということでしょうか? それともAの右隣には=testx(C14)と入力してその右も同様に関数を入力しておかないとだめですか? 何度もトライしたのですが、#VALUE! になってしまいます。
cesolution

2016/09/06 04:44

gasuko様 度々すみません、私の方はSheet3で作成しており、変更するのを失念しておりました。 まず、VBEでSheet1をダブルクリックしてください。 すると、Sheet1専用のマクロを登録することができます。 そこで、以下のコードをご入力ください。 Private Sub Worksheet_Change(ByVal Target As Range) Dim WS As Worksheet Set WS = Worksheets("Sheet1") Dim i As Integer If (Target.Row >= 3 And Target.Row <= 11) And (Target.Column >= 3 And Target.Column <= 8) Then For i = 1 To 5 WS.Cells(14, 3 + i) = testx(Cells(14, 2 + i), i + 3) Debug.Print (testx(Cells(14, 2 + i), i + 3)) Next i End If End Sub 続いて、標準モジュールの方に、以下のコードを登録してください。 Function testx(x, j) Dim WS As Worksheet Set WS = Worksheets("Sheet3") Dim i As Integer Dim y As Integer Select Case x Case "A" x = 0 Case "B" x = 1 Case "C" x = 2 Case "D" x = 3 Case "E" x = 4 Case "F" x = 5 Case "G" x = 6 Case "H" x = 7 Case "I" x = 8 End Select For i = 1 To 8 If WS.Cells(3 + ((x + i) Mod 9), j) = 1 Then y = (x + i) Mod 9 Exit For End If Next Select Case y Case 0 testx = "A" Case 1 testx = "B" Case 2 testx = "C" Case 3 testx = "D" Case 4 testx = "E" Case 5 testx = "F" Case 6 testx = "G" Case 7 testx = "H" Case 8 testx = "I" End Select End Function 今度こそいけると思うのですが、宜しくお願いいたします。
cesolution

2016/09/06 04:45

あっすみません。Function testxの中のSet WSをSheets1にしておりませんでした。標準モジュールの3行目をSet WS = Worksheets("Sheet3")にご変更ください。
cesolution

2016/09/06 04:46

度々すみません、Set WS = Worksheets("Sheet1")です。
gasuko

2016/09/06 05:34

コメントありがとうございます。やはり出来ないですね・・・。 実現したい内容がこんなにも難しいとは(´・ω・`)
cesolution

2016/09/06 06:38

gasukoさん シンプルにマクロ実行時に変更するように書き換えてみました。 以下でいかがでしょうか? マクロ実行でcheckをランさせてみてください。 Sub check() Const N = 5 Dim WS As Worksheet Set WS = Worksheets("Sheet1") Dim i As Integer Dim j As Integer Dim k As Integer Dim x As Integer Dim member() As String member = Split("A,B,C,D,E,F,G,H,I", ",") For i = 0 To N For k = 0 To 8 If WS.Cells(14, 3 + i) = member(k) Then x = k Debug.Print (k) Exit For End If Next For j = 1 To 8 If WS.Cells(3 + ((x + j) Mod 9), i + 4) = 1 Then WS.Cells(14, 4 + i) = member((x + j) Mod 9) Exit For End If Next j Next i End Sub 宜しくお願いいたします。
gasuko

2016/09/07 00:14

おかげさまで動かすことができました! VBAが使えるようになると本当に便利だなと思いました。 この度は本当にお世話になりました。色々とありがとうございました!(^^)!
guest

0

Sub 当番() Function testx(x) Dim WS As Worksheet Set WS = Worksheets("Sheet1") Dim i As Integer Dim y As Integer Select Case x Case "A" x = 0 Case "B" x = 1 Case "C" x = 2 Case "D" x = 3 Case "E" x = 4 Case "F" x = 5 Case "G" x = 6 Case "H" x = 7 Case "I" x = 8 End Select For i = 1 To 8 If WS.Cells(3 + ((x + i) Mod 9), Selection.Column) = 1 Then y = (x + i) Mod 9 Exit For End If Next Select Case y Case 0 testx = "A" Case 1 testx = "B" Case 2 testx = "C" Case 3 testx = "D" Case 4 testx = "E" Case 5 testx = "F" Case 6 testx = "G" Case 7 testx = "H" Case 8 testx = "I" End Select End Function End Sub

投稿2016/09/05 07:27

gasuko

総合スコア27

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問