Excel VBA質問箱 IV

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

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


7573 / 13646 ツリー ←次へ | 前へ→

【38087】時間帯別利用率の算出 あい 06/5/26(金) 9:38 質問[未読]
【38094】Re:時間帯別利用率の算出 lespoir2 06/5/26(金) 10:40 回答[未読]
【38095】Re:時間帯別利用率の算出 neptune 06/5/26(金) 10:44 発言[未読]
【38102】Re:時間帯別利用率の算出 あい 06/5/26(金) 13:26 発言[未読]
【38106】Re:時間帯別利用率の算出 neptune 06/5/26(金) 14:47 回答[未読]
【38101】Re:時間帯別利用率の算出 あい 06/5/26(金) 13:23 質問[未読]
【38103】Re:時間帯別利用率の算出 M 06/5/26(金) 14:06 発言[未読]
【38110】Re:時間帯別利用率の算出 Kein 06/5/26(金) 16:04 回答[未読]
【38107】Re:時間帯別利用率の算出 ハト 06/5/26(金) 14:50 回答[未読]
【38181】Re:時間帯別利用率の算出 sin 06/5/29(月) 12:09 発言[未読]
【38198】Re:時間帯別利用率の算出 ハト 06/5/29(月) 15:16 発言[未読]
【38203】Re:時間帯別利用率の算出 sin 06/5/29(月) 17:44 発言[未読]
【38204】Re:時間帯別利用率の算出 あい 06/5/29(月) 17:50 お礼[未読]
【38108】Re:時間帯別利用率の算出 再送 ichinose 06/5/26(金) 14:59 発言[未読]
【38109】Re:時間帯別利用率の算出 再送 追伸 ichinose 06/5/26(金) 15:09 発言[未読]
【38205】Re:時間帯別利用率の算出 再送 あい 06/5/29(月) 17:52 お礼[未読]

【38087】時間帯別利用率の算出
質問  あい  - 06/5/26(金) 9:38 -

引用なし
パスワード
   以前質問させていただいたのですが、さらに追加がありますので再度質問させていただきます。
Sheet1に下記のようなデータがあります。

A列  B列     C列    D列   E列   F列    G列
番号 部屋番号  ON日付   ON時刻 OFF日付  OFF時刻  売上 
1    1    2006/05/01 22:30 2006/05/02 09:00  \1000
2    1    2006/05/02 13:00 2006/05/02 17:05  \800
3    1    2006/05/02 18:00 2006/05/03 03:10  \2000
4    2    2006/05/02 15:50 2006/05/02 19:50  \100
5    2    2006/05/02 20:35 2006/05/03 09:50  \1400  
6    3    2006/05/01 19:00 2006/05/02 05:45  \1100
7    3    2006/05/02 08:23 2006/05/02 11:39  \800
8    3    2006/05/02 13:24 2006/05/03 14:58  \3500




このデータはサーバから取得したい日付を指定して取ってきているのでA列が何行目まであるかはその時々によって変わります。
今回はこのデータを元に1時間ごとの利用率を算出したいのです。
実際の利用率の値が上記のデータの時どうなるかはわかりませんが、考え方は以下のとおりです。
2006/05/02の16:00〜17:00までをみると、部屋番号1,2,3全て利用されています。そうなるとこの時間帯の利用率は100%となります。
また2006/05/02の12:00〜13:00の利用率は全ての部屋は利用されていない為0%となります。
なお1日ごとに利用率を算出し、一覧表示とグラフ表示を考えています。
非常に厄介な計算になりそうでどうしたらいいかわかりません。
どうぞよろしくお願いします。

【38094】Re:時間帯別利用率の算出
回答  lespoir2  - 06/5/26(金) 10:40 -

引用なし
パスワード
   あい さん
次のような表を作ればよいのではないでしょうか
1 は 利用 0 は空き
時間帯1=時刻0-時刻1
時間帯2=時刻1-時刻2

 例えば 部屋1 が時刻1にON になり 時刻2 にOFFになっていたら 1* の部分に記入
 これをレコードの分だけ繰り返す。

   時間帯1 時間帯2 時間帯3 時間帯4
