Copy Rows to different sheets, IF cell value matches to another sheet - excel

I have 2 worksheets. sheet1 is monthly Value on col A. Sheet 2 is daily value on col A, I would Like Excel to look for the same value in worksheet 2 (Daily), then once it finds that exact value, to copy the matched rows form sheet 1 (monthly) and paste it in sheet 2 (Daily).
Any ideas how to write a VBA code that will automate this copy and paste values process? (see the screenshot)
[1]: https://i.stack.imgur.com/G5LqW.png
[on the right handside, data is per month (last day of each month), i need to match col Aof both sheets, and bring the data to other sheet on exact day (last day of that month)][1]

Untested
Sub Copy18()
Dim wb As Workbook
Dim wsD2 As worksheet, wsM2 As Worksheets
Dim LastRow As long, LastCol As Long, i as long
Dim Cell As Range, Rng As Range, SearchR As Range, CopyRng As Range, PasteRng As Range
Set wb = ThisWorkbook
Set wsD2 = wb.Sheets("Daily-2")
Set wsM2 = wb.Sheets("Monhly-2")
LastCol = wsM2.Cells(1, Columns.Count).End(xlToLeft).Column
LastRow = wsM2.Cells(Rows.Count, 1).End(xlUp).Row
Set Rng = wsD2.Range(wsD2.Cells(1,1), wsD2.Cells(LastRow, LastCol))
For Each Cell in Rng
Set SearchR = wsM2.Range("A:A").Find(Cell.Value, LookAt:=xlWhole)
If Not SearchR Is Nothing Then
i = LastCol = wsM2.Cells(SearchR.Row, Columns.Count).End(xlToLeft).Column
Set CopyRng = wsM2.Range(wsM2.Cells(SearchR.Row, 1), wsM2.Cells(SearchR.Row, i))
Set PasteRng = wsD2.Range(wsD2.Cells(LastRow + 1, 1), wsD2.Cells(LastRow + 1, i))
PasteRng.Value = CopyRng.Value
LastRow = LastRow + 1
End If
Next Cell
End Sub

Related

scan column for a variable and select the row

i have a big datasheet and i need a code to scan a column( screenshot "selection") for a x or add a checkbox. If there is a x the row should be selected and some of the columns should be transposed into a new table.
i have an code to scan the column for x and have the code to transpose the columns i need but i need some help to combine these codes together.
scan column(selection) for an x and select the rows
transpose some cells(selected colums) of the selected row into a new table ( i have the code)
For Each c In Range("K:K")
' If c.Value = "x" Then
' MsgBox "x found at " & c.Address
'End If
'Next c
Sub TransposeColumn2Row()
Dim ws1 As Worksheet, ws2 As Worksheet
Dim Myarray() As Variant
Dim LastRow As Integer, LastColumn As Integer
Dim StartCell As Range
Set ws1 = ThisWorkbook.Sheets("Sheet1")
Set ws2 = ThisWorkbook.Sheets("Sheet2")
Dim i As Long
Dim j As Long
Set StartCell = ws1.Range("A1")
LastRow = ws1.Cells(ws1.Rows.Count, StartCell.Column).End(xlUp).Row
LastColumn = ws1.Cells(StartCell.Row, ws1.Columns.Count).End(xlToLeft).Column
'copy specific columns into worksheet 2
j = 1
For i = 1 To LastColumn Step 1
Select Case i
Case 1, 4, 8, 6, 9, 3, 5 'target columns to copy
With ws1
Myarray() = .Range(.Cells(1, i), .Cells(LastRow, i)).Value
End With
With ws2
.Range(.Cells(j, 1), .Cells(j, LastRow)) = Application.WorksheetFunction.Transpose(Myarray())
End With
j = j + 1
Case Else
End Select
Next i
Erase Myarray()
End Sub
Help me combine these codes
Thx in advance
If this is a one-time task, I would use a formula:
=TRANSPOSE(FILTER(FILTER(A:J, {1,0,1,1,1,1,0,1,1,0}), K:K="x"))
The exact notation depends on local settings (the formula looks different in my case). But this one can be used with Evaluate in VBA. Here we mark columns to copy with an array {1,0,1,1,1,1,0,1,1,0} and then filter the rows with "x" in the column K.
As for VBA, this case would be easier to solve with ListObject in general case. But we can also Intersect columns of interest with marked rows and .Copy toDestination:
Sub CopyMarked()
Dim Source As Worksheet
Dim Destination As Worksheet
Dim Data As Range
Dim Criteria As Range
Set Source = ActiveSheet
Set Destination = Worksheets.Add(After:=Source)
Set Data = Source.Range("A:A, C:F, H:I") ' columns 1,4,8,6,9,3,5
Set Criteria = Source.Columns("K").SpecialCells(xlCellTypeConstants).EntireRow
Intersect(Data, Criteria).Copy
Destination.Range("a1").PasteSpecial xlPasteValues, Transpose:=True
End Sub

