|
▼てつ さん:
おはようございます。
とりあえずの間に合わせとして、Case 0.16 To 0.259 を提示しました。
(よく考えると、Case 0.16 To 0.251 でもいいはずですけど)
既に検索して関連情報を把握されたかとは思いますが、エクセルは
効率優先のため、小数点演算は「超々々々近似値演算」によって処理しています。
効率は若干おちますが(といって、気にするレベルではありません)これを
強制的に「10進演算」で処理した結果で取得するには、たとえば
CDec関数を使います。
Select Case CDec(t3 - Fix(t3))
こうしますと、もとの Case 0.16 To 0.25 でもOKのはずです。
お試しください。
>最初と最後の間の行数は一定ではないのですが大丈夫でしょうか
もし、データ開始行が 1行目あるいは2行目。で、データのある最後の行まで
という仕様であれば、最後の行を動的にVBAで把握することができます。
ただ、もしかしたら、本当に、固定されていない行から始まり、最後のデータ行の
下に、別のデータがあって、その中で、時間データを抽出しなければいけないと
いうことであれば、現在のコードでOKです。(Matchを使う手もありますが)
ただ、念のための、有無をNothingかどうかでチェックしておられるところは
いいのですが、なかった場合、メッセージを出すものの、
For i = Gy1 + 1 To Gy2 - 1 以降の処理がされてしまいますね。
メッセージ(2ヶ所)を出した後に、Exit Sub をいれておかれればよろしいかと。
実行のタイミングがWorksheet_SelectionChange。
これはこれで、なかなか考えられた起動方法だなぁとも思いますが、
たとえばシートのデータを変更するために、どこかのセルを選択するたびに
実行されてしまいます。
むしろ、普通のプロシジャとして標準モジュールに記述し、マクロショートカットキーで
呼び出すなり、シートにボタンを配置して、そのクリックで起動するなりのほうが
扱いやすいかもしれません。
変数規定は、それを使う前に宣言すればいいわけですが、コードの可読性、保守性の
観点から、コードの最初に集めておいたほうがよろしいですね。
また、インデントは「適切」につけないと、かえって可読性が悪くなります。
ということで、そういった部分だけお化粧直しをしました。
Sub Sample()
Dim Gy1 As Variant, Gy2 As Variant, i As Long
Dim myH1 As Integer, myH2 As Integer, myS As Integer
Dim myM1 As Integer, myM2 As Integer
Dim T As Variant, t1 As Double, t2 As Double, t3 As Double, M As Double
Dim myM As Integer
Gy1 = Application.Match("最初", Columns("A"), 0)
If Not IsNumeric(Gy1) Then
MsgBox "最初の文字列がありません"
Exit Sub
Else
Gy1 = Gy1 + 1
End If
Gy2 = Application.Match("最後", Columns("A"), 0)
If Not IsNumeric(Gy2) Then
MsgBox "最後の文字列がありません"
Exit Sub
Else
Gy2 = Gy2 - 1
End If
For i = Gy1 To Gy2
If WorksheetFunction.CountBlank(Range("A" & i & ":B" & i)) > 0 Then
'検索範囲のA or B列が空白の場合は時数は空白とする
Range(i, "C").ClearContents
Else
myH1 = Mid(Cells(i, 1).Value, 1, 2) 'A列の「時」を取得
myM1 = Mid(Cells(i, 1).Value, 3) 'A列の「分」を取得
myH2 = Mid(Cells(i, 2).Value, 1, 2) 'B列の「時」を取得
myM2 = Mid(Cells(i, 2).Value, 3) 'B列の「分」を取得
myS = "00"
t1 = TimeSerial(myH1, myM1, myS) 'A列の文字を時刻に変換する
t2 = TimeSerial(myH2, myM2, myS) 'B列の文字を時刻に変換する
t3 = (t2 - t1) * 24 'AからBの時間を計算する
T = Int(t3)
If t1 >= t2 Then 'B列よりもA列が大きいときは「エラー」と表示する
Cells(i, 3) = "エラー"
ElseIf t3 - Fix(t3) < 0 Then '「分」を四捨六入し、0.0時間表示する
Cells(i, 3) = T
Else
Select Case CDec(t3 - Fix(t3))
Case 0 To 0.05
Cells(i, 3) = T
Case 0.06 To 0.15
Cells(i, 3) = T + 0.1
Case 0.16 To 0.25
Cells(i, 3) = T + 0.2
Case 0.26 To 0.35
Cells(i, 3) = T + 0.3
Case 0.36 To 0.45
Cells(i, 3) = T + 0.4
Case 0.46 To 0.55
Cells(i, 3) = T + 0.5
Case 0.56 To 0.65
Cells(i, 3) = T + 0.6
Case 0.66 To 0.75
Cells(i, 3) = T + 0.7
Case 0.76 To 0.85
Cells(i, 3) = T + 0.8
Case 0.86 To 0.95
Cells(i, 3) = T + 0.9
Case 0.96 To 0.99
Cells(i, 3) = T + 1
End Select
End If
End If
Next i
End Sub
|
|