部屋1 1*   0    1    1
部屋2 0    1    1    1

合計


▼あい さん:
>以前質問させていただいたのですが、さらに追加がありますので再度質問させていただきます。
>Sheet1に下記のようなデータがあります。
>
>A列  B列     C列    D列   E列   F列    G列
>番号 部屋番号  ON日付   ON時刻 OFF日付  OFF時刻  売上 
>1    1    2006/05/01 22:30 2006/05/02 09:00  \1000
>2    1    2006/05/02 13:00 2006/05/02 17:05  \800
>3    1    2006/05/02 18:00 2006/05/03 03:10  \2000
>4    2    2006/05/02 15:50 2006/05/02 19:50  \100
>5    2    2006/05/02 20:35 2006/05/03 09:50  \1400  
>6    3    2006/05/01 19:00 2006/05/02 05:45  \1100
>7    3    2006/05/02 08:23 2006/05/02 11:39  \800
>8    3    2006/05/02 13:24 2006/05/03 14:58  \3500
>・
>・
>・
>
>このデータはサーバから取得したい日付を指定して取ってきているのでA列が何行目まであるかはその時々によって変わります。
>今回はこのデータを元に1時間ごとの利用率を算出したいのです。
>実際の利用率の値が上記のデータの時どうなるかはわかりませんが、考え方は以下のとおりです。
>2006/05/02の16:00〜17:00までをみると、部屋番号1,2,3全て利用されています。そうなるとこの時間帯の利用率は100%となります。
>また2006/05/02の12:00〜13:00の利用率は全ての部屋は利用されていない為0%となります。
>なお1日ごとに利用率を算出し、一覧表示とグラフ表示を考えています。
>非常に厄介な計算になりそうでどうしたらいいかわかりません。
>どうぞよろしくお願いします。

【38095】Re:時間帯別利用率の算出
発言  neptune  - 06/5/26(金) 10:44 -

引用なし
パスワード
   ▼あい さん:
>2006/05/02の16:00〜17:00までをみると、部屋番号1,2,3全て利用されています。そうなるとこの時間帯の利用率は100%となります。
>また2006/05/02の12:00〜13:00の利用率は全ての部屋は利用されていない為0%となります。
具体的に算出の計算式(Excelのではない奴)を自分と回答者の為に書こう。
Ex:単位時間(12:00〜13:00)に使用した部屋数/総部屋数 とか。

>なお1日ごとに利用率を算出し、一覧表示とグラフ表示を考えています。
>非常に厄介な計算になりそうでどうしたらいいかわかりません。
>どうぞよろしくお願いします。
頭からいったんプログラムの事はどけておき、紙の上で、又はExcelのシート上では
どうやって計算するのかを考えて、その答えを紙にでも書いておきましょう。
・・・考えをまとめるという意味。

その後、まとめた考えをVBA化するという手順です。

先ずは、
日付、時間、をキーにしてソートする必要がありそうですね。

ところで、何がわからないのか質問文からは判断できません。
まさか、全部というわけではないでしょう?

【38101】Re:時間帯別利用率の算出
質問  あい  - 06/5/26(金) 13:23 -

引用なし
パスワード
   少し言葉足らずだったので追加させていただきます。

時間帯別利用率は下記の方法で出します。
算出したい時間帯の1時間あたり利用されているすべての部屋番号の時間の合計÷(総部屋数×60分)です。

その時間帯あたりの時間合計を算出する方法がわかりません。

よろしくお願いします。

【38102】Re:時間帯別利用率の算出
発言  あい  - 06/5/26(金) 13:26 -

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

言葉足らずですいません。
データはすでに部屋番号順、日付順、時間順でソートしてあります。

考え方はわかっているのですが、知識不足のためどうやってこれをうまく実現すればいいのかがわかりません。

ということは全部わからないということになるのかもしれませんが。。。

