VBA Split on column - multiple variables - excel

I have a VBA code that splits my data into seperate worksheets, based on the variables in a chosen column.
This works great, however I have a few variables that I want in the same sheet, dispite having a different name.
Example:
In column B I have company A, B, C, D & E. These companies gets split into different worksheets.
However, company A & C has the same parent company, and therefore should be in the same worksheet.
How can i add this to my code, if I include a table like below in my file?
Column A
Column B
Company A
Group 'World'
Company B
Group 'Other'
Company C
Group 'World'
Company D
Group 'Other'
Company E
Group 'Other'
Sub Step1_split()
Dim lr As Long
Dim ws As Worksheet
Dim vcol, i As Integer
Dim icol As Long
Dim myarr As Variant
Dim title As String
Dim titlerow As Integer
'This macro splits data into multiple worksheets based on the variables on a column found in Excel.
'An InputBox asks you which columns you'd like to filter by, and it just creates these worksheets.
Application.ScreenUpdating = False
vcol = Application.InputBox(prompt:="Which column would you like to filter by?", title:="Filter column", Default:="2", Type:=1)
Set ws = ActiveSheet
lr = ws.Cells(ws.Rows.Count, vcol).End(xlUp).Row
title = "A1"
titlerow = ws.Range(title).Cells(1).Row
icol = ws.Columns.Count
ws.Cells(1, icol) = "Unique"
For i = 2 To lr
On Error Resume Next
If ws.Cells(i, vcol) <> "" And Application.WorksheetFunction.Match(ws.Cells(i, vcol), ws.Columns(icol), 0) = 0 Then
ws.Cells(ws.Rows.Count, icol).End(xlUp).Offset(1) = ws.Cells(i, vcol)
End If
Next
myarr = Application.WorksheetFunction.Transpose(ws.Columns(icol).SpecialCells(xlCellTypeConstants))
ws.Columns(icol).Clear
For i = 2 To UBound(myarr)
ws.Range(title).AutoFilter field:=vcol, Criteria1:=myarr(i) & ""
If Not Evaluate("=ISREF('" & myarr(i) & "'!A1)") Then
Sheets.Add(after:=Worksheets(Worksheets.Count)).Name = myarr(i) & ""
Else
Sheets(myarr(i) & "").Move after:=Worksheets(Worksheets.Count)
End If
ws.Range("A" & titlerow & ":A" & lr).EntireRow.Copy Sheets(myarr(i) & "").Range("A1")
'Sheets(myarr(i) & "").Columns.AutoFit
Next
ws.AutoFilterMode = False
ws.Activate
Application.ScreenUpdating = True
End Sub
I have tried adding an IF formula in the code, but have no idea how to do it.

Create a sheet named "Groups" for your table of relationships. Build an array of company names to use in the filter criteria.
Option Explicit
Sub Step1_split()
Dim wb As Workbook, wsGroups As Worksheet
Dim wsSrc As Worksheet, wsTarget As Worksheet
Dim rngFilter As Range, rngCopy As Range
Dim lastrow As Long, r As Long, grp As String
Dim i As Long, n As Long, arCrit, vcol
Set wb = ThisWorkbook
With wb
Set wsSrc = .Sheets(1) '.ActiveSheet
Set wsGroups = .Sheets("Groups") ' as req
End With
vcol = Application.InputBox( _
prompt:="Which column would you like to filter by ?", _
title:="Filter column", Default:="2", Type:=1)
If vcol = "False" Then Exit Sub ' cancel
' filter range
With wsSrc
lastrow = .Cells(.Rows.Count, vcol).End(xlUp).Row
Set rngFilter = .Cells(1, vcol).Resize(lastrow)
Set rngCopy = .Cells(1, 1).Resize(lastrow)
.AutoFilterMode = False
End With
' get parent-company details
Dim dict As Object, k
Set dict = CreateObject("Scripting.Dictionary")
With wsGroups
lastrow = .Cells(.Rows.Count, "A").End(xlUp).Row
For r = 2 To lastrow
grp = Trim(.Cells(r, "B"))
If Not dict.exists(grp) Then
dict.Add grp, New Collection
End If
dict(grp).Add Trim(.Cells(r, "A"))
Next
End With
' create sheet for each group, clear existing
Application.ScreenUpdating = False
i = wb.Sheets.Count
For Each k In dict.keys
grp = Replace(CStr(k), "'", "") ' take out single quotes
On Error Resume Next
Set wsTarget = wb.Sheets(grp)
On Error GoTo 0
If wsTarget Is Nothing Then
wb.Sheets.Add(after:=wb.Sheets(i)).Name = grp
i = i + 1
Set wsTarget = wb.Sheets(i)
Else
wsTarget.Cells.Clear
End If
' create aray
ReDim arCrit(0 To dict(k).Count - 1)
For n = 1 To dict(k).Count
arCrit(n - 1) = dict(k)(n)
Next
'Debug.Print k, Join(arCrit, ";")
' filter with array as criteria and copy
With rngFilter
.AutoFilter Field:=1, Criteria1:=arCrit, _
Operator:=xlFilterValues
rngCopy.Copy wsTarget.Range("A1")
End With
Set wsTarget = Nothing
Next
wsSrc.AutoFilterMode = False
Application.ScreenUpdating = True
MsgBox "Done"
End Sub

