select row based on cell value - vba

I am working on a macro to move data from one sheet to another based on matching cell values.
Let's say I have 2 sheets, Sheet1 & Sheet2, respectively.
Sheet1 contains data that I wanted to be copied into Sheet2.
Sheet2 contains a value in column "C", and this value with have multiple matches in column "C" of
Sheet1 (which are already sorted and same values are grouped together).
My overall goal is to copy cells from Sheet1 to Sheet2 based on matching values in column "C". I want to insert these values one row below the row with matching column "C" values.
The difficulty lies in the fact that the range of values copied from Sheet1 to Sheet2 will differ with each different value in Column "c" of Sheet2, because there will be a different number of rows with respect to a particular cell value.
(I would show a simple picture for this, but it won't allow me to post a picture due to low post count - I can email this if needed for clarification)
I am okay with basic macro stuff and rely on the Macro Record for some stuff as well. But with my current knowledge and lack of the macro recorder's ability to make a macro like this, I am just stumped!
My request:
Help with macro that selects a range of cells based on matching cell values to copy
Help with inserting the copied range starting 1 row below the cell value of interest (cell value is row 2, insert cells starting at row 3)
Have this repeated for each value listed in Sheet2
I think I can figure the basic coding with this. If I can just get help with the particular string that does what I am looking for would be great! I am not trying to just be handed the answer, but I have been working on this issue for 8+hrs and can't find anything online that is similar to this...

This code assumes that you have sorted the data as you have in the example:
Sub transfer()
'If everything is sorted, you can do it like this:
Dim x, y 'x is the sheet1 row, y is the sheet2 row
y = 2 'they start at the same place x = 2, y = 2
For x = 2 To Sheets(1).Cells(Sheets(1).Rows.Count, "A").End(xlUp).Row
If Sheets(1).Cells(x, 1) = Sheets(2).Cells(y, 1) Then 'If the cell value matches
Sheets(1).Range("A" & x).Copy 'Copy the cell value from Sheet1
Sheets(2).Cells(y + 1, 1).Insert Shift:=xlDown 'And insert it below the Sheet2 Cell
'Then copy the rest of the data (columns C and D)
Sheets(1).Range("C" & x & ":D" & x).Copy Destination:=Sheets(2).Cells(y + 1, 2)
Else
x = x - 1 'We haven't found a match for this cell yet so check it again
End If
y = y + 1 'After incrementing y
Next x
End Sub
Sorry for slow reply - I can explain the code to you soon if need be!
Hope this helps! :)
I wrote this specifically for the example you gave me, so hopefully you are able to build upon this concept if your needs change.

Related

Loop through column values from one sheet and paste COUNTIF value from another column into another sheet

I have two sheets in an Excel file and need to perform a COUNTIF formula from one sheet and paste the respective information in another sheet. The original sheet just has the type in 1st column with an empty 2nd column. I am trying to loop through the Type from Sheet 1, in each increment loop through the Type from Sheet 2, and past the Count of column 2 from Sheet 2 into Column 2 of sheet 1.
My current VBA code is as follows:
Sub TestOE()
'For loop to go until end of filled cells in 1st column of each sheet
a = Worksheets("Sheet1").Cells(Rows.Count, 1).End(xlUp).Row
b = Worksheets("Sheet2").Cells(Rows.Count, 1).End(xlUp).Row
'Loop
For i = 2 To a
For j = 2 To b
If Worksheets("Sheet1").Cells(i, 1).Value = Worksheets("Sheet2").Cells(j, 1).Value Then
Worksheets("Sheet1").Cells(i, 2).Value = Application.WorksheetFunction.CountIf(Range("B:B"), 1)
End If
Next j
Next i
End Sub
This code is only pasting 0's in the desired outcome on Sheet 1.
Sheet to extract information from
Sheet to paste information in
Desired Outcome in destination sheet
You can simply use sumif function to sum the values based on criteria.
here is the formula
=COUNTIF(Sheet1!$A$2:$A$20,Sheet2!A2)
if you want to sum the col B then
=SUMIF(Sheet1!$A$2:$A$20,Sheet2!A2,Sheet1!$B$2:$B$20)
In a few steps, you can accomplish what you want without VBA, and just use a pivot table. Just do as follows.
Select your data set, including the header.
Click on insert tab, then PivotTable. See example for Office 365
Since you want a different worksheet, set PivotTable to be "New Worksheet" See example.
You'll need to drag the TYPE field into the rows, and binary into the values. CountIF is the same as summing binary, so you can leave as sum. See Example
And you'll have an output nearly identical to what you're looking for:

