• ベストアンサー

マクロで当番表

Excelマクロで当番表を作成しているのですが、わからない事があるのでお教えください。 例えば1週間毎にAさん、Bさん、Cさん、Dさん4人を振り分けたいのですが、分岐、判断方法がわかりません。 1年間のカレンダーは出来上がっています。 当方の企業は完全週休2日で祝祭日も休みです。カレンダーの休日にはセルを塗りつぶしています。(マクロで34の薄い水色です。) そこで、休日セルの塗りつぶしを背景で、日曜日~土曜日までを曜日で情報を受け取り作成したいのですが、うまくいきません。 月曜から金曜までをAさん、次の週の月曜から金曜までをBさんにしたいのです。 また、Dさんが終わればAさんに戻る。 下記は曜日と背景の例です。 if then ElseでもDo until loopでも他の方法でもよろしいのでお教えください。 曜日=Right(Sheets("カレンダー").Cells(行, 列).Value, 1) 背景 = Cells(行, 曜日列).Interior.ColorIndex

質問者が選んだベストアンサー

  • ベストアンサー
  • papayuka
  • ベストアンサー率45% (1388/3066)
回答No.9

#3です。 > ただ、4月28日から5月7日までの長期連休時はにBさんが抜けます。 > また、myList = Array("Aさん", "Bさん", "Cさん", "Dさん")で人数が変わってもよいのでしょうか? 1週間以上の休みを想定してませんでしたので、人数変更と合わせて修正してみました。 Sub Test2() Dim r As Range, myList, i As Integer, j As Integer, flg As Integer i = 0: flg = 0 For j = 2 To 24 Step 2   ActiveSheet.Columns(j).ClearContents Next j myList = Array("Aさん", "Bさん", "Cさん", "Dさん", "Eさん") For j = 1 To 24 Step 2  With ActiveSheet      For Each r In .Range(.Cells(2, j), .Cells(65536, j).End(xlUp))     If Weekday(r, vbMonday) <= 5 Then      If r.Interior.ColorIndex <> 34 Then        r.Offset(0, 1) = myList(i): flg = flg + 1      End If     Else      If Weekday(r, vbMonday) = 7 And flg > 0 Then        i = i + 1: flg = 0        If i > UBound(myList) Then i = 0      End If     End If   Next r  End With Next j End Sub

lay-man
質問者

お礼

早いご解答ありがとうございました。 早速、試してうまく動作しました。 これを元に私のマクロの勉強も弾みがつきます。 大変ありがとうございました。 また、わからない事がありましたらよろしくお願いします。

その他の回答 (8)

  • nicotinism
  • ベストアンサー率70% (1019/1452)
回答No.8

こういうのを標準モジュールに貼り付けて Function Rota(sDay As Date, tDay As Date, rt As Long) As String Dim c As Variant   'sDay 当番開始日   'tDay 判断日   'rt  何人でローテーションか      Set c = Worksheets("祝日表").Range("a:a").Find( _         Format(tDay, "m月d日"), LookIn:=xlValues, lookat:=xlWhole)         '↑祝日表の書式と併せるため   If Not c Is Nothing Then 'Find で条件に見合うものが有った場合     Rota = Trim(Str(rt + 3))     Exit Function   End If      Select Case Weekday(tDay, vbMonday)     Case 1 To 5       '週(7)で割った商を rt で割った余りを求めています       Rota = Str((DateDiff("d", sDay, tDay) \ 7) Mod rt + 1)     Case 6       Rota = Str(rt + 1)     Case 7       Rota = Str(rt + 2)   End Select   Rota = Trim(Rota) End Function ワークシートのセルに日付が入っているとしてB列に名前を出したい。 C列に当番者の名前がある。としたら たとえば4人の例ですが A1 12月1日    B1    C1 たなか A2 12月2日    B2    C2 さとう A3 12月3日    B3    C3 すずき A4 12月4日    B4    C4 やまだ A5 12月5日    B5    C5 土 A6 12月6日    B6    C6 日 A6 12月7日    B7    C7 祝 A6 12月8日    B8    C8 ・・・・・・・・・・・・・・・ シートをもうひとつ用意して(上記モジュールではシート名を祝日表としています) A列に年間の祝日の一覧を作成 A1 1月1日 A2 1月2日 A3 1月3日 ・・・・・ としたら、Sheet1のB列のセルに =INDIRECT("C" & rotaNo($A$1,A1,4)) で ズズーとコピペで名前が入ります。

  • papayuka
  • ベストアンサー率45% (1388/3066)