Related

Split Excel worksheet into multiple worksheets based on a column with VBA

I have the following data:
Data in sheet 1 :
Name Fund Source Remark Approved (Y/N)
Alice C&C Ok Y
John C&C Ok N
Data in sheet 2 :
Sr No Name Category Requirement - A Requirement - B Requirement - C Requirement - D Eligibility Remarks
1 Alice A+ 3 2 0 0 Ok
Data in sheet 3 :
Month Delivery Support Pay Client Name Remark Mfg Year Model Year Remarks
Jan Cash 269 Alice 2022 2022
Question is simple and may be repetitive.
I have an Excel workbook which contains 3 sheets
I have a criteria column which should be applied to all 3 sheets for splitting this workbook into mulitple workbooks
I am looking for a macro which enables me to create multiple Excel workbooks based on the column Name like:
Excel/CSV for all Names like Alice, John
The only challenge I am facing here is
The header on which the filter criteria should be applied to is different in sheet 3 (In sheet 1 and 2 the header is Client but in sheet 3 it is named as client name)
The final workbook should contain 3 sheets but should only show name of one individual (For example, 2 different workbooks will be created here one for Alice and one for John)
I have tried coding in VBA but was only able to filter one sheet.
Can someone help me with a macro which would help in generating multiple workbooks based on the above details?
Here is the code :
Sub Splitdatabycol()
Dim lr As Long
Dim ws As Worksheet
Dim vcol, i As Integer
Dim icol As Long
Dim myarr As Variant
Dim title As String
Dim titlerow As Integer
Dim xTRg As Range
Dim xVRg As Range
Dim xWSTRg As Worksheet
Dim xWS As Worksheet
On Error Resume Next
Set xTRg = Application.InputBox("Please select the header rows:", "Prompt", "", Type:=8)
If TypeName(xTRg) = "Nothing" Then Exit Sub
Set xVRg = Application.InputBox("Please select the column you want to split data based on:", "Prompt", "", Type:=8)
If TypeName(xVRg) = "Nothing" Then Exit Sub
vcol = xVRg.Column
Set ws = xTRg.Worksheet
lr = ws.Cells(ws.Rows.Count, vcol).End(xlUp).Row
title = xTRg.AddressLocal
titlerow = xTRg.Cells(1).Row
icol = ws.Columns.Count
ws.Cells(1, icol) = "Unique"
Application.DisplayAlerts = False
If Not Evaluate("=ISREF('xTRgWs_Sheet!A1')") Then
Sheets.Add(after:=Worksheets(Worksheets.Count)).Name = "xTRgWs_Sheet"
Else
Sheets("xTRgWs_Sheet").Delete
Sheets.Add(after:=Worksheets(Worksheets.Count)).Name = "xTRgWs_Sheet"
End If
Set xWSTRg = Sheets("xTRgWs_Sheet")
xTRg.Copy
xWSTRg.Paste Destination:=xWSTRg.Range("A1")
ws.Activate
For i = (titlerow + xTRg.Rows.Count) To lr
On Error Resume Next
If ws.Cells(i, vcol) <> "" And Application.WorksheetFunction.Match(ws.Cells(i, vcol), ws.Columns(icol), 0) = 0 Then
ws.Cells(ws.Rows.Count, icol).End(xlUp).Offset(1) = ws.Cells(i, vcol)
End If
Next
myarr = Application.WorksheetFunction.Transpose(ws.Columns(icol).SpecialCells(xlCellTypeConstants))
ws.Columns(icol).Clear
For i = 2 To UBound(myarr)
ws.Range(title).AutoFilter field:=vcol, Criteria1:=myarr(i) & ""
If Not Evaluate("=ISREF('" & myarr(i) & "'!A1)") Then
Set xWS = Sheets.Add(after:=Worksheets(Worksheets.Count))
xWS.Name = myarr(i) & ""
Else
xWS.Move after:=Worksheets(Worksheets.Count)
End If
xWSTRg.Range(title).Copy
xWS.Paste Destination:=xWS.Range("A1")
ws.Range("A" & (titlerow + xTRg.Rows.Count) & ":A" & lr).EntireRow.Copy xWS.Range("A" & (titlerow + xTRg.Rows.Count))
Sheets(myarr(i) & "").Columns.AutoFit
Next
xWSTRg.Delete
ws.AutoFilterMode = False
ws.Activate
Application.DisplayAlerts = True
End Sub
I think an advanced filter might work well for this scenario:
Sub newWorkbookPerName()
Dim ws1 As Worksheet, ws2 As Worksheet, ws3 As Worksheet, splitWb As Workbook
Dim ws1EndColumn As Long, ws2EndColumn As Long, ws3EndColumn As Long
Dim ws1Name As Long, ws2Name As Long, ws3Name As Long
Set ws1 = ThisWorkbook.Worksheets("Sheet1")
Set ws2 = ThisWorkbook.Worksheets("Sheet2")
Set ws3 = ThisWorkbook.Worksheets("Sheet3")
If ws1.Range("A2").Value2 <> "" Then
ws1EndColumn = ws1.Range("A1").End(xlToRight).Column
ws2EndColumn = ws2.Range("A1").End(xlToRight).Column
ws3EndColumn = ws3.Range("A1").End(xlToRight).Column
'Use AdvancedFilter to filter and copy data - https://excelmacromastery.com/vba-advanced-filter/
'use match to find Name column
ws1Name = Application.WorksheetFunction.Match("Name", ws1.Range(ws1.Cells(1, 1), ws1.Cells(1, ws1EndColumn)), 0)
ws2Name = Application.WorksheetFunction.Match("Name", ws2.Range(ws2.Cells(1, 1), ws2.Cells(1, ws1EndColumn)), 0)
ws3Name = Application.WorksheetFunction.Match("*Name", ws3.Range(ws3.Cells(1, 1), ws3.Cells(1, ws1EndColumn)), 0)
'Put together criteria range for AdvanceFilter
ws1.Range(ws1.Cells(1, 1), ws1.Cells(1, ws1EndColumn)).Offset(0, ws1EndColumn + 5).Value2 = ws1.Range(ws1.Cells(1, 1), ws1.Cells(1, ws1EndColumn)).Value2
ws2.Range(ws2.Cells(1, 1), ws2.Cells(1, ws2EndColumn)).Offset(0, ws2EndColumn + 5).Value2 = ws2.Range(ws2.Cells(1, 1), ws2.Cells(1, ws2EndColumn)).Value2
ws3.Range(ws3.Cells(1, 1), ws3.Cells(1, ws3EndColumn)).Offset(0, ws3EndColumn + 5).Value2 = ws3.Range(ws3.Cells(1, 1), ws3.Cells(1, ws3EndColumn)).Value2
For Each Name In ws1.Range("A2", ws1.Range("A1").End(xlDown))
Workbooks.Add
ActiveWorkbook.SaveAs ThisWorkbook.Path & "\" & Name & ".xlsx"
Set splitWb = ActiveWorkbook
'Sheet1
ws1.Cells(2, ws1Name).Offset(0, ws1EndColumn + 5).Value2 = Name
ws1.Range("A1").CurrentRegion.AdvancedFilter xlFilterCopy, ws1.Cells(1, ws1EndColumn + 6).CurrentRegion, splitWb.Worksheets("Sheet1").Range("A1")
'Sheet2
splitWb.Sheets.Add after:=splitWb.Worksheets(splitWb.Worksheets.Count)
ws2.Cells(2, ws2Name).Offset(0, ws2EndColumn + 5).Value2 = Name
ws2.Range("A1").CurrentRegion.AdvancedFilter xlFilterCopy, ws2.Cells(1, ws2EndColumn + 6).CurrentRegion, splitWb.Worksheets("Sheet2").Range("A1")
'Sheet3
splitWb.Sheets.Add after:=splitWb.Worksheets(splitWb.Worksheets.Count)
ws3.Cells(2, ws3Name).Offset(0, ws3EndColumn + 5).Value2 = Name
ws3.Range("A1").CurrentRegion.AdvancedFilter xlFilterCopy, ws3.Cells(1, ws3EndColumn + 6).CurrentRegion, splitWb.Worksheets("Sheet3").Range("A1")
splitWb.Close SaveChanges:=True
Next
End If
End Sub

