Copying and pasting datas to the selected row - vba

I have a code piece from my working code which copies and pastes datas from other Worksheets to one masterworkbooks mastersheet. The code below lets me copy and paste datas from column BX to column A's first empty row and does the same for column CC to column B's first empty row. However, I would like to paste the column CC to Column B's (10th) row. How can I do this?
lRow = copySheet.Cells(copySheet.Rows.Count, 1).End(xlUp).Row
With copySheet.Range("BX2:BX" & lRow)
pasteSheet.Cells(Rows.Count, "A").End(xlUp).Offset(1, 0)
.Resize(.Rows.Count, .Columns.Count) = .Value
End With
'Determine last row of Column B in copySheet
lRow = copySheet.Cells(copySheet.Rows.Count, 1).End(xlUp).Row
With copySheet.Range("CC2:CC" & lRow)
pasteSheet.Cells(Rows.Count, "B").End(xlUp).Offset(1, 0)
.Resize(.Rows.Count, .Columns.Count) = .Value
End With
Could you show me how I can determine how many rows are seletected to be copied?
Edit: Now I would like to add an if condition for another column, which should say:
if
column U in Worksheet "data" has cell value "8636" then these values
should be pasted to Column H in Worksheet "KomKo"(pastesheet); to the
next row as I used the code above in the "with" part.
Else( If the value in Column H is not 8636) then it should paste the
value inside this column to Column G at Worksheet "KomKo"(pastesheet)
with same preferences as above again
.
How can I do this ?

Change pasteSheet.Cells(Rows.Count, "B").End(xlUp).Offset(1, 0).Resize(.Rows.Count, .Columns.Count) = .Value to that pasteSheet.Range("B10").Resize(.Rows.Count, .Columns.Count) = .Value
************* ANSWER TO QUESTION EDIT ****************
******* Added maxR - highest last row from column H and G *******
You could do something like this to get what you need:
Sub check8636values()
Dim copySheet, pasteSheet As Worksheet
Dim lRowU, lRowH, lRowG, maxR, i As Long
'Dont forget to change to the correct sheet names!!!!
Set copySheet = ThisWorkbook.Sheets("data")
Set pasteSheet = ThisWorkbook.Sheets("KomKo")
lRowU = copySheet.Cells(copySheet.Rows.Count, "U").End(xlUp).Row
For i = 1 To lRowU
lRowG = pasteSheet.Cells(pasteSheet.Rows.Count, "G").End(xlUp).Row + 1
lRowH = pasteSheet.Cells(pasteSheet.Rows.Count, "H").End(xlUp).Row + 1
maxR = Application.Max(lRowG,lRowH)
If copySheet.Cells(i, "U").Value = "8636" Then
pasteSheet.Cells(maxR, "H").Value = copySheet.Cells(i, "U").Value
pasteSheet.Cells(maxR, "Y").Value = copySheet.Cells(i, "T").Value
Else
pasteSheet.Cells(maxR, "G").Value = copySheet.Cells(i, "U").Value
pasteSheet.Cells(maxR, "X").Value = copySheet.Cells(i, "T").Value
End If
Next i
End Sub

since you're dealing with one-column ranges only there's no need for the With-End With blocks to abbreviate the Resize method parameters: just use lRow for the first one only
moreover since you're not showing if copySheet and pasteSheet are from the same workbook it's safer to reference them before .Rows.Count, and prevent issue deriving from their source workbook excel version
'Determine last row of Column B in copySheet
lRow = copySheet.Cells(copySheet.Rows.Count, 1).End(xlUp).Row
pasteSheet.Cells(pasteSheet.Rows.Count, "A").End(xlUp).Offset(1, 0).Resize(lRow) = copySheet.Range("BX2:BX" & lRow).Value
pasteSheet.Range("B10").Resize(lRow).Value = copySheet.Range("CC2:CC" & lRow).Value

Related

copy lane from different sheet if the same value