Subtract via VBA: Rows values in Column C = Row values in Column A - Row values in Column B

I wrote a code that allows me, after pasting data into my worksheet, to add a column with the new data into a table dynamically into my "Weekly" sheet of the same worksheet. This means that every single time I add data on a weekly basis, my VBA code add a new column into the "Weekly" sheet that we will call ColumnC.
What I am missing here is the subtraction of the values contained in ColumnC and ColumnA into ColumnB considering that these are dynamic, that is that the week after we will need ColumnE - ColumnC into ColumnD:
Is there someone who can point towards the right direction?
Sub SubtractDynamicColumns()
Dim sht As Worksheet
Dim LastColumn As Long, PreviousData As Long, PreviousColumn As Long
Set sht = ThisWorkbook.Worksheets("Weekly")
LastColumn = sht.Cells(2, sht.Columns.Count).End(xlToLeft).Column
PreviousData = sht.Cells(2, sht.Columns.Count).End(xlToLeft).Column - 2
PreviousColumn = sht.Cells(2, sht.Columns.Count).End(xlToLeft).Column - 1
End Sub
Thank you
I got this to work, but it puts the values in as values, not as a formula.
Sub SubtractDynamicColumns()
Dim sht As Worksheet
Dim LastColumn As Long, PreviousData As Long, PreviousColumn As Long
Dim LastRow As Long, row_no As Long
Set sht = ThisWorkbook.Worksheets("Weekly")
LastColumn = sht.Cells(2, sht.Columns.Count).End(xlToLeft).Column
LastRow = ActiveSheet.Cells(Cells.Rows.Count, LastColumn).End(xlUp).Row
PreviousData = sht.Cells(2, sht.Columns.Count).End(xlToLeft).Column - 2
PreviousColumn = sht.Cells(2, sht.Columns.Count).End(xlToLeft).Column - 1
For row_no = 2 To LastRow
sht.Cells(row_no, PreviousColumn).Value = (Cells(row_no, LastColumn).Value - Cells(row_no, PreviousData).Value)
Next
End Sub
Sub SubtractDynamicColumns()
Dim rng As Range
Set rng = ThisWorkbook.Worksheets("Weekly").Range("A1").CurrentRegion ' A1 - any cell in the range
Intersect(rng.Columns(rng.Columns.Count - 1), rng.Offset(1)).FormulaR1C1 = "=RC[1]-RC[-1]" 'get the penultimate column except for the header row and set the formula
End Sub

How to copy whole columns from one sheet to the next if it finds a match in the header in sheet 2