Split one worksheet into different worksheets based on two conditions/columns (each condition in one columns)

I have a file that has column A with different names and column B with different departments (that person in A belongs to). Column C-E is related data to each person. I searched online and found there are some VBA codes to split one worksheet into multi sheets based on one column. I'm wondering is there a method to split worksheets that considering both columns simultaneously? Ps: the split worksheets would be named with the content of columns A and B.
Here is the code I use to split based on one column. Any suggestion is welcomed. Thanks a lot.
Sub parse_data()
Dim lr As Long
Dim ws As Worksheet
Dim vcol, i As Integer
Dim icol As Long
Dim myarr As Variant
Dim title As String
Dim titlerow As Integer
'This macro splits data into multiple worksheets based on the variables on a column found in Excel.
'An InputBox asks you which columns you'd like to filter by, and it just creates these worksheets.
Application.ScreenUpdating = False
vcol = Application.InputBox(prompt:="Which column would you like to filter by?", title:="Filter column", Default:="3", Type:=1)
Set ws = ActiveSheet
lr = ws.Cells(ws.Rows.Count, vcol).End(xlUp).Row
title = "A1"
titlerow = ws.Range(title).Cells(1).Row
icol = ws.Columns.Count
ws.Cells(1, icol) = "Unique"
For i = 2 To lr
On Error Resume Next
If ws.Cells(i, vcol) <> "" And Application.WorksheetFunction.Match(ws.Cells(i, vcol), ws.Columns(icol), 0) = 0 Then
ws.Cells(ws.Rows.Count, icol).End(xlUp).Offset(1) = ws.Cells(i, vcol)
End If
Next
myarr = Application.WorksheetFunction.Transpose(ws.Columns(icol).SpecialCells(xlCellTypeConstants))
ws.Columns(icol).Clear
For i = 2 To UBound(myarr)
ws.Range(title).AutoFilter field:=vcol, Criteria1:=myarr(i) & ""
If Not Evaluate("=ISREF('" & myarr(i) & "'!A1)") Then
Sheets.Add(after:=Worksheets(Worksheets.Count)).Name = myarr(i) & ""
Else
Sheets(myarr(i) & "").Move after:=Worksheets(Worksheets.Count)
End If
ws.Range("A" & titlerow & ":A" & lr).EntireRow.Copy Sheets(myarr(i) & "").Range("A1")
'Sheets(myarr(i) & "").Columns.AutoFit
Next
ws.AutoFilterMode = False
ws.Activate
Application.ScreenUpdating = True
End Sub
Dictionaries are useful for creating lists of unique values.
Option Explicit
Sub CreateDeptPerson()
Const RNG_HEADER = "A1:E1"
Const START_ROW = 2 ' row 1 header
Dim wb As Workbook, ws As Worksheet, arHeader As Variant
Dim iRow As Long, iLastRow As Long, i As Long, n As Integer
Dim dict As Object, key As String
Set dict = CreateObject("Scripting.Dictionary")
' add existing sheets to dictionary
Set wb = ThisWorkbook
For Each ws In wb.Sheets
iRow = ws.UsedRange.Rows.Count + ws.UsedRange.Row ' last row +1
dict.Add ws.Name, iRow
Next
' extent of data
Set ws = wb.Sheets("Sheet1") ' change to name of data sheet
iLastRow = ws.Cells(Rows.Count, "A").End(xlUp).Row
arHeader = ws.Range(RNG_HEADER).Value2
' scan down column A
For iRow = START_ROW To iLastRow
'sheet name as "dept name"
key = Trim(ws.Cells(iRow, "B")) & " " & Trim(ws.Cells(iRow, "A"))
' add a sheet if not in dictionary
If Not dict.exists(key) Then
With wb.Sheets.Add(after:=wb.Sheets(wb.Sheets.Count))
.Name = key
.Range(RNG_HEADER) = arHeader
End With
' add name to dictionary
dict.Add key, 2
n = n + 1
End If
' copy row to the sheet named key
i = dict(key)
ws.Cells(iRow, 1).EntireRow.Copy wb.Sheets(key).Cells(i, 1)
dict(key) = i + 1 'move down for next record
Next
MsgBox n & " Sheets Created"
End Sub

