I am struggling to get a code to loop through a set numbers of worksheets (sheets 10 to 16) for the second sub in the code.
The code was provided by another user (thanks "Taller"!) which i have adapted so it loops through in the first sub but i cannot get the second sub "Checkoverlap" to loop which only works on sheet 10.
The original question is on this link: VBA Create Gantt Chart style timeline from data in 3 column
It was a follow up question, so i have posted it as a new question as i am told that is the correct protocol for.
This is the code I have got to so far.
Sub Demo()
Call SwitchOff
Dim ws As Integer
For ws = 10 To 16
With Sheets(ws).Activate
Dim i As Long, iCol As Long
Dim arrData, rngData As Range, olRng As Range
Dim arrRes, iR As Long, iM As Long, iH As Long
Dim LastRow As Long, iOffSet As Long
' Init. output table
Columns("F:F").ClearContents
Columns("F:F").NumberFormatLocal = "hh:mm"
Range("F2").Value = "6:00"
Range("F3:F290").Formula = "=R[-1]C+TIMEVALUE(""0:5:0"")"
' load header location into Dict
Const HEADER_START = "G1"
Dim objDic As Object, c As Range
Set objDic = CreateObject("scripting.dictionary")
With Range(HEADER_START, Range(HEADER_START).End(xlToRight))
.Offset(1).Resize(290).Clear
For Each c In Range(HEADER_START, Range(HEADER_START).End(xlToRight)).Cells
objDic(c.Value) = c.Column - Range(HEADER_START).Column
Next
End With
' load data into an array
Set rngData = Range("A1").CurrentRegion
arrData = rngData.Value
' loop through data
For i = LBound(arrData) + 1 To UBound(arrData)
iH = VBA.Hour(arrData(i, 1))
iM = VBA.Minute(arrData(i, 1))
' round to x5/x0 min.
If iM Mod 5 <> 0 Then
iM = iM + (5 - iM Mod 5)
If iM = 60 Then
iH = iH + 1
iM = 0
End If
End If
' before 6am in the next day
If iH < 6 Then iH = iH + 24
iOffSet = ((iH - 6) * 60 + iM) / 5
If objDic.exists(arrData(i, 3)) Then
iCol = objDic(arrData(i, 3))
' populate output table
On Error Resume Next
With Range(HEADER_START).Offset(1, iCol)
CheckOverlap olRng, .Offset(iOffSet)
.Offset(iOffSet).Value = arrData(i, 2)
.Offset(iOffSet).Interior.Color = rgbLightGreen
.Offset(iOffSet - 1).Interior.Color = rgbOrange
.Offset(iOffSet - 2).Interior.Color = rgbOrange
.Offset(iOffSet - 3).Interior.Color = rgbOrange
.Offset(iOffSet - 4).Interior.Color = rgbOrange
.Offset(iOffSet - 5).Interior.Color = rgbOrange
End With
Else
MsgBox "Missing team in output header: " & arrData(i, 3)
End If
Next i
If Not olRng Is Nothing Then
olRng.Interior.Color = vbRed
End If
End With
Next ws
End Sub
Sub CheckOverlap(ByRef allRng As Range, cRng As Range)
Dim c As Range
For Each c In cRng.Offset(-1).Resize(3)
If Len(c.Value) > 0 Then
If allRng Is Nothing Then
Set allRng = Application.Union(c, cRng)
Else
Set allRng = Application.Union(allRng, c, cRng)
End If
End If
Next
End Sub
You don't need to make any change on the second sub "Checkoverlap".
Changes on the first sub are
With Sheets(ws).Activate
- Activate
is a method. It can't be used in With
clause..
before Range()
and Columns()
within With...End With
to qualify the range object.Microsoft documentation:
Option Explicit
Sub Demo()
Call SwitchOff
Dim ws As Long
Dim i As Long, iCol As Long
Dim arrData, rngData As Range, olRng As Range
Dim arrRes, iR As Long, iM As Long, iH As Long
Dim LastRow As Long, iOffSet As Long
Const HEADER_START = "G1"
Dim objDic As Object, c As Range
Set objDic = CreateObject("scripting.dictionary")
For ws = 10 To 16
With Sheets(ws)
objDic.RemoveAll
' Init. output table
.Columns("F:F").ClearContents
.Columns("F:F").NumberFormatLocal = "hh:mm"
.Range("F2").Value = "6:00"
.Range("F3:F290").Formula = "=R[-1]C+TIMEVALUE(""0:5:0"")"
' load header location into Dict
With .Range(HEADER_START, .Range(HEADER_START).End(xlToRight))
.Offset(1).Resize(290).Clear
For Each c In .Range(HEADER_START, .Range(HEADER_START).End(xlToRight)).Cells
objDic(c.Value) = c.Column - .Range(HEADER_START).Column
Next
End With
' load data into an array
Set rngData = .Range("A1").CurrentRegion
arrData = rngData.Value
' loop through data
For i = LBound(arrData) + 1 To UBound(arrData)
iH = VBA.Hour(arrData(i, 1))
iM = VBA.Minute(arrData(i, 1))
' round to x5/x0 min.
If iM Mod 5 <> 0 Then
iM = iM + (5 - iM Mod 5)
If iM = 60 Then
iH = iH + 1
iM = 0
End If
End If
' before 6am in the next day
If iH < 6 Then iH = iH + 24
iOffSet = ((iH - 6) * 60 + iM) / 5
If objDic.exists(arrData(i, 3)) Then
iCol = objDic(arrData(i, 3))
' populate output table
' On Error Resume Next
With .Range(HEADER_START).Offset(1, iCol)
CheckOverlap olRng, .Offset(iOffSet)
.Offset(iOffSet).Value = arrData(i, 2)
.Offset(iOffSet).Interior.Color = rgbLightGreen
.Offset(iOffSet - 1).Interior.Color = rgbOrange
.Offset(iOffSet - 2).Interior.Color = rgbOrange
.Offset(iOffSet - 3).Interior.Color = rgbOrange
.Offset(iOffSet - 4).Interior.Color = rgbOrange
.Offset(iOffSet - 5).Interior.Color = rgbOrange
End With
Else
MsgBox "Missing team in output header: " & arrData(i, 3)
End If
Next i
If Not olRng Is Nothing Then
olRng.Interior.Color = vbRed
End If
End With
Next ws
End Sub
Sub CheckOverlap(ByRef allRng As Range, cRng As Range)
Dim c As Range
For Each c In cRng.Offset(-1).Resize(3)
If Len(c.Value) > 0 Then
If allRng Is Nothing Then
Set allRng = Application.Union(c, cRng)
Else
Set allRng = Application.Union(allRng, c, cRng)
End If
End If
Next
End Sub