I have two tables that have an identical column structure where the information passed from a different department is put into the first template.
I want to look at the SKU from Table 1 and pass back everything that matches on that row in Table 2 - whilst ignoring any SKU code that is not on Table 1.
Graphical illustration of problem
The code is part of a larger sub (variables are declared prior etc.) which uses a scripting dictionary and then goes through a For loop - but this is not efficient:
Set dlCD1 = CreateObject("Scripting.Dictionary")
Row = 1
On Error GoTo Error
For Each cCD1 In Sheets("TABLE 2 SHEET").Range("c1:c" & MaxLineMPS)
tmpCD1 = Trim(cCD1.Value)
If Len(tmpCD1) < 10 Then tmpCD1 = "0" & tmpCD1
If Len(tmpCD1) > 0 Then dlCD1(tmpCD1) = dlCD1(tmpCD1) + 1
Next cCD1
For Each kCD1 In dlCD1.keys
With Sheets("TABLE 1 SHEET").Range("a2:x" & MaxLineMatrice)
.AutoFilter Field:=3, Criteria1:=kCD1
End With
If Sheets("TABLE 1 SHEET").Range("A2:A" & MaxLineMatrice).SpecialCells(xlCellTypeVisible).Count > 1 Then
With Sheets("TABLE 1 SHEET").Range("d$3:x" & "$" & MaxLineMatrice).SpecialCells(xlCellTypeVisible)
.Value = Sheets("TABLE 2 SHEET").Range("$d" & "$" & Row & ":$x" & "$" & Row).Value
End With
Else: End If
Row = Row + 1
Debug.Print kCD1, dlCD1(kCD1)
Next kCD1
Worksheets("TABLE 1 SHEET").AutoFilterMode = False
dlCD1.RemoveAll
I have thousands of SKU codes and this takes time to loop through. I am told that by doing this outside of the sheet I can do the job faster.
Here's my whole code:
Sub Month_RiempiFuturo()
Dim MinLineMatrice As Integer, MaxLineMatrice As Integer, MinLineMPS As Integer, MaxLineMPS As Integer, row As Integer
Dim dlCD1 As Object, cCD1 As Range, kCD1, tmpCD1 As String, dlCD2 As Object, cCD2 As Range, kCD2, tmpCD2 As String
Dim StartTime As Double, SecondsElapsed As Double
Dim PT1 As PivotTable
Application.EnableEvents = False
Application.DisplayStatusBar = False
Application.ScreenUpdating = False
ActiveSheet.DisplayPageBreaks = False
Application.Calculation = xlCalculationManual
Worksheets("TABLE SHEET 1").AutoFilterMode = False
Worksheets("TABLE SHEET 2").AutoFilterMode = False
StartTime = Timer
MinLineMatrice = 3
MaxLineMatrice = Sheets("TABLE SHEET 1").Range("A" & Rows.Count).End(xlUp).Row
MinLineMPS = 1
MaxLineMPS = Sheets("TABLE SHEET 2").Range("C" & Rows.Count).End(xlUp).Row
LastLineFINITY = Sheets("FINITY CAPACITY PLANNED").Range("A" & Rows.Count).End(xlUp).Row
Set PT1 = Worksheets("shift").PivotTables("Tabella_pivot1")
Worksheets("TABLE SHEET 1").Range("d3:x" & MaxLineMatrice).ClearContents
Set dlCD1 = CreateObject("Scripting.Dictionary")
Row = 1
On Error GoTo Error
For Each cCD1 In Sheets("TABLE SHEET 2").Range("c1:c" & MaxLineMPS)
tmpCD1 = Trim(cCD1.Value)
If Len(tmpCD1) < 10 Then tmpCD1 = "0" & tmpCD1
If Len(tmpCD1) > 0 Then dlCD1(tmpCD1) = dlCD1(tmpCD1) + 1
Next cCD1
For Each kCD1 In dlCD1.keys
With Worksheets("TABLE SHEET 1").Range("a2:x" & MaxLineMatrice)
.AutoFilter Field:=3, Criteria1:=kCD1
End With
If Sheets("TABLE SHEET 1").Range("A2:A" & MaxLineMatrice).SpecialCells(xlCellTypeVisible).Count > 1 Then
With Sheets("TABLE SHEET 1").Range("d$3:x" & "$" & MaxLineMatrice).SpecialCells(xlCellTypeVisible)
.Value = Sheets("TABLE SHEET 2").Range("$d" & "$" & Row & ":$x" & "$" & Row).Value
End With
Else: End If
Row = Row + 1
Debug.Print kCD1, dlCD1(kCD1)
Next kCD1
Worksheets("TABLE SHEET 1").AutoFilterMode = False
dlCD1.RemoveAll
Set dlCD1 = CreateObject("Scripting.Dictionary")
For Each cCD1 In Sheets("Finity capacity planned").Range("a2:a" & LastLineFINITY)
tmpCD1 = Trim(cCD1.Value)
If Len(tmpCD1) > 0 Then dlCD1(tmpCD1) = dlCD1(tmpCD1) + 1
Next cCD1
Set dlCD2 = CreateObject("Scripting.Dictionary")
For Each cCD2 In Sheets("Finity capacity planned").Range("b2:b" & LastLineFINITY)
tmpCD2 = Trim(cCD2.Value)
If Len(tmpCD2) > 0 Then dlCD2(tmpCD2) = dlCD2(tmpCD2) + 1
Next cCD2
For Each kCD1 In dlCD1.keys
With Sheets("Finity capacity planned").Range("A1:Ak" & LastLineFINITY)
.AutoFilter Field:=1, Criteria1:=kCD1
.AutoFilter Field:=2, Criteria1:=Array( _
dlCD2.keys()(0), dlCD2.keys()(2), dlCD2.keys()(4), dlCD2.keys()(6), dlCD2.keys()(8), dlCD2.keys()(10)), Operator:=xlFilterValues
End With
With Sheets("Finity capacity planned").Range("A2:Ak" & LastLineFINITY).SpecialCells(xlCellTypeVisible)
.Interior.ColorIndex = 15
End With
With Sheets("Finity capacity planned").Range("A1:Ak" & LastLineFINITY)
.AutoFilter Field:=1, Criteria1:=kCD1
.AutoFilter Field:=2, Criteria1:=Array( _
dlCD2.keys()(1), dlCD2.keys()(3), dlCD2.keys()(5), dlCD2.keys()(7), dlCD2.keys()(9), dlCD2.keys()(11)), Operator:=xlFilterValues
End With
With Sheets("Finity capacity planned").Range("A2:Ak" & LastLineFINITY).SpecialCells(xlCellTypeVisible)
.Interior.ColorIndex = 19
End With
Debug.Print kCD1, dlCD1(kCD1)
Next kCD1
Worksheets("Finity capacity planned").AutoFilterMode = False
dlCD1.RemoveAll
dlCD2.RemoveAll
With PT1
.RefreshTable
End With
Application.EnableEvents = True
Application.DisplayStatusBar = True
Application.ScreenUpdating = True
ActiveSheet.DisplayPageBreaks = True
Application.Calculation = xlCalculationAutomatic
SecondsElapsed = Round(Timer - StartTime, 2)
MsgBox "This code including the time for user prompts to be acknowledged took " & SecondsElapsed & " Seconds", vbInformation, "McManus automation speed testing"
Exit Sub
Error:
Application.EnableEvents = True
Application.DisplayStatusBar = True
Application.ScreenUpdating = True
ActiveSheet.DisplayPageBreaks = True
Application.Calculation = xlCalculationAutomatic
MsgBox "Something went wrong"
End Sub
You can use Find function to find the row number you are looking for. Then using this row number, you can have the data from that row.
I didn't dig into your code too much, because it is a bit messy. So considering that:
Blank Lookup sheet name is "TABLE 1 SHEET",
Master Lookup sheet name is "TABLE 2 SHEET",
Results sheet name is "TABLE 3 SHEET",
then you can try the following:
Sub findmydata()
Dim ws1 As Worksheet, ws2 As Worksheet, ws3 As Worksheet
Dim i As Long, j As Long, foundrow As Long, lastrow1 As Long, lastrow2 As Long
Set ws1 = Sheets("TABLE 1 SHEET")
Set ws2 = Sheets("TABLE 2 SHEET")
Set ws3 = Sheets("TABLE 3 SHEET")
lastrow1 = ws1.Cells(ws1.Rows.Count, "A").End(xlUp).Row
lastrow2 = ws2.Cells(ws2.Rows.Count, "A").End(xlUp).Row
For i = 1 To lastrow1
On Error Resume Next
foundrow = ws2.Range("A1:A" & lastrow2).Find(ws1.Cells(i, 1).Value).Row
If Err.Number = 91 Then
ws3.Cells(i, 1) = ws1.Cells(i, 1)
Else
For j = 1 To 4
ws3.Cells(i, j) = ws2.Cells(foundrow, j)
Next j
End If
Next
End Sub
Related
I have an array loading column references from column C.
The user will enter the current month, e.g. March, then the array should load February column value "U" and January value "L", then the rest of my code will run.
How do I setup the array to stop after the value "L" is found?
Sub CopyData() 'with array
Dim wb1 As Workbook
Dim wkshtname As String
Dim colArray(1 To 5) As Variant
Dim i As Range, rng As Range
Dim lrow As Long, colcounter As Long, y As Long, retcol As Long, z As Long
Dim StartHere As String, x As String, col As String
Dim cell
Dim sht As Worksheet
Set wb1 = ThisWorkbook
wkshtname = "Retro-" & wb1.Sheets("Instructions").Range("B4").Value
StartHere = wb1.Sheets("Instructions").Range("B4")
lrow = wb1.Sheets("Member Prem.Pymts").Cells(Rows.Count, 1).End(xlUp).Row
If StartHere = "January" Then
MsgBox "No Retro Commissions to be posted", vbOKOnly
Exit Sub
End If
'delete sheet if it exists
For Each sht In wb1.Worksheets
If sht.Name = wkshtname Then
Application.DisplayAlerts = False
wb1.Sheets(wkshtname).Delete
Application.DisplayAlerts = True
End If
Next sht
With wb1
.Sheets.Add(After:=.Sheets(.Sheets.Count)).Name = wkshtname
With .Sheets(wkshtname)
.Cells(1).Resize(1, 8).Value = Array("ID", "Last Name", "First Name", "Premium", "Commission Amt", "month for", "agent", "sheet row")
End With
'returns Paid in Month 30-150 day columns
col = Application.WorksheetFunction.Match(StartHere, wb1.Sheets("Lookups").Range("$A$1:$A$13"), 0)
z = 1
For retcol = 1 To 5
colArray(retcol) = wb1.Sheets("Lookups").Cells(col - z, 3)
z = z + 1
Next retcol
With .Sheets("Member Prem.Pymts") 'reference target sheet
y = 1
For colcounter = LBound(colArray, 1) To UBound(colArray, 1)
x = 4 'starting row number data is found on
For Each i In .Range(colArray(colcounter) & "4:" & colArray(colcounter) & lrow) 'loop through Member Prem.Payments column cells
If i.Value = StartHere Then
wb1.Sheets(wkshtname).Cells(Rows.Count, "A").End(xlUp).Offset(1, 0) = .Range("A" & x)
wb1.Sheets(wkshtname).Cells(Rows.Count, "B").End(xlUp).Offset(1, 0) = .Range("B" & x)
wb1.Sheets(wkshtname).Cells(Rows.Count, "C").End(xlUp).Offset(1, 0) = .Range("C" & x)
wb1.Sheets(wkshtname).Cells(Rows.Count, "D").End(xlUp).Offset(1, 0) = .Range("BR" & x)
wb1.Sheets(wkshtname).Cells(Rows.Count, "E").End(xlUp).Offset(1, 0) = wb1.Sheets("Commissions to Pay").Range(wb1.Sheets("Lookups").Cells(col - y, 4) & x)
wb1.Sheets(wkshtname).Cells(Rows.Count, "F").End(xlUp).Offset(1, 0) = .Range(colArray(colcounter) & "2")
wb1.Sheets(wkshtname).Cells(Rows.Count, "G").End(xlUp).Offset(1, 0) = .Range("DR" & x)
wb1.Sheets(wkshtname).Cells(Rows.Count, "H").End(xlUp).Offset(1, 0) = x
End If
x = x + 1
Next
y = y + 1
Next colcounter
End With
End Sub
This is what is stored in the array when I run the code.
I'm trying to load the array and then the array needs to stop loading after the value is "L".
The array will never have more than 5 elements.
EDIT: Stripped down to the core problem for testing
Sub CopyData()
Dim rngMonths As Range, c As Range, wb1
Dim colArray(), StartHere, col, retcol As Long
Set wb1 = ActiveWorkbook
Set rngMonths = wb1.Sheets("Lookups").Range("A2:A13") 'month lookup range
StartHere = "March" 'for testing
col = Application.Match(StartHere, rngMonths, 0)
If Not IsError(col) Then
Set c = rngMonths.Cells(col)
ReDim colArray(1 To 5) '<<<<<<<<<<<<
For retcol = 1 To 5
colArray(retcol) = c.Offset(0, 2).Value 'col C value
If colArray(retcol) = "L" Then Exit For 'exit if Col C="L"
Set c = c.Offset(-1) 'next cell up
Next retcol
ReDim Preserve colArray(1 To retcol) '<<<<<resize array
Debug.Print Join(colArray, ",")
Else
MsgBox "No month match!", vbExclamation
Exit Sub
End If
End Sub
I have the following data:
The problem I'm trying to solve is that sometimes the Column H (Place) and Column I (Country) switch places (ex: lines 9,10,11). What I would like to do is:
First check if the year is within the last 3 years (I don't need to fix data older than that).
Load a range of values into an array.
Compare if the values in Column H are in the array.
If not, then switch values between columns. I did that by simply copying and pasting.
I'm stuck at this point. Sorry if it's ugly, first time dealing with arrays
The list I load into the array is in one workbook and the data is on another workbook. Does it work or they need to be on the same workbook?
Sub check_data()
Sheets("list").Activate 'this workbook
Dim DirArray As Variant
DirArray = Range("a1:a18").Value 'loads the range into an array
mypath = "//mynetworkpath/" 'sets the path
file = Dir(mypath & "filename.csv") 'indicates name of the file
Workbooks.Open (mypath & file) 'opens the file
Dim lastrow As Long
lastrow = Cells(Rows.Count, 2).End(xlUp).Row 'sorting by year
Range("A2:K" & lastrow).Sort key1:=Range("B2:B" & lastrow), _
order1:=xlDescending, Header:=xlNo
end_year = Format(Now, "yyyy") - 3 ' last 3 years
x = 2 'starts from second row
Do Until Cells(x, 2) = end_year 'cells(row,col)
For y = LBound(DirArray) To UBound(DirArray)
If Sheet1.Cells(x, 8) = DirArray(y) Then
Range("H" & x).Select
Selection.Copy
Range("M" & x).Select
ActiveSheet.Paste
Range("I" & x).Select
Application.CutCopyMode = False
Selection.Copy
Range("H" & x).Select
ActiveSheet.Paste
Range("M" & x).Select
Application.CutCopyMode = False
Selection.Copy
Range("I" & x).Select
ActiveSheet.Paste
Exit For
End If
Next
x = x + 1
Loop
ActiveWorkbook.Save
ActiveWorkbook.Close True
End Sub
Any guidance is helpful!
Thanks
You can leave the list on the worksheet and use match to check the values:
Sub check_data()
Const FPATH As String = "\\mynetworkpath\" 'use Const for fixed values
Dim rngVals As Range, wb As Workbook, lastrow As Long
Dim ws As Worksheet, tmp, file
Set rngVals = ThisWorkbook.Sheets("list").Range("a1:a18") 'your lookup list
file = Dir(FPATH & "filename.csv")
If Len(file) > 0 Then
Set wb = Workbooks.Open(FPATH & file) 'opens the file
Set ws = wb.Worksheets(1)
lastrow = ws.Cells(ws.Rows.Count, 2).End(xlUp).Row
ws.Range("A2:K" & lastrow).Sort key1:=ws.Range("B2:B" & lastrow), _
order1:=xlDescending, Header:=xlNo
end_year = Year(Now) - 3 ' last 3 years
x = 2 'starts from second row
Do Until Cells(x, 2) = end_year 'cells(row,col)
tmp = ws.Cells(x, 8).Value
'use Match to check the value against the list
m = Application.Match(tmp, rngVals, 0)
If Not IsError(m) Then
'got a match, so swap the values from H and I
ws.Cells(x, 8).Value = ws.Cells(x, 9).Value
ws.Cells(x, 9).Value = tmp
End If
x = x + 1
Loop
wb.Save
wb.Close
End If 'got the file
End Sub
I use the following code to cycle through rows in a spreadsheet, and save unique items into a 2D array. I know the number of unique items, and the arrLen variable holds that number.
If a row with the same prNr (unique number identifying a set of items) as a previous row is found, a check is done to see which has the lower priority. If it has a lower priority, it should replace the item in the 2D array.
My problem is that the prArrCount variable increments past the number of unique prNr entries in my spreadsheet. According to me it should not do this, but can someone help me find out why?
'Cycle through PRs, store values in 2D array
'Create 2D array
Dim prData() As String
ReDim prData(arrLen, 6)
'Find the last row in the spreadsheet to iterate through all entries
Dim lastRow As Integer
lastRow = ActiveSheet.Cells(Rows.Count, 1).End(xlUp).Row
'Create data variables
Dim i, prArrCount As Integer
Dim prNr As String
Dim description As String
Dim Value As Double
Dim srmRFQ As String
Dim requisitionDate As Date
Dim deliveryDate As Date
Dim delivery As Integer
Dim delta As Integer
Dim priority As Integer
Dim newPR As Integer
Dim initFlag As Integer
'Set initial values
initFlag = 1
prArrCount = 0
newPR = 1
'Start for loop to iterate through all entries in the spreadsheet
For i = 2 To lastRow
'Read in the PR line values
prNr = Range("B" & i).Value
description = Range("G" & i).Value
srmRFQ = Range("E" & i).Value
requisitionDate = DateValue(Range("O" & i).Value)
Value = Range("R" & i).Value
If Not Left(Range("P" & i).Value, 1) = "0" Then
deliveryDate = DateValue(Range("P" & i).Value)
Else
deliveryDate = 0
End If
If Range("S" & i).Value = "" Then
delivery = 0
Else
delivery = Range("S" & i).Value
End If
If Range("Z" & i).Value = "Invalid" Then
priority = 9999
delta = 0
Else
priority = Range("Z" & i).Value
delta = Range("Y" & i).Value
End If
'Check if it is the first iteration of the loop
If initFlag = 1 Then
initFlag = 0
ElseIf Not prNr = prData(prArrCount, 0) Then
prArrCount = prArrCount + 1
newPR = 1
End If
'Check if values should be written into 2D PR array
If newPR = 1 Then
prData(prArrCount, 0) = prNr '(0) PR Number
prData(prArrCount, 1) = description '(1) Description
prData(prArrCount, 2) = priority '(2) Days left to order
prData(prArrCount, 3) = deliveryDate '(3) Delivery date
prData(prArrCount, 4) = delivery '(4) Lead time
newPR = 0
ElseIf priority < prData(prArrCount, 2) Then
prData(prArrCount, 0) = prNr '(0) PR Number
prData(prArrCount, 1) = description '(1) Description
prData(prArrCount, 2) = priority '(2) Days left to order
prData(prArrCount, 3) = deliveryDate '(3) Delivery date
prData(prArrCount, 4) = delivery '(4) Lead time
End If
Next i
I like to use scripting dictionaries to manage duplicates. The below creates a scripting dictionary and adds a 5 row 1D array as the value for any new prNr. If the prNr exists, it checks if the priority of the prior version is greater, and if so, stores the new array as the value of that key in the dictionary.
'Cycle through PRs, store values in 2D array
'Create 2D array
Dim prData() As String
ReDim prData(arrLen, 6)
'Find the last row in the spreadsheet to iterate through all entries
Dim lastRow As Integer
lastRow = ActiveSheet.Cells(Rows.Count, 1).End(xlUp).Row
'Create data variables
Dim i as Integer, prArrCount As Integer
Dim prNr As String
Dim description As String
Dim Value As Double
Dim srmRFQ As String
Dim requisitionDate As Date
Dim deliveryDate As Date
Dim delivery As Integer
Dim delta As Integer
Dim priority As Integer
Dim newPR As Integer
Dim initFlag As Integer
Dim dict As New Scripting.Dictionary 'Note you need the Microsoft Scripting Runtime Library
Dim x(4) as Variant
Dim Key as Variant
Dim Anchor as Range
'Set initial values
initFlag = 1
prArrCount = 0
newPR = 1
'Start for loop to iterate through all entries in the spreadsheet
For i = 2 To lastRow
'Read in the PR line values
prNr = Range("B" & i).Value
description = Range("G" & i).Value
srmRFQ = Range("E" & i).Value
requisitionDate = DateValue(Range("O" & i).Value)
Value = Range("R" & i).Value
If Not Left(Range("P" & i).Value, 1) = "0" Then
deliveryDate = DateValue(Range("P" & i).Value)
Else
deliveryDate = 0
End If
If Range("S" & i).Value = "" Then
delivery = 0
Else
delivery = Range("S" & i).Value
End If
If Range("Z" & i).Value = "Invalid" Then
priority = 9999
delta = 0
Else
priority = Range("Z" & i).Value
delta = Range("Y" & i).Value
End If
x(0) = prNr
x(1) = description
x(2) = priority
x(3) = deliveryDate
x(4) = delivery
If Not dict.Exists(prNr) Then
dict.Add prNr, x
Else
If priority < dict(prNr)(2) Then
dict(prNr) = x
End If
End If
Next i
With Workbooks("Workbook Name").Sheets("Sheet Name") 'Change references to match what you need
For Each Key in dict.Keys
Set Anchor = .Range("A" & .Rows.Count).End(xlUp).Offset(1,0)
For i = Lbound(dict(key),1) to Ubound(dict(key),1)
Anchor.Offset(0,i) = dict(key)(i)
Next i
Next key
End With
Please see my edit. This will output each key in a new line, and each element in the array related to the key starting in column A. You just need to update the workbook, worksheet and range to match your needs.
After a lot of googling and trying I am asking you for help regarding the following Problem.
Worksheet 1 (Database) has the ID's and a lot of Information in Column D
Worksheet 2 (Skills) has the ID's in Row 1 and all respective skills in the rows below the column for each ID.
Worksheet 3 (Output) is needed to populate Listboxes and Graphs and can be considered empty
For Illustration purposes: http://imgur.com/a/Nt88C
Via comboboxes, the skill the user is looking for is selected. This Skill then needs to be matched against the skills of each ID on Worksheet 2.
If a match is found, the respective ID shall be found on Worksheet 1 and certain Information from there copied to Worksheet 3.
My take on this has been to find each ID in Worksheet 1, match it with all ID's on Worksheet 2 and look through the respective rows for a match. However, every more efficient way is welcome.
Here my code:
The comboboxes
Dim wb As Workbook
Set wb = ActiveWorkbook
Dim ws1, ws2, ws3, ws4 As Worksheet
Set ws1 = wb.Worksheets("Meta DB")
Set ws2 = wb.Worksheets("Criteria")
Set ws3 = wb.Worksheets("Supplier Criteria TreeView")
Set ws4 = wb.Worksheets("Supplier Skills")
'1. - - get all Suppliers for the selected Input
'Redefine for clarity
Dim strFind As String
'1.0. - - Clear previously used ranges
ws3.Range("A2:L28").Clear
ws3.Range("A30:L100").Clear
ws3.Range("V2:V20").Clear
'1.1. - - Get value to search for and range to go through (depending on combobox selections)
If Me.comboProduct.ListIndex = -1 And Me.comboSubGroup.ListIndex = -1 And Me.comboCG.ListIndex <> -1 Then
strFind = Me.comboCG.value
ElseIf Me.comboProduct.ListIndex = -1 And Me.comboSubGroup.ListIndex <> -1 And Me.comboCG.ListIndex <> -1 Then
strFind = Me.comboSubGroup.value
ElseIf Me.comboProduct.ListIndex <> -1 And Me.comboSubGroup.ListIndex <> -1 And Me.comboCG.ListIndex <> -1 Then
strFind = Me.comboProduct.value
End If
Try 1:
Dim rng1, rng2 As Range
Dim lRow, j, k As Long
Dim IDrow As String
'Paste starting at row 2 or 30 in ws3, respectively (Active / Inactive)
j = 2
k = 30
For Each rng1 In ws1.Range("D4:D500")
If Rng <> "" Then
For Each rng2 In ws4.Range("A1:ZZ1")
If rng2 <> "" Then
If rng1.value = rng2.value Then
For lRow = 2 To ws4.UsedRange.Rows.Count
IDrow = ws4.Cells(lRow, rng2).value
If InStr(1, IDrow, strFind, vbTextCompare) > 0 Then
'Check for active Supplier in current Database-row
If ws1.Range("E" & rng1) = "Yes" Then
'Copy row of Database to row j of ws3 then increment j
ws1.Range("B" & rng1 & ":" & "E" & rng1).Copy Destination:=ws3.Range("B" & j & ":" & "E" & j) 'Copy Name, Potential Supplier, ID, Active
j = j + 1
'ElseIf inactive Supplier, post further down from 30 onwards. Second listbox populates from there
ElseIf ws1.Range("E" & rng1) = "No" Then
ws1.Range("B" & rng1 & ":" & "E" & rng1).Copy Destination:=ws3.Range("B" & k & ":" & "E" & k) 'Copy Name, Potential Supplier, ID, Active
k = k + 1
Else
Exit Sub
End If
End If
Next lRow
End If
End If
Next rng2
End If
Next rng1
Try 2:
Dim IDAr, MyAr, TempAr As Variant
Dim lRow, lastRow, entryrow, LCol, e As Long
Dim ColumnLetter As String
entryrow = ws3.Range("B" & Rows.Count).End(xlUp).row + 1
ws1LRow = ws1.Range("D" & ws1.Rows.Count).End(xlUp).row
IDAr = ws1.Range("D4:D" & lRow).value
Set f = ws4.Range("A1:ZZ1").Find(What:=IDAr, LookIn:=xlValues, Lookat:=xlWhole, MatchCase:=False)
ColumnLetter = Split(f.Address, "$")(1)
lastRow = ws4.Range(ColumnLetter & "2:" & ColumnLetter & "50").End(xlUp).row
MyAr = ws4.Range(ColumnLetter & "1:" & ColumnLetter & lastRow).value
With ws3
'If IsArray(MyAr) Then
For i = LBound(MyAr) To UBound(MyAr)
TempAr = Split(MyAr(i, 1), "\")
For e = 0 To 2
TempAr(e) = ValueToCompare
If InStr(1, ValueToCompare, strFind, vbTextCompare) > 0 Then
ws3.Range("B" & entryrow).value = "Test if it works"
'.
'.
'.
End If
Next e
Next i
Thank you all in advance for any tips!
Sub CodeForLazyPoster()
Dim rIDs As Excel.Range
Dim ID As Excel.Range
Dim lFoundRow As Long
Set rIDs = Worksheets("Sheet1").Range("a1:a10")
For Each ID In rIDs
lFoundRow = FindRow(ID)
If lFoundRow > 0 Then
If FindSkill("Maths", Worksheets("Sheet2").Range("B" & lFoundRow)) Then
' Copy here
End If
End If
Next ID
End Sub
Function FindRow(strFind) As Long
FindRow = 0
On Error Resume Next
FindRow = Application.WorksheetFunction.Match( _
strFind, Worksheets("Sheet2").Range("a1:a10"), False)
End Function
Function FindSkill(strSkill As String, rngLookIn As Excel.Range) As Boolean
Dim tmp As Integer
FindSkill = False
On Error GoTo eHandle
tmp = Application.WorksheetFunction.Match(strSkill, rngLookIn, False)
FindSkill = True
Exit Function
eHandle:
End Function
I have the routine below where I'm copying all the contents of a sheet if the sheet name matches the array name.
I've got the sheets copying to the destination, but I'm not getting the array value curRow to increment.
What am I missing here?
Sub test()
Dim curRow As Integer, CurrentRow As Integer, LastRow As Integer, LastRow2 As Integer
Dim activeWorksheet As Worksheet
Set activeWorksheet = ActiveSheet
Dim ws As Worksheet
Dim arArray As Variant
Sheets("Total Tabs").Activate
arArray = Sheets("Total Tabs").Range("A1", Range("A" & Rows.Count).End(xlUp))
LastRow = ActiveSheet.Range("A" & Rows.Count).End(xlUp).Row
curRow = 1
CurrentRow = 2
For curRow = 1 To LastRow
For Each ws In ActiveWorkbook.Worksheets
' If curRow <> 1 Then
' curRow = curRow + 1
' End If
If ws.name = arArray(curRow, 1) Then
LastRow2 = ws.Range("A" & Rows.Count).End(xlUp).Row + 1
For CurrentRow = 2 To LastRow2
ws.Range("A" & CurrentRow & ":N" & CurrentRow).Copy Destination:=Sheets("Reps No Longer Here").Range("A" & CurrentRow)
CurrentRow = CurrentRow + 1
Next
curRow = curRow + 1
End If
Next ws
Next curRow
End Sub
UPDATE:
Here is the final code that I have and works as it should. Included is also the ability to hide the tab once it has been processed.
I'm sure it can be optimized, but here it is:
Sub CombineDataToRNLH()
Dim curRow As Integer, CurrentRow As Integer, LastRow As Integer, LastRow2 As Integer
Dim activeWorksheet As Worksheet
Set activeWorksheet = ActiveSheet
Dim ws As Worksheet
Dim arArray As Variant
Dim pasterow As Integer
Dim RepName As String
'Activate the sheet with the list and then read the list of names
'straight into an array
Sheets("Total Tabs").Activate
arArray = Sheets("Total Tabs").Range("A1", Range("A" & Rows.Count).End(xlUp))
'Find last element in the array and calculate as rows
LastRow = ActiveSheet.Range("A" & Rows.Count).End(xlUp).Row
curRow = 1 'Index for evaluating array elements
CurrentRow = 2 'Counter for use in processing all rows in matched sheet to destination sheet
LastRow2 = 1 'Find number of rows in the matched tab
pasterow = 2 'Counter to ensure that I'm always copying data to the first available row
'Set up loop so that I can match array elements to individual sheet names
For curRow = 1 To LastRow
For Each ws In ActiveWorkbook.Worksheets
If ws.name = arArray(curRow, 1) Then
LastRow2 = ws.Range("A" & Rows.Count).End(xlUp).Row
For CurrentRow = 2 To LastRow2
ws.Range("A" & CurrentRow & ":N" & CurrentRow).Copy _
Destination:=Sheets("Reps No Longer Here").Range("A" & pasterow)
If CurrentRow = LastRow2 Then
curRow = curRow + 1
pasterow = pasterow + 1
ws.Visible = xlSheetVeryHidden 'Set it to very hidden.
Exit For
End If
pasterow = pasterow + 1
Next
End If
Next ws
Next curRow
Sheets("How To").Activate
End Sub
I think your code can be simplified and streamlined a bit. From what I gather, you want to loop through some sheets (as defined in your aaArray variable) and copy the data to a "Reps No Longer Here" tab. See if this does what you're after:
Sub test()
Dim LastRow As Long, _
LastRow2 As Long
Dim ws As Worksheet
Dim arArray As Variant
Dim sheetName As Variant
With Application
.ScreenUpdating = False
End With
With Sheets("Total Tabs")
arArray = .Range("A1", .Range("A" & Rows.Count).End(xlUp))
For Each sheetName In arArray
On Error Resume Next
Set ws = Sheets(sheetName)
On Error GoTo 0
If ws Is Nothing Then
' we don't need to do anything since the sheet doesn't exist
Else
LastRow2 = ws.Range("A" & Rows.Count).End(xlUp).Row
LastRow = Sheets("Reps No Longer Here").Range("A" & Rows.Count).End(xlUp).Row + 1
ws.Range("A2:N" & LastRow2).Copy Destination:=Sheets("Reps No Longer Here").Range("A" & LastRow)
End If
Next sheetName
End With
With Application
.ScreenUpdating = True
End With
End Sub