Compare two columns in different workbooks

I would appreciate if I can get help in creating this macro. I have two workbooks, and want to compare the specific column from 1st workbook, Ex: Column H with next work book, Ex: column A. After comparison highlight the matching cells in 1st workbook. I have tried below script for comparison, it is executing successfully, but not seeing any result.
Sub test()
Dim ws1 As Worksheet, ws2 As Worksheet, w(), i As Long
Dim r As Range, myCol As String
Set ws1 = ThisWorkbook.Sheets(1)
Set ws2 = Workbooks("workbook.xlsx").Sheets(1)
With CreateObject("VBScript.RegExp")
.Pattern = "^([a-z]|[a-h][a-z]|[a-i][a-v])$"
.IgnoreCase = True
Do
myCol = InputBox("Enter Column")
Loop While Not .test(myCol)
End With
With CreateObject("Scripting.Dictionary")
.comparemode = vbTextCompare
For Each r In ws1.Range(myCol & "1", ws1.Range(myCol & Rows.Count).End(xlUp))
If Not IsEmpty(r) And Not .exists(r.Value) Then
ReDim w(0): w(0) = r.Row
.Add r.Value, w
Else
w = .Item(r.Value)
ReDim Preserve w(UBound(w) + 1)
w(UBound(w)) = r.Row
.Item(r.Value) = w
End If
Next
For Each r In ws2.Range("a1", ws2.Range("a" & Rows.Count).End(xlUp))
If .exists(r.Value) Then
For i = 0 To UBound(.Item(r.Value))
ws1.Range(myCol & .Item(r.Value)(i)).Offset(, 1).Resize(, 23).Value = _
r.Offset(, 1).Resize(, 23).Value
Next
End If
Next
End With
Set ws1 = Nothing: Set ws2 = Nothing
End Sub
Try
Sub test()
Dim ws1 As Worksheet, ws2 As Worksheet, w(), i As Long, n As Integer
Dim r As Range, myCol As String, wbname As String, msg As String
Set ws1 = ThisWorkbook.Sheets(1)
Dim myworkbooks As Variant, mycolors As Variant
' workbooks to compare
myworkbooks = Array("Workbook1.xlsx", "Workbook2.xlsx", "Workbook3.xlsx")
mycolors = Array(vbYellow, vbGreen, vbBlue)
' select column
With CreateObject("VBScript.RegExp")
.Pattern = "^([a-z]|[a-h][a-z]|[a-i][a-v])$"
.IgnoreCase = True
Do
myCol = InputBox("Enter Column")
Loop While Not .test(myCol)
End With
' build dictionary
With CreateObject("Scripting.Dictionary")
.comparemode = vbTextCompare
For Each r In ws1.Range(myCol & "1", ws1.Range(myCol & Rows.Count).End(xlUp))
If IsEmpty(r) Then
' skip empty cells
Else
If Not .exists(r.Value) Then
ReDim w(0): w(0) = r.Row
.Add r.Value, w
Else
w = .Item(r.Value)
ReDim Preserve w(UBound(w) + 1)
w(UBound(w)) = r.Row
.Item(r.Value) = w
End If
End If
Next
' compare and highlight match
For n = 0 To UBound(myworkbooks)
Debug.Print "Opening " & myworkbooks(n)
msg = msg & vbCrLf & myworkbooks(n)
Set ws2 = Workbooks(myworkbooks(n)).Sheets(1)
For Each r In ws2.Range("a1", ws2.Range("a" & Rows.Count).End(xlUp))
If .exists(r.Value) Then
For i = 0 To UBound(.Item(r.Value))
ws1.Range(myCol & .Item(r.Value)(i)).Interior.color = mycolors(n)
Next
End If
Next r
Next n
End With
Set ws1 = Nothing: Set ws2 = Nothing
MsgBox "Completed scanning" & msg, vbInformation
End Sub