I'm working with two sheets. One sheet has the full raw data while the other has a select few headers from sheet 1. If it finds a match on the header, i need it to copy the full column from sheet one to sheet 2
and it copies it to sheet 2
Here is my code so far but i can't figure out how to break the loop so that it goes through every column on sheet 1 until it finds a match:
Private Sub CommandButton1_Click()
Dim ShtOne As Worksheet, ShtTwo As Worksheet
Dim shtOneHead As Range, shtTwoHead As Range`enter code here`
Dim headerOne As Range, headerTwo As Range
Set ShtOne = Sheets("Sheet1")
Set ShtTwo = Sheets("Sheet2")
'row count
Dim b As Long
b = ShtOne.Cells(Rows.Count, 1).End(xlUp).Row
'column count in sheet 1
Dim a As Long
a = ShtOne.Cells(1, Columns.Count).End(xlToLeft).Column
'column count in sheet 2
Dim c As Long
c = ShtTwo.Cells(1, Columns.Count).End(xlToLeft).Column
Dim lastCol As Long
'get all of the headers in the first sheet, assuming in row 1
lastCol = ShtOne.Cells(1, Columns.Count).End(xlToLeft).Column
Set shtOneHead = ShtOne.Range("A1", ShtOne.Cells(1, lastCol))
'get all of the headers in second sheet, assuming in row 1
lastCol = ShtTwo.Cells(1, Columns.Count).End(xlToLeft).Column
Set shtTwoHead = ShtTwo.Range("A1", ShtTwo.Cells(1, lastCol))
'stops the visual flickering of files opening and closing - run at the background
Application.ScreenUpdating = False
'start loop from first row to last row
'For i = 1 To a
i = 1
j = 0
'actually loop through and find values
For Each headerOne In shtOneHead
j = j + 1
For Each headerTwo In shtTwoHead
'copy and paste each value
If headerTwo.Value = headerOne.Value Then
'copies one row at a time (a bit slow)
' headerOne.Offset(i, 0).Copy
' headerTwo.Offset(i, 0).PasteSpecial xlPasteAll
'copies whole rows at a time
ShtOne.Columns(i).Copy ShtTwo.Columns(j)
i = i + 1
Application.CutCopyMode = False
Exit For
End If
Next headerTwo
Next headerOne
'Next
End Sub
Assuming your headers are on row 1 for both sheets and that you will always be pasting on the second row on Sheet2.
Only loop through your column headers on the second sheet. Use Range.Find to search for each header on Sheet1. If the header is found, copy and paste accordingly
Sub Headerz()
Dim ws1 As Worksheet: Set ws1 = ThisWorkbook.Sheets("Sheet1")
Dim ws2 As Worksheet: Set ws2 = ThisWorkbook.Sheets("Sheet2")
Dim LC As Long, i As Long, LR As Long
Dim Found As Range
LC = ws2.Cells(1, ws2.Columns.Count).End(xlToLeft).Column
For i = 1 To LC
Set Found = ws1.Rows(1).Find(ws2.Cells(1, i).Value)
If Not Found Is Nothing Then
LR = ws1.Cells(ws1.Rows.Count, Found.Column).End(xlUp).Row
ws1.Range(ws1.Cells(2, Found.Column), ws1.Cells(LR, Found.Column)).Copy
ws2.Cells(2, i).PasteSpecial xlPasteValues
End If
Set Found = Nothing
Next i
End Sub

Copy Paste works only if Range is greater then 20 rows

Would you know what is the following code adjustment needed. Range I have set up (A1:B20) changes over time. The first block of data stays be between A1:B20 and the second block of data always will be between A25:B60. Ranges will change over time. First block of data could reach 200 rows going down. After my code reaches the second block of data and my range falls between that block of data it picks up the range only if I have adjusted manually the range. Please note, Second block of data normally provides duplicates from the first block.
How could I have my code automatically select the first block of data past my range output without having to adjust the "range" manually?
Sub CopyPaste()
Dim lastRow As Long
Dim Sheet2 As Worksheet
Dim Results As Worksheet
Dim LookupLastrow As Long
'code line will set values from sheet
("Sheet1") into ("Sheet2") starting 5 rows down.
Set Results = Sheets("Sheet2")
lastRow = ThisWorkbook.Sheets("Sheet2").Cells(Rows.Count, 1).End (xlUp).row
Range("A1:B20" & lastRowcount).Copy
Results.Range("A" & lastRow + 5).PasteSpecial xlPasteValuesAndNumberFormats
Application.GoTo ActiveSheet.Range("A1"), True
Application.CutCopyMode = False
End Sub
Think simple. No need to build strings for range addresses, and no need for using the clipboard with .Copy and .Paste. Use a direct assignment to the .Value property in a table of cells.
Public Sub CopyValues()
Dim r_src As Range, r_dst As Range
' Source starts at row 20
Set r_src = Sheets("Sheet 2").Cells(20, 1)
' Destination starts at row 5
Set r_dst = Sheets("Sheet 1").Cells(5, 1)
Dim n As Long
' Count the non-empty cells
n = r_src.Range(r_src, r_src.End(xlDown)).Rows.Count
' Copy n rows and 2 columns with one command
r_dst.Resize(n, 2).Value = r_src.Resize(n, 2).Value
End Sub
Based on the picture you showed, the following code will capture the entire top and bottom sections, regardless of how many lines or columns exists. This assumes your top section will start in "A8" as shown. You can edit the code to reflect your actual sheet names.
Sub CopyPaste()
Dim OrigLastRow As Long
Dim OrigLastCol As Long
Dim DestLastRow As Long
Dim OrigRng As Range
Dim ws1 As Worksheet
Dim ws2 As Worksheet
Set ws1 = ThisWorkbook.Worksheets("Origin")
Set ws2 = ThisWorkbook.Worksheets("Destination")
OrigLastRow = ws1.Cells(Rows.Count, 1).End(xlUp).Row
OrigLastCol = ws1.Cells(10, Columns.Count).End(xlToLeft).Column
DestLastRow = ws2.Cells(Rows.Count, 1).End(xlUp).Row + 5
Set OrigRng = ws1.Range(ws1.Cells(8, 1), ws1.Cells(OrigLastRow, OrigLastCol))
OrigRng.Copy
ws2.Cells(DestLastRow, 1).PasteSpecial xlPasteValuesAndNumberFormats
Application.CutCopyMode = False
End Sub
The version below creates a top and bottom section like your picture and copies both sections separately with a 5 row gap in the destination.
Sub CopyPaste2()
Dim OrigLastRow As Long
Dim OrigLastCol As Long
Dim TopLastRow As Long
Dim BotLastRow As Long
Dim DestLastRow As Long
Dim OrigTopRng As Range
Dim OrigBotRng As Range
Dim ws1 As Worksheet
Dim ws2 As Worksheet
Set ws1 = ThisWorkbook.Worksheets("Origin")
Set ws2 = ThisWorkbook.Worksheets("Destination")
'Assumes contiguous data from row 8 down
TopLastRow = ws1.Cells(8, 1).End(xlDown).Row
BotLastRow = ws1.Cells(Rows.Count, 1).End(xlUp).Row
OrigLastCol = ws1.Cells(10, Columns.Count).End(xlToLeft).Column
DestLastRow = ws2.Cells(Rows.Count, 1).End(xlUp).Row + 5
'Assumes we are starting the top range in row 8
Set OrigTopRng = ws1.Range(ws1.Cells(8, 1), ws1.Cells(TopLastRow, OrigLastCol))
'Columns I & J as shown in the picture
Set OrigBotRng = ws1.Range(ws1.Cells(TopLastRow + 5, 9), ws1.Cells(BotLastRow, 10))
OrigTopRng.Copy
ws2.Cells(DestLastRow, 1).PasteSpecial xlPasteValuesAndNumberFormats
'Recalculate destination last row
DestLastRow = ws2.Cells(Rows.Count, 1).End(xlUp).Row + 5
OrigBotRng.Copy
ws2.Cells(DestLastRow, 1).PasteSpecial xlPasteValuesAndNumberFormats
Application.CutCopyMode = False
End Sub