回答No.7

#3です。 > 例「1火(一日の火曜日)」 > 曜日=Right(Sheets("カレンダー").Cells(行, 曜日列).Value, 1) Excelで日付を扱う場合、通常はこういうワープロ的な使い方をしません。 以下を新規ブックで試して下さい。 1)A2 に 2006/1/1 と入力 2)A3 に =A2+1   と入力 3)A3 を A32 までコピー 4)A2:A32を選択して、書式-セル-セルの書式設定で表示形式タブで分類を 「ユーザー定義」にして「種類」に  daaa  と入力します。 これで A2~A32 に 1日 ~ 31火 と表示されます。 A2 だけを 2007/1/1 に変えれば、あっという間に2007年1月のカレンダーになります。 表示形式によってセルに「2006/1/1」と入力したものを自在に表示出来るのです。 そして計算にも使えるようになりますし、条件付き書式で色付けも容易に出来ます。 yyyy/mm/dd (aaa)  → 2006/01/01 (日) yyyy/mm/dd (aaaa)  → 2006/01/01 (日曜日) gee/m/d (ddd)    → H18/1/1 (Sun) (aaa)        → (日) A2~W2に日付型でデータがある場合の例を私なりに書いてみました。 Sub Test1() Dim r As Range, myList, i As Integer, j As Integer, flg As Boolean i = 0: flg = False myList = Array("Aさん", "Bさん", "Cさん", "Dさん") For j = 1 To 24 Step 2  With ActiveSheet   For Each r In .Range(.Cells(2, j), .Cells(65536, j).End(xlUp))     If Weekday(r, vbMonday) <= 5 Then      If r.Interior.ColorIndex <> 34 Then        r.Offset(0, 1) = myList(i): flg = True      End If     Else      If Weekday(r, vbMonday) = 7 And flg Then        i = i + 1: If i > 3 Then i = 0      End If     End If   Next r  End With Next j End Sub

lay-man
質問者

お礼

#3さん Test1でうまくいきました。 ありがとうございます。 ただ、4月28日から5月7日までの長期連休時はにBさんが抜けます。 勉強して解決したいと思います。 また、myList = Array("Aさん", "Bさん", "Cさん", "Dさん")で人数が変わってもよいのでしょうか?

noname#30052
noname#30052
回答No.6

No2です。追伸  あ、もし配列がわかるなら配列にした方がすっきりしますよ。  Selectなんか使わなくても済みますからね^^

noname#30052
noname#30052
回答No.5

