Excel VBA質問箱 IV

当質問箱は、有志のボランティア精神のおかげで成り立っています。
問題が解決したら、必ずお礼をしましょうね。
本サイトの基本方針をまとめました。こちら をご一読ください。

投稿種別の選択が必要です。ご注意ください。
迷惑投稿防止のため、URLの入力を制限しています。ご了承ください。


7514 / 13644 ツリー ←次へ | 前へ→

【38516】料金計算マクロ mai 06/6/5(月) 16:16 質問[未読]
【38524】Re:料金計算マクロ ハト 06/6/5(月) 18:11 回答[未読]
【38526】Re:料金計算マクロ ハト 06/6/5(月) 18:34 発言[未読]
【38579】Re:料金計算マクロ sin 06/6/6(火) 16:13 発言[未読]
【38606】Re:料金計算マクロ ハト 06/6/7(水) 10:31 発言[未読]
【38618】Re:料金計算マクロ ハト 06/6/7(水) 13:52 発言[未読]
【38623】Re:料金計算マクロ sin 06/6/7(水) 15:53 発言[未読]
【38629】Re:料金計算マクロ ハト 06/6/7(水) 16:29 発言[未読]
【38537】Re:料金計算マクロ ハト 06/6/6(火) 10:32 回答[未読]
【38602】Re:料金計算マクロ roxy 06/6/7(水) 9:29 お礼[未読]
【38608】Re:料金計算マクロ roxy 06/6/7(水) 10:40 質問[未読]
【38612】Re:料金計算マクロ ハト 06/6/7(水) 11:06 発言[未読]
【38532】Re:料金計算マクロ ichinose 06/6/6(火) 8:57 発言[未読]
【38533】Re:料金計算マクロ 訂正 ichinose 06/6/6(火) 9:10 発言[未読]
【38601】Re:料金計算マクロ 訂正 roxy 06/6/7(水) 9:27 お礼[未読]
【38624】Re:料金計算マクロ 訂正 ichinose 06/6/7(水) 16:02 発言[未読]
【38627】Re:料金計算マクロ 訂正 ハト 06/6/7(水) 16:23 発言[未読]
【38645】Re:料金計算マクロ 訂正 roxy 06/6/7(水) 17:58 発言[未読]
【38690】Re:料金計算マクロ 訂正 sin 06/6/8(木) 15:54 発言[未読]

【38516】料金計算マクロ
質問  mai  - 06/6/5(月) 16:16 -

引用なし
パスワード
   料金計算のマクロを組みたいです。
3つの時間帯で料金が変化します。以下の通りです。

朝:0:00〜6:00  60分 \200
昼:6:00〜20:00 20分 \400
夜:20:00〜0:00 30分 \300

また夜には最大上限金額があり、20:00以降6:00までの間で
\1500を超えても\1500以上に料金がなることはありません。

セルに時間を入力するとマクロで料金計算ができるというものを作りたいと考えております。

例えば、5:00〜8:00でしたら料金は\200+\2400=\2800
となります。
また21:00〜0:00でしたら料金は\1500となります。

もし5:50から7:10でしたら、最初の1時間(5:50〜6:50)は\200、
その後は(6:50〜7:10)は\400となります。
それぞれの時間帯に1分でも入っている場合はその料金が採用されます。

また単位時間を1分でも過ぎると料金は加算されます。
例えば19:02〜20:00ならば\1200となります。

少し解りづらいかもしれませんがよろしくお願いします。 

【38524】Re:料金計算マクロ
回答  ハト  - 06/6/5(月) 18:11 -

引用なし
パスワード
   ちょっとベタなやり方ですが考えてみました
※24時間以上のケースがない前提です
参考にしてカスタマイズして下さい

Sub Test_Time()

Dim ws As Worksheet
Dim STime As Date
Dim ETime As Date
Dim NTime As Date
Dim TTime As Date

