The following code does not address "sub question" in respect to *named ranges" as I did not understand that part.
Yet, the following code is a bit shorter and maybe even easier to read. Also, some minor improvements were made in respect to speed:
Option Explicit
Public Sub tmpSO()
Dim WS As Worksheet
Dim X As Long, Y As Long, Z As Long
X = 12
Z = 0
Set WS = ThisWorkbook.Worksheets("Schedule")
With Worksheets("Project Status")
For Y = 4 To WS.Cells(WS.Rows.Count, 2).End(xlUp).Row
If WS.Cells(Y, 2).Font.Bold And WS.Cells(Y, 2).Value2 < 1 Then
WS.Cells(Y, 2).Offset(0, 1).Copy Destination:=.Cells(X, 3)
WS.Cells(Y, 2).Offset(0, 3).Copy Destination:=.Cells(X, 6)
WS.Cells(Y, 2).Offset(0, 4).Copy Destination:=.Cells(X, 7)
WS.Cells(Y, 2).Offset(0, 0).Copy Destination:=.Cells(X, 8)
X = X + 1
Z = Z + 1
' Else
' Y = Y + 1
End If
If Z = 7 Then Exit For
Next Y
End With
End Sub
Maybe you can elaborate a bit more why you want to use named ranges and what you wish to achieve with them that you cannot achieve with the above code as is.
Update:
Miqi180 made me aware that there might be a performance difference when avoiding Offset
by directly referencing the cells instead. So, I staged a small performance test on my system (Office 2016, 64-bit) to test this assumption. Apparently, there is a major performance difference of ~14% (comparing the average of 10 iterations using Offset
and another 10 iterations avoiding it).
This is the code I used to test the speed difference. Please do let me know if you believe that this setup is flawed:
Option Explicit
' Test whether you are using the 64-bit version of Office.
#If Win64 Then
Declare PtrSafe Function getTickCount Lib "kernel32" Alias "QueryPerformanceCounter" (cyTickCount As Currency) As Long
#Else
Declare Function getTickCount Lib "kernel32" Alias "QueryPerformanceCounter" (cyTickCount As Currency) As Long
#End If
Public Sub SpeedTestDirect()
Dim i As Long
Dim ws As Worksheet
Dim dttStart As Date
Dim startTime As Currency, endTime As Currency
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Application.EnableEvents = False
Set ws = ThisWorkbook.Worksheets(1)
ws.Cells.Delete
dttStart = Now
getTickCount startTime
For i = 1 To 1000000
ws.Cells(i, 1).Value2 = 1
ws.Cells(i, 2).Value2 = 1
ws.Cells(i, 3).Value2 = 1
ws.Cells(i, 4).Value2 = 1
ws.Cells(i, 5).Value2 = 1
ws.Cells(i, 6).Value2 = 1
Next i
Application.EnableEvents = True
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
getTickCount endTime
Debug.Print "Runtime: " & endTime - startTime, Format(Now - dttStart, "hh:mm:ss")
End Sub
Public Sub SpeedTestUsingOffset()
Dim i As Long
Dim ws As Worksheet
Dim dttStart As Date
Dim startTime As Currency, endTime As Currency
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Application.EnableEvents = False
Set ws = ThisWorkbook.Worksheets(1)
ws.Cells.Delete
dttStart = Now
getTickCount startTime
For i = 1 To 1000000
ws.Cells(i, 1).Offset(0, 0).Value2 = 1
ws.Cells(i, 1).Offset(0, 1).Value2 = 1
ws.Cells(i, 1).Offset(0, 2).Value2 = 1
ws.Cells(i, 1).Offset(0, 3).Value2 = 1
ws.Cells(i, 1).Offset(0, 4).Value2 = 1
ws.Cells(i, 1).Offset(0, 5).Value2 = 1
Next i
Application.EnableEvents = True
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
getTickCount endTime
Debug.Print "Runtime: " & endTime - startTime, Format(Now - dttStart, "hh:mm:ss")
End Sub
Based on this finding the improved code should be (thanks to Miqi180):
Public Sub tmpSO()
Dim WS As Worksheet
Dim X As Long, Y As Long, Z As Long
X = 12
Z = 0
Set WS = ThisWorkbook.Worksheets("Schedule")
With Worksheets("Project Status")
For Y = 4 To WS.Cells(WS.Rows.Count, 2).End(xlUp).Row
If WS.Cells(Y, 2).Font.Bold And WS.Cells(Y, 2).Value2 < 1 Then
WS.Cells(Y, 3).Copy Destination:=.Cells(X, 3)
WS.Cells(Y, 5).Copy Destination:=.Cells(X, 6)
WS.Cells(Y, 6).Copy Destination:=.Cells(X, 7)
WS.Cells(Y, 2).Copy Destination:=.Cells(X, 8)
X = X + 1
Z = Z + 1
' Else
' Y = Y + 1
End If
If Z = 7 Then Exit For
Next Y
End With
End Sub
Yet, it should be noted that the speed can still be very much improved by moving over to (1) copying values only / directly using .Cells(X, 3).Value2 = WS.Cells(Y, 2).Value2
(for example) and (2) furthermore by using arrays instead.
Of course this does not include yet the standard suggestions such as Application.ScreenUpdating = False
, Application.Calculation = xlCalculationManual
, and Application.EnableEvents = False
.