No2です。 No1さんやNo3さんの言う通り、日付と曜日は分けたほうが 良いですよ。今後も楽になると思います。 でもどうしても今の形を壊したくない&とにかく動きゃいいんだ というのであれば。。。 No2のロジックをそのまま縦書きにしたバージョンを書いておきます。 (またしても動けばいいや状態ですがw) Sub Macro1() pp = 1  '1:A 2:B 3:C 4:D For ii = 1 To 23 Step 2  'ii:処理対象の欄No     Call Macro2(pp, ii) Next ii End Sub Sub Macro2(pp, ii) gg = 1 '行Noカウンタ(開始位置を設定) ' 曜日が設定されているところまで繰り返し実行~♪ Do     If Right(Sheets("カレンダー").Cells(gg, ii).Value, 1) = "" Then Exit Do     If Cells(gg, ii).Interior.ColorIndex <> 34 Then         If Right(Sheets("カレンダー").Cells(gg, ii).Value, 1) = "月" Then             If pp = 4 Then              pp = 1             Else              pp = pp + 1             End If         End If         Select Case pp             Case Is = 1                 Sheets("カレンダー").Cells(gg, ii + 1).Value = "A"             Case Is = 2                 Sheets("カレンダー").Cells(gg, ii + 1).Value = "B"             Case Is = 3                 Sheets("カレンダー").Cells(gg, ii + 1).Value = "C"             Case Is = 4                 Sheets("カレンダー").Cells(gg, ii + 1).Value = "D"         End Select     Else         Sheets("カレンダー").Cells(gg, ii + 1).Value = "" '休日はNull     End If     gg = gg + 1  '行Noのカウントアップ♪ Loop End Sub VBAは本職じゃないので綺麗な命令にゃできませんが その辺はご勘弁をw No3さんへ >私は投稿前にエディタで半角空白2個を全角空白1個に置換してからコピペしています。 了解です。ありがとうございます。

  • toshi_2000
  • ベストアンサー率30% (306/1002)
回答No.4

No.1です。 A列に年月日、B列に背景でC列に当番を入れるマクロは、次の通りです。 これを元に変更して、月毎にFORループを分ければ、貴方のお望みのものができそうです。 Sub TEST() Dim TN(4) As String TN(1) = "A" TN(2) = "B" TN(3) = "C" TN(4) = "D" J = 0 For I = 1 To 365 If Weekday(Cells(I, 1)) > 1 And Weekday(Cells(I, 1)) < 7 And Cells(I, 2).Interior.ColorIndex <> 34 Then If SHU > Weekday(Cells(I, 1)) Or Cells(I, 1) - DAY1 >= 7 Then J = J + 1 If J = 5 Then J = 1 End If End If Cells(I, 3) = TN(J) SHU = Weekday(Cells(I, 1)) DAY1 = Cells(I, 1) End If Next End Sub

  • papayuka
  • ベストアンサー率45% (1388/3066)
回答No.3

データの持ち方等が不明瞭です。 「曜日」にはどんなデータが入るのでしょう? 「月」「火」のような文字列ですか? 通常カレンダー等は日付(2006/12/1 等)を入力してセルの書式設定を geee/mm/dd (aaa) とか aaaa とかにして処理をします。 そうする事で Weekday 関数で数値による条件判断が可能になります。 サンプルがほしいのであれば、データ構造を書かないと書けません。 現状のマクロもアップした方が良いかも。 #2さんへ > ____は空白です。(投稿すると空白が勝手に詰まってしまうので。。(・_・;) 私は投稿前にエディタで半角空白2個を全角空白1個に置換してからコピペしています。 これでインデントは保持されます。 VBEエディタの場合なら、その状態でコピペしても半角空白に変換してくれますし、、、

lay-man
質問者

補足

はじめに、訂正があります。 曜日=Right(Sheets("カレンダー").Cells(行, 列).Value, 1) 背景 = Cells(行, 曜日列).Interior.ColorIndex            ↓ 曜日=Right(Sheets("カレンダー").Cells(行, 曜日列).Value, 1) 背景 = Cells(行, 列).Interior.ColorIndex 大変、舌足らずですみません。 A列に日付と曜日が入っています。例「1火(一日の火曜日)」 曜日列はA列のことをさしています B列に当番表を作成したいのです。 要は、背景の塗りつぶしの色と曜日で判断したいのです。 よろしくお願いします。

noname#30052
noname#30052
回答No.2