【38103】Re:時間帯別利用率の算出
発言  M  - 06/5/26(金) 14:06 -

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

時間の計算はシリアル値ですので、この辺を少し勉強されては如何でしょう。
24時間が1という単位です。
参考までURLをつけておきます。
一度目を通してください。

http://support.microsoft.com/default.aspx?scid=kb;ja;416574

【38106】Re:時間帯別利用率の算出
回答  neptune  - 06/5/26(金) 14:47 -

引用なし
パスワード
   ▼あい さん:
>▼neptune さん:
>
>言葉足らずですいません。
>データはすでに部屋番号順、日付順、時間順でソートしてあります。
判りました。

>考え方はわかっているのですが、知識不足のためどうやってこれをうまく実現すればいいのかがわかりません。

それでは、考え方に従って、手順を書いてみてください。
あいさんが、手順を書いて、それに従って、VBA化のお手伝いならします。

私は、お手伝いはしますが、全部は書きません。
それでよければ手順を書いてみてください。それを見て意見なり、提案なり
させてもらいます。
時間は掛かりますが、自分流でも自分の理解の範囲で自分で作成しなければ、
あとであいさんが困ることになりますから。

それでよければ手順を書いてみてください。良くなければ、他の方の全部
のResをお待ちください。

【38107】Re:時間帯別利用率の算出
回答  ハト  - 06/5/26(金) 14:50 -

引用なし
パスワード
   こんにちわ
Sheet1のデータを集計し、Sheet2へ表出力するところまで作ってみました
表の体裁、グラフへの出力は考えてませんのでそこはカスタマイズしてください


Sub Test()

Dim i As Integer
Dim j As Integer
Dim k As Integer

Dim TCnt() As Long

Dim SDate As Date
Dim EDate As Date

Dim MDate

Dim OnDate
Dim OfDate

Dim OnTime
Dim OfTime

Dim TM As Long

Dim ws As Worksheet

Const RCNT As Integer = 3  '総部屋数、ここでは仮に3としている

  Set ws = ThisWorkbook.Worksheets("Sheet1")
  
  SDate = Application.WorksheetFunction.Min(ws.Range(ws.Range("C2"), ws.Range("C65535").End(xlUp)))
  EDate = Application.WorksheetFunction.Max(ws.Range(ws.Range("E2"), ws.Range("E65535").End(xlUp)))

  MDate = DateDiff("d", SDate, EDate)

  ReDim TCnt(MDate, 23)


  For i = 2 To ws.Range("C65535").End(xlUp).Row
    
    OnDate = DateDiff("d", SDate, ws.Cells(i, 3))
    OfDate = DateDiff("d", SDate, ws.Cells(i, 5))
    
    For j = OnDate To OfDate
      
      If j = OnDate Then
        OnTime = Hour(ws.Cells(i, 4))
      Else
        OnTime = 0
      End If
      
      If j = OfDate Then
        OfTime = Hour(ws.Cells(i, 6))
      Else
        OfTime = 23
      End If
      
      For k = OnTime To OfTime
        
        If OnDate = OfDate And OnTime = OfTime Then
          TM = Minute(ws.Cells(i, 6)) - Minute(ws.Cells(i, 4))
        ElseIf j = OnDate And k = OnTime Then
          TM = Minute(ws.Cells(i, 4))
        ElseIf j = OfDate And k = OfTime Then
          TM = Minute(ws.Cells(i, 6))
        Else
          TM = 60
        End If
       
        TCnt(j, k) = TCnt(j, k) + TM
      
      Next k
       
    Next j
        
  Next i

  Set ws = Nothing
  Set ws = ThisWorkbook.Worksheets("Sheet2")
  
  For j = 0 To MDate
    ws.Cells(j + 2, 1) = DateAdd("d", j, SDate)
    For k = 0 To 23
      ws.Cells(j + 2, k + 2) = TCnt(j, k) / (60 * RCNT) * 100
    Next k
  Next j

  Set ws = Nothing
  
End Sub

