• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:excel vba 時間計算と条件分岐の質問)

Excel VBAで勤怠表の時間計算と条件分岐の質問

cj_moverの回答

  • ベストアンサー
  • cj_mover
  • ベストアンサー率76% (292/381)
回答No.1

こんにちは。 mac互換といわれると、最近の事情はまったく知らないのですが、 とりあえず3例挙げてみます。 ところで、投稿用に便宜的に書き換えた?のでしょうけれど、 > STAR_TIME = Cells(0, STAR_CL)   '出勤時間の行です Cells の rowindex に 0 を指定するのは (相対参照で書く場合以外は)失敗しますから、 便宜的に、変数 i に置き換えて提示します。 IF ... ElseIf ... Else ... End If で書いていると後から見ても条件分岐が解り難そうですから、 一般的な、Select Case ... Case ... End Select で書いてみます。 勤務時間と比較する時間値は、色々な書き方がありますが、 やはり読み易さ重視で、TimeValue()関数で書きます。 出力値は、"0:45"のように文字列の直値でもOKなので、 これも読み易いものを選びます。 時刻を出力するのにDate型を出力する場合は必ず 書式の表示形式を設定しておかなければなりませんから、 時刻値の出力は文字列値の方が却ってバリアントです。 ご提示された(抜粋された)記述を読む限りは、 With フレーズ を使う必然性が低いので、 こちらでは、新規の変数として、休憩時間を指す myRecess に一旦格納してから、この変数値をセル出力するように (他の記述での変数の扱い方に合わせるように)書いています。 とりあえず、普通な感じで。 ' ' /// Dim myRecess As Variant Dim i As Long ' ...   STAR_TIME = Cells(i, STAR_CL) ' 出勤時間   LAST_TIME = Cells(i, LAST_CL) ' 退勤時間   myTime = LAST_TIME - STAR_TIME ' 休憩時間   Select Case myTime   Case Is >= TimeValue("8:00") ' 8 時間以上で休憩時間は1時間     myRecess = "1:00"   Case Is >= TimeValue("6:00") ' 6 時間以上8時間未満で休憩時間45分     myRecess = "0:45"   Case Is >= TimeValue("4:00") ' 4 時間以上6時間未満で休憩時間30分     myRecess = "0:30"   Case Else ' 4 時間未満で休憩時間0分     myRecess = "0:00" '   End Select   Cells(i, RECESS_CL) = myRecess ' ... ' ' /// ここに書かれていない他の記述での条件さえ合えば、 Hour(myTime) 時刻値の"時"だけを比較する方法もあります。 別段コメントを付加しなくても意味が呑み込み易いという意味で ビギナー向き、の書き方です。 ' ' /// Dim myRecess As Variant Dim i As Long ' ...   STAR_TIME = Cells(i, STAR_CL) ' 出勤時間   LAST_TIME = Cells(i, LAST_CL) ' 退勤時間   myTime = LAST_TIME - STAR_TIME ' 休憩時間   Select Case Hour(myTime)   Case Is >= 8 ' 8 時間以上で休憩時間は1時間     myRecess = "1:00"   Case 6 To 8 ' 6 時間以上8時間未満で休憩時間45分     myRecess = "0:45"   Case 4 To 6 ' 4 時間以上6時間未満で休憩時間30分     myRecess = "0:30"   Case Else ' 4 時間未満で休憩時間0分     myRecess = "0:00" '   End Select   Cells(i, RECESS_CL) = myRecess ' ... ' ' /// また、Switch()を知っている人なら、以下のようなシンプルな書き方 の方が解り易く馴染み易い、という場合もあるでしょうから、 一応挙げておきますが、 実質4行という短い記述にはなるものの、慣れていない人には扱い難いですね。 ' ' /// Dim i As Long ' ...   STAR_TIME = Cells(i, STAR_CL) ' 出勤時間   LAST_TIME = Cells(i, LAST_CL) ' 退勤時間   myTime = LAST_TIME - STAR_TIME ' 休憩時間   Cells(i, RECESS_CL) = Switch(myTime >= TimeValue("8:00"), "1:00", _                   myTime >= TimeValue("6:00"), "0:45", _                   myTime >= TimeValue("4:00"), "0:30", _                   myTime >= 0, "0:00") ' ... ' ' /// > このあと勤務時間の集計も行なう為、時間の計算方法なども教えて頂けると助かります。 教室ではないのでスキルアップ講座的に授けることは、時間的・空間的に無理です。 逆に教室で教わるにしても、実例に則して学ぶのが易しく効率的ですから、 解らなかったことを都度都度、訊ねるようにした方が、 身に付くと思いますし、未然に混乱を避ける意味もあるかと思います。 とりあえず、以上です。

