I've been trying to find a solution to the following problem for a week but couldn't find anything...
Here is the point ; I've got three different worksheets in my workbook;
worksheets("Board")
worksheets("reference")
worksheets("FinalBoard")
In worksheets("Board") there are multiple column filled with datas with differents headers. I could do a code that paste each datas bellow in sheets("FinalBoard") one bellow the other only if those headers begin by the value "Fruit".
=>worksheets("Board")
A
B
C
D
Fruit-1
Fruit-2
Fruit-3
Vege-1
x
x
x
Y
x
x
x
Y
here is my code;
Sub test()
Worksheets("FinalBoard").Activate
Dim wsInput As Worksheet
Dim wsOutput As Worksheet
Dim lRowInput As Long
Dim lRowOutput As Long
Dim lCol As Long
Dim i As Long
Dim Col As String
'~~> Setting sheets
Set wsInput = Sheets("Board")
Set wsOutput = Sheets("FinalBoard")
With wsInput
'~~> Find last column in Row 2
lCol = .Cells(2, .columns.Count).End(xlToLeft).column
'~~> Loop through columns
For i = 1 To lCol
'~~> Check for my criterias
If .Cells(2, i).Value2 Like "Fruit*" Then
'~~> Get column name
Col = Split(.Cells(, i).Address, "$")(1)
'~~> Get the last row in that column
lRowInput = .Range(Col & .rows.Count).End(xlUp).row
'~~> Find the next row to write to
If lRowOutput = 0 Then
lRowOutput = 2
Else
lRowOutput = wsOutput.Range("B" & wsOutput.rows.Count).End(xlUp).row + 1
End If
'~~> Copy all datas bellow each headers
.Range(Col & "3:" & Col & lRowInput).Copy _
wsOutput.Range("B" & lRowOutput)
End If
Next i
End With
End Sub
However, the problem is here I'd like to add an extra condition. During this process, if each of these headers match with a cell contained in a list of words in worksheets("reference") then copy the value beside that cell(located in column "B") and paste it in worksheets("Final Board") in column("A").
=>worksheets("reference") ;
A
B
Fruit-1
N01
Fruit-2
N02
Fruit-3
N03
Fruit-4
N04
worksheets("FinalBoard") ;
| A | B |
| -------- | -------------- |
| Code | X VALUES |
| N01 | x |
| N02 | x|
|N03|x|
As soon as I run my code, nothing happens; no message, no error.
I'd also like to insert the following code in the previous I showed you to ease the process and not run this macro again!
Here is it:
Dim wsTEST1, wsTEST2, wsTEST3 As Worksheet
Dim lCol As Long
Dim i, j, e As Long
Dim Col As String
Dim cell As Range
Dim lastlineRef, lastlineDistrib, lastlineResult As Long
'~~> Declaration
Set wsTEST1 = Sheets("Board")
Set wsTEST2 = Sheets("Reference")
Set wsTEST3 = Sheets("FinalBoard")
With wsTEST1
'~~> loop through columns ( declaration)
lCol = .Cells(2, .columns.Count).End(xlToLeft).column
lastlineRef = Worksheets("Reference").Range("A" & rows.Count).End(xlUp).row
lastlineResult = Worksheets("FinalBoard").Range("A" & rows.Count).End(xlUp).row
'~~> loop through columns
For i = 1 To lCol 'unti last column
'~~> research criterias
If .Cells(2, i).Value Like "Fruit*" Then
For e = 1 To lastlineResult
If wsTEST1.Cells(2, i).Value = Worksheets("Reference").Range("A" & i) Then
Worksheets("Reference").Range("A" & e).Offset(, 1).Copy Worksheets("FinalBoard").Range("A" & e)
End If
Next e
End If
Next i
End With
end sub
I feel like I'm so close to find the correct code... I'd heavily appreciate your help once again ! :)
You could use a Dictionary Object for the lookup.
Sub test()
Dim wsInput As Worksheet, wsOutput As Worksheet, wsRef As Worksheet
Dim lRowInput As Long, lRowOutput As Long, iLastRef As Long
Dim lCol As Long, i As Long, n As Long, s As String
' dictionary as look up table
Dim dict As Object, key As String
Set dict = CreateObject("Scripting.Dictionary")
Set wsRef = Sheets("reference")
With wsRef
iLastRef = .Cells(Rows.Count, "A").End(xlUp).Row
For i = 1 To iLastRef
key = Trim(.Cells(i, "A"))
dict(key) = .Cells(i, "B")
Next
End With
'~~> Setting sheets
Set wsInput = Sheets("Board")
Set wsOutput = Sheets("FinalBoard")
lRowOutput = 2
With wsInput
' Find last column in Row 2
lCol = .Cells(2, .Columns.Count).End(xlToLeft).Column
' Loop through columns
For i = 1 To lCol
'~~> Check for my criterias
s = Trim(.Cells(2, i).Value2)
If s Like "Fruit*" Then
' Get the last row in that column
lRowInput = .Cells(.Rows.Count, i).End(xlUp).Row
n = lRowInput - 2 ' no of rows to copy
' Copy all datas bellow each headers
.Cells(3, i).Resize(n).Copy wsOutput.Range("B" & lRowOutput)
' add col A if match
If dict.exists(s) Then
wsOutput.Range("A" & lRowOutput).Resize(n) = dict(s)
End If
lRowOutput = lRowOutput + n
End If
Next i
End With
End Sub
Related
Would anyone will be able to help me with this script please?
As it stand, this current macro separate the data once the value/text have changes and insert new row but I just cannot work it out how to include the headers once the row have been inserted.
Sub Insert Row()
Dim ws As Worksheet
Dim lr As Long
Dim i As Long
Set ws = Worksheets("Sheet1") 'the sheet with the data
lr = ws.Range("A" & Rows.Count).End(xlUp).Row 'last row with data in Column A
For i = lr - 1 To 2 Step -1
If ws.Range("A" & i).Value <> ws.Range("A" & i + 1).Value Then ws.Range("A" & i + 1).EntireRow.Insert
Next i
End Sub
Thank you in advanced.
Duplicate Headers
A Quick Fix
Sub InsertHeaders()
Const FIRST_ROW As Long = 1
Const EMPTY_ROWS As Long = 1
Dim ws As Worksheet: Set ws = ThisWorkbook.Worksheets("Sheet1")
Dim LastRow As Long: LastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
Dim r As Long
For r = LastRow To FIRST_ROW + 2 Step -1
With ws.Cells(r, "A")
If .Value <> .Offset(-1).Value Then
.EntireRow.Resize(EMPTY_ROWS + 1).Insert
ws.Rows(1).Copy ws.Rows(.Row - 1)
End If
End With
Next r
End Sub
Please ignore my comment, as I just realize that it will be a different result if in column A there is a cell with the same value.
Example Data :
Expected result after running the sub :
Sub test()
Dim rgHdr As Range: Dim rgData As Range: Dim cell As Range
Dim i As Integer: Dim arr: Dim ins As Integer:dim sh as worksheet
Set sh = Sheets("Sheet1") 'change if needed
ins = 3 'change if needed
With sh
.Range("A1").EntireRow.Resize(ins).Insert Shift:=xlDown
Set rgHdr = .Range("A1").EntireRow.Resize(1 + ins)
Set rgData = .Range("K" & 2 + ins, .Range("K" & Rows.Count).End(xlUp))
End With
Set arr = CreateObject("scripting.dictionary")
For Each cell In rgData: arr.Item(cell.Value) = 1: Next
For i = 1 To arr.Count - 1
rgHdr.Copy
sh.Cells(rgData.Find(arr.Keys()(i), _
after:=rgData.End(xlDown)).Row, 1).Insert Shift:=xlDown
Next
sh.Range("A1").EntireRow.Resize(ins).Delete
End Sub
sh = the sheets where the data is.
ins = skip how many blank rows.
The code use "insert copied cells" method, so it make three blank rows (the value of ins) before the header, then set the first three rows as rgHdr, set the rgData from K2 down to the last row with value.
arr = unique value in column K.
then it loop to each element in arr, get the first row occurence of the found cell which value is the looped element in arr, insert the copied rgHdr to that row.
Then finally it delete those three (ins value is 3) additional blank rows.
I want to fill each empty cells of a board with a precise range of data.
I 've got two worksheets;
-worksheets("Board")
- worksheets("FinalBoard")
In worksheet worksheets("Board") I've got the following board ;
Category
Fruits-1
Fruits-2
Fruits-3
A
Banana
Cherries
Orange
D
Apple
Mango
Strawberries
B
Pineapple
Watermelon
Grenade
I want to pick each columns data only if the header starts with "Fruits" and paste them in one colum in worksheet worksheets("FinalBoard") . I was able to do so with columns named Fruits, with the following code;
Sub P_Fruits()
Dim wsInput As Worksheet
Dim wsOutput As Worksheet
Dim lRowInput As Long
Dim lRowOutput As Long
Dim lCol As Long
Dim i As Long
Dim n As Long
Dim s As String
Dim col As String
'~~> Sheets settings
Set wsInput = Sheets("Board")
Set wsOutput = Sheets("FinalBoard")
With wsInput
'~~> Find last column in Row 2
lCol = .Cells(1, .Columns.Count).End(xlToLeft).Column
'~~> loop through columns
For i = 1 To lCol
'~~> research criterias
If .Cells(1, i).Value2 Like "Fruit-*" Then
'~~> Get columns name
col = Split(.Cells(, i).Address, "$")(1)
'~~> Get the last row in that column
lRowInput = .range(col & .Rows.Count).End(xlUp).row
'~~> Find the next row to write to
If lRowOutput = 0 Then
lRowOutput = 2
Else
lRowOutput = wsOutput.range("B" & wsOutput.Rows.Count).End(xlUp).row + 1
End If
'~~> Copy-paste in the 2nd worksheet every data if the headers is found
.range(col & "2:" & col & lRowInput).Copy _
wsOutput.range("B" & lRowOutput)
End If
Next i
end with
end sub
however I'd like to do so for the column "category" and put the category's type in front of each fruits in column A and thus repeat the copied range category multiple time , as much as there were headers beginning with "Fruits" in worksheets("Board") . I tried to add an extra code to the previous one but it didnt work. Here is what I'd like as a result;
Category-pasted
Fruits-pasted
A
Banana
D
Apple
B
Pineapple
A
Cherries
D
Melon
B
Watermelon
A
Orange
D
Strawberries
B
Grenade
Here is what I had with the code I added instead...
Category-pasted
Fruits-pasted
Banana
Apple
Pineapple
Cherries
Melon
Watermelon
Orange
Strawberries
Grenade
A
D
B
My finale code;
Sub Fruits_add()
Dim wsInput As Worksheet
Dim wsOutput As Worksheet
Dim lRowInput As Long
Dim lRowOutput As Long
Dim lCol As Long
Dim i As Long
Dim n As Long
Dim s As String
Dim col As String
'~~> Sheets settings
Set wsInput = Sheets("Board")
Set wsOutput = Sheets("FinalBoard")
With wsInput
'~~> Find last column in Row 2
lCol = .Cells(1, .Columns.Count).End(xlToLeft).Column
'~~> loop through columns
For i = 1 To lCol
'~~> research criterias
If .Cells(1, i).Value2 Like "Fruit-*" Then
'~~> Get column name
col = Split(.Cells(, i).Address, "$")(1)
'~~> Get the last row in that column
lRowInput = .range(col & .Rows.Count).End(xlUp).row
'~~> Find the next row to write to
If lRowOutput = 0 Then
lRowOutput = 2
Else
lRowOutput = wsOutput.range("B" & wsOutput.Rows.Count).End(xlUp).row + 1
End If
'~~> Copy-paste
.range(col & "2:" & col & lRowInput).Copy _
wsOutput.range("B" & lRowOutput)
End If
Next i
'Code to repeat category type added
With wsInput
'~~> Find last column in Row 2
lCol = .Cells(1, .Columns.Count).End(xlToLeft).Column
'~~> loop through columns
For i = 1 To lCol
'~~> research criterias
If .Cells(1, i).Value2 Like "Category*" Then
'~~> Get column name
col = Split(.Cells(, i).Address, "$")(1)
'~~> Get the last row in that column
lRowInput = .range(col & .Rows.Count).End(xlUp).row
'~~> Find the next row to write to
If lRowOutput = 0 Then
lRowOutput = 2
Else
lRowOutput = wsOutput.range("A" & wsOutput.Rows.Count).End(xlUp).row + 1
End If
'~~> copy-paste each category type in column A
.range(col & "2:" & col & lRowInput).Copy _
wsOutput.range("A" & lRowOutput)
End If
Next i
End With
End With
I feel like I'm close to the solution. I'd appreciate your help guys, thank you!
This code will produce the required results but uses a different approach.
The first thing it does is read the source data into an array, it then goes through that array and extracts the fruits/categories from every column with a header starting with 'Fruit.
Option Explicit
Sub Fruits_add()
Dim wsInput As Worksheet
Dim wsOutput As Worksheet
Dim arrDataIn As Variant
Dim arrDataOut As Variant
Dim idxCol As Long
Dim idxRow As Long
Dim cnt As Long
'~~> Sheets settings
Set wsInput = Sheets("Board")
Set wsOutput = Sheets("FinalBoard")
' assumes data on 'Board' starts in A1
With wsInput
arrDataIn = .Range("A1").CurrentRegion.Value
End With
ReDim arrDataOut(1 To 2, 1 To UBound(arrDataIn, 1) * UBound(arrDataIn, 2))
For idxCol = LBound(arrDataIn, 2) To UBound(arrDataIn, 2)
If arrDataIn(1, idxCol) Like "Fruits*" Then
For idxRow = LBound(arrDataIn, 1) + 1 To UBound(arrDataIn, 1)
cnt = cnt + 1
arrDataOut(1, cnt) = arrDataIn(idxRow, 1)
arrDataOut(2, cnt) = arrDataIn(idxRow, idxCol)
Next idxRow
End If
Next idxCol
If cnt > 0 Then
ReDim Preserve arrDataOut(1 To 2, 1 To cnt)
End If
With wsOutput
.Range("A1:B1").Value = Array("Category-pasted", "Fruit-pasted")
.Range("A2").Resize(cnt, 2) = Application.Transpose(arrDataOut)
End With
End Sub
As I explained in my comments you don't need the second loop if you already found the correct row - get the category column early and reuse it later
You can add this variable declaration at the top first
Dim col As String
Then continue with your code for first loop (deleting second loop
With wsInput
'~~> Find last column in Row 2
lCol = .Cells(1, .Columns.Count).End(xlToLeft).Column
'~~> loop through columns
For i = 1 To lCol
Add this to retrieve categories first
If .Cells(1, i).Value2 Like "Category*" Then
'~~> Get column name
colCat = Split(.Cells(, i).Address, "$")(1)
End If
'~~> research criterias
If .Cells(1, i).Value2 Like "Fruit-*" Then
'~~> Get column name
col = Split(.Cells(, i).Address, "$")(1)
'~~> Get the last row in that column
lRowInput = .range(col & .Rows.Count).End(xlUp).row
'~~> Find the next row to write to
If lRowOutput = 0 Then
lRowOutput = 2
Else
lRowOutput = wsOutput.range("B" & wsOutput.Rows.Count).End(xlUp).row + 1
End If
'~~> Copy-paste
.range(col & "2:" & col & lRowInput).Copy _
wsOutput.range("B" & lRowOutput)
Then add this to paste the categories
'~~> copy-paste each category type in column A
.range(colCat & "2:" & colCat & lRowInput).Copy _
wsOutput.range("A" & lRowOutput)
End If
Next i
End With
So I have an excel sheet where I want to loop through Sheet1 and find data pairs similar to Sheet2. So, I have for example A1:B1 and I need to find a row on Sheet2 that has exactly the same values next to each other (but it could be A33:B33 or anywhere) and copy the row over to Sheet1 (in column C or anything)
I am also trying to make it a dynamic loop so it checks for A1:B1 pair against Sheet2 then A2:B2 and so on until the last row.
Now the code I have only checks if A1:B1 on Sheet1 matches A1:B1 on Sheet2 (but not anywhere on the sheet). Also, I cannot make it so that it dynamically checks against every row on Sheet1 (I tried to make it with the x = x + 1 but it doesn't work)
Here is my code:
Sub matchme()
Dim sh1 As Worksheet
Dim sh2 As Worksheet
Dim r As Range
Set sh1 = Sheets("Sheet1")
Set sh2 = Sheets("Sheet2")
r = lastrow = sh1.Range("A" & Rows.Count).End(xlUp).Row
For x = 1 To r
If sh1.Range("A" & x) = sh2.Range("A" & x) And sh1.Range("B" & x) = sh1.Range("A" & x) & sh2.Range("B" & x) Then
sh1.Range("A" & x).EntireRow.Copy Destination:=sh2.Range("C" & x)
x = x + 1
Next x
End Sub
Please help, I have been struggling with this for days now and I need to hand in a report by the end of today, and I just cannot find anything helpful on the internet. I really appreciate any advice
If You want to use loops, try that:
Sub matchme()
Dim sh1 As Worksheet
Dim sh2 As Worksheet
Dim x As Long
Dim i As Long
Dim j As Long
Dim lastrow As Long
Dim lastRow2 As Long
Dim lastCol2 As Long
Set sh1 = Sheets("Sheet1")
Set sh2 = Sheets("Sheet2")
lastrow = sh1.Range("A" & Rows.Count).End(xlUp).Row
With sh2
lastRow2 = .Cells(Rows.Count, 1).End(xlUp).Row
lastCol2 = .Cells(1, Columns.Count).End(xlUp).Column
End With
For x = 1 To lastrow
For i = 1 To lastRow2
For j = 1 To lastCol2
If sh1.Cells(x, 1) = sh2.Cells(i, j) Then
If sh1.Cells(x, 2) = sh2.Cells(i, j + 1) Then
MsgBox "Found match!"
End If
End If
Next j
Next i
Next x
End Sub
I haven't tested this.
I've assumed you are searching for sheet1 A values in sheet2 column A only.
When a match is found, the column C value on sheet2 is copied to column C on sheet1.
Sub x()
Dim rFind As Range, s As String, r As Range
With Sheet1
For Each r In .Range("A1", .Range("A" & Rows.Count).End(xlUp))
Set rFind = Sheet2.Columns(1).Find(What:=r.Value, Lookat:=xlWhole, MatchCase:=False, SearchFormat:=False)
If Not rFind Is Nothing Then
s = rFind.Address
Do
If rFind.Offset(, 1).Value = r.Offset(, 1).Value Then
r.Offset(, 2).Value = rFind.Offset(, 2).Value
End If
Set rFind = Sheet2.Columns(1).FindNext(rFind)
Loop While rFind.Address <> s
End If
Next r
End With
End Sub
To get the pairs of Sheet1 and look for them in Sheet2:
I've used this code:
Application.ScreenUpdating = False
Dim i As Long
Dim LastRow As Long
Dim rng As Range
Dim wk1 As Worksheet
Dim wk2 As Worksheet
Dim SearchThis As String
Set wk1 = ThisWorkbook.Worksheets("Sheet1")
Set wk2 = ThisWorkbook.Worksheets("Sheet2")
LastRow = wk1.Range("A" & wk1.Rows.Count).End(xlUp).Row
'<--------------------------------->
'For more type of SPECIAL CELLS, and choose exactly the type you need
'please read https://learn.microsoft.com/en-us/office/vba/api/excel.range.specialcells
For i = 1 To LastRow Step 1
SearchThis = UCase(wk1.Range("A" & i).Value & wk1.Range("B" & i).Value)
For Each rng In wk2.Cells.SpecialCells(xlCellTypeConstants, 23)
If UCase(rng.Value & rng.Offset(0, 1).Value) = SearchThis Then
'code to copy where you want
Debug.Print rng.Row
End If
Next rng
Next i
Set wk1 = Nothing
Set wk2 = Nothing
Application.ScreenUpdating = True
The output of this code is:
Those are the row numbers where the pairs are. You just need to add a code to copy the entire row.
Hope this helps
Try below code (comments in code):
Dim sh1 As Worksheet
Dim sh2 As Worksheet
Dim r As Range
Set sh1 = Sheets("Sheet1")
Set sh2 = Sheets("Sheet2")
lastRow = sh1.Range("A" & Rows.Count).End(xlUp).Row
iLastRow = sh2.Range("A" & Rows.Count).End(xlUp).Row
For j = 1 To lastRow
For i = 1 To iLastRow
If sh1.Cells(j, 1) = sh2.Cells(i, 1) And sh1.Cells(j, 2) = sh2.Cells(i, 2) Then
sh1.Cells(i, 3) = "Write some information"
End If
'you don't need to increment loop variable "Next" does it for you
'also i is better suited for iterator name :)
Next
Next
Part 1: Check if column B values exist in column C. If yes then change the font of the string in column B to Bold.
Part 2: I've used the code below and it worked well. Never tried it with 50k rows.
Sub matching()
LastRow = Sheet1.Cells(Rows.Count, 2).End(xlUp).Row
Application.ScreenUpdating = False
For x = 1 To LastRow
'Column B = Username
If Sheet1.Range("B" & x).Font.Bold = True Then Sheet1.Range("A" & x).Value = "yay"
Next x
Application.ScreenUpdating = True
End Sub
If you have to handle too many rows, is better to use Dictionary to store values of column C & use Array to store values in column B.
Notes:
Add "Microsoft Scripting Runtime" reference (Tools - References - "Microsoft Scripting Runtime")
Dictionary is case sensitive.
You may need to change the sheet name in line Set ws = ThisWorkbook.Worksheets("Sheet1") to fulfill your needs
You could try:
Option Explicit
Sub matching()
Dim ws As Worksheet
Dim dict As Scripting.Dictionary
Dim LastRowB As Long, LastRowC As Long, Count As Long, x As Long
Dim rng As Range, cell As Range
Dim arr As Variant
Set ws = ThisWorkbook.Worksheets("Sheet1")
Set dict = New Scripting.Dictionary
Application.ScreenUpdating = False
With ws
'Find the lastrow of column B
LastRowB = .Cells(.Rows.Count, "B").End(xlUp).Row
'Find the lastrow of column C
LastRowC = .Cells(.Rows.Count, "C").End(xlUp).Row
'Set an array with the values in column B - We assume that values start from row 1
arr = .Range("B1:B" & LastRowB)
'Set the range of the dicitonary - We assume that values start from row 1
Set rng = .Range("C1:C" & LastRowC)
Count = 0
'Loop range and create a dictionary with th eunique values
For Each cell In rng
If Not dict.Exists(cell.Value) Then
dict.Add Key:=cell.Value, Item:=Count
Count = Count + 1
End If
Next cell
'Loop the array & bold
For x = LBound(arr) To UBound(arr)
If dict.Exists(arr(x, 1)) Then
.Range("B" & x).Font.Bold = True
End If
Next x
End With
Application.ScreenUpdating = True
End Sub
Here you go.
Sub bold()
Dim lastrow As Double
Dim cel As Range
lastrow = Sheet1.Cells(Rows.Count, 1).End(xlUp).Row
For Each cel In Range("B1" & ":B" & lastrow)
If Not ActiveSheet.Range("C:C").Find(cel.Value) Is Nothing Then cel.Font.bold = True
Next cel
End Sub
I am not a programmer by trade but I am trying to automate a small portion of a report I use every day out of curiosity and self interest. Basically, we receive and manually enter contact information (name, e-mail, phone number, etc.) and mark select groups that a person is interested in joining. We then copy and paste that contact information entered into a different sheet for each group.
I want to have a macro that checks the specific columns for each interest group for a "x" and if it finds that value copy and paste the contact information collected to the specific interest groups worksheet. People are able to select multiple interest groups and their contact information is added to each separate interest group spreadsheet.
Report columns look as follows:
Group 1 Group 2 Group 3 Name Organization Phone E-mail Notes
Row Contact Information looks similar to:
x x John ABC Inc. 000-000-0000 john.smith#fake.com Call me ASAP!
The macro checks the column I have marked interest in Group 1 in and if it finds "x" then it copies the full range to the Group 1 worksheet.
I want it to be able to check multiple columns (i.e. Group 1, 2, 3) for "x" and then copy and paste the information to the right of those columns to the appropriate sheet for the group. If they have interest in multiple groups, their contact info should be copied to each specific worksheet.\
Do I need to have separate counters for each group worksheet and is there a way to write a if then statement that checks for x in each of the columns and then runs the appropriate code to copy and paste into that group?
Sub Update()
Dim c As Range
Dim j As Integer
Dim Source As Worksheet
Dim Target1 As Worksheet
Dim Target2 As Worksheet
Dim Target3 As Worksheet
Set Source = ActiveWorkbook.Worksheets("Interest Group Tracking")
Set Target1 = ActiveWorkbook.Worksheets("Group 1")
j = 1 'Start copying to row 1 in target sheet
For Each c In Source.Range("A1:A1000") 'not sure if there is a way to not set a limit for the range
If c = "x" Then
Source.Rows(c.Row).Copy Target1.Rows(j + 1)
j = j + 1
End If
Next c
End Sub
No errors besides the occasional syntax but don't really know how to structure the loop for checking for each group. I am continuing to research and test things I find and will update if I need to.
See if this helps... I've added comments in the code, but please feel free to ask any other questions:
Sub Update()
Dim wb As Workbook: Set wb = ThisWorkbook
Dim Source As Worksheet: Set Source = wb.Worksheets("Interest Group Tracking")
Dim Target As Worksheet
Dim R As Long, C As Long, lRowSrc As Long, lRowDst As Long
With Source
lRowSrc = .Cells(.Rows.Count, 1).End(xlUp).Row 'get the last row in your source sheet
For R = 1 To lRowSrc 'Loop through all rows in the source
For C = 1 To 3 'Loop through the 3 columns in the source
If .Cells(R, C) = "x" Then
Set Target = wb.Worksheets("Group " & C) 'Assuming all groups have the same names, Group 1, Group 2, etc
lRowDst = Target.Cells(Target.Rows.Count, 1).End(xlUp).Row + 1 'get last row + 1 in the target sheet
.Rows(R).Copy Target.Rows(lRowDst)
End If
Next C
Next R
End With
End Sub
EDIT: additional sample
Sub Update()
Dim wb As Workbook: Set wb = ThisWorkbook
Dim Source As Worksheet: Set Source = wb.Worksheets("Interest Group Tracking")
Dim Target As Worksheet
Dim shNames() As String: shNames = Split("ABC Group,Voter Accesibility,Animal Rights Activism", ",") 'Add sheet names here in the order of the groups
Dim R As Long, C As Long, lRowSrc As Long, lColSrc As Long, lRowDst As Long
With Source
lRowSrc = .Cells(.Rows.Count, 1).End(xlUp).Row 'get the last row in your source sheet
For R = 1 To lRowSrc 'Loop through all rows in the source
For C = 1 To 3 'Loop through the 3 columns in the source
If .Cells(R, C) = "x" Then
Set Target = wb.Worksheets(shNames(C - 1)) 'shNames array starts at 0
lRowDst = Target.Cells(Target.Rows.Count, 1).End(xlUp).Row + 1 'get last row + 1 in the target sheet
Target.Range(Target.Cells(lRowDst, 1), Target.Cells(lRowDst, 10 - C + 1)) = .Range(.Cells(R, C), .Cells(R, 10)).Value 'allocate the values
End If
Next C
Next R
End With
End Sub
Another way of doing it.
Option Explicit
Sub CopyData()
Dim srcWB As Workbook
Dim srcWS As Worksheet
Dim destWS As Worksheet
Dim CopyRange As Variant
Dim i As Long, j As Long
Dim srcLRow As Long, destLRow As Long
Dim LCol As Long
Set srcWB = ActiveWorkbook
Set srcWS = srcWB.ActiveSheet
srcLRow = srcWS.Cells(srcWS.Rows.Count, "A").End(xlUp).Row
'loop through column 1 to 3
For i = 1 To 3
For j = 2 To srcLRow
'loop through rows
If srcWS.Cells(j, i).value = "x" Then
Set destWS = srcWB.Sheets("Sheet" & i)
destLRow = destWS.Cells(destWS.Rows.Count, "A").End(xlUp).Row
LCol = srcWS.Cells(j, srcWS.Columns.Count).End(xlToLeft).Column 'if you need to grab last used column
' Copy data
Set CopyRange = srcWS.Range(Cells(j, 1), Cells(j, LCol))
CopyRange.Copy
' paste data from one sht to another
destWS.Cells(destLRow + 1, 1).PasteSpecial Paste:=xlPasteAll, Transpose:=False
Application.CutCopyMode = False
End If
Next j
Next i
MsgBox "Process completed!", vbInformation
End Sub
I changed the main piece of logic at the end but this should work. Instead of copy and pasting, I just made the range in the group1 sheet equal to the row's range. I also use the last used row.
Sub Update()
Dim c As Range
Dim j As Integer
Dim k As Integer
Dim Source As Worksheet
Dim Target1 As Worksheet
Dim Target2 As Worksheet
Dim Target3 As Worksheet
Dim curSheet As Worksheet
Dim lastRow, lastRow1, lastRow2, lastRow3, lastCol As Long
Dim group1, group2, group3, curGroup As Long
Set Source = ActiveWorkbook.Worksheets("Interest Group Tracking")
Set Target1 = ActiveWorkbook.Worksheets("Group 1")
Set Target2 = ActiveWorkbook.Worksheets("Group 2")
Set Target3 = ActiveWorkbook.Worksheets("Group 3")
j = 1
group1 = 1
group2 = 1
group3 = 1
With Source
lastCol = .Cells(1, .Columns.Count).End(xlToLeft).Column
lastRow1 = .Cells(.Rows.Count, 1).End(xlUp).Row
lastRow2 = .Cells(.Rows.Count, 2).End(xlUp).Row
lastRow3 = .Cells(.Rows.Count, 3).End(xlUp).Row
If lastRow1 > lastRow2 And lastRow1 > lastRow3 Then
lastRow = lastRow1
End If
If lastRow2 > lastRow1 And lastRow2 > lastRow3 Then
lastRow = lastRow2
End If
If lastRow3 > lastRow1 And lastRow3 > lastRow2 Then
lastRow = lastRow3
End If
For j = 1 To lastRow
For k = 1 To 3
If .Cells(j, k) = "x" Then
Set curSheet = ActiveWorkbook.Sheets("Group" & " " & k)
If k = 1 Then
curGroup = group1
ElseIf k = 2 Then
curGroup = group2
ElseIf k = 3 Then
curGroup = group3
Else
GoTo line1
End If
curSheet.Range(curSheet.Cells(curGroup, 1), curSheet.Cells(curGroup, lastCol)).Value = .Range(.Cells(j, 1), .Cells(j, lastCol)).Value
End If
If k = 1 Then
group1 = group1 + 1
ElseIf k = 2 Then
group2 = group2 + 1
ElseIf k = 3 Then
group3 = group3 + 1
End If
line1:
Next k
Next j
End With
End Sub