【38108】Re:時間帯別利用率の算出 再送
発言  ichinose  - 06/5/26(金) 14:59 -

引用なし
パスワード
   ▼あい さん:
こんにちは。
投稿が大分わかりやすくなってきましたが・・・、

>以前質問させていただいたのですが、さらに追加がありますので再度質問させていただきます。
関連しているのでリンクを貼ったほうが見ている方がもっと下記の内容を
連想しやすいと思いますよ!!

>Sheet1に下記のようなデータがあります。
>
>A列  B列     C列    D列   E列   F列    G列
>番号 部屋番号  ON日付   ON時刻 OFF日付  OFF時刻  売上 
>1    1    2006/05/01 22:30 2006/05/02 09:00  \1000
>2    1    2006/05/02 13:00 2006/05/02 17:05  \800
>3    1    2006/05/02 18:00 2006/05/03 03:10  \2000
>4    2    2006/05/02 15:50 2006/05/02 19:50  \100
>5    2    2006/05/02 20:35 2006/05/03 09:50  \1400  
>6    3    2006/05/01 19:00 2006/05/02 05:45  \1100
>7    3    2006/05/02 08:23 2006/05/02 11:39  \800
>8    3    2006/05/02 13:24 2006/05/03 14:58  \3500
>・
>・
>・
前にも書きましたが、せっかく入力データは上記のように明確にされたのですから、
結果もわかりやすく記述してください。


>このデータはサーバから取得したい日付を指定して取ってきているのでA列が何行目まであるかはその時々によって変わります。
>今回はこのデータを元に1時間ごとの利用率を算出したいのです。
>実際の利用率の値が上記のデータの時どうなるかはわかりませんが、考え方は以下のとおりです。
>2006/05/02の16:00〜17:00までをみると、部屋番号1,2,3全て利用されています。そうなるとこの時間帯の利用率は100%となります。
>また2006/05/02の12:00〜13:00の利用率は全ての部屋は利用されていない為0%となります。
>なお1日ごとに利用率を算出し、一覧表示とグラフ表示を考えています。
↑この説明はよかったと思います。


A列から、G列は、あい さんが提示されたようなデータが入っていた場合
(日付、時間は、シリアル値とします。尚、ソートはされていなくてもよいです)、


標準モジュールに以下のコードを記述してください。
H列とI列は、コードが作業列として使います(2行目以降)。

集計したい日付をセルH1にシリアル値で指定して下さい
例。2006/5/2


H1に日付を指定した後に、mainを実行してみて下さい。

結果の一覧表は、JからL列に表示します。


'=================================================================
Sub main()
  Const 日付 = "$h$1"
  Const 一覧表 = "$J$1:$k$24"
  Dim idx As Long
  Dim 部屋数 As Long
  Dim wkadd As String
  Dim セル範囲 As Range
  Set セル範囲 = Range("a2", Cells(Rows.Count, 1).End(xlUp))
  If セル範囲.Row > 1 Then
    With セル範囲
     wkadd = セル範囲.Offset(0, 1).Address
     部屋数 = Evaluate("=sum(1/(countif(" & wkadd & "," & wkadd & ")))")
     .Offset(0, 7).Resize(, 2).Formula = _
           Array("=MAX(C2+D2," & 日付 & ")", "=MIN(E2+F2," & 日付 & "+1)")
     Names.Add "日付", "=" & Range(日付).Address(, , xlR1C1, True)
     Names.Add "開始時刻", "=" & .Offset(0, 7).Address(, , xlR1C1, True)
     Names.Add "終了時刻", "=" & .Offset(0, 8).Address(, , xlR1C1, True)
     With Range(一覧表)
       For idx = 1 To 24
        .Range("a" & idx).Resize(, 2).Value = Array(TimeSerial(idx - 1, 0, 0), TimeSerial(idx, 0, 0))
        Next
       .NumberFormat = "h:mm"
       .Range("c1").FormulaArray = _
         "=SUM(IF((開始時刻>日付+K1)+(終了時刻<日付+J1)>0,0," & _
        "(IF(終了時刻>=日付+K1,日付+K1,終了時刻)-IF(開始時刻<=日付+J1,日付+J1,開始時刻))/(K1-J1)))/" & 部屋数
       .Range("c1").AutoFill Destination:=.Range("c1:c24"), Type:=xlFillDefault
       .Range("c1:c24").NumberFormat = "0.0%"
       End With
     End With
    End If