How to apply multiple criteria to .Find?

I adapted code I found online.
It finds the string "car" in column A and returns the rows as an array
It assigns a variable to the length of the array (how many matches it found)
It assigns a variable to generate a random number between 0 and the length of the array
It then prints a random matching row's value into K3
Dim myArray() As Variant
Dim x As Long, y As Long
Dim msg As String
With ActiveSheet.Range("A1:A" & ActiveSheet.Range("A" & Rows.Count).End(xlUp).Row)
Set c = .find("Car", LookIn:=xlValues)
If Not c Is Nothing Then
firstAddress = c.Address
Do
ReDim Preserve myArray(y)
myArray(y) = c.Row
y = y + 1
Set c = .findNext(c)
If c Is Nothing Then
GoTo DoneFinding
End If
Loop While c.Address <> firstAddress
End If
DoneFinding:
End With
For x = LBound(myArray) To UBound(myArray)
msg = msg & myArray(x) & " "
Next x
ArrayLen = UBound(myArray) - LBound(myArray)
random_index = WorksheetFunction.RandBetween(0, ArrayLen)
MsgBox myArray(random_index)
Dim test As String
test = "B" & myArray(random_index)
Range("K3").Value = Range(test)
Example
I'm struggling with adapting the find code to allow for multiple criteria. So in my example, it finds "Car". What if I want to find matches that had "Car" in column A and "Red" in column D?
I tried
With ActiveSheet.Range("A1:A" & "D1:D" & ActiveSheet.Range("A" & Rows.Count).End(xlUp).Row & ActiveSheet.Range("D" & Rows.Count).End(xlUp).Row)
Set c = .find("Car", "Red", LookIn:=xlValues)
I get type mismatch on the Set line.
In case it is confusing, it currently looks for a string e.g. "Car" but I will eventually link this to the variable which will be assigned to a data validation list. So if the user chooses "car" from a drop down list, this is what it will search for.
Maybe Advancde Filter is something that fit your needs:
Example Code
Option Explicit
Public Sub FilterData()
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets("YourSheetName")
Dim LastRow As Long
LastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
Dim CriteriaRange As Range
Set CriteriaRange = ws.Range("A1", "E2")
Dim DataRange As Range
Set DataRange = ws.Range("A4", "E" & LastRow)
DataRange.AdvancedFilter Action:=xlFilterInPlace, CriteriaRange:=CriteriaRange, Unique:=False
End Sub
Public Sub ShowAll()
On Error Resume Next
ActiveSheet.ShowAllData
On Error GoTo 0
End Sub
Edit according comment:
You can use the advanced filter and then loop through the filter results:
Option Explicit
Public CurrentRow As Long
Public Sub FilterData()
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets("YourSheetName")
Dim LastRow As Long
LastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
Dim CriteriaRange As Range
Set CriteriaRange = ws.Range("A1", "E2")
Dim DataRange As Range
Set DataRange = ws.Range("A4", "E" & LastRow)
DataRange.AdvancedFilter Action:=xlFilterInPlace, CriteriaRange:=CriteriaRange, Unique:=False
End Sub
Public Sub ShowAll()
On Error Resume Next
ActiveSheet.ShowAllData
CurrentRow = 1
On Error GoTo 0
End Sub
Public Sub GetNextResult()
FilterData
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets("YourSheetName")
Dim LastRow As Long
LastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
Dim DataRange As Range
Set DataRange = ws.Range("A4", "E" & LastRow)
Dim FilteredData As Range
Set FilteredData = DataRange.Resize(ColumnSize:=1).SpecialCells(xlCellTypeVisible)
If CurrentRow + 1 > FilteredData.Cells.Count Then
CurrentRow = 1
End If
CurrentRow = CurrentRow + 1
Dim i As Long
Dim Cell As Variant
For Each Cell In FilteredData
i = i + 1
If i = CurrentRow Then
Cell.EntireRow.Select
'or
'MsgBox Cell.Value & vbCrLf & Cell.Offset(0, 1) & vbCrLf & Cell.Offset(0, 2) & vbCrLf & Cell.Offset(0, 3) & vbCrLf & Cell.Offset(0, 4)
End If
Next Cell
End Sub

