VBA dynamic row lookup while looping - excel

I'm very new to VBA and should probably spend some time on debugging and learning the formalities of how code should be written.
I am using a loop that uses the Hlookup function to populate a table from on one sheet from data on a master sheet. (This is in the Sub SetMatrix). Within the Sub that performs this task I use some other UDF's, one which copies and pastes the variables (names from a 3rd sheet which may change) I want to lookup from the master sheet.
In any case it runs perfectly fine when the I use a hardcoded number for the row in the lookup function. However, once I try to use a variable (jpmRow instead of a number like 50) for the row it will work the first time only. Then when I run it again I get RunTime error 91 - object variable or withblock variable not set. The debugger take me back to the DynamicRange UDF, Set StartCell line, which confuses me because that is not where I am setting the row variable. Meanwhile if I use a constant for the row it lets me rerun the sub with success every time.
Here is the code:
Option Explicit
Dim wsTemplate As Worksheet
Dim ws As Worksheet
Dim TxtCell As Range
Dim PortfolioCell As String
Dim StartCell As Range
Dim EndCell As Range
Dim RangeParameter As Range
Dim jpmRow As Integer
Dim myColumn As Integer
Dim myRow As Integer
Function DynamicRange(TxtToFind As String) As Range
Dim k As Integer
k = iCount
Set ws = Sheets("Template")
Set StartCell = ws.Cells.Find(TxtToFind).Offset(2, 0)
myColumn = StartCell.Column
myRow = StartCell.Row
Set EndCell = ws.Cells(myRow + k - 1, myColumn)
Set DynamicRange = ws.Range(StartCell.Address, EndCell.Address)
'Set DynamicRange = RangeParameter
End Function
Function iCount() As Integer
Set ws = Sheets("Template")
Set StartCell = ws.Cells.Find("Ticker").Offset(2, 0)
Set EndCell = ws.Cells.Find("Total").Offset(-1, 0)
iCount = ws.Range(StartCell.Address, EndCell.Address).Rows.Count
End Function
Sub SetMatrix()
Dim StartTable As Range
Dim iRows As Range
Dim iColumns As Range
Dim myArray(50, 50) As Integer
Dim wsJPM As Worksheet
Dim i As Integer
Dim j As Integer
Set StartTable = Sheets("Correlation Matrix").Range("A3")
Set iRows = Range(StartTable.Offset(1, 0).Address, StartTable.Offset(iCount, 0).Address)
Set iColumns = Range(StartTable.Offset(0, 1).Address, StartTable.Offset(0, iCount).Address)
Set wsJPM = Sheets("JPM")
Sheets("Correlation Matrix").Cells.ClearContents
Sheets("Correlation Matrix").Cells.ClearFormats
DynamicRange("Asset Class").Copy iRows
DynamicRange("Asset Class").Copy
iColumns.PasteSpecial Transpose:=True
For i = 1 To iCount
For j = 1 To iCount
jpmRow = wsJPM.Cells.Find(StartTable.Offset(i, 0), SearchOrder:=xlColumns, LookAt:=xlWhole).Row
StartTable.Offset(i, j).Value = Application.WorksheetFunction.HLookup(StartTable.Offset(0, j), Sheets("JPM").Range("B1:BZ100"), jpmRow, False)
Next j
Next i
End Sub

Related

Populating multiple cells in row from a reference table, depending on single cell value