End Sub

上記のコードは、数式を設定しているだけのコードです。
つまり、数式でも可能と言うことです。

試してみて下さい。

【38109】Re:時間帯別利用率の算出 再送 追伸
発言  ichinose  - 06/5/26(金) 15:09 -

引用なし
パスワード
   コードmainを実行後、元のデータがのデータ数が変わっていなければ、

集計日付の入っているセルH1の日付を変更すれば、
別の日の一覧表も見られます。
数式をそのまま残してありますから、データの変更にも対応しています。

つまり、データ数の変更がなければ、mainの実行は一度でよい
と言うことです。

【38110】Re:時間帯別利用率の算出
回答  Kein  - 06/5/26(金) 16:04 -

引用なし
パスワード
   利用率の計算式はそちらでやって下さい。
とりあえず全ての時間帯の、各室の利用状況を表示する表を作る
ところまでのマクロを提示しておきます。
表は I列 以降に作られます。AB:AC列を作業列として使います。

Sub Mk_Room_Schedule()
  Dim MxR As Long, Tm As Long
  Dim i As Long, j As Long
  Dim Get1 As Long, Get2 As Long, MyC As Long
  Dim StD As String, Edt As String
  Dim MxDy As Date, MiDy As Date
  Dim C As Range
   
  Range("B1", Range("B65536").End(xlUp)).AdvancedFilter _
  xlFilterCopy, , Range("I1"), True
  With Range("I2", Range("I65536").End(xlUp))
   .Copy
   Range("J1").PasteSpecial , , , True
   .ClearContents
  End With
  MxR = Range("A65536").End(xlUp).Row
  With Range("AB2:AB" & MxR)
   .Resize(, 2).NumberFormat = "h:mm:ss"
   .Formula = _
   "=FLOOR($D2,TIMEVALUE(""1:00:00""))"
   .Offset(, 1).Formula = _
   "=CEILING($F2,TIMEVALUE(""1:00:00""))"
  End With
  With Application
   MxDy = .Max(Range("C2:C" & MxR & ", E2:E" & MxR))
   MiDy = .Min(Range("C2:C" & MxR & ", E2:E" & MxR))
  End With
  Tm = (MxDy - (MiDy - 1)) * 24
  With Range("I2")
   .Resize(Tm + 1).NumberFormat = "@"
   .Value = Format(MiDy, "yyyy/m/d") & TimeSerial(0, 0, 0)
   j = 1
   For i = 1 To Tm
     If i Mod 24 = 0 Then
      j = 0: MiDy = MiDy + 1
     End If
     .Offset(i).Value = Format(MiDy, "yyyy/m/d") & _
     TimeSerial(j, 0, 0)
     j = j + 1
   Next i
  End With
  With Range("I1")
   .Value = "↓日付・時刻; " & .Value & "→"
   .EntireColumn.AutoFit
   .Select
  End With
  With Application
   For Each C In Range("B2:B" & MxR)
     MyC = .Match(C.Value, Rows(1), 0) - 9
     Sdt = C.Offset(, 1).Text & C.Offset(, 26).Text
     Edt = C.Offset(, 3).Text & C.Offset(, 27).Text
     Debug.Print Sdt & " : " & Edt
     Get1 = .Match(Sdt, Range("I:I"), 0)
     Get2 = .Match(Edt, Range("I:I"), 0)
     Range("I" & Get1 & ":I" & Get2).Offset(, MyC) _
     .Value = "入室"
   Next
  End With
End Sub

【38181】Re:時間帯別利用率の算出
発言  sin  - 06/5/29(月) 12:09 -

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