曜日ではなく列Noで判断して設定してはいかがですか? ざっと例を書くと。。。 ii = 1 '列Noカウンタ(開始位置を設定) rr = 27 '調整値(27,0,1~5) Do `曜日が設定されているところまで繰り返し実行~♪ ____If Right(Sheets("カレンダー").Cells(1, ii).Value, 1) = "" Then Exit Do ____If Cells(1, ii).Interior.ColorIndex <> 34 Then ________Select Case (ii + rr) Mod 28 '列No÷4週(28日)の余り ____________Case Is < 7 '1週目 ________________Sheets("カレンダー").Cells(2, ii).Value = "A" ____________Case Is < 14 '2週目 ________________Sheets("カレンダー").Cells(2, ii).Value = "B" ____________Case Is < 21 '3週目 ________________Sheets("カレンダー").Cells(2, ii).Value = "C" ____________Case Is < 28 '4週目 ________________Sheets("カレンダー").Cells(2, ii).Value = "D" ________End Select ____Else ________Sheets("カレンダー").Cells(2, ii).Value = "" '休日はNull ____End If ____ii = ii + 1 '列Noのカウントアップ♪ Loop ____は空白です。(投稿すると空白が勝手に詰まってしまうので。。(・_・;) 上記の例では曜日が1行目にあるものとし、2行目に担当者名を設定してます。iiとrrの初期設定値を調整すればうまく入ると思います。 ん~。。。即席なんであんまり綺麗なロジックじゃないですね~^^; まぁ、あくまで1例として参考にして下さい☆ 複数行に分かれてる場合は上記のようなsubルーチンを作って、開始行番号をパラメータで受け渡せば良いかと思います。 頑張ってください♪

lay-man
質問者

補足

上記の例いちどやってみます。 ありがとうございます。 A.C.E.G.I.K.M.O.Q.S.U.W列に1日から28日または30日、31日と入っています。(日付と曜日が同一セルに) B.D.F.H.J.L.N.P.R.T.V.X列が空白セルです。 ここに当番者名を展開したいのです。 うまく言い表せませんがよろしくお願いします。

  • toshi_2000
  • ベストアンサー率30% (306/1002)
回答No.1

どううまくいかないのでしょうか。 もう少し詳細を教えていただければ回答できるかも知れません。 Sheets("カレンダー")の構造(どの列にどんなデータが入っているとか)

lay-man
質問者

補足

#2さんの補足で説明したとおりですが、うまく説明ができません。 マクロをはじめてまだ、日が浅いのでお許しください。

関連するQ&A

  • 勤務表の休暇振分表示

    社員の休日を自動的に振り分ける表を作成したい と思っているのですが・・うまくいきません。 A1セル2006/7/1を元にカレンダーを作成しています。 A列が日付、B列を曜日とし条件書式を組み合わせ、 行に土曜と祝日と日曜に色分けをし月が変われば表示しない 設定としています。月をかえたらその月のカレンダーに なるようにしています。 C・D列には条件書式を反映しています。 仕事をしたらB列を元に条件に合うD列のセル(曜日行)に 担当者名を表示したいと思います。 担当者名には、番号をつけ、別の列に表示してあります。 C列には担当に値する番号を入力し C列にB列(曜日列)が土・日・祝日ならばDセルには何も 表示しない。 B列が月から木ならそれぞれ翌日の曜日のDセルに担当者名を 表示する。 (例えば7月3日(月)の場合C列にAと入力すると7月4日 の行のDセルにAに値する担当者名を表示する) ただし、金なら翌週の月の行のDセルに担当者名を表示する。 どうかお力をお貸しください! 急いでいます。よろしくお願いします。

  • 日付データで計算し、土、日分の2行追加する方法

    excel2010 日付データで計算し、土、日の2行を追加するマクロを作成しました。 途中は、正しく2行追加されます。 しかしながら、最終行が月曜日だけだと、最終行(月曜日)と最終行-1(金曜日)の間に 2行追加されません。 作成したマクロのどこが悪いのかを教えていただきたく。 構成は次の通り A列に日付のデータがA4セルから貼り付けられています。 A3セルは、題目で日付という文字列があります。 A列には、最初土、日の日付(行)がありません。 土、日の行、2行分を追加するために、計算式で行と次の行の差が3以上だったら 2行追加というマクロを設定します。 マクロは次の通り Sub donichiadd() '' Dim MxR As Long Dim h As Long MxR = Range("A65536").End(xlUp).Row - 1 For h = MxR To 5 Step -1 If Cells(h, 1) - Cells(h - 1, 1) >= 3 Then Cells(h, 1).Resize(2).EntireRow.insert End If Next h End Sub マクロは以上。 データが下記だとします。 A4セル:6/1 A5セル:6/2 A6セル:6/3 A7セル:6/4 A8セル:6/5 A9セル:6/8 A10セル:6/9 A11セル:6/10 A12セル:6/11 A13セル:6/12 A14セル:6/15 この状態でマクロを実行すると、 6/8と6/5の間は2行追加されますが、 6/15と6/12の間には2行追加されません。 尚、A15セルに6/16があった場合にマクロを実行すると、 6/15と6/12の間に2行追加されます。 最終行が月曜日だけだと、土、日分の2行を追加することが出来ない状態です。 どこが悪いのか教えていただきたく。

  • マクロで作ってほしいのです。

    ある行のセルの決まった文字を検索し他の行のセルに別の文字を入力するマクロを作ってほしいのです。下の例で言えばA列にある"大根"(A5,A7)をさがしD5,D7に"特売日"と入力するマクロを作ってほしいのです。よろしくお願いいたします。

  • エクセルマクロで対応するセルの値を表示したい

    簡単なことで引っかかってしまいました。助けてください A1のセルに数字が入っています。 A2のセルにA1の数字の行、3列目のセルに書いてあるものを表示したい。 A2のセルに =CELLS(A1,3).Value のようなことをしたいのですが、マクロでは CELLS というものがありません。 なにか関数があると思うのですが、教えてください。

  • エクセルマクロでのグラフ作成について

    エクセルのマクロでグラフを作成したいのですが 設定したい値のセルが行も列も飛び飛びなんです。このような場合、どうやってセルを設定すればいいか教えてください。 セルの自動マクロ記録でやってみると、例えばですが ActiveChart.SetSourceData Source:=Sheets("グラフ").Range( _ "A5,A10,A15,A20,A25,A30,A35,D5,D10,D15,D20,D25,D30,D35"), PlotBy:= xlColumns このような設定で希望通りのグラフが出来上がります。 A列(X軸)とD列(Y軸)の値で、列は固定で数行置きのデータでのグラフが作りたいのです。 しかもどの行かは固定ではありませんので、セルアドレスをそのまま入力するのではなく、Cells(,) で設定したいのですが、Unionを使ってみたり、色々試したのですが、うまくできません。 おわかりの方教えて頂けませんでしょうか。 よろしくお願いいたします。

  • 該当の曜日に色を塗るマクロの作成方法2(VBA)

    いつも拝見させていただき、みなさまのご回答に感謝しています! 以前、質問をさせていただいたのですが、 VBA初心者の私では、やはり自分自身で応用ができず、 大分悩んだのですが解決できず、とても困っています。 前回ご回答してくださったtom04様、ありがとうございました。 『該当の曜日に色を塗るマクロ』を作成したいのですが、 当然ですが行や列を挿入すると「Weekdayプロパティを取得できません。」と エラーになってしまいます。 実際のセル番地を記載しますので、 ご回答をお願いいたします。 勉強不足で申し訳ございません。 【サンプルVBA】----------------------------- ≪使用PC≫ windows XP Excel2003 前回質問URL:http://okwave.jp/qa/q7714972.html ■曜日毎の『ボタン』を7つ作成する。 『月曜日』というボタンを押すと、日付と月曜日のセルに色を塗る。 『火曜日』というボタンを押すと、日付と火曜日のセルに色を塗る。 『水曜日』・・・・・ 【例】 年は(セルA1) 月は(セルA2) 日は(セルA3~セルAE3) 曜日は(セルA4~セルAE4) ※年と月と日は、べた打ちで数値を入力。 ※曜日は月と日から関数を入力し、自動で出ています。 IF(A$3="","",DATEVALUE($A$1&"/"&$A$2&"/"&A$3)) 【月曜日sample VBA】 Sub monday_sample() Dim j As Long Rows(3 & ":" & 4).Interior.ColorIndex = xlNone For j = 1 To 31 If Cells(4, j) <> "" Then If WorksheetFunction.Weekday(Cells(4, j)) = 2 Then Range(Cells(3, j), Cells(4, j)).Interior.ColorIndex = 6 End If End If Next j End Sub 【実用したいVBA】--------------------------- 年は(セルA3) 月は(セルA4) 日は(セルD6~セルAH6) 曜日は(セルD7~セルAH7) ※年と月と日は、べた打ちで数値を入力。 ※曜日は月と日から関数を入力し、自動で出ています。 例:セルD7→『IF(D$6="","",DATEVALUE($A$3&"/"&$A$4&"/"&D$6))』 -------------------------------------------- なにとぞよろしくお願いいたします。

  • エクセル2003のマクロ作成の件

    同一連続セルにあるグループの中で、D列に「完了」があれば、F列に「4」を入力し、その同一連続セル内で、検索し、D列の対応中を探します。その「対応中」の先頭が、完了にした担当者と同じであれば、「9」を。違えば、「0」を。完了は、同一セル内の最後にきていない事もあります。該当しない時や単一セルの時は、何もせず、空白のままにします。A列には、空白行がなく、3万行ほどあります。特定文字を探し、その1行上を探すなどののマクロはできるのですが、条件が重なると、作成が出来ません。今まで、手動で、数値を入れていたのですが、マクロで作成出来ないものでしょうか?マクロ初心者です。

  • マクロCellsがわからなくて困っています

    マクロのCellsについて、夜も眠れないほど悩んでいます。 助けてください。 相談は以下です。 Cells(1,1).Select の行、列部分に、他のセルに入力済みの数値を指定したり、算出することはできますか? たとえば、あらかじめセルに数値が入っていたら Cells(1,A1).Select Cells(1,B1-A1).Select のように。(誤った文章ですが・・・) またこの方法に使えるCells以外の言葉があれば、教えてくださいませ!

  • マクロのエラーについて

    マクロ記録とネットを参考に、初めて下記のマクロを作成しましたが、マクロを作成したBOOKでは、エラー無く動作し、テスト用に2番目の別BOOKのマクロ編集に貼り付けマクロ実行したところ、エラー1004が出ました。なぜなのでしょうか? 通常は原紙ファイルのシートにデータをコピー⇒貼り付け・保存、ピボットテーブルで集計したものを印刷し使用しています。 下記画像の表にて、D列4行目(黄色)の同日付をセル結合、E列5行目(水色)の同時間をセル結合したものを複数枚作成しています。 この作業をマクロ処理化したいのですが、社内にVBAの扱える人はおらず、外注の許可も出ないので自分で何とかしたいと思っています。 どなたか良いコードや下記コードの訂正などご教授頂けないでしょうか。 宜しくお願いいたします。 Sub 予定表セル結合2() K = 0 For K = 1 To 100 If Cells(4, 4 + K) <> Cells(4, 5 + K) Then セル範囲3 = 5 + K 工程名 = Cells(4, 5 + K) ElseIf Cells(4, 4 + K) = Cells(4, 5 + K) And Cells(4, 5 + K) <> Cells(4, 6 + K) Then セル範囲4 = 5 + K '工程名2 = Cells(4, 5 + K) Range(Cells(4, セル範囲3), Cells(4, セル範囲4)).Select  ***ここでエラーです*** Application.DisplayAlerts = False Selection.Merge 'セル結合 Application.DisplayAlerts = True End If Next K ***この後5列目の同時間のセル結合をしたいのです**** End Sub

  • マクロでの色の塗りつぶしについて

    A1のセルに○、A2のセルには○、A3のセルには×・・・といった行があるとします。 その中から○のセルを探し、その○のD列(A1が○ならD1)を色で塗りつぶしたい時 どのようなマクロにすればよいか教えてください。