pti06mwa-qaz
質問者

お礼

素早く丁寧なご回答、感謝致します。問題なく動作しました。ありがとうございました。 今まで意識していなかったのですが、IfステートメントとSelect Caseステートメントの使い分けがわからず、どちらも条件分岐が出来るステートメントという認識に留まっていました。強引にIfで押し進めて来たな...と、反省しております。 variant型も、購入した本で極力使うなと書いてあったもので、なんとなく意識から外れていまして、 当たり前ですが、(極力)というからには使う機会があるのですね。 不等号も、上から順番に処理を進めていくのであんなに悪戦苦闘する必要は無かったとのだと。(だいぶ時間を使いました。) Swichは知らなかったので勉強になります。ファイルサイズが増えていくようなら、このような短い記述の方が処理が軽くなったりするのでしょうか。こういった関数を積極的に使えるように、勉強を重ねたいと思います。 以下、少しだけ疑問におつきあい頂けませんでしょうか。 TimeValue関数は、やはり時間の表示もしてくれるみたいなのですが、時刻と時間を区別しなくても問題ないということですか? 私がFormatでわざわざ時刻を指定してしまっていた。という認識でよいのでしょうか。

関連するQ&A

  • Excel VBAについて

    早速ですがExcelVBAについて質問です。 年齢がN列にあるとき、M列に年代を入れたいと思います。(例:19才なら10代、30才なら30代) 以下のように作成しましたが、すべてに20と入ったり正常に動作しないときがあります。 Excelは2003で作成していますが、いずれ2007でも使いたいです。 もっと正確に実行できるコードを教えてください。 ワークシート関数での解決は望んでいません。データ数も多く他の作業もマクロで処理するのでマクロを希望しています。よろしくお願いします。 -------------------------- Sub ByAge() Range("N1").Value = "年代別" Dim i As Long, N As Integer For i = 2 To Cells(Rows.Count, 1).End(xlUp).Row If Cells(i, 13).Value >= 60 And Cells(i, 13).Value < 70 Then Cells(i, 14).Value = 60 ElseIf Cells(i, 13).Value >= 50 And Cells(i, 13).Value < 60 Then Cells(i, 14).Value = 50 ElseIf Cells(i, 13).Value >= 50 And Cells(i, 13).Value < 60 Then Cells(i, 14).Value = 40 ElseIf Cells(i, 13).Value >= 30 And Cells(i, 13).Value < 40 Then Cells(i, 14).Value = 30 ElseIf Cells(i, 13).Value >= 20 And Cells(i, 13).Value < 30 Then Cells(i, 14).Value = 20 End If Next i MsgBox "完了!" End Sub --------------------------

  • マクロ 条件分岐の仕方

    いつも回答ありがとうございます。 条件分岐について質問です。 文字に『N 』含まれている時の条件処理と、『N』が含まれていない時の条件処理を記述記述しました。一応、この記述で上手く動作しているので問題ないのですが、他に記述方法はないのでしょうか?宜しくお願い致します。 Sub 色を塗る2() Dim b As Long '仮シートの列 Dim res As Variant '色の設定 Dim c As Variant '最後に定期をした日付のセル番地 Worksheets("仮シート").Activate b = 2 Do While Worksheets("仮シート").Cells(2, b).Value <> "" With Worksheets(Worksheets("仮シート").Cells(2, b).Value) Set c = .Columns("C").Find("定期", , xlValues, 1, , 2).Offset(, -1) If Worksheets("仮シート").Cells(2, b).Value Like "*N*" Then If (Date - 30) <= c And c <= Date Then res = 8 ElseIf (Date - 60) <= c And c <= (Date - 31) Then res = 10 ElseIf c <= (Date - 61) Then res = 3 End If End If If Worksheets("仮シート").Cells(2, b).Value Like "*N*" = False Then If (Date - 10) <= c And c <= Date Then res = 8 ElseIf (Date - 30) <= c And c <= (Date - 11) Then res = 10 ElseIf c <= (Date - 31) Then res = 3 End If End If Worksheets("仮シート").Cells(3, b).Interior.ColorIndex = res End With b = b + 1 Loop End Sub

  • エクセルのVBA、ループ処理について

    if文とループ処理をどう組み合わせればいいのかわかりません 以下のコードで、iの数をを増やしていく処理を行いたいのですが、エラーがでてしまいうまくいきません どのように書けばいいのでしょうか 教えてください For i = 2 To 11 If Cells("4,i") > 80 Then Cells("5,i").Value = "A" ElseIf Cells("4,i") > 70 Then Cells("5,i").Value = "B" ElseIf Cells("4,i") > 60 Then Cells("5,i").Value = "C" Else Cells("4,i").Value = "D" End If Next

  • Excel VBA ・・・教えてください

    何度も質問させて頂いてます。すみません、 下記のプログラムはこの場で教えて頂いたプログラムで、 実行すると●の後を▲や■が追いかける動きをします。 下記のプログラムをある程度使用して 1~20の数字が順々で追いかけっこする プログラムを作成するにはどのようにすればいいのでしょうか… できればプログラムは長めにならず 20の数字から簡単に増やすことのできるような そんなプログラムが作成したいです… どなたかアドバイスお持ちの方 教えて下さいお願いします... Dim time1 As Integer, time As Integer Dim X As Integer, Y As Integer Dim X1 As Integer, Y1 As Integer Dim X2 As Integer, Y2 As Integer Dim maru As String, yoko As String, tate As String Dim sankaku As String, shikaku As String Sub 描画() Cells(Y2, X2).Value = shikaku Cells(Y1, X1).Value = sankaku Cells(Y, X).Value = maru End Sub Sub 削除() Cells(Y2, X2).Value = "" End Sub Sub 待機() For time1 = 0 To 1000 For time2 = 0 To 1000 Next Next End Sub Sub 座標移動() X2 = X1 Y2 = Y1 X1 = X Y1 = Y If yoko = "右" Then X = X + 1 Else X = X - 1 End If If X = 30 Then yoko = "左" ElseIf X = 1 Then yoko = "右" End If If tate = "上" Then Y = Y + 1 Else Y = Y - 1 End If If Y = 20 Then tate = "下" ElseIf Y = 1 Then tate = "上" End If End Sub Sub main() maru = "●" sankaku = "▲" shikaku = "■" X = 1 Y = 1 X1 = 1 Y1 = 1 X2 = 1 Y2 = 1 yoko = "右" tate = "上" Do 描画 待機 削除 待機 座標移動 Loop End Sub

  • ▲ExcelのVBA▼困っています

    何度もVBAで質問させてもらい助けてもらっています。 懲りずにまた質問ですが… 下のプログラムは"●"が跳ね返るものなのですが… ●の後を■と▲が追うようなプログラムにするには なにを追加すればいいのでしょうか…?; どなたか教えて下さい;;お願いします;; Dim time1 As Integer, time As Integer Dim X As Integer, Y As Integer Dim maru As String, yoko As String, tate As String Sub 描画() Cells(X, Y).Value = maru End Sub Sub 削除() Cells(X, Y).Value = "" End Sub Sub 待機() For time1 = 0 To 1000 For time2 = 0 To 1000 Next Next End Sub Sub 座標移動() If yoko = "右" Then Y = Y + 1 Else Y = Y - 1 End If If Y = 30 Then yoko = "左" ElseIf Y = 1 Then yoko = "右" End If If tate = "上" Then X = X + 1 Else X = X - 1 End If If X = 20 Then tate = "下" ElseIf X = 1 Then tate = "上" End If End Sub Sub main() maru = "●" X = 1 Y = 1 yoko = "右" tate = "上" Do 描画 待機 削除 待機 座標移動 Loop End Sub

  • エクセルVBAについて質問です

    お世話になります。 早速ですが、下記の構文を作成しましたが、Activecell.Rowの部分で悪さをし 上手く動きません。 行いたかった事としては、Functionにて関数を手作りしようと試みたのですが、 結局は壁にぶちあたってしまったって所です。。。 内容としては、エクセルが手動計算だった場合は、一回りで動作が終了するので 問題なく想定の値が叩き出されますが、自動計算にした途端に「別セルに入れた 計算式まで、Activecell.Rowに引きずられて計算をし、別の値に変わってしまう」 現象となってしまいました。。。(説明下手で済みません) Public Function Shotoku(houshu As Long) Dim ACcel As Variant Dim FR As Range With Worksheets("所得税月額表(平成24年分)") ACcel = houshu If ACcel < 88000 Then Shotoku = 0 Exit Function End If For Each FR In .Range("C13:C347") If ACcel < FR Then If Cells(ActiveCell.Row, 51) = 0 Then       ←問題の個所です Shotoku = .Cells(FR.Row, 4) ElseIf Cells(ActiveCell.Row, 51) = 1 Then    ←問題の個所です Shotoku = .Cells(FR.Row, 5) ElseIf Cells(ActiveCell.Row, 51) = 2 Then    ←問題の個所です Shotoku = .Cells(FR.Row, 6) ElseIf Cells(ActiveCell.Row, 51) = 3 Then    ←問題の個所です Shotoku = .Cells(FR.Row, 7) ElseIf Cells(ActiveCell.Row, 51) = 4 Then    ←問題の個所です Shotoku = .Cells(FR.Row, 8) ElseIf Cells(ActiveCell.Row, 51) = 5 Then    ←問題の個所です Shotoku = .Cells(FR.Row, 9) ElseIf Cells(ActiveCell.Row, 51) = 6 Then    ←問題の個所です Shotoku = .Cells(FR.Row, 10) ElseIf Cells(ActiveCell.Row, 51) = 7 Then    ←問題の個所です Shotoku = .Cells(FR.Row, 11) End If Exit For End If Next End With End Function 計算式を当て込んで、例えば2行目のIF文の条件に引っかかった場合、他の セルまでその行を読んでしまうので、条件が変わってしまう事態になってます。 イメージではActivecell.Rowがダメなんだと思いますが、これ以外のセル番地の 取得方法が分からなくって><; どなたかお助け願います!!!

  • エクセルVBAでの質問

    お世話になります。 エクセルVBAのプログラムコードをコピーし、 エクセルの通常シートへ貼り付けした際、 「’」で始まる説明分または注釈をプロシージャ画面の 様に色づけしたいと思い下記の様なコードを書きました。 しかし、VBA実行後、元のコードが行によって、空白 から始まって行の途中に「’」がある場合など、 少し手前の文字から着色されたりしていました。 何故なのでしょうか。 どこがおかしいのでしょうか。 空白が半角か全角になっている為にこのような現象に なっているのでしょうか。 しかしその解決方法が分からなく、 どなたかご教授頂きたく宜しくお願い致します。   記 Sub サンプル() Dim x As Integer Dim y As Integer Dim z As Integer Dim myrng As String Dim zz As Integer For y = 1 To 10 For x = 1 To Cells(Rows.Count, y).End(xlUp).Row If InStr(Trim(Cells(x, y).Value), "'") = 1 Then Cells(x, y).Font.ColorIndex = 10 ElseIf InStr(Trim(Cells(x, y).Value), "'") = 0 Then Else z = InStr(Trim(Cells(x, y).Value), "'") myrng = Cells(x, y) zz = Len(myrng) Cells(x, y).Characters(z, zz).Font.ColorIndex = 10 End If Next x Next y End Sub

  • エクセルVBAで、分岐がうまくできません。

    A,B,,Cのりんごとみかんの3種類の仕入れパターンがあり仕入の数量を算出したいですが、適正値が算出されません。 どのようにしたら、適正値を算出できるにのか教えてください。 Sub test() Dim i As Integer 'A リンゴは、500以下になったら1000個になるように仕入 'A みかんは、500以下になったら1000個になるように仕入 'A みかんまたはりんごの片方が500以下になったらみかんとりんごを1000個になるように仕入 i = 2 Do While Worksheets("sheet1").Cells(i, 1) <> "" If Cells(i, 1) = "A" And Cells(i, 2) <= 500 Or Cells(i, 3) <= 500 Then Worksheets("sheet1").Cells(i, 4) = 1000 - Cells(i, 2) Worksheets("sheet1").Cells(i, 5) = 1000 - Cells(i, 3) 'End If 'i = i + 1 'Loop 'B リンゴは、400以下になったら2000個になるように仕入 'B みかんは、400以下になったら2000個になるように仕入 'A みかんまたはりんごの片方が400以下になったらみかんとりんごを2000個になるように仕入 i = 2 'Do While Worksheets("sheet1").Cells(i, 1) <> "" ElseIf Cells(i, 1) = "B" And Cells(i, 2) <= 400 Or Cells(i, 3) <= 400 Then Worksheets("sheet1").Cells(i, 4) = 2000 - Cells(i, 2) Worksheets("sheet1").Cells(i, 5) = 2000 - Cells(i, 3) 'End If 'i = i + 1 'Loop ''C リンゴは、300以下になったら3000個になるように仕入 ''C みかんは、300以下になったら3000個になるように仕入 'A みかんまたはりんごの片方が300以下になったらみかんとりんごを3000個になるように仕入 i = 2 'Do While Worksheets("sheet1").Cells(i, 1) <> "" ElseIf Cells(i, 1) = "C" And Cells(i, 2) <= 300 Or Cells(i, 3) <= 300 Then Worksheets("sheet1").Cells(i, 4) = 3000 - Cells(i, 2) Worksheets("sheet1").Cells(i, 5) = 3000 - Cells(i, 3) End If i = i + 1 Loop End Sub

  • ExcelのVBAで高さの設定

    どなたか教えて下さい。 報告書のフォーマットの作成をしています。 A列からE列までは日付や名前等の内容が入力されています。 F列にはそれに関するコメントが入力されています。 コメントの文字数は、少なければ10字程度、多ければ320文字程度あります。 文字数に合わせて高さを変更させたいです。 その為、以下のような事を行いました。 (1)G列にLEN関数を用いて、文字数を表示 (2)G列の文字数によって高さを変更させるVBAを作成 Sub Macro1() For i = 2 To 100 If Cells(i, 6) < 72 Then Rows(i).RowHeight = 80 ElseIf 73 < Cells(i, 6) < 108 Then Rows(i).RowHeight = 120 ElseIf 109 < Cells(i, 6) < 144 Then Rows(i).RowHeight = 160 ElseIf 145 < Cells(i, 6) < 180 Then Rows(i).RowHeight = 200 ElseIf 181 < Cells(i, 6) < 216 Then Rows(i).RowHeight = 240 ElseIf 217 < Cells(i, 6) < 252 Then Rows(i).RowHeight = 280 ElseIf 253 < Cells(i, 6) < 288 Then Rows(i).RowHeight = 320 ElseIf 289 < Cells(i, 6) < 324 Then Rows(i).RowHeight = 360 End If Next End Sub このVBAに記述間違いがあるようで、 「文字数が72文字以内であれば、高さを80に変更。 文字数が73文字以上で108文字未満であれば、高さは120」 までは認識し・高さの設定を行ってくれますが、108文字以上あっても高さは120になってしまいます。 どなたか教えて下さい。 よろしくお願い致します。

  • Excel 2003 VBA 条件分岐

    質問させて頂きます。 私が現在行いたい事を下記に記述します。  1・あるボタンを押すと新規ワークシートが追加されAPIで天気予報を取得、天気予報の更新。  2・天気予報が更新されると晴/雨/曇などとその日により勿論値は変化します。  3・ 2で変化された値によって、同ワークシート内に A10セルに「晴」と言う文字が有れば晴れマークの    画像を貼ります。曇の場合 曇りマークです。 ですが、2 までは上手く出来ますたが、3 で思う用に動作してくれません。 私が現在記述しているコードは下記。 Private Sub tenki_Click() Worksheets("tenki").Activate ActiveWorkbook.XmlMaps("rss_対応付け").DataBinding.Refresh Dim Tiyo As String Dim Kumori As String Tiyo = "C:\SeaNavi\resource\image\Sunny.bmp" Kumori = "C:\SeaNavi\resource\image\Cloudy.bmp" If Range("A10").Value Like "*晴*" Then ActiveSheet.Pictures.Insert(Tiyo).Select With Selection.ShapeRange .IncrementLeft 300 .IncrementTop 5 End With ElseIf Range("A10").Value Like "*曇*" Then ActiveSheet.Pictures.Insert(Kumori).Select With Selection.ShapeRange .IncrementLeft 300 .IncrementTop 5 End With End If 私は If Range("A10").Value Like "*晴*" Then の部分を次の用に理解しています。 If Range("A10").Value は値を取得し Like "*晴*" Then でA10セルの値(文字列)に「晴」と言う文字があれば True でなければ False を返すと考えています。 ですが実行結果は、A10セルには「晴」と言う文字は含まれていませんが、画像を貼る構文が実行されたりなど不具合が絶えません。また、ウォッチウィンドウで If Range("A10").Value の値を見ましたが、 Empty値となっています。ですが条件分岐の式自体は True を返しています。 もう何がなんだか分かりません。 冗長的で説明不足な部分も有ると思いますが対応お願いします。