▼ハト さん:
お手本のようなスマートなやり方に感心しました。
勉強になります。

ところで、
>        ElseIf j = OnDate And k = OnTime Then
>          TM = Minute(ws.Cells(i, 4))

          Tm = 60 - Minute(ws.Cells(i, 4))
にしないと開始利用時間が合わないのでは?
A列の番号1は22:30なのでたまたま合うのですが
A列の番号2の13:00〜は13:00台の利用時間が0分に
A列の番号4の15:50〜は15:00台の利用時間が50分に
になってしまいます。


私はこれまで日時系の関数をほとんど使ったことがなかったので、
今回勉強のためにハト さんのコードを元にやり方を変えて
試してみました。
時系列に並べ替えて結果を表示しようというものです。
しかし、かなり不細工なコードになってしまいました。;;
特に
'日付/時間帯ごとに集計
から下の部分をもう少しスマートに出来そうな気がするのですが・・・
もしアドバイスなど頂けると幸いです。

(結局、ループが多すぎて実用には向きませんが・・・)


Sub Test2()

  Dim BDate() As Date
  Dim i As Integer
  Dim j As Integer
  Dim k As Integer
  Dim m As Integer
  Dim ws As Worksheet
  Dim SDate As Date
  Dim ed As Integer
  Dim TDate As Date
  Dim MDate As Integer
  Dim Tm As Long

  Const RCNT As Integer = 3  '総部屋数、ここでは仮に3としている

  Set ws = ThisWorkbook.ActiveSheet
  ed = ws.Range("C65535").End(xlUp).Row

  ReDim BDate(2 To ed, 2)

'行ごとにON日付/時刻、OFF日付/時刻を日付型配列に格納
  For i = 2 To ed
    BDate(i, 1) = CDate(CDate(Cells(i, 3)) & " " & CDate(Cells(i, 4)))
    BDate(i, 2) = CDate(CDate(Cells(i, 5)) & " " & CDate(Cells(i, 6)))
  Next i

'時系列に並べ替え
  For i = 2 To ed
    For j = i + 1 To ed
      If BDate(i, 1) > BDate(j, 1) Then
        TDate = BDate(i, 1)
        BDate(i, 1) = BDate(j, 1)
        BDate(j, 1) = TDate
        
        TDate = BDate(i, 2)
        BDate(i, 2) = BDate(j, 2)
        BDate(j, 2) = TDate
      End If
    Next j
  Next i

  MDate = DateDiff("d", BDate(2, 1), BDate(ed, 2))
  SDate = Format(BDate(2, 1), "yyyy/mm/dd")

  Worksheets.Add after:=ws
  Set ws = Nothing
  Set ws = ThisWorkbook.ActiveSheet


  For i = 0 To 23
    ws.Cells(1, i + 2) = i & ":00"
  Next i

  k = 2
  m = 2

'日付/時間帯ごとに集計
  For i = 0 To MDate
    ws.Cells(i + 2, 1) = DateAdd("d", i, SDate)
    TDate = DateAdd("d", i, SDate)
    
    For j = 0 To 23
      Tm = 0
      
      Do Until BDate(k, 1) >= DateAdd("h", j + 1, TDate)
        If BDate(k, 2) > DateAdd("h", j, TDate) Then
          If BDate(k, 1) > DateAdd("h", j, TDate) And BDate(k, 2) < DateAdd("h", j + 1, TDate) Then
            Tm = Tm + Minute(BDate(k, 2)) - Minute(BDate(k, 1))
          ElseIf BDate(k, 1) > DateAdd("h", j, TDate) And BDate(k, 2) >= DateAdd("h", j + 1, TDate) Then
            Tm = Tm + 60 - Minute(BDate(k, 1))
          ElseIf BDate(k, 1) <= DateAdd("h", j, TDate) And BDate(k, 2) < DateAdd("h", j + 1, TDate) Then
            Tm = Tm + Minute(BDate(k, 2))
          ElseIf BDate(k, 1) <= DateAdd("h", j, TDate) And BDate(k, 2) >= DateAdd("h", j + 1, TDate) Then
            Tm = Tm + 60
          End If
        End If
        k = k + 1
        If k > ed Then Exit Do
      Loop

      k = m

      Do Until BDate(m, 2) >= DateAdd("h", j + 1, TDate) Or m = ed
        k = m + 1
        m = m + 1
      Loop

      ws.Cells(i + 2, j + 2) = Application.Round(Tm / (60 * RCNT) * 100, 0) & " %"
    Next j
  Next i

  Columns("b:y").ColumnWidth = 5.25
  
  Set ws = Nothing