Copying range of cells to another sheet

I want to copy a range of cells, say F10:F59, of the Form sheet, then transpose and paste them to another range on another sheet named Stock Manual Senin, say B11:BA25.
This is what I currently have:
Sub InputPAGS_Senin()
Dim copySheet As Worksheet
Dim pasteSheet As Worksheet
Dim vntRange As Variant
Dim lastRow As Long
Set copySheet = Sheets("Form")
Set pasteSheet = Sheets("Stock Manual Senin")
' Calculate last row of data.
lastRow = pasteSheet.Cells(Rows.Count, 1).End(xlUp).Offset(1).Row
' Copy 2 cells.
pasteSheet.Cells(lastRow + 1, 1).Offset(0, 1) = copySheet.Range("N2").Value
' Paste column range into array.
vntRange = copySheet.Range("F10:F59").Value
' Paste transpose array into row range.
Sheets("Stock Manual Senin").Select
Range("B11:BA25").Select
pasteSheet.Cells(lastRow + 1, 1).Offset(0, 3).Resize(, copySheet _
.Range("F10:F59").Rows.Count).Value = Application.Transpose(vntRange)
End Sub
the paste target should be in row 11, but it'd paste in row 285 cause target range is located between the others table's row.
Can anyone advise me on how I should continue please? Thank you.
xlUp Becomes xlDown
You have to calculate the last row from NAMA TOKO down (xlDown). Do not delete NAMA TOKO and PAGS / MIGO, then you can use the following
lastRow = pasteSheet.Cells(9, 2).End(xlDown).Offset(1).Row
or even better
lastRow = pasteSheet.Cells(9, 2).End(xlDown).Row + 1
Does something like this work? I just did a manual pivot as I wrote out the values.
Sub SOTest()
Dim copySheet As Worksheet
Dim CopyRange As Range
Dim Cell As Range
Dim pasteSheet As Worksheet
Dim lastRow As Long
Dim ColIndex As Long
Set copySheet = ThisWorkbook.Worksheets("Form")
Set pasteSheet = ThisWorkbook.Worksheets("Stock Manual Senin")
Set CopyRange = copySheet.Range("F10:F59")
ColIndex = 2 'Column B
With pasteSheet
lastRow = .Cells(.Rows.Count, 2).End(xlUp).Row + 1
End With
Application.ScreenUpdating = False
For Each Cell In CopyRange
pasteSheet.Cells(lastRow, ColIndex).Value = Cell.Value
ColIndex = ColIndex + 1
Next
Application.ScreenUpdating = True
End Sub

Resources