I have 5 columns in sheet1, and the same in sheet 2.The name of the product is in A. But sometimes the caracteristics of the products (in B,C,D,E) can change in sheet 2. I want that it actualize the caracteristics in Sheet1.
I tried a Vlookup, but it works only zith one Cell
Sub test()
With Sheets("Feuil1")
.Range("B1").Value = WorksheetFunction.VLookup(.Range("A1").Value, Sheets("Feuil2").Range("A1:B100"), 2, False)
End With
End Sub
Moreover, I cant copy all the line because the colomn F should not changeā€¦ And products in sheet1 in column A are not tidy and get some duplicates...
You need a loop for this to update each row and you need to update each column as well.
I recommend to use WorksheetFunction.Match instead so you only need to match once per row to get the row number and then you can copy the desired values of that row.
Option Explicit
Public Sub UpdateData()
Dim WsDest As Worksheet 'destination workbook to write in
Set WsDest = ThisWorkbook.Worksheets("Feuil1")
Dim WsSrc As Worksheet 'source workbook to match with
Set WsSrc = ThisWorkbook.Worksheets("Feuil2")
Dim LastRow As Long 'last used row in workbook
LastRow = WsDest.Cells(WsDest.Rows.Count, "A").End(xlUp).Row
Dim iRow As Long, MatchedRow As Long
For iRow = 1 To LastRow 'loop through all rows from row 1 to last used row and update each row
MatchedRow = 0 'initialize
On Error Resume Next 'if no match found then ignore error
MatchedRow = WorksheetFunction.Match(WsDest.Cells(iRow, "A"), WsSrc.Columns("A"), 0) 'get the row number of the match
On Error GoTo 0 'reactivate error reporting
'if it didn't match then MatchedRow is still 0
If MatchedRow > 0 Then 'if a match was found then copy values
WsDest.Cells(iRow, "B").Value = WsSrc.Cells(MatchedRow, "B").Value
WsDest.Cells(iRow, "C").Value = WsSrc.Cells(MatchedRow, "C").Value
WsDest.Cells(iRow, "D").Value = WsSrc.Cells(MatchedRow, "D").Value
WsDest.Cells(iRow, "E").Value = WsSrc.Cells(MatchedRow, "E").Value
Else
'didn't find a match
'you can remove the Else part if you want to do nothing here
End If
Next iRow
End Sub
If the columns you want to copy are continous like B, C, D, E you can do it in one copy action which is faster than 4 copy actions (1 for each column):
WsDest.Range("B" & iRow & ":E" & iRow).Value = WsSrc.Range("B" & MatchedRow & ":E" & MatchedRow).Value

Looping and finding similar number in VBA

I am very new to VBA. Just started reading it up 2 days ago. I am wondering how could I write a VB codes assigned to a button to read through the whole column and search for similar numbers.
After that identifying similar numbers, it would need to move on to another column to check if the character in the column are same too.
If both of the logic = true . How can i change the cell of the value of another column?
Sample data
For the current example. The code should know that the first column had matching numbers. After that it will check for the name which is "a" in the example. After that it will automatically change the point to 1 and 0. If there are 3 same ones it will be 1,0,0 for the point
You may try recording whatever you want to do with record macros first, then filter out the codes that are not necessary. If you do not know how to record it using macros, click on the link below. You can learn from the recorded macros and slowly improvise your codes in the future from the experience you may gain.
Here's [a link] (http://www.dummies.com/software/microsoft-office/excel/how-to-record-a-macro-in-excel-2016/)
As per image attached in image I am assuming numbers are in Column A, column to check characters is Column J and result needs to be displayed in Column O then try following code.
Sub Demo()
Dim dict1 As Object
Dim ws As Worksheet
Dim cel As Range, fCell As Range
Dim lastRow As Long, temp As Long
Dim c1
Set dict1 = CreateObject("Scripting.Dictionary")
Set ws = ThisWorkbook.Sheets("Sheet2") 'change Sheet2 to your data sheet
With ws
lastRow = .Cells(.Rows.Count, "A").End(xlUp).Row 'last row with data in Column A
c1 = .Range("A2:A" & lastRow)
For i = UBound(c1, 1) To 1 Step -1 'enter unique values with corresponding values in dict1
dict1(c1(i, 1)) = .Range("J" & i + 1) '+1 for Row 2
Next i
Set fCell = .Range("A2")
For Each cel In .Range("A2:A" & lastRow) 'loop through each cell in Column A
temp = WorksheetFunction.CountIf(.Range(fCell, cel.Address), cel) 'get count
If temp > 1 Then
If cel.Offset(0, 9) = dict1(cel.Value) Then
cel.Offset(0, 14).Value = 0
Else
cel.Offset(0, 14).Value = 1
End If
Else
cel.Offset(0, 14).Value = 1
End If
Next cel
End With
End Sub
EDIT
Sub Demo()
Dim ws As Worksheet
Dim lastRow As Long
Application.ScreenUpdating = False
Set ws = ThisWorkbook.Sheets("Sheet2") 'change Sheet3 to your data range
With ws
lastRow = .Cells(.Rows.count, "A").End(xlUp).Row 'last row with data in Column A
.Range("O2").Formula = "=IF(MOD(SUMPRODUCT(($A$2:$A2=A2)*($J$2:$J2=J2)),3)=1,1,0)" 'enter formula in Cell O2
.Range("O2").AutoFill Destination:=.Range("O2:O" & lastRow) 'drag formula down
.Range("O2:O" & lastRow).Value = .Range("O2:O" & lastRow).Value 'keep only values
End With
Application.ScreenUpdating = True
End Sub