Dim TVal As Long
Dim NVal As Long

  TVal = 0
  NVal = 0

  Set ws = ThisWorkbook.Worksheets("Sheet1")
  
  STime = TimeValue(ws.Range("A1").Text)
  ETime = TimeValue(ws.Range("B1").Text)

  If STime > ETime Then
    NTime = TimeValue("23:59")
  Else
    NTime = ETime
  End If
  
  TTime = STime
  
  Do
    Select Case TTime
      Case Is > TimeValue("23:29")
        TTime = TTime - TimeValue("23:30")
        NVal = NVal + 300
        NTime = ETime
      Case Is >= TimeValue("20:00")
        TTime = TTime + TimeValue("0:30")
        NVal = NVal + 300
      Case Is >= TimeValue("6:00")
        TTime = TTime + TimeValue("0:20")
        TVal = TVal + 400
      Case Else
        TTime = TTime + TimeValue("1:00")
        NVal = NVal + 200
    End Select
      
    If TTime >= NTime Then Exit Do
  Loop

  If NVal > 1500 Then NVal = 1500
  TVal = TVal + NVal

  ws.Range("C1").Value = TVal

End Sub

【38526】Re:料金計算マクロ
発言  ハト  - 06/6/5(月) 18:34 -

引用なし
パスワード
   一部訂正させてください

>      Case Is > TimeValue("23:29")
>        TTime = TTime - TimeValue("23:30")
>        NVal = NVal + 300
>        NTime = ETime

ここは↓のように修正

        NVal = NVal + 300
        If NTime = ETime Then Exit Do

         TTime = TTime - TimeValue("23:30")
         NTime = ETime

【38532】Re:料金計算マクロ
発言  ichinose  - 06/6/6(火) 8:57 -

引用なし
パスワード
   ▼mai さん:
おはようございます。
新規ブックの標準モジュールに

'===============================================================
Option Explicit
Sub main()
  Dim idx As Long, jdx As Long
  Dim t_m As Long
  Dim n_m() As Variant
  Dim st As Date, ed As Date
  Dim std As Date
  Dim l_rng As Range
  On Error Resume Next
  Set l_rng = Range("d1:d3")
  t_m = 0
  st = Range("a1").Value
  ed = Range("b1").Value
  std = Int(st)
  If st > ed Then ed = ed + 1
  Do While st < ed
    idx = Application.Match(st - Int(st), l_rng, 1)
    If l_rng.Cells(idx, 4).Value = -1 Then
     t_m = t_m + l_rng.Cells(idx, 2).Value
    Else
     jdx = Int(st) - std + l_rng.Cells(idx, 4).Value
     Err.Clear
     n_m(jdx) = n_m(jdx) + l_rng.Cells(idx, 2).Value
     If Err.Number <> 0 Then
       ReDim Preserve n_m(jdx)
       n_m(jdx) = 0
       n_m(jdx) = n_m(jdx) + l_rng.Cells(idx, 2).Value
       End If
     End If
    st = st + l_rng.Cells(idx, 3).Value
    st = CDate(CStr(st))
    Loop
  For idx = LBound(n_m()) To UBound(n_m())
   t_m = t_m + IIf(n_m(idx) > 1500, 1500, n_m(idx))
   Next
  MsgBox t_m
End Sub
'===============================================================
Sub set_hyo()
  Call set_list
  Range("A1:B1").NumberFormatLocal = "h:mm"
End Sub
'===============================================================
Function set_list() As Range
  Const セル範囲 = "d1:d3"
  Const リスト = "={""0:00"",200,""1:00"",0;""6:00"",400,""0:20"",-1;""20:00"",300,""0:30"",1}"
  Set set_list = Range(セル範囲)
  set_list.Resize(, 4).FormulaArray = Evaluate(リスト)
End Function

としてください。


1.まず、プロシジャーset_hyoを実行してアクティブシートに
  料金表を作成してください。