Looping through columns to find search criteria and paste cell values from another sheet beneath the criteria

The workbook contains three sheets:
Item-style (contains in colA the item no., colB the style of the item)
Style (List of styles we want)
Style template (List of items within the styles specified in the cols)
I need a macro that does three things:
Copy the list of styles from the Style sheet and paste & transpose in Style template starting from row 2. Row 1 of all columns needs to be left blank.
The macro needs to select each style in style template one by one, which is now in different columns. These will be the search criteria.
On the basis of style selected in step 2, the macro needs to do a search in item-style sheet and select all the items that have the selected style and paste all these items beneath the corresponding style in style-template sheet. If there are no items corresponding to the selected style, then it should mention "No items" beneath the corresponding style.
Here's a link to the workbook for easy understanding
StyleProject
Though the workbook mentions only three styles the macro should have the capability of working with more than 50 styles.
Here's the code I have:
Sub StyleProject()
Application.ScreenUpdating = False
Dim ws As Worksheet
Dim ws2 As Worksheet
Dim ws3 As Worksheet
Set ws = Sheets("Item-Style")
Set ws2 = Sheets("Style")
Set ws3 = Sheets("Style Template")
Dim rng As Range, secRng As Range
Dim i, j, k
Sheets("Style Template").Activate
finalcol = Cells(2, 50).End(x1toleft).Column
For i = 2 To finalcol
j = Cells(2, i).Value
lr = ws.Range("A" & Rows.Count).End(xlUp).Row
For k = 2 To lr
Set rng = ws.Range("B" & i)
If StrComp(CStr(rng.Text), j, 1) = 0 Then
ws.Rows(k & ":" & k).Copy
nxtRow = ws3.Range(i & Rows.Count).End(xlUp).Row + 1
ws2.Rows(nxtRow & ":" & nxtRow).PasteSpecial Paste:=xlPasteValues, _
Operation:=xlNone, SkipBlanks:=False, Transpose:=False
Set rng = Nothing
End If
Next k
Next i
Application.ScreenUpdating = True
End Sub
It ends up in error trying to figure out nextrng I believe.
Sub StyleProject()
Dim wsStyle As Worksheet
Dim wsData As Worksheet
Dim wsTemplate As Worksheet
Dim StyleCell As Range
Dim rngFound As Range
Dim arrResults() As Variant
Dim strFirst As String
Dim ResultIndex As Long
Dim StyleIndex As Long
Set wsStyle = Sheets("Style")
Set wsData = Sheets("Item Data")
Set wsTemplate = Sheets("Style Template")
With wsStyle.Range("A2", wsStyle.Cells(Rows.Count, "A").End(xlUp))
If .Row < 2 Then Exit Sub 'No data
ReDim arrResults(1 To 1 + Evaluate("MAX(COUNTIF(" & wsData.Columns("B").Address(External:=True) & "," & .Address(External:=True) & "))"), 1 To .Cells.Count)
For Each StyleCell In .Cells
StyleIndex = StyleIndex + 1
ResultIndex = 1
arrResults(ResultIndex, StyleIndex) = StyleCell.Text
Set rngFound = wsData.Columns("B").Find(StyleCell.Text, wsData.Cells(Rows.Count, "B"), xlValues, xlWhole)
If Not rngFound Is Nothing Then
strFirst = rngFound.Address
Do
ResultIndex = ResultIndex + 1
arrResults(ResultIndex, StyleIndex) = wsData.Cells(rngFound.Row, "A").Text
Set rngFound = wsData.Columns("B").Find(StyleCell.Text, rngFound, xlValues, xlWhole)
Loop While rngFound.Address <> strFirst
End If
Next StyleCell
End With
If UBound(arrResults, 1) > 1 Then
wsTemplate.Range("B2", wsTemplate.Cells(Rows.Count, Columns.Count)).Clear
wsTemplate.Range("B2").Resize(UBound(arrResults, 1), UBound(arrResults, 2)).Value = arrResults
With wsTemplate.Range("B2").Resize(, UBound(arrResults, 2))
.Font.Bold = True
.Borders(xlEdgeBottom).LineStyle = xlContinuous
.EntireColumn.AutoFit
End With
End If
Set wsStyle = Nothing
Set wsData = Nothing
Set wsTemplate = Nothing
Set StyleCell = Nothing
Set rngFound = Nothing
Erase arrResults
End Sub

Resources