Sub NBSPCODES()
Dim rgSteer As Range
Dim rg As Range
Dim sh As Worksheet
Dim cell As Range
Dim RC As Long
Dim LC As Long
Dim rgDest As Range
Dim MonthCol As Long
Dim i As Long
Dim c As Range
Dim cek As Boolean
'create the range of spcode as rgSteer variable
With Sheets("Config")
Set rgSteer = .Range("L4", .Range("L" & Rows.Count).End(xlUp))
End With
'loop to each sheets
For Each sh In Sheets
If sh.Name = "Config" Or sh.Name = "Summary" Then GoTo nxt 'skip the loop (too many end if so I reverse the if)
'get the column number where the header value is ENTRY_MONTH as MonthCol variable
'get the last column of the header as LC variable
MonthCol = sh.Rows(2).Find("ENTRY_MONTH").Column
LC = sh.Range("A2").End(xlToRight).Column
'loop to each cell in rgSteer
For Each cell In rgSteer
'check if the looped cell value (spcode from sheet Configure) is found in the looped sheet column 2
If Not sh.Columns(2).Find(cell.Value) Is Nothing Then
'if it is found, then set a range as c variable to find the value of
'spcode to be replaced (the looped cell.offset(0,1) value) is already in the looped sheet column 2 or not
Set c = sh.Columns(2).Find(cell.Offset(0, 1).Value, after:=sh.Range("B1"))
If Not c Is Nothing Then
'if found
'check if the entry_month from sheet Configure (looped cell.Offset(0,2) value
'is the same with the found cell (the c variable) row, MonthCol value - if same then have cek as false
If Cells(c.row, MonthCol).Value = cell.Offset(0, 2).Value Then cek = False
Else
'if not found have cek variable as true
cek = True
End If
End If
'the below code will be processed if it does find the spcode from sheet Configure in the looped sheet column 2
'but it doesn't find the spcode to be replaced and the entry_month from sheet Configure in the looped sheet
If cek = True Then
With sh.Columns(2)
.Replace cell.Value, True, xlWhole, , False, False, False
Set rg = .SpecialCells(xlConstants, xlLogical).Offset(0, -1)
RC = Application.CountA(rg)
.Replace True, cell.Value, xlWhole, , False, , False, False
End With
For i = 1 To LC - 1: Set rg = Union(rg, rg.Offset(0, 1)): Next i
Set rgDest = sh.Range("A" & Rows.Count).End(xlUp).Offset(1, 0)
Set rgDest = rgDest.Resize(RC, LC)
rg.Copy Destination:=rgDest
rgDest.Columns(2).Value = cell.Offset(0, 1).Value
rgDest.Columns(MonthCol).Value = cell.Offset(0, 2).Value
End If
Next
nxt:
Next sh
End Sub
FYI, if the value under "Existing" is not unique .... For example (based on your image of sheet config), you have 651 ... then this number is to be replaced with 661, entry month 4. if there is another 651 value under "Existing" and the replacing value is (for example) 123 - entry month 7, then the sub at the time the loop in rgSteer find the second 651, it will copy again those 651 range under SpCode, paste to rgDest and fill the rgDest column 2 replacement with 123. Which give you a result that now there are 2 similar data under the last row of the original data.... one with 661 SpCode entry month 4 and one with 123 SpCode entry month 7.
The code assumed that the SpCode data is not sorted. For example, under SpCode of the looped sheet, row 5 to 7 value is 651, row 100 value is 651, row 123 value is 651. That's why it use the union rather than set the rg from rg to rg.offset(0,LC-1).
Once again, it's not tested in my side.
Still, to be honest I'm not so sure if the sub above is "bullet proof", because maybe the data in the looped sheet is already contains something like this :
651 with entry_month 4
651 with entry_month 9
661 with entry_month 7
661 with entry_month 5
661 with entry_month 3
Say for example in sheet configure, the data is : 651 - 661 - 3
So when the sub run, in the looped sheet it find 651 ...
then it check if 661 is already in the looped sheet or not...
it find out that 661 is already there (the c variable is not nothing) ---> this will be the the first 661 found cell in the looped sheet with entry_month 7
then it check if the found (c.row, MonthCol) value is the same with entry month from sheet Configure (3 from the example) or not. Because 7 <> 3 then it won't flag cek = false, the "if" continue and flag cek as true continue the replace-copy-paste process. Resulting like this :
651 with entry_month 4
651 with entry_month 9
661 with entry_month 7
661 with entry_month 5
661 with entry_month 3
661 with entry_month 3 (addition data, changing 651 to 661 entry_month 4 to 3)
661 with entry_month 3 (addition data, changing 651 to 661 entry_month 9 to 3)
So if the data in the looped sheet like the example above and you don't want the result to be like that, then the sub is not "bullet proof".
The sub then need to be revised, to check the entry_month value of each row in column B of the looped sheet with 661 value by looping or find-next method. From the example above, so at the third iteration, it then find out that the third found cell contains 661 in column B of the looped sheet - its entry_month is 3 (the same with the one in sheet Configure), then it flag cek = false, no replace-copy-paste process.