Несколько строк копирования
Настройте значения в разделе констант. Поиграйте с форматированием во 2-й версии. Изучите 3-ю версию.
РЕДАКТИРОВАТЬ:
Когда эти константы играют главную роль в вашем лице, возникает мысль создать аргументированную подпункт:
Sub Practice_LoopA(NameColumn As Long, IdColumn As Long, HeaderRow As Long, _
TargetCell As String, Multiplier As Long)
'...
End Sub
и используйте его в другом подпрограмме, например:
Sub Other()
Practice_LoopA 1, 2, 1, "D1", 4
End Sub
Начальное решение
Option Explicit
Sub Practice_Loop()
Const NameColumn As Long = 1 ' Product Name Column Number
Const IdColumn As Long = 2 ' Product ID Column Number
Const HeaderRow As Long = 1 ' Headers Row Number
Const TargetCell As String = "D1" ' Target First Cell Range Address
Const Multiplier As Long = 4 ' Multiplier
Dim rng As Range ' Last Non-Empty Cell Range,
' Non-Empty Column Range in Name Column,
' Non-Empty Column Range in ID Column
Dim ProductName As Variant ' Product Name Array
Dim ProductID As Variant ' Product ID Array
Dim Target As Variant ' Target Array
Dim i As Long ' Product Name/ID Elements (Rows) Counter
Dim j As Long ' Multiplier Counter
Dim k As Long ' Target Array Elements (Rows) Counter
' Write values from Ranges to Arrays.
Set rng = Columns(NameColumn).Find(What:="*", LookIn:=xlFormulas, _
SearchDirection:=xlPrevious)
If rng Is Nothing Then Exit Sub
Set rng = Range(Cells(HeaderRow, NameColumn), rng)
ProductName = rng
Set rng = rng.Offset(, IdColumn - NameColumn)
ProductID = rng
Set rng = Nothing
' Define Target Array.
ReDim Target(1 To UBound(ProductName) * Multiplier + 1, 1 To 2)
' Write headers from Arrays to Target Array.
Target(1, 1) = ProductName(1, 1)
Target(1, 2) = ProductID(1, 1)
' Write values from Arrays to Target Array.
k = 2 ' Headers are in row 1.
For i = 2 To UBound(ProductName)
For j = 1 To Multiplier
Target(k, 1) = ProductName(i, 1)
Target(k, 2) = ProductID(i, 1)
k = k + 1
Next j
Next i
' Write values from Target Array to Target Range.
Set rng = Range(TargetCell).Resize(UBound(Target), 2)
'rng.EntireColumn.ClearContents
rng = Target
End Sub
Sub Practice_Loop_With_Formatting()
Const NameColumn As Long = 1 ' Product Name Column Number
Const IdColumn As Long = 2 ' Product ID Column Number
Const HeaderRow As Long = 1 ' Headers Row Number
Const TargetCell As String = "D1" ' Target First Cell Range Address
Const Multiplier As Long = 4 ' Multiplier
Dim rng As Range ' Last Non-Empty Cell Range,
' Non-Empty Column Range in Name Column,
' Non-Empty Column Range in ID Column
Dim ProductName As Variant ' Product Name Array
Dim ProductID As Variant ' Product ID Array
Dim Target As Variant ' Target Array
Dim i As Long ' Product Name/ID Elements (Rows) Counter
Dim j As Long ' Multiplier Counter
Dim k As Long ' Target Array Elements (Rows) Counter
' Write values from Ranges to Arrays.
Set rng = Columns(NameColumn).Find(What:="*", LookIn:=xlFormulas, _
SearchDirection:=xlPrevious)
If rng Is Nothing Then Exit Sub
Set rng = Range(Cells(HeaderRow, NameColumn), rng)
ProductName = rng
Set rng = rng.Offset(, IdColumn - NameColumn)
ProductID = rng
Set rng = Nothing
' Define Target Array.
ReDim Target(1 To UBound(ProductName) * Multiplier + 1, 1 To 2)
' Write headers from Arrays to Target Array.
Target(1, 1) = ProductName(1, 1)
Target(1, 2) = ProductID(1, 1)
' Write values from Arrays to Target Array.
k = 2 ' Headers are in row 1.
For i = 2 To UBound(ProductName)
For j = 1 To Multiplier
Target(k, 1) = ProductName(i, 1)
Target(k, 2) = ProductID(i, 1)
k = k + 1
Next j
Next i
' Define Target Range.
Set rng = Range(TargetCell).Resize(UBound(Target), 2)
'rng.EntireColumn.ClearContents
' Write values from Target Array to Target Range.
rng = Target
' Apply formatting.
With rng
' Format Target Range here, in between the other with statements
' and/or after all the other with statements...
.EntireColumn.AutoFit
With .Rows(1)
' Format Headers here...
.Font.Bold = True
End With
With .Cells(1).Offset(1).Resize(.Rows.Count - 1, .Columns.Count)
' Format 'Body' Range (Data (below Headers)) here...
End With
With .Cells(1).Offset(1).Resize(.Rows.Count - 1)
' Format First Column (ProductName) of 'Body' Range (Data) here...
End With
With .Cells(2).Offset(1).Resize(.Rows.Count - 1)
' Format Second Column (ProductID) of 'Body' Range (Data) here...
End With
End With
End Sub
Sub Practice_Loop_Study()
Const NameColumn As Long = 1 ' Product Name Column Number
Const IdColumn As Long = 2 ' Product ID Column Number
Const HeaderRow As Long = 1 ' Headers Row Number
Const TargetCell As String = "D1" ' Target First Cell Range Address
Const Multiplier As Long = 4 ' Multiplier
Dim rng As Range ' Last Non-Empty Cell Range,
' Non-Empty Column Range in Name Column,
' Non-Empty Column Range in ID Column
Dim ProductName As Variant ' Product Name Array
Dim ProductID As Variant ' Product ID Array
Dim Target As Variant ' Target Array
Dim i As Long ' Product Name/ID Elements (Rows) Counter
Dim j As Long ' Multiplier Counter
Dim k As Long ' Target Array Elements (Rows) Counter
Debug.Print String(50, "-") & vbCrLf & "Before:"
' Define Last Non-Empty Cell Range in Name Column,
Set rng = Columns(NameColumn).Find(What:="*", LookIn:=xlFormulas, _
SearchDirection:=xlPrevious)
Debug.Print "Last Non-Empty Cell Range Address = " & rng.Address
' Check if any data in Name Column.
If rng Is Nothing Then Exit Sub
' Define Non-Empty Column Range in Name Column.
Set rng = Range(Cells(HeaderRow, NameColumn), rng)
Debug.Print "Product Name Range Address = " & rng.Address
' Write values from Product Name Range to Product Name Array.
ProductName = rng
' Define Non-Empty Column Range in ID Column.
Set rng = rng.Offset(, IdColumn - NameColumn)
Debug.Print "Product ID Range Address = " & rng.Address
' Write values from Product ID Range to Product ID Array.
ProductID = rng
' Range not needed any more.
Set rng = Nothing
' Define Target Array.
ReDim Target(1 To UBound(ProductName) * Multiplier + 1, 1 To 2)
' Write headers from Arrays to Target Array.
Target(1, 1) = ProductName(1, 1)
Target(1, 2) = ProductID(1, 1)
' Write values from Arrays to Target Array.
k = 2 ' Headers are in row 1.
For i = 2 To UBound(ProductName)
For j = 1 To Multiplier
Target(k, 1) = ProductName(i, 1)
Target(k, 2) = ProductID(i, 1)
k = k + 1
Next j
Next i
' Define Target Range.
Set rng = Range(TargetCell).Resize(UBound(Target), 2)
'rng.EntireColumn.ClearContents
' Write values from Target Array to Target Range.
rng = Target
Debug.Print String(50, "-") & vbCrLf & "After:"
' Apply formatting.
With rng
Debug.Print "Target Range Address = " & .Address
' Format Target Range here, in between the other with statements
' and/or after all the other with statements...
.EntireColumn.AutoFit
With .Rows(1)
Debug.Print "Headers Address = " & .Address
' Format Headers here...
.Font.Bold = True
End With
With .Cells(1).Offset(1).Resize(.Rows.Count - 1, .Columns.Count)
Debug.Print "'Body' Range Address = " & .Address
' Format 'Body' Range (Data (below Headers)) here...
End With
With .Cells(1).Offset(1).Resize(.Rows.Count - 1)
Debug.Print "Product Name Range Address = " & .Address
' Format First Column (ProductName) of 'Body' Range (Data) here...
End With
With .Cells(2).Offset(1).Resize(.Rows.Count - 1)
Debug.Print "Product ID Range Address = " & .Address
' Format Second Column (ProductID) of 'Body' Range (Data) here...
End With
End With
End Sub