Overwrite row data in one sheet with data from a second sheet satisfying 4 conditions

I've looked at several threads and there are some that touch on my problem, however, I've never used VBA and haven't a clue how to change the coding to suit my problem.
I would like to overwrite rows of data on sheet 2 from sheet 1, providing the data in columns A, B, C & D (live data starting row 2) are a match on both sheets 1 & 2.
Essentially sheet 2 is my data store, and sheet 1 is a template of sheet 2. All the possible combinations of data in the first four columns already exist in sheet 2 with the remaining data in the row unknown. So when I get that unknown data, I would like to overwrite that row in sheet 2.
A lot of people have made threads about copying rows over where one specific term is searched for in a column, whereas, I will have many different terms to search for, but as I said, they will need to be a match on both sheets.
Hope I've made sense! Please help!
You may be able to do this with a formula rather than using VBA.
Paste this formula into cell E1 of sheet1 if you have no headers:
=IF(AND(A1=INDEX(Sheet2!A:A,MATCH(A1,Sheet2!A:A,FALSE)),B1=INDEX(Sheet2!B:B,MATCH(B1,Sheet2!B:B,FALSE)), C1=INDEX(Sheet2!C:C,MATCH(C1,Sheet2!C:C,FALSE)),D1=INDEX(Sheet2!D:D,MATCH(D1,Sheet2!D:D,FALSE))),INDEX(Sheet2!E:E,MATCH(A1,Sheet2!A:A,FALSE)),"NO")
Or this one into E2 if you have a header row:
=IF(AND(A2=INDEX(Sheet2!A:A,MATCH(A2,Sheet2!A:A,FALSE)),B2=INDEX(Sheet2!B:B,MATCH(B2,Sheet2!B:B,FALSE)), C2=INDEX(Sheet2!C:C,MATCH(C2,Sheet2!C:C,FALSE)),D2=INDEX(Sheet2!D:D,MATCH(D2,Sheet2!D:D,FALSE))),INDEX(Sheet2!E:E,MATCH(A2,Sheet2!A:A,FALSE)),"NO")
Then drag that across using the little toggle on the bottom right of the cell as far across sheet1 as you want the columns to come in from your sheet2.
Then highlight the whole row you just created and drag the little toggle at the bottom right as far down the sheet as you have data (or try double clicking the toggle to auto fill down).
I tried this on a small set of data and it seems to work so it should work for your larger data set as long as all possible variations of the 4 columns on sheet1 are available on sheet2 with associated data in the following columns.
If you get a result of "NO" in any cell then Excel can't find a row in sheet2 which has the exact combination matching the one on sheet1.
EDIT - UPDATED ANSWER BELOW.
Try this, which is much more likely to work for you.
Sub CopyItOver()
Dim sh1 As Worksheet, sh2 As Worksheet
Set sh1 = Sheets("Sheet1")
Set sh2 = Sheets("Sheet2")
For Each c1 In sh1.Range("A1", sh1.Range("A1").End(xlDown))
For Each c2 In sh2.Range("A1", sh2.Range("A1").End(xlDown))
If c2.Value = c1.Value Then
If c2.Offset(0, 1).Value = c1.Offset(0, 1).Value Then
If c2.Offset(0, 2).Value = c1.Offset(0, 2).Value Then
If c2.Offset(0, 3).Value = c1.Offset(0, 3).Value Then
c1.EntireRow.Value = c2.EntireRow.Value
End If
End If
End If
End If
Next c2
Next c1
End Sub

Using loop and sum functions with Vlookup