End Sub

【38198】Re:時間帯別利用率の算出
発言  ハト  - 06/5/29(月) 15:16 -

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

▼sin さん:
>横から失礼します。
>
>▼ハト さん:
>お手本のようなスマートなやり方に感心しました。
>勉強になります。

ありがとうございます。
でも自分もまだまだ勉強中です(^^;

>ところで、
>>        ElseIf j = OnDate And k = OnTime Then
>>          TM = Minute(ws.Cells(i, 4))
>は
>          Tm = 60 - Minute(ws.Cells(i, 4))
>にしないと開始利用時間が合わないのでは?

申し訳ありません、おっしゃる通り自分のミスです。
          TM = 60 - Minute(ws.Cells(i, 4))
です
お恥ずかしい(^^;


>'行ごとにON日付/時刻、OFF日付/時刻を日付型配列に格納
>  For i = 2 To ed
>    BDate(i, 1) = CDate(CDate(Cells(i, 3)) & " " & CDate(Cells(i, 4)))
>    BDate(i, 2) = CDate(CDate(Cells(i, 5)) & " " & CDate(Cells(i, 6)))
>  Next i
>
>'時系列に並べ替え
>  For i = 2 To ed
>    For j = i + 1 To ed
>      If BDate(i, 1) > BDate(j, 1) Then
>        TDate = BDate(i, 1)
>        BDate(i, 1) = BDate(j, 1)
>        BDate(j, 1) = TDate
>        
>        TDate = BDate(i, 2)
>        BDate(i, 2) = BDate(j, 2)
>        BDate(j, 2) = TDate
>      End If
>    Next j
>  Next i
>
>  MDate = DateDiff("d", BDate(2, 1), BDate(ed, 2))

このやり方ですとMDateの算出に問題があります

     ON        OFF
2006/05/28 21:00   2006/05/28 23:30
2006/05/28 22:00   2006/05/29 01:00
2006/05/28 22:30   2006/05/28 23:00

のようなデータの場合、ONの日時はソートされても
OFFの日時はソートされていないのでにMDateの値が正しく設定されません

あと、ソートは
日時をエクセル上に作業列として書き出し、
エクセルのソート機能(Range.Sort)を使った後、配列に入れる方法もあります


>'日付/時間帯ごとに集計
うーん、アドバイスって程の物じゃないですが

DateAdd("h", j, TDate)
DateAdd("h", j + 1, TDate)

の2つが何度も出てきますんで
    
>    For j = 0 To 23
>      Tm = 0
      DateA = DateAdd("h", j, TDate)
      DateB = DateAdd("h", j + 1, TDate)

と変数に代入し、↓のような部分を
>      Do Until BDate(k, 1) >= DateAdd("h", j + 1, TDate)
>        If BDate(k, 2) > DateAdd("h", j, TDate) Then

↓の様にした方がすっきりするかな?
      Do Until BDate(k, 1) >= DateB
        If BDate(k, 2) > DateA Then

あと↓は
>      k = m
>
>      Do Until BDate(m, 2) >= DateAdd("h", j + 1, TDate) Or m = ed
>        k = m + 1
>        m = m + 1
>      Loop

↓の様にしましょう
      Do Until BDate(m, 2) >= DateAdd("h", j + 1, TDate) Or m = ed
        m = m + 1
      Loop

      k = m

アドバイスらしくなくて申し訳ないです

【38203】Re:時間帯別利用率の算出
発言  sin  - 06/5/29(月) 17:44 -

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


>このやり方ですとMDateの算出に問題があります
>
>     ON        OFF
>2006/05/28 21:00   2006/05/28 23:30
>2006/05/28 22:00   2006/05/29 01:00
>2006/05/28 22:30   2006/05/28 23:00
>
>のようなデータの場合、ONの日時はソートされても
>OFFの日時はソートされていないのでにMDateの値が正しく設定されません


ご指摘通りイタい間違いでした。
↓の様にしてみました。


'時系列に並べ替え
  Dim EDate As Date
  For i = 2 To ed
    For j = i + 1 To ed
      If BDate(i, 1) > BDate(j, 1) Then
        TDate = BDate(i, 1)
        BDate(i, 1) = BDate(j, 1)
        BDate(j, 1) = TDate
        
        TDate = BDate(i, 2)
        BDate(i, 2) = BDate(j, 2)
        BDate(j, 2) = TDate
      End If
      
      If EDate < BDate(j, 2) Then
        EDate = BDate(j, 2)
      End If
    Next j
  Next i

  MDate = DateDiff("d", BDate(2, 1), EDate)

さらに冗長になってしまった・・・


>あと、ソートは
>日時をエクセル上に作業列として書き出し、
>エクセルのソート機能(Range.Sort)を使った後、配列に入れる方法もあります

はい、使ったことはありませんがエクセルのソート機能で出来るらしいというのは
知っていたのですが、シートを作業用に使用するのは好みではないので・・・


>>'日付/時間帯ごとに集計
>うーん、アドバイスって程の物じゃないですが
>
>DateAdd("h", j, TDate)
>DateAdd("h", j + 1, TDate)
>
>の2つが何度も出てきますんで
>    
>>    For j = 0 To 23
>>      Tm = 0
>      DateA = DateAdd("h", j, TDate)
>      DateB = DateAdd("h", j + 1, TDate)
>
>と変数に代入し、↓のような部分を
>>      Do Until BDate(k, 1) >= DateAdd("h", j + 1, TDate)
>>        If BDate(k, 2) > DateAdd("h", j, TDate) Then
>
>↓の様にした方がすっきりするかな?
>      Do Until BDate(k, 1) >= DateB
>        If BDate(k, 2) > DateA Then

確かに見易さがだいぶ違いますね。
ここはテスト中、何回か引っかかった場所なので
始めから変数化しておくべきでした。
ありがとうございます。

>
>あと↓は
>>      k = m
>>
>>      Do Until BDate(m, 2) >= DateAdd("h", j + 1, TDate) Or m = ed
>>        k = m + 1
>>        m = m + 1
>>      Loop
>
>↓の様にしましょう
>      Do Until BDate(m, 2) >= DateAdd("h", j + 1, TDate) Or m = ed
>        m = m + 1
>      Loop
>
>      k = m

言われてみると確かにマヌケな事してました。^^;


>アドバイスらしくなくて申し訳ないです

いえいえ、勉強になりました、ありがとうございました。
これからも宜しくお願いします。
(記事番号【37734】の時もお世話になりました)


※「投稿種別」はスレ主ではないので、あえて「お礼」ではなく
 「発言」にしておきました。
 気持ちは「お礼」なのですが・・・



【38204】Re:時間帯別利用率の算出
お礼  あい  - 06/5/29(月) 17:50 -

引用なし
パスワード
   ▼ハト さん:
こんにちは。
少しカスタマイズして利用させていただきたいと思います。
まずコードの内容を理解するところから始めているのでまだ実現できていませんが・・・
ありがとうございました。
勉強になりました。

【38205】Re:時間帯別利用率の算出 再送
お礼  あい  - 06/5/29(月) 17:52 -

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

こんにちは。
色々とご指摘ありがとうございます。
頭の中が整理できていない上に期限が迫っていて焦っており、大変わかりづらい説明になってしまっていることをお許しください。
少しカスタマイズして利用させていただこうと思います。
また何かありましたらよろしくお願いします。

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