Copy and Paste dynamic ranges to new sheet in Excel with VBA

I am new to macro writing and I need some help.
I have one sheet and need to copy the columns and reorder them to paste into a software program.
I want to copy A2 - the last data entry in column A and paste it into A1 on Sheet2
I want to copy B2 - the last data entry in column A and paste it into K1 on Sheet2
I want to copy C2 - the last data entry in column A and paste it into C1 on Sheet2
I want to copy D2 - the last data entry in column A and paste it into D1 on Sheet2
Then from Sheet 2, I want to copy A1:KXXXX (to the last entry in column A) and save it on the clipboard to paste into the other application
Here is my code, I have tried... (I know this is just for copying column A, but I got stuck there.)
Sub Copy()
aLastRow = ActiveSheet.Cells(Rows.Count, 1).End(xlUp).Row
Range("A2" & aLastRow).Select
Selection.Copy
Sheets("Sheet2").Select
Range("A1").Select
ActiveSheet.Paste
End Sub
Thank you so much for your help!
Jess
Try this instead. Given that you said you got an error with the paste code and I am still using that, I think you'll still have an error there. Post the error message. Hopefully we can figure that out.
Sub copyStuff()
Dim wsIn As Worksheet
Set wsIn = Application.Worksheets("Sheet1")
Dim endRow As Long
wsIn.Activate
endRow = wsIn.Cells(wsIn.Rows.Count, "A").End(xlUp).Row
Dim r As Range
Dim wsOut As Worksheet
Set wsOut = Application.Worksheets("Sheet2")
' column a to column a
Set r = wsIn.Range(Cells(2, 1), Cells(endRow, 1))
r.Copy
wsOut.Range("A1").PasteSpecial xlPasteAll
' column b to column k
Set r = wsIn.Range(Cells(2, 2), Cells(endRow, 2))
r.Copy
wsOut.Range("K1").PasteSpecial xlPasteAll
' column c to column c
Set r = wsIn.Range(Cells(2, 3), Cells(endRow, 3))
r.Copy
wsOut.Range("C1").PasteSpecial xlPasteAll
' column d to column d
Set r = wsIn.Range(Cells(2, 4), Cells(endRow, 4))
r.Copy
wsOut.Range("D1").PasteSpecial xlPasteAll
' Copy data from sheet 2 into clipboard
wsOut.Activate
Set r = wsOut.Range(Cells(1, 1), Cells(endRow - 1, 11))
r.Copy
End Sub
My original answer is below here. You can disregard.
This should accomplish your first goal:
Sub copyStuff()
Dim wsIn As Worksheet
Set wsIn = Application.Worksheets("Sheet1")
Dim endRow As Long
endRow = wsIn.Cells(wsIn.Rows.Count, "A").End(xlUp).Row
Dim r As range
Set r = wsIn.range(Cells(2, 1), Cells(endRow, 4))
r.Copy
Dim wsOut As Worksheet
Set wsOut = Application.Worksheets("Sheet2")
wsOut.range("A1").PasteSpecial xlPasteAll
End Sub
I copied all 4 columns at once since that would be much faster but it assumes the columns are the same length. If that isn't true you would need to copy one at a time.
The data should be in the clipboard at the end of the macro.
Edit: I removed "wsIn.Activate" since it isn't really needed.
Edit 2: Oops! I just noticed you wanted the output in different columns. I'll work on it.
Generally you want to avoid .Select and .Paste when copying values and rather copy by .value = .value:
Sub Copy()
Dim aLastRow As Long
Dim clipboard As MSForms.DataObject
Set clipboard = New MSForms.DataObject
aLastRow = Sheets("Sheet1").Cells(Rows.Count, 1).End(xlUp).Row
Sheets("Sheet2").Range("A1:A" & aLastRow - 1).Value = Sheets("Sheet1").Range("A2:A" & aLastRow).Value
Sheets("Sheet2").Range("K1:K" & aLastRow - 1).Value = Sheets("Sheet1").Range("B2:B" & aLastRow).Value
Sheets("Sheet2").Range("C1:D" & aLastRow - 1).Value = Sheets("Sheet1").Range("C2:D" & aLastRow).Value
clipboard.SetText Sheets("Sheet2").Range("A1:K" & aLastRow - 1).Value
clipboard.PutInClipboard
End Sub