I am attempting to populate columns D-J of table1, with the values in table2, columns B-H. The values should be based upon the value of column C in table1.
I have the code below, but I believe that is copying the tables as is and not doing a check of the value in column C.
Images:
Sub wps()
Dim rng As Range
Dim strTable As String
Dim strAddress As String
Dim i As Long
With Worksheets("Procedures")
For i = 1 To .ListObjects.Count
strTable = .ListObjects(i).Name
Set rng = .ListObjects(strTable).Range
strAddress = rng.Cells(2, 3).Address
rng.Copy Destination:=Worksheets("Base Data").Range(strAddress)
With Worksheets("Base Data")
.ListObjects(i).Name = "quals"
End With
Next i
End With
End Sub
It looks like a destination.value=source.value situation, using a single Match(). You could wrap this in a loop on your destWS.
Maybe something like (mock-up, untested):
For i = 2 to lastRowDest
dim sourceWS as worksheet
set sourceWS = sheets(1)
dim destWS as worksheet
set destWS = sheets(2)
destinationSearchTerm = destWS.Cells(i,"C").Value
dim sourceRow as long
sourceRow = Application.Match(destinationSearchTerm, sourceWS.Columns("A"), 0)
destWS.Range(destWS.Cells(i,"D"), destWS.Cells(i,"J") = sourceWS.Range(sourceWS.Cells(sourceRow,"B"),sourceWS.Cells(sourceRow,"H")
Next i

VBA - create a Dictionary from multiple worksheets and ranges

I'm creating a dictionary from multiple worksheets and ranges.
My code is working, but is very unpleasant to look at.
There should be something fundamental missing in my knowledge, which is not surprise, as this is my first project in VBA.
How to achieve this in a single loop?
Any help is highly appreciated.
' Get the range of all the adjacent data using CurrentRegion
Dim rg1 As Range, rg2 As Range, rg3 As Range, rg4 As Range, rg5 As Range, rg6 As Range, rg7 As Range
Set rg1 = sheet1.Range("A1").CurrentRegion
Set rg2 = sheet2.Range("A1").CurrentRegion
Set rg3 = sheet3.Range("A1").CurrentRegion
Set rg4 = sheet4.Range("A1").CurrentRegion
Set rg5 = sheet5.Range("A1").CurrentRegion
Set rg6 = sheet6.Range("A1").CurrentRegion
Set rg7 = sheet7.Range("A1").CurrentRegion
Dim oID As clsItem, i As Long, j As Long, Id As Long
'read through the data
For i = 3 To rg1.rows.count
Id = rg1.Cells(i, 1).value
' Create a new clsDetector object
Set oID = New clsItem
' Add the new clsDetector object to the dictionary
dictName.add Id, oID
' Set the values
oID.ItemName = rg1.Cells(i, 70).value
Next i
'
'
'Same loops for rg2, rg3, rg4, rh5, rg6 and rg7
'
'
Since the sheets goes from 1 to 7 you can loop through them like this.
Sub LoadRangesIntoDict()
Dim i As Integer
Dim s As Integer
Dim ws As Worksheet
Dim rng As Range
Dim oID As clsItem, i As Long, j As Long, Id As Long
' Loop through each sheet
For s = 1 To 7
Set ws = Sheets("Sheet" & s)
Set rng = ws.Range("A1").CurrentRegion
'read through the data
For i = 3 To rng.Rows.Count
Id = rng.Cells(i, 1).Value
' Create a new clsDetector object
Set oID = New clsItem
' Add the new clsDetector object to the dictionary
dictName.Add Id, oID
' Set the values
oID.ItemName = rng.Cells(i, 70).Value
Next i
Next s
End Sub

Create buttons for work book from instruction sheet on the workbook

Sorry That I posted my whole code for better visual. I created getcol function to give it the string( column name ) and it returns the range of that column
Public Function getColRange(colName As String) As String
'create variables that will be used in this function
Dim first As String
Dim last As String
Dim col As String
Dim first_row As Integer
Dim first_str As String
Dim last_col As String
Dim last_row As Integer
Dim last_str As String
'loop to check if colname is equal in range between columns A and X, easy to change below
For Each i In Range("A1:X1")
If i = colName Then
'catches column, first and last rows
col = Split(i.Address(1, 0), "$")(0)
last_row = Range("A2").End(xlDown).Row
first_row = 2
'make first and last addresses as strings
first_str = "" & col & first_row
last_str = "" & first_col & last_row
'function ouput in the next line is a combination of above two strings
getColRange = "" & first_str & ":" & col & last_str
End If
Next
End Function
Option Explicit
Sub proper_text()
Dim name_rng As Range
Dim name_cell As Range
Dim name_selection As String
Dim city_rng As Range
Dim city_cell As Range
Dim city_selection As String
Dim col_name As String
Dim trim_name_row As Long
Dim trim_name_rng As Range
Dim trim_name_cell As Range
Dim col_city As String
Dim trim_city_row As Long
Dim trim_city_rng As Range
Dim trim_city_cell As Range
With Credentialing_Work_History
' First Part
name_selection = getColRange("Company_Name")
Set name_rng = Range(name_selection)
For Each name_cell In name_rng
name_cell.Value = WorksheetFunction.Proper(name_cell.Value)
Next
city_selection = getColRange("Company_City")
Set city_rng = Range(city_selection)
For Each city_cell In city_rng
city_cell.Value = WorksheetFunction.Proper(city_cell.Value)
Next
'Second Part
col_name = getColRange("Company_Name")
' To 'Find the last used cell in Col A
trim_name_row = Range(col_name).End(xlDown).Row
'Declare the range used by having the coordinates of rows and column till the last cell used.
Set trim_name_rng = Range(Cells(2, 9), Cells(trim_name_row, 9))
' Loop through the range and remove any trailing space
For Each trim_name_cell In trim_name_rng
trim_name_cell = RTrim(trim_name_cell)
'Go to the next Cell
Next trim_name_cell
col_city = getColRange("Company_Name")
trim_city_row = Range(col_city).End(xlDown).Row
Set trim_city_rng = Range(Cells(2, 10), Cells(trim_city_row, 10))
For Each trim_city_cell In trim_city_rng
trim_city_cell = RTrim(trim_city_cell)
Next trim_city_cell
End With
End Sub
Referring to the Same Worksheet
Always use Option Explicit. If you would have used it, you would have noticed that the variables city_selection and city_cell, and i are not declared.
When having a 'ton' of variables, keep them close to the 'action' to make the code more readable (see in Quick Fix). Use shorter variable names, always preferably (but not necessarily) descriptive.
When using the With statement, you have to use the period (dot, .) in front of Worksheets, Range, Cells, Columns, Rows...etc., e.g.:
With Credentialing_Work_History
Set name_rng = .Range(name_selection)
End With
In this example, you have made sure that the range is in the worksheet Credentialing_Work_History.
You don't have to loop through the cells of the range, you can use Proper and Trim on a range (if you will allow Trim instead of RTrim).
You have to qualify your ranges i.e. make sure they refer to the correct worksheet. See this also in the corrections of the function (added ws parameter).
Note that the function would be more useful if it would return a range instead of a range address so you could use e.g. Set name_rng = getColRange(Credentialing_Work_History, "Company_Name"). That could be one of your next tasks.
The Code
Option Explicit
Sub proper_text()
' Name
Dim name_selection As String
Dim name_rng As Range
name_selection = getColRange(Credentialing_Work_History, "Company_Name")
If name_selection <> "" Then
Set name_rng = Credentialing_Work_History.Range(name_selection)
name_rng.Value = Application.Trim(Application.Proper(name_rng.Value))
End If
' City
Dim city_rng As Range
Dim city_selection As String
city_selection = getColRange(Credentialing_Work_History, "Company_City")
If name_selection <> "" Then
Set city_rng = Credentialing_Work_History.Range(city_selection)
city_rng.Value = Application.Trim(Application.Proper(city_rng.Value))
End If
End Sub
Function getColRange(ws As Worksheet, colName As String) As String
'create variables that will be used in this function
Dim first As String
Dim last As String
Dim col As String
Dim first_col As String
Dim first_row As Long
Dim first_str As String
Dim last_col As String
Dim last_row As Long
Dim last_str As String
Dim rg As Range
'loop to check if colname is equal in range between columns A and X, easy to change below
For Each rg In ws.Range("A1:X1")
If rg = colName Then
'catches column, first and last rows
col = Split(rg.Address(1, 0), "$")(0)
last_row = ws.Range("A2").End(xlDown).Row
first_row = 2
'make first and last addresses as strings
first_str = "" & col & first_row
last_str = "" & first_col & last_row
'function ouput in the next line is a combination of above two strings
getColRange = "" & first_str & ":" & col & last_str
End If
Next rg
End Function
Sub proper_text_QuickFix()
Dim ws As Worksheet: Set ws = Credentialing_Work_History
' Name
Dim name_selection As String
Dim name_rng As Range
Dim name_cell As Range
name_selection = getColRange(ws, "Company_Name")
Set name_rng = ws.Range(name_selection)
Debug.Print name_rng.Address
For Each name_cell In name_rng
name_cell.Value = WorksheetFunction.Proper(name_cell.Value)
Next
' City
Dim city_name_selection As String
Dim city_rng As Range
Dim city_name_cell As Range
city_name_selection = getColRange(ws, "Company_City")
Set city_rng = ws.Range(city_name_selection)
Debug.Print city_rng.Address
For Each city_name_cell In city_rng
city_name_cell.Value = WorksheetFunction.Proper(city_name_cell.Value)
Next
' Trim Name
Dim col_name As String
Dim trim_name_row As Integer
Dim trim_name_rng As Range
Dim trim_name_cell As Range
col_name = getColRange(ws, "Company_Name")
trim_name_row = ws.Range(col_name).End(xlDown).Row
Set trim_name_rng = ws.Range(ws.Cells(2, 9), ws.Cells(trim_name_row, 9))
Debug.Print name_rng.Address
For Each trim_name_cell In trim_name_rng
trim_name_cell = RTrim(trim_name_cell)
Next trim_name_cell
' Trim City
Dim col_city As String
Dim trim_city_row As Integer
Dim trim_city_rng As Range
Dim trim_city_cell As Range
col_city = getColRange(ws, "Company_City")
trim_city_row = ws.Range(col_city).End(xlDown).Row
Set trim_city_rng = ws.Range(ws.Cells(2, 10), ws.Cells(trim_city_row, 10))
Debug.Print trim_city_rng.Address
For Each trim_city_cell In trim_city_rng
trim_city_cell = RTrim(trim_city_cell)
Next trim_city_cell
End Sub

Unable to populate unique values in third sheet comparing the values of the second sheet to the first one

I've got three sheets - main,specimen and output in an excel workbook. The sheet main and speciment contain some information. Some of the information in two sheets are identical but few of them are not. My intention is to paste those information in output which are available in speciment but not in main.
I've tried like [currently it fills in lots of cells producing duplicates]:
Sub getData()
Dim cel As Range, celOne As Range, celTwo As Range
Dim ws As Worksheet: Set ws = ThisWorkbook.Worksheets("main")
Dim ws1 As Worksheet: Set ws1 = ThisWorkbook.Worksheets("specimen")
Dim ws2 As Worksheet: Set ws2 = ThisWorkbook.Worksheets("output")
For Each cel In ws.Range("A2:A" & ws.Cells(Rows.Count, 1).End(xlUp).row)
For Each celOne In ws1.Range("A2:A" & ws1.Cells(Rows.Count, 1).End(xlUp).row)
If cel(1, 1) <> celOne(1, 1) Then ws2.Range("A" & Rows.Count).End(xlUp).Offset(1, 0).value = celOne(1, 1)
Next celOne
Next cel
End Sub
main contains:
UNIQUE ID FIRST NAME LAST NAME
A0000477 RICHARD NOEL AARONS
A0001032 DON WILLIAM ABBOTT
A0290191 REINHARDT WESTER CARLSON
A0290284 RICHARD WARREN CARLSON
A0002029 RAYMOND MAX ABEL
A0002864 DARRYL SCOTT ABLING
A0003916 GEORGES YOUSSEF ACCAOUI
specimen contains:
UNIQUE ID FIRST NAME LAST NAME
A0288761 ROBERT HOWARD CARLISLE
A0290284 RICHARD WARREN CARLSON
A0290688 THOMAS A CARLSTROM
A0002029 RAYMOND MAX ABEL
A0002864 DARRYL SCOTT ABLING
output should contain [EXPECTED]:
UNIQUE ID FIRST NAME LAST NAME
A0288761 ROBERT HOWARD CARLISLE
A0290688 THOMAS A CARLSTROM
How can I achieve that?
If you have the latest version of Excel, with the FILTER function and dynamic arrays, you can do this with an Excel formula.
I changed your Main and Specimen data into tables.
On the Output worksheet you can then enter this formula into a single cell:
=FILTER(specTbl,ISNA(MATCH(specTbl[UNIQUE ID],mnTbl[UNIQUE ID],0)))
The remaining fields will autopopulate with the results.
For a VBA solution, I like to use Dictionaries, and VBA arrays for speed.
'set reference to microsoft scripting runtime
' or use late-binding
Option Explicit
Sub findMissing()
Dim wsMain As Worksheet, wsSpec As Worksheet, wsOut As Worksheet
Dim dN As Dictionary, dM As Dictionary
Dim vMain As Variant, vSpec As Variant, vOut As Variant
Dim I As Long, v As Variant
With ThisWorkbook
Set wsMain = .Worksheets("Main")
Set wsSpec = .Worksheets("Specimen")
Set wsOut = .Worksheets("Output")
End With
'Read data into vba arrays for processing speed
With wsMain
vMain = .Range(.Cells(1, 1), .Cells(.Rows.Count, 1).End(xlUp)).Resize(columnsize:=3)
End With
With wsSpec
vSpec = .Range(.Cells(1, 1), .Cells(.Rows.Count, 1).End(xlUp)).Resize(columnsize:=3)
End With
'add ID to names dictionary
Set dN = New Dictionary
For I = 2 To UBound(vMain, 1)
dN.Add Key:=vMain(I, 1), Item:=I
Next I
'add missing ID's to missing dictionary
Set dM = New Dictionary
For I = 2 To UBound(vSpec, 1)
If Not dN.Exists(vSpec(I, 1)) Then
dM.Add Key:=vSpec(I, 1), Item:=WorksheetFunction.Index(vSpec, I, 0)
End If
Next I
'write results to output array
ReDim vOut(0 To dM.Count, 1 To 3)
vOut(0, 1) = "UNIQUE ID"
vOut(0, 2) = "FIRST NAME"
vOut(0, 3) = "LAST NAME"
I = 0
For Each v In dM.Keys
I = I + 1
vOut(I, 1) = dM(v)(1)
vOut(I, 2) = dM(v)(2)
vOut(I, 3) = dM(v)(3)
Next v
Dim R As Range
With wsOut
Set R = .Cells(1, 1)
Set R = R.Resize(UBound(vOut, 1) + 1, UBound(vOut, 2))
With R
.EntireColumn.Clear
.Value = vOut
.Style = "Output"
.EntireColumn.AutoFit
End With
End With
End Sub
Both show the same result (except the formula solution does not bring over the column headers; but you can do that with a formula =mnTbl[#Headers] in the cell above the original formula above).
Another option is to join the values of each row in each range and store them in arrays.
Then compare arrays and output the unique values.
In this case, your uniques come from evaluating the whole row, and not just the Unique ID.
Please read code's comments and adjust it to fit your needs.
Public Sub OutputUniqueValues()
Dim mainSheet As Worksheet
Dim specimenSheet As Worksheet
Dim outputSheet As Worksheet
Dim mainRange As Range
Dim specimenRange As Range
Dim mainArray As Variant
Dim specimenArray As Variant
Dim mainFirstRow As Long
Dim specimenFirstRow As Long
Dim outputCounter As Long
Set mainSheet = ThisWorkbook.Worksheets("main")
Set specimenSheet = ThisWorkbook.Worksheets("specimen")
Set outputSheet = ThisWorkbook.Worksheets("output")
' Row at which the output range will be printed (not including headers)
outputCounter = 2
' Process main data ------------------------------------
' Row at which the range to be evaluated begins
mainFirstRow = 2
' Turn range rows into array items
mainArray = ProcessRangeData(mainSheet, mainFirstRow)
' Process specimen data ------------------------------------
' Row at which the range to be evaluated begins
specimenFirstRow = 2
' Turn range rows into array items
specimenArray = ProcessRangeData(specimenSheet, specimenFirstRow)
' Look for unique values and output results in sheet
OutputUniquesFromArrays outputSheet, outputCounter, mainArray, specimenArray
End Sub
Private Function ProcessRangeData(ByVal dataSheet As Worksheet, ByVal firstRow As Long) As Variant
Dim dataRange As Range
Dim evalRowRange As Range
Dim lastRow As Long
Dim counter As Long
Dim dataArray As Variant
' Get last row in sheet (column 1 = column A)
lastRow = dataSheet.Cells(dataSheet.Rows.Count, 1).End(xlUp).Row
' Set the range of specimen sheet
Set dataRange = dataSheet.Range("A" & firstRow & ":C" & lastRow)
' Redimension the array to the number of rows in range
ReDim dataArray(dataRange.Rows.Count)
counter = 0
' Join each row values so it's easier to compare them later and add them to an array
For Each evalRowRange In dataRange.Rows
' Use Trim function if you want to omit the first and last characters if they are spaces
dataArray(counter) = Trim(evalRowRange.Cells(1).Value) & "|" & Trim(evalRowRange.Cells(2).Value) & "|" & Trim(evalRowRange.Cells(3).Value)
counter = counter + 1
Next evalRowRange
ProcessRangeData = dataArray
End Function
Private Sub OutputUniquesFromArrays(ByVal outputSheet As Worksheet, ByVal outputCounter As Long, ByVal mainArray As Variant, ByVal specimenArray As Variant)
Dim specimenFound As Boolean
Dim specimenCounter As Long
Dim mainCounter As Long
' Look for unique values ------------------------------------
For specimenCounter = 0 To UBound(specimenArray)
specimenFound = False
' Check if value in specimen array exists in main array
For mainCounter = 0 To UBound(mainArray)
If specimenArray(specimenCounter) = mainArray(mainCounter) Then specimenFound = True
Next mainCounter
If specimenFound = False Then
' Write values to output sheet
outputSheet.Range("A" & outputCounter).Value = Split(specimenArray(specimenCounter), "|")(0)
outputSheet.Range("B" & outputCounter).Value = Split(specimenArray(specimenCounter), "|")(1)
outputSheet.Range("C" & outputCounter).Value = Split(specimenArray(specimenCounter), "|")(2)
outputCounter = outputCounter + 1
End If
Next specimenCounter
End Sub

How do you create a loop using two dynamic variables?

I have multiple cells ("positions") that require particular interior colors and values.
Each of these cells is associated with its own corresponding cell in another worksheet.
At the moment I have about 35 of these positions, but I may have 150 in the future, so adding these manually would be tedious! This is the code I have at the moment:
Dim FirstSheet As Worksheet
Dim Secondsheet As Worksheet
Dim position1 As Range
Dim position2 As Range
Dim position3 As Range
Dim lnCol As Long
Set FirstSheet As ThisWorkbook.Worksheets("FirstSheet")
Set SecondSheet As ThisWorkbook.Worksheets("SecondSheet")
Set position1 = Firstsheet.Range("G11")
Set position2 = Firstsheet.Range("F11")
Set Position3 = Firstsheet.Range("E11")
lnCol = 'this is a column number which is found earlier in the sub.
position1.Interior.Color = SecondSheet.Cells(8, lnCol).Interior.Color
position2.Interior.Color = SecondSheet.Cells(9, lnCol).Interior.Color
position3.Interior.Color = SecondSheet.Cells(10, lnCol).Interior.Color
position1.Offset(2, 0).Value = SecondSheet.Cells(8, lnCol).Value
position2.Offset(2, 0).Value = SecondSheet.Cells(9, lnCol).Value
position3.Offset(2, 0).Value = SecondSheet.Cells(10, lnCol).Value
Ideally, I would like a loop that would use two arrays that change at the same time, but I have no idea how to make it work! This is an example of what I would like to see:
For Each PositionVar In Array(position1, position2, position3)
PositionVar.Interior.Color = dynamicvariable.Interior.Color
PositionVar.Offset(2,0).Value = dynamicvariable.Value
Next PositionVar
Any help would be greatly appreciated!
Why dont you use two loops stacked together to solve this? For example:
for each rng in Array(Range1, Range2, Range3)
for each position in rng
'Do whatever you like with this Range
next position
next rng
You could use:
Option Explicit
Sub test()
Dim i As Long, y As Long, LastColumn As Long, Counter As Long, lnCol As Long
Dim ws1 As Worksheet, ws2 As Worksheet
Counter = 8
lnCol = 3 'Change value
With ThisWorkbook
'Set the sheet with positions
Set ws1 = .Worksheets("Sheet1")
'Set the second sheet
Set ws2 = .Worksheets("Sheet2")
End With
With ws1
'Find the LastColumn of row 11
LastColumn = .Cells(11, .Columns.Count).End(xlToLeft).Column
'Loop from the last column until column 5th
For i = LastColumn To 5 Step -1
With .Cells(11, i)
.Interior.Color = ws2.Cells(Counter, lnCol).Interior.Color
.Offset(2, 0).Value = ws2.Cells(Counter, lnCol).Value
End With
Counter = Counter + 1
Next i
End With
End Sub
NOTE
The limitation of using Last column is that if there is no values in row 11 you should use a variable instead of last column referring to the total value of column you want
Managed to find an answer by using arrays and a control variable. You just need to ensure that the corresponding variables are in the same order!. Hope this helps others.
Dim PositionArray As Variant
Dim SecondSheetArray As Variant
Dim i As Variant
PositionArray = Array(position1, position2, position3)
SecondSheetArray = Array(SecondSheet1, SecondSheet2, SecondSheet3)
For i = 0 To UBound(PositionArray)
PositionArray(i).Interior.Color = OverviewArray(i).Interior.Color
PositionArray(i).Offset(2, 0).Value = OverviewArray(i).Value
Next i

Resources