I've got a macro that essentially searches column C in Sheet1 for the value "Rec" and copies the corresponding value in column D, then pastes it into the last open cell in column B of Sheet2. It does just what it is supposed to do and is as follows:
Sub FindPasteGSVInNextCell()
Worksheets("Sheet2").Activate
Range("B" & Rows.Count).End(xlUp).Offset(1, 0).Value = _
WorksheetFunction.VLookup("Rec", Sheet1.Range("C2:H25"), 2, False)
End Sub
I now want the code, instead of just searching for a single "Rec" value, to search for all rows with "Rec" in column C and to sum up all of their corresponding values in column D, then place that sum into Sheet2.
I am assuming that I need some kind of Do Until loop or something, but I am not exactly sure how to format it... I am a beginner with VBA, so any help would be greatly appreciated.
vlookup will not work as it will continue to only grab the first instance of "Rec".
On Sheet 2 list all the possible categories in column A then in column B1 put
= sumif(Sheet1!C:C,A1,Sheet1!D:D)
then copy down. This will Get you the totals by category.
If you want to use VBA, you will still need a list of categories setup somewhere, either hard coded or listed somewhere that you can loop through.
If your list was in column A on Sheet2 then you would:
dim ws as worksheet
set ws = Worksheets("Sheet2")
For each i in ws.range(ws.Range("A1"),ws.Range("A1").offset(xldown)).Cells
i.offset(,1) = WorksheetFunction.Sumif(Worksheets("Sheets1").Range("C:C"), _
i,Worksheets("Sheets1").Range("D:D"))
next i

VBA Subroutine to fill formula down column

I have a current Sub that organizes data certain way for me and even enters a formula within the first row of the worksheet, but I am running into the issue of wanting it to be able to adjust how far down to fill the formula based on an adjacent column's empty/not empty status. For example, each time I run a report, I will get an unpredictable amount of returned records that will fill out rows in column A, however, since I want to extract strings from those returned records into different Columns, I have to enter formulas for each iteration within the next three columns (B, C, and D). Is there a way to insert a line that will evaluate the number of rows in Column A that are not blank, and then fill out the formulas in Columns B, C, and D to that final row? (I know that tables will do this automatically once information is entered in the first row, but for logistical reasons, I cannot use tables).
My current code that fills out the formula in Column B, Row 2 is:
Range("B2").Select
ActiveCell.FormulaR1C1 = "=MID(RC[-1],FIND(""By:"",RC[-1])+3,22)"
Thanks!
The formula that you actually need is
=IF(A2="","",MID(A2,FIND("By:",A2)+3,22))
instead of
=MID(A2,FIND("By:",A2)+3,22) '"=MID(RC[-1],FIND(""By:"",RC[-1])+3,22)"
This checks if there is anything in cell A and then act "accordingly"
Also Excel allows you to enter formula in a range in one go. So if you want the formula to go into cells say, A1:A10, then you can use this
Range("A1:A10").Formula = "=IF(A2="","",MID(A2,FIND("By:",A2)+3,22))"
Now how do we determine that 10? i.e the Last row. Simple
Sub Sample()
Dim ws As Worksheet
Dim lRow As Long
'~~> Change the name of the sheet as applicable
Set ws = ThisWorkbook.Sheets("Sheet1")
With ws
'~~> Find Last Row in Col A
lRow = .Range("A" & .Rows.Count).End(xlUp).Row
.Range("B2:B" & lRow).Formula = "=IF(A2="""","""",MID(A2,FIND(""By:"",A2)+3,22))"
End With
End Sub
More About How To Find Last Row
You can use this to populate columns B:D based on Column A
Range("B2:D" & Range("A" & Rows.Count).End(xlUp).Row).Formula = _
"=MID($A2,FIND(""By:"",$A2)+3,22)"

Adjust criteria to depend on multiple values

I have been working on a code to copy the data from one specific range(always the same) and paste in another spreadsheet always in the row below. So basically, it starts pasting on row 11, but if I run again it will paste on the row 12 and there it goes.. The code has been working fine, but there is only one problem. It identifies the next empty row(to paste) based on the value of the column AP, but i want it to identify based on the values of all the columns between AP:BA. Thus, if there is any value on those cells, it should copy on the row below, not only if there is a value on AP. Does someone know how to change my code in order to solve this problem? Thank You very much
Sub Copy_Shanghai()
Dim count As Integer
count = 11
Do While Worksheets("Time Evolution").Range("AP" & count).Value <> ""
'<>"" means "is not empty", as long as this happens we go down looking for empty cell
count = count + 1
Loop
'Now count is row with first empty cell outside of top 10 rows in column C
Worksheets("Fill").Range("E5:P5").Copy
Worksheets("Time Evolution").Range("AP" & count).PasteSpecial xlPasteValues
End Sub