How to copy data from a row if a certain value is present in column, using VBA?

I've been working on a spreadsheet to help with reporting and I'm stumped on the final element. Essentially, if column G of a worksheet contains a certain text string, I want to copy the appropriate row to another worksheet under the existing data in that sheet.
After two hours of googling I've tried various solutions but haven't been able to configure one to do what I want it to. Currently I'm working with the below:
Dim x As Integer
Dim Thisvalue As String
Dim NextRow As Range
Sheets("Week 4").Select
' Find the last row of data
FinalRow = Cells(Rows.Count, 1).End(xlUp).Row
' Loop through each row
For x = 2 To FinalRow
' Decide if to copy based on column D
Thisvalue = Cells(x, 7).Value
If Thisvalue = "Customer placed on hold" Then
Cells(x, 1).Resize(1, 33).Copy
Sheets("Retained data").Select
NextRow = Cells(Rows.Count, 1).End(xlUp).Row + 1
Cells(NextRow, 1).Select
ActiveSheet.Paste
Sheets("Week 4").Select
End If
Next x
End Sub
However, I think I'm on the wrong track and in all honesty I've forgotten so much about VBA that I'm essentially starting from scratch again as far as my knowledge goes. Any help would be greatly appreciated!
The code below will loop throug all cells in Column G (until FinalRow), and check for value "Customer placed on hold". When it finds, it copies the entire row to the next avaialble row at "Retained data" worksheet.
Note: it's better to avoid using Select and ActiveSheet as they might change according to your current ActiveSheet. Instead it's better to use referenced Sheet objects, .Cells and Ranges.
Code
Option Explicit
Sub CopyRow()
Dim x As Long
Dim Thisvalue As String
Dim NextRow As Long
Dim FinalRow As Long
With Sheets("Week 4")
' Find the last row of data in Column A
FinalRow = .Cells(.Rows.Count, 1).End(xlUp).Row
' Loop through each row
For x = 2 To FinalRow
' Decide if to copy based on column G
If .Cells(x, 7).Value = "Customer placed on hold" Then
' Find the last row of data
NextRow = Sheets("Retained data").Cells(Sheets("Retained data").Rows.Count, 1).End(xlUp).Row
' copy > paste in 1 line
.Cells(x, 7).EntireRow.Copy Sheets("Retained data").Range("A" & NextRow + 1)
End If
Next x
End With
End Sub
Try this one:
Sub Makro2()
Dim x As Integer
Dim Thisvalue As String
Sheets("Week 4").Select
' Find the last row of data
FinalRow = Cells(Rows.Count, 1).End(xlUp).Row
' Loop through each row
For x = 2 To FinalRow
' Decide if to copy based on column D
Thisvalue = Cells(x, 7).Value
If Thisvalue = "Customer placed on hold" Then
Range(Cells(x, 1), Cells(x, 33)).Copy
With Sheets("Retained data")
.Cells(.Cells(Rows.Count, 1).End(xlUp).Row + 1, 1).PasteSpecial xlPasteAll
End With
End If
Next x
End Sub
since you want to check column "G" values against a string ("Customer placed on hold") then you want to avoid looping through column "A" cells and loop through "string" cells of columns "G" only
then you can avoid looping through all cells and just Find() the wanted ones:
Sub CopyRow()
Dim firstAddress As String
Dim f As Range
With Worksheets("Week 4") '<--| reference your relevant worksheet
With .Range("G2", .Cells(.Rows.COUNT, "G").End(xlUp)).SpecialCells(xlCellTypeConstants, xlTextValues) '<--| loop through its column G "string" values only
Set f = .Find(what:="Customer placed on hold", lookat:=xlWhole, LookIn:=xlValues, after:=.Areas(.Areas.COUNT).Cells(.Areas(.Areas.COUNT).COUNT)) '<--| search for wanted string in referenced range, starting from the cell after its last cell (i.e.: the first cell)
If Not f Is Nothing Then '<--| if found
firstAddress = f.Address '<--| store its address to stop 'Find()' loop at its wrapping back to the first found cell
Do
With Worksheets("Retained data") '<--| reference target sheet
f.EntireRow.Copy .Cells(.Rows.COUNT, 1).End(xlUp).Offset(1) '<--| copy found cell entire row into last referenced worksheet first not empty cell
End With
Set f = .FindNext(f) '<--| find next cell matching wanted value
Loop While f.Address <> firstAddress '<--| exit loop when it wraps back to first found cell
End If
End With
End With
End Sub
should your column "G" data extend beyond actual range of column "A" data, and you be interested in limiting the range to this latter, then you just have to change:
With .Range("G2", .Cells(.Rows.COUNT, "G").End(xlUp)).SpecialCells(xlCellTypeConstants, xlTextValues) '<--| loop through its column G "string" values only
to
With Intersect(.Range("A2", .Cells(.Rows.COUNT, "A").End(xlUp)).EntireRow, .Range("G2", .Cells(.Rows.COUNT, "G").End(xlUp)).SpecialCells(xlCellTypeConstants, xlTextValues)) '<--| loop through its column G "string" values only down to its column "A" last not empty row