2.アクティブシートのセルA1が開始時刻、B1が終了時刻とします。

3.尚、入力された時刻が 開始時刻<終了時刻という場合は、終了時刻は翌日の時刻
 だと解釈します。
4.開始時刻、終了時刻を入力後、プロシジャーmainを実行してください。
  料金が表示されます。


入力例

 セルA1  5:00  B1 8:00  料金 2600

 セルA1 21:00  B1 0:00  料金 1500
 (この場合、自動的に翌日の0:00と解釈します)

 セルA1  5:00  B1 7:10  料金 600

 セルA1 19:00  B1 21:00  料金 1800


という結果を表示します。
確認してください。

これ難しいのは、時刻は少数だから誤差が出るんだよね!!
補正したつもりですが、十分な確認をしていません・・。

検証してみてください。

【38533】Re:料金計算マクロ 訂正
発言  ichinose  - 06/6/6(火) 9:10 -

引用なし
パスワード
   3.尚、入力された時刻が 開始時刻>終了時刻という場合は、終了時刻は翌日の時刻
 だと解釈します。

【38537】Re:料金計算マクロ
回答  ハト  - 06/6/6(火) 10:32 -

引用なし
パスワード
   ▼ハト さん:
>ちょっとベタなやり方ですが考えてみました
>※24時間以上のケースがない前提です
>参考にしてカスタマイズして下さい
>
DateAdd関数を使った方が処理がすっきりしました(^^;

Sub Test_Time()

Dim ws As Worksheet
Dim STime As Date
Dim ETime As Date
Dim NTime As Date
Dim TTime As Date

Dim TVal As Long
Dim NVal As Long

  TVal = 0
  NVal = 0

  Set ws = ThisWorkbook.Worksheets("Sheet1")
  
  STime = TimeValue(ws.Range("A1").Text)
  ETime = TimeValue(ws.Range("B1").Text)

  
  If STime > ETime Then
    NTime = DateAdd("d", 2, ETime)
  Else
    NTime = DateAdd("d", 1, ETime)
  End If
  
  STime = DateAdd("d", 1, STime)
  
  TTime = STime
  
  Do
    Select Case TimeValue(TTime)
      Case Is >= TimeValue("20:00")
        TTime = DateAdd("n", 30, TTime)
        NVal = NVal + 300
      Case Is >= TimeValue("6:00")
        TTime = DateAdd("n", 20, TTime)
        TVal = TVal + 400
      Case Else
        TTime = DateAdd("h", 1, TTime)
        NVal = NVal + 200
    End Select
      
    If TTime >= NTime Then Exit Do
  Loop

  If NVal > 1500 Then NVal = 1500
  TVal = TVal + NVal

  ws.Range("C1").Value = TVal

End Sub

【38579】Re:料金計算マクロ
発言  sin  - 06/6/6(火) 16:13 -

引用なし
パスワード
   横から失礼します。

▼ハト さん:
またコッソリ勉強させていただいてました^^
今回も上手いロジックですね。

それでちょっとよく分からないのですが、
私のところで12:00以降の結果が合わないのですが・・・

↓このようにハトさんのものにテストを埋め込んでみました。

Sub Test_Time()

Dim ws As Worksheet
Dim STime As Date
Dim ETime As Date
Dim NTime As Date
Dim TTime As Date
Dim ATime As Date
Dim i As Long
Dim TVal As Long
Dim NVal As Long

  Set ws = ThisWorkbook.Worksheets("Sheet1")
  ws.Columns("a:b").ColumnWidth = 12

  ATime = TimeValue("6:00")
  For i = 1 To 14
    ws.Cells(i, 1) = ATime
    ATime = ATime + TimeValue("1:00")
    ws.Cells(i, 2) = ATime
  Next i

  For i = 1 To 14
    TVal = 0
    NVal = 0

    STime = TimeValue(ws.Range(Cells(i, 1), Cells(i, 1)).Text)
    ETime = TimeValue(ws.Range(Cells(i, 2), Cells(i, 2)).Text)

    If STime > ETime Then
      NTime = TimeValue("23:59")
    Else
      NTime = ETime
    End If

    TTime = STime

    Do
      Select Case TTime
        Case Is > TimeValue("23:29")
          NVal = NVal + 300
          If NTime = ETime Then Exit Do
          TTime = TTime - TimeValue("23:30")
          NTime = ETime
        Case Is >= TimeValue("20:00")
          TTime = TTime + TimeValue("0:30")
          NVal = NVal + 300
        Case Is >= TimeValue("6:00")
          TTime = TTime + TimeValue("0:20")
          TVal = TVal + 400
        Case Else
          TTime = TTime + TimeValue("1:00")
          NVal = NVal + 200
      End Select

      If TTime >= NTime Then Exit Do
    Loop

    If NVal > 1500 Then NVal = 1500
    TVal = TVal + NVal

    ws.Cells(i, 3) = TVal
  Next i
End Sub


これを実行すると開始が12:00以降だと結果が1200ではなく1600になってしまいます。
そして13:00〜13:20ではちゃんと結果が400になるのですが
13:00〜13:40では結果が800のはずが1200になっています。
(〜13:39は800〜13:41は1200で問題ありません)
どうも”12:00以降だけ”2回以上ループすると
>      If TTime >= NTime Then Exit Do
の"="が働いていないような感じです。

ちょっと原因がよく分かりません。エクセルの設定か何かでしょうか?

ちなみ【38537】のDateAddを使用したものでは問題は起きませんでした。

【38601】Re:料金計算マクロ 訂正
お礼  roxy  - 06/6/7(水) 9:27 -

引用なし
パスワード
   ▼ichinose さん:

おはようございます。
実はこのツールC言語で作られたものをVBAで改良を加えてシンプル化するということになっています。
私はC言語はほとんどわかりませんし、ソースももらってないのですが処理の流れだけ聞きました。
誤差の件はシリアル値で取るとやはり出るので、全て分単位で時間を取ってきて計算しているみたいです。
確かに誤差が出たときに微妙にずれが生じますね。
ちょっと考えてみます。
ありがとうございました。
 

【38602】Re:料金計算マクロ
お礼  roxy  - 06/6/7(水) 9:29 -

引用なし
パスワード
   ▼ハト さん:

おはようございます。

確かに最初のコードよりだいぶすっきりしていますね。
誤差が出ないか十分検証した後使わせてもらいます。

元々はC言語ベースで書かれていたものを私がVBAで作成しなおしているのですが、結構複雑にされているので、これで済めばすっきりとしていいと思います。

ありがとうございました。

【38606】Re:料金計算マクロ
発言  ハト  - 06/6/7(水) 10:31 -

引用なし
パスワード
   おはようございます

自分のところでも確認しました

ichinose さんが書かれているように時刻は小数なので誤差が生じているのではないでしょうか?

セルに『1:00』と打ち込んで
セルの書式設定を時刻⇒標準に変更すると
『0.0416666666666667』
と表示されます

なかなか難しいものですね

【38608】Re:料金計算マクロ
質問  roxy  - 06/6/7(水) 10:40 -

引用なし
パスワード
   ▼ハト さん:

すいません。ちょっと聞きたいのですが・・・

初心者であまりわからなくて、ハトさんのコードを今確認中に疑問にぶち当たってしまいました。
下記の箇所ですが、

>  If STime > ETime Then
>    NTime = DateAdd("d", 2, ETime)
>  Else
>    NTime = DateAdd("d", 1, ETime)
>  End If

なぜ ETime に1日、もしくは2日を足しているのですか?
日付のデータをセットしていないということで、その処理の関係でしょうか??

それと足りない箇所がありました。
このデータ開始と終了から料金を割り出すとしていましたが、やはり開始日と終了日のデータも必要だと判明しました。
となると上記の部分を変更するということになるのでしょうか?

なぜ日付のデータが必要かと言うと、1日をまたがった計算もありうるし、曜日によって料金が変わったりするからです。
質問文がたりなくてすいません。。。

お手数かけますが宜しくお願いします。

【38612】Re:料金計算マクロ
発言  ハト  - 06/6/7(水) 11:06 -

引用なし
パスワード
   おはようございます

▼roxy さん:
>▼ハト さん:
>
>すいません。ちょっと聞きたいのですが・・・
>
>初心者であまりわからなくて、ハトさんのコードを今確認中に疑問にぶち当たってしまいました。
>下記の箇所ですが、
>
>>  If STime > ETime Then
>>    NTime = DateAdd("d", 2, ETime)
>>  Else
>>    NTime = DateAdd("d", 1, ETime)
>>  End If
>
>なぜ ETime に1日、もしくは2日を足しているのですか?
>日付のデータをセットしていないということで、その処理の関係でしょうか??

その通りです
日をまたいでいる場合、時間を足していくと、時刻だけと日付+時刻の比較になったりしてしまいますので擬似的に日付を付与しました

>それと足りない箇所がありました。
>このデータ開始と終了から料金を割り出すとしていましたが、やはり開始日と終了日のデータも必要だと判明しました。
>となると上記の部分を変更するということになるのでしょうか?

そうなりますね、日付と時刻が別セルならば、
その2つを1つにまとめる処理に変更してください

>なぜ日付のデータが必要かと言うと、1日をまたがった計算もありうるし、曜日によって料金が変わったりするからです。
>質問文がたりなくてすいません。。。
>
>お手数かけますが宜しくお願いします。

曜日によって料金が変わるんですか
そうすると今の単純なのをマトリックスを使うか、料金表とのマッチ処理を使う処理に変更する必要がありそうですね

【38618】Re:料金計算マクロ
発言  ハト  - 06/6/7(水) 13:52 -

引用なし
パスワード
   DataAddを使っても誤差が出るようです

誤差を計測してみたところ
『1.11022302462516E-16』
小数点以下16桁(^^;

1分の値が
『0.000694444444444444』

これだと比較している箇所はRoundを使って、
小数点以下8桁をまるめてしまえば誤差を無視できそうですね(^^;

    If TTime >= NTime Then Exit Do
               ↓
    If Round(TTime, 8) >= Round(NTime, 8) Then Exit Do

【38623】Re:料金計算マクロ
発言  sin  - 06/6/7(水) 15:53 -

引用なし
パスワード
   ▼ハト さん:
ありがとうございます。

>DataAddを使っても誤差が出るようです
>
>誤差を計測してみたところ
>『1.11022302462516E-16』
>小数点以下16桁(^^;
この計測の仕方、よろしければご教授下さい。

>
>1分の値が
>『0.000694444444444444』
>
>これだと比較している箇所はRoundを使って、
>小数点以下8桁をまるめてしまえば誤差を無視できそうですね(^^;
>
>    If TTime >= NTime Then Exit Do
>               ↓
>    If Round(TTime, 8) >= Round(NTime, 8) Then Exit Do
わたしもどこかで「日時はシリアル値」というのを聞いたのを思い出し、
調べたところ詳細に解説されてました^^
http://www.h3.dion.ne.jp/~sakatsu/TimeSerial_Error.htm

なので私も
>    If TTime >= NTime Then Exit Do

      TTime = TimeValue(Format(TTime, "h:mm"))
      NTime = TimeValue(Format(NTime, "h:mm"))
      If TTime >= NTime Then Exit Do
としてみたところ解決しました。


ただ、↓のようにテストしていたのですが、
14:00〜16:00や17:00〜18:00など割り切れている
ところでは誤差が出ないように思えるのですが・・・
しかし上記のようにすると正しい結果が得られるので
表示の仕方の問題でしょうか?


Sub Test_Time()

Dim ws As Worksheet
Dim STime As Date
Dim ETime As Date
Dim NTime As Date
Dim TTime As Date
Dim ATime As Date
Dim i As Long
Dim j As Long
Dim TVal As Long
Dim NVal As Long

  Set ws = ThisWorkbook.Worksheets("Sheet1")
  ws.Columns("a:b").ColumnWidth = 12
  ws.Columns("e:f").ColumnWidth = 16

  ATime = TimeValue("6:00")
  For i = 1 To 14
    ws.Cells(i, 1) = ATime
    ATime = ATime + TimeValue("1:00")
    ws.Cells(i, 2) = ATime
  Next i

  j = 1

  For i = 1 To 14
    TVal = 0
    NVal = 0

    STime = TimeValue(ws.Range(Cells(i, 1), Cells(i, 1)).Text)
    ETime = TimeValue(ws.Range(Cells(i, 2), Cells(i, 2)).Text)

    If STime > ETime Then
      NTime = TimeValue("23:59")
    Else
      NTime = ETime
    End If

    TTime = STime
    ws.Cells(j, 5) = CStr(STime) & "〜" & CStr(ETime)

    Do
      Select Case TTime
        Case Is > TimeValue("23:29")
          NVal = NVal + 300
          If NTime = ETime Then Exit Do
          TTime = TTime - TimeValue("23:30")
          NTime = ETime
        Case Is >= TimeValue("20:00")
          TTime = TTime + TimeValue("0:30")
          NVal = NVal + 300
        Case Is >= TimeValue("6:00")
          TTime = TTime + TimeValue("0:20")
          TVal = TVal + 400
        Case Else
          TTime = TTime + TimeValue("1:00")
          NVal = NVal + 200
      End Select

      j = j + 1
      ws.Cells(j, 5) = CDbl(TTime)
      ws.Cells(j, 6) = CDbl(NTime)

'      TTime = TimeValue(Format(TTime, "h:mm"))
'      NTime = TimeValue(Format(NTime, "h:mm"))
      If TTime >= NTime Then Exit Do
    Loop

    j = j + 1
    If NVal > 1500 Then NVal = 1500
    TVal = TVal + NVal
    ws.Cells(i, 3) = TVal
  Next i
  Range("a1").Select
End Sub

【38624】Re:料金計算マクロ 訂正
発言  ichinose  - 06/6/7(水) 16:02 -

引用なし
パスワード
   ▼roxy さん:
>誤差の件はシリアル値で取るとやはり出るので、全て分単位で時間を取ってきて計算しているみたいです。
>確かに誤差が出たときに微妙にずれが生じますね。

提示してコードで誤差がでたのですか?
だとしたら、誤差が発生した時刻情報(開始時刻と終了時刻)を教えてください。

私の環境では誤差が出てこないのですが、

'===========================================
Sub main()
  Const Lim_cost = 1500
  Dim idx As Long, jdx As Long
  Dim t_m As Long
  Dim n_m() As Variant
  Dim st As Date, ed As Date
  Dim std As Date
  Dim l_rng As Range
  On Error Resume Next
  Set l_rng = Range("d1:d3")
  t_m = 0
  st = Range("a1").Value
  ed = Range("b1").Value
  std = Int(st)
  If st > ed Then ed = ed + 1
  Do While st < ed
    idx = Application.Match(st - Int(st), l_rng, 1)
    If l_rng.Cells(idx, 4).Value = -1 Then
     t_m = t_m + l_rng.Cells(idx, 2).Value
    Else
     jdx = Int(st) - std + l_rng.Cells(idx, 4).Value
     Err.Clear
     n_m(jdx) = n_m(jdx) + l_rng.Cells(idx, 2).Value
     If Err.Number <> 0 Then
       ReDim Preserve n_m(jdx)
       n_m(jdx) = 0
       n_m(jdx) = n_m(jdx) + l_rng.Cells(idx, 2).Value
       End If
     End If
    st = st + l_rng.Cells(idx, 3).Value
    st = CDate(Format(st, "yyyy/m/d hh:mm"))
    Loop
  For idx = LBound(n_m()) To UBound(n_m())
   t_m = t_m + IIf(n_m(idx) > Lim_cost, Lim_cost, n_m(idx))
   Next
  MsgBox t_m
End Sub

mainを上記と差し替えて見てください。


>1日をまたがった計算もありうるし、曜日によって料金が変わったりするからです。


曜日による料金は、料金表にその料金の追加で計算は可能です。

また、元々日をまたがった計算も可能にしてあります。

例。
セルA1に

2006/6/7 16:00:00

セルB1に

2006/6/9 16:00:00

と指定し、mainを実行すると36600という料金が表示されます。
確認してみてください。

それから、ハトさんのコードも拝見しました。

私とハトさんでは、計算の仕様が違っています。

夜には最大上限金額の計算方法です。
20:00以降6:00までの間で
\1500を超えても\1500以上に料金がなることはありません

私は、

20:00から、翌日の6:00までの料金を1500を超えないようにしてあります。
つまり、
開始を0:00 終了を23:00とした場合は、
0:00〜6:00-----200*6=1200
6:00〜20:00----14*3*400=16800
20:00〜23:00---3*2*300=1800--->1500(上限金額設定)

で1200+16800+1500=19500という料金にしていますが。

ハトさんは、

16800+1500=18300にしています。


これが、本来はどちらが仕様ですか?


私も迷いましたが、経営者側が儲かる仕様
(料金というのだから経営している事象だと思って・・)
にしました。

この辺もはっきりしてください。

【38627】Re:料金計算マクロ 訂正
発言  ハト  - 06/6/7(水) 16:23 -

引用なし
パスワード
   こんにちは

>それから、ハトさんのコードも拝見しました。
>
>私とハトさんでは、計算の仕様が違っています。
>
>夜には最大上限金額の計算方法です。
>20:00以降6:00までの間で
>\1500を超えても\1500以上に料金がなることはありません
>
>私は、
>
>20:00から、翌日の6:00までの料金を1500を超えないようにしてあります。
>つまり、
>開始を0:00 終了を23:00とした場合は、
>0:00〜6:00-----200*6=1200
>6:00〜20:00----14*3*400=16800
>20:00〜23:00---3*2*300=1800--->1500(上限金額設定)
>
>で1200+16800+1500=19500という料金にしていますが。
>
>ハトさんは、
>
>16800+1500=18300にしています。
>
>
>これが、本来はどちらが仕様ですか?
>
>
>私も迷いましたが、経営者側が儲かる仕様
>(料金というのだから経営している事象だと思って・・)
>にしました。

これはうっかりしてました
icinoseさんの計算方法が仕様ですね

ご指摘ありがとうございます

【38629】Re:料金計算マクロ
発言  ハト  - 06/6/7(水) 16:29 -

引用なし
パスワード
   >>誤差を計測してみたところ
>>『1.11022302462516E-16』
>>小数点以下16桁(^^;
>この計測の仕方、よろしければご教授下さい。

計測なんて書いてますが、単に
   NTime - TTime
の値を調べただけです

>わたしもどこかで「日時はシリアル値」というのを聞いたのを思い出し、
>調べたところ詳細に解説されてました^^
>http://www.h3.dion.ne.jp/~sakatsu/TimeSerial_Error.htm

参考になります
ありがとうございました

【38645】Re:料金計算マクロ 訂正
発言  roxy  - 06/6/7(水) 17:58 -

引用なし
パスワード
   ▼ichinose さん:

>提示してコードで誤差がでたのですか?
>だとしたら、誤差が発生した時刻情報(開始時刻と終了時刻)を教えてください。

→数回試してみて誤差が出たような気がしたのですが、はっきりと覚えていません。(ローカルウインドウで値を確かめていました。)
これはコードを十分把握してからもう一度検証しようと思っていたのですが、まだ検証できていません。
もう一度コードと照らし合わせてみながら確かめます。
ありがとうございます。


>私は、
>20:00から、翌日の6:00までの料金を1500を超えないようにしてあります。
>つまり、
>開始を0:00 終了を23:00とした場合は、
>0:00〜6:00-----200*6=1200
>6:00〜20:00----14*3*400=16800
>20:00〜23:00---3*2*300=1800--->1500(上限金額設定)
>で1200+16800+1500=19500という料金にしていますが。
>ハトさんは、
>16800+1500=18300にしています。
>これが、本来はどちらが仕様ですか?


→すいません。ここは見落としていました。
ichinose さんの仕様が正しい解釈です。
あくまでも連続している時間が長ければサービスがあるという上限金額設定ですので、前日の分は参照しません。
曜日の件も考えてみます。

【38690】Re:料金計算マクロ 訂正
発言  sin  - 06/6/8(木) 15:54 -

引用なし
パスワード
   ▼roxy さん:
こんにちは

もしまだご覧でしたら、
私も”誤差”含んでいるのが気になっていたので、
方法の1つとしてすべて整数でやるというのはどうですか?
そうすればシリアル値の”誤差”を気にしなくてよくなります。


ハトさんのを元に整数処理にして、日付越えを入れてみました。
このやり方なら上限金額もOKなはずです。
'********************************************************
Sub Test_Time()

Dim ws As Worksheet

Dim SDate As Date
Dim EDate As Date
Dim MDate As Long

Dim STime As Long
Dim ETime As Long

Dim TVal As Long
Dim NVal() As Long

  MDate = 0
  TVal = 0
  i = 0
  ReDim NVal(i)
  NVal(i) = 0

  Set ws = ThisWorkbook.Worksheets("Sheet1")
 
  SDate = ws.Range("A1").Text
  EDate = ws.Range("C1").Text
  STime = (CLng(Format(ws.Range("B1").Text, "h")) * 60) + CLng(Format(ws.Range("B1").Text, "n"))
  ETime = (CLng(Format(ws.Range("D1").Text, "h")) * 60) + CLng(Format(ws.Range("D1").Text, "n"))

  MDate = DateDiff("d", SDate, EDate)
  ETime = ETime + (1440 * MDate)
  
  Do
    Select Case STime
      Case Is >= 1200      '20:00
        STime = STime + 30
        NVal(i) = NVal(i) + 300
      Case Is >= 360      '6:00
        STime = STime + 20
        TVal = TVal + 400
        If NVal(i) <> 0 Then
          i = i + 1
          ReDim Preserve NVal(i)
        End If
      Case Else
        STime = STime + 60
        NVal(i) = NVal(i) + 200
    End Select
    
    If STime >= 1440 Then      '24:00
      STime = STime - 1440
      ETime = ETime - 1440
    End If
    
    If STime >= ETime Then Exit Do
  Loop

  For i = LBound(NVal) To UBound(NVal)
    If NVal(i) > 1500 Then
      TVal = TVal + 1500
    Else
      TVal = TVal + NVal(i)
    End If
  Next i

  ws.Range("E1").Value = TVal
End Sub
'********************************************************


余談ですが、
>もし5:50から7:10でしたら、最初の1時間(5:50〜6:50)は\200、
>その後は(6:50〜7:10)は\400となります。
>それぞれの時間帯に1分でも入っている場合はその料金が採用されます。
これ、ちょっと微妙に思えるのですが・・・
3:59〜6:59 ¥600
4:01〜6:59 ¥1600
仕様・・・

7514 / 13644 ツリー ←次へ | 前へ→
ページ:  ┃  記事番号:
2610219
(SS)C-BOARD v3.8 is Free