Copy columns based on set paramaters

I am copying information from one workbook to another. The code I have so far works great if every column has data. It does not work when I am trying to repeatedly copy information from column A and B of worksheet(supplementary expenses) to worksheet(expenses) and column B is blank. As the next time the sub is run and Column B does have values they are placed in the next blank cell, not the cell that is correlated to column A.
Here is the code I have so far:
Sub SupplementaryExpenses()
Dim x As Workbook
Dim y As Workbook
Set y = Workbooks.Open("File Path")
Set x = Workbooks.Open("File Path")
x.Sheets("b.1 Supplementary expenses").Range("a9", Range("a9").End(xlDown)).Copy
y.Sheets("Expenses").Range("a1").End(xlDown).Offset(1, 0).PasteSpecial xlPasteValues
x.Sheets("b.1 Supplementary expenses").Range("b9", Range("b9").End(xlDown)).Copy
y.Sheets("Expenses").Range("b1").End(xlDown).Offset(1, 0).PasteSpecial xlPasteValues
x.Sheets("b.1 Supplementary expenses").Range("c9", Range("c9").End(xlDown)).Copy
y.Sheets("Expenses").Range("c1").End(xlDown).Offset(1, 0).PasteSpecial xlPasteValues
Also any time this sub is run it would be helpful if there were someway to fill column L with the flag 201601 and then change to 201602 when I bring in the next months data.
Try this:
Sub SupplementaryExpenses()
Dim x As Workbook
Dim y As Workbook
Dim lastrow As Long
Dim tRow as long
Set y = Workbooks.Open("File Path")
Set x = Workbooks.Open("File Path")
With x.Sheets("b.1 Supplementary expenses")
lastrow = .Range("A" & .Rows.Count).End(xlUp).Row
tRow = y.Sheets("Expenses").Range("a1").End(xlDown).Offset(1, 0).Row
y.Sheets("Expenses").Range("A" & trow).Resize(lastrow - 8, 3).Value = .Range(.Cells(9, 1), .Cells(lastrow, 3)).Value
y.Sheets("Expenses").Range("D" & trow).Resize(lastrow - 8, 1).Value = .Range(.Cells(9, 8), .Cells(lastrow, 8)).Value
End With
End Sub
It will take all of the three columns at once and assign the values to the new area. It will not care about blanks in column B or C.
This should be faster than copy/paste as you only want the values.
Get the last used row and change out your range statements similar to this:
Dim LastRow
LastRow = Cells.Find(What:="*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
x.Sheets("b.1 Supplementary expenses").Range(Cells(9, 1), Cells(LastRow, a)).Copy 'this is R1C1 format meaning row then column
You can use this for filling a column
If you put it after the rest of your code and ensure that you have the sheet you want column L populated with active:
sDate = Format(Date, "yyyymm")
For i = 2 To LastRow' you may need to grab this anew if you added lines
If Cells(i, "L") = vbNullString Then 'ensures that there isn't anything in the cell
Cells(i, "L").value = sDate
End If
Next