Copy & Paste into next empty row & column respectively - vba

I asked a number of times on this question & all the while, I being given vague answer, which isn't much help. Thus I just research on my own and came up with the following code from my research. Which works but doesn't exactly give me the desired outcome stated in the image attached. Whereby the codes paste the data from its specified cells but paste in column A which isn't the outcome wanted, but rather to paste from column B onward for sheets DX,DY & DZ.
Is there also a way I can get column A to update the date by itself base on Date entered in cell S9 which tag along with the data for sheets DX,DY & DZ. Likewise for sheet RAW, that update row 6 with the date entered in S9 of sheet GP Data
Sub Prism2ndStep()
'
' Prism2ndStep Macro
'
r = 1
Sheets("GP Data").Range("S12:S14").Copy
If Sheets("GP Data").Range("S12") = Sheets("DX").Range("A65536").End(xlUp) _
Then r = 0
Sheets("DX").Range("A65536").End(xlUp).Offset(r, 0).PasteSpecial _
Paste:=xlPasteValues, Transpose:=True
Application.CutCopyMode = False
j = 1
Sheets("GP Data").Range("T12:T14").Copy
If Sheets("GP Data").Range("T12") = Sheets("DX").Range("A65536").End(xlUp) _
Then j = 0
Sheets("DX").Range("A65536").End(xlUp).Offset(j, 0).PasteSpecial _
Paste:=xlPasteValues, Transpose:=True
Application.CutCopyMode = False
k = 1
Sheets("GP Data").Range("U12:U14").Copy
If Sheets("GP Data").Range("U12") = Sheets("DX").Range("A65536").End(xlUp) _
Then k = 0
Sheets("DX").Range("A65536").End(xlUp).Offset(k, 0).PasteSpecial _
Paste:=xlPasteValues, Transpose:=True
Application.CutCopyMode = False
Dim copySheet As Worksheet
Dim pasteSheet As Worksheet
Set copySheet = Worksheets("GP Data")
Set pasteSheet = Worksheets("RAW")
copySheet.Range("P12:R14").Copy
With pasteSheet
.Cells(7, .Columns.Count).End(xlToLeft).Offset(0, 7).PasteSpecial _
Paste:=xlPasteValues, Operation:=xlNone, _
SkipBlanks:=False, Transpose:=False
End With
End Sub

Try this macro for copying data from "GP Data" S12:S14 and pasting it into column B:D in DX tab.
Edited
Sub prism2ndStep()
'get date from cell p9
strdate = Sheets("GP Data").Range("S9").Value
arrData = Sheets("GP Data").Range("S12:S14").Value
Set rngwrite = Nothing
Set rngwrite = Sheets("DX").Range("A:A").Find(strdate, LookIn:=xlFormulas)
Do While rngwrite Is Nothing
With Sheets("DX").Range("A60000")
.End(xlUp).AutoFill (.End(xlUp).Resize(2))
End With
Set rngwrite = Sheets("DX").Range("A:A").Find(CDate(strdate), LookIn:=xlFormulas)
Loop
rngwrite.Offset(, 1).Resize(, 3).Value = Application.Transpose(arrData)
End Sub
Sub prism2ndStep2()
'get data
arrData = Sheets("GP Data").Range("P12:R14").Value
'find get the first non-blank column in row 7 from right to left
Set rngwrite = Sheets("RAW").Range("IV7").End(xlToLeft).Offset(, 1)
'paste data
rngwrite.Resize(3, 3).Value = arrData
'drag dates across row 7
rngwrite.Offset(-1).Value = rngwrite.Offset(-1, -3).Value + 1
End Sub

Related

VBA: Looking for a value and copy and paste the value in a other sheet

I have a problem with my VBA code. The problem is that I have duplicate names - the main sheet "Manager" and the names of the sheets.
The code should go to every sheet and look for the value "Engagements ID" and then go one cell down. In every sheet the number of Engagements ID is different, so the code should search in every sheet (500 rows) - look for the value "Engagements ID" then copy and paste the cell what is one row below into my main sheet, which is called "Manager".
Thank you for help!! :) The value what I looking for is on every sheet in column B.
This is my code:
Option Explicit
Sub Check_Account()
Dim rng As Range
Dim xName As String
Dim i, j As Integer
For i = 3 To 6
xName = Cells(i, 1)
If xName = "" Then Exit Sub
On Error Resume Next
ActiveWorkbook.Sheets(xName).Select
Sheets(xName).Select
For j = 1 To 500
If rng.Cells(j, 2) = "Engagements ID" Then
rng.Offset(1, 0).Select
Selection.Copy
Sheets("Manager").Select
If Range("B" & i) = "" Then
Range("B" & i).Select
Selection.PasteSpecial Paste:=xlPasteValues,
Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
ActiveWorkbook.Sheets(xName).Select
Sheets(xName).Select
Cells(j, 2).Offset(1, 0).Select
Else
Range("B" & i).Offset(1, 0).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
ActiveWorkbook.Sheets(xName).Select
Sheets(xName).Select
Cells(j, 2).Offset(1, 0).Select
End If
End If
Next j
On Error GoTo 0
Next i
End Sub
Please try this code. I think you will like it.
Option Explicit
Sub Check_Account()
' 24 Nov 2017
Dim TabName As String
Dim Rng As Range
Dim Fnd As Range
Dim Rl As Long ' last row
Dim FirstFnd As Long
Dim i As Integer
For i = 3 To 6
' Tab names are found at Manager!A3:A6
TabName = Worksheets("Manager").Cells(i, "A").Value
If Len(TabName) = 0 Then Exit For
On Error Resume Next
With Worksheets(TabName)
If Err Then
MsgBox "Worksheet """ & TabName & """ doesn't exist.", _
vbInformation, "Missing Worksheet"
Else
Rl = .Cells(.Rows.Count, "B").End(xlUp).Row
Set Rng = Range(.Cells(1, "B"), .Cells(Rl, "B"))
Set Fnd = Rng.Find("Engagements ID", _
After:=Rng.Cells(Rng.Cells.Count), _
LookIn:=xlValues, _
LookAt:=xlPart, _
SearchOrder:=xlByColumns, _
SearchDirection:=xlNext, _
MatchCase:=False, _
MatchByte:=False)
If Not Fnd Is Nothing Then
FirstFnd = Fnd.Row
Do
With Worksheets("Manager")
Rl = .Cells(.Rows.Count, "B").End(xlUp).Row + 1
' start writing in row 2
If Rl < 2 Then Rl = 2
.Cells(Rl, "B").Value = Fnd.Offset(1).Value
End With
Set Fnd = Rng.FindNext(Fnd)
Loop While Not Fnd Is Nothing And Fnd.Row <> FirstFnd
End If
End If
End With
Next i
End Sub
I have tried and tested the code below, and I believe it does what you expected it to do:
Sub foo()
For i = 3 To 6
xName = Sheets("Manager").Cells(i, 1).Value
LastRow = Sheets(xName).Cells(Sheets(xName).Rows.Count, "B").End(xlUp).Row
For x = 1 To LastRow
If Sheets(xName).Cells(x, 2).Value = "Engagements ID" Then
Sheets("Manager").Cells(i, 2).Value = Sheets(xName).Cells(x + 1, 2).Value
End If
Next x
Next i
End Sub
This does not have any validation against possible errors, if the manager sheet does not exist, then you will get an error... But at least the code is more concise and it points you in the right direction.

VBA: Build a Table by (Copy/Paste) by Using Criteria to Select Rows, Then Specifiy Columns

I want to build a table on one Excel Sheet "Ship" by pulling data from another excel sheet "Efficiency." The row data on the "Efficiency" sheet is categorized by "Shipped", "Leave", "Import" and "Export".
Each category (shipped, leave, import, export) has several items and they're in no specific order. The table on the "Efficiency" sheet occupies columns A:H, and starts at row 2; the length can vary.
I want to be able to search the rows for "Shipped" and copy columns A, D:F and H of the matching rows and paste them beginning at cell B4 of the "Ship" sheet. Can anyone help me please?
Sub Ship()
ActiveSheet.Range("$A$1:$H$201").AutoFilter Field:=4, Criteria1:="Shipped"
' this is looking in a specific range, I want to make it more dynamic
Range("A4:A109").Select
'This is the range selected to copy, again I want to make this part more dynamic
Application.CutCopyMode = False
Selection.Copy
Range("A4:A109,D4:F109,H4:H109").Select
Range("G4").Activate
Application.CutCopyMode = False
Selection.Copy
Sheets("Ship").Select
Range("B4").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
End Sub
This code has been tested based on your the information as given in your question:
Sub Ship()
Dim wsEff As Worksheet
Dim wsShip As Worksheet
Set wsEff = Worksheets("Efficiency")
Set wsShip = Worksheets("Shipped")
With wsEff
Dim lRow As Long
'make it dynamic by always finding last row with data
lRow = .Range("A" & .Rows.Count).End(xlUp).Row
'changed field to 2 based on your above comment that Shipped is in column B (the code you posted has 4).
.Range("A1:H" & lRow).AutoFilter Field:=2, Criteria1:="Shipped"
Dim rngCopy As Range
'only columns A, D:F, H
Set rngCopy = Union(.Columns("A"), .Columns("D:F"), .Columns("H"))
'filtered rows, not including header row - assumes row 1 is headers
Set rngCopy = Intersect(rngCopy, .Range("A1:H" & lRow), .Range("A1:H" & lRow).Offset(1)).SpecialCells(xlCellTypeVisible)
rngCopy.Copy
End With
wsShip.Range("B4").PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
End Sub
try the below code
Sub runthiscode()
Worksheets("Efficiency").Select
lastrow = Range("A" & Rows.Count).End(xlUp).Row
startingrow = 4
For i = 2 To lastrow
If Cells(i, 2) = "Shipped" Then
cella = Cells(i, 1)
celld = Cells(i, 4)
celle = Cells(i, 5)
cellf = Cells(i, 6)
cellh = Cells(i, 8)
Worksheets("Ship").Cells(startingrow, 2) = cella
Worksheets("Ship").Cells(startingrow, 5) = celld
Worksheets("Ship").Cells(startingrow, 6) = celle
Worksheets("Ship").Cells(startingrow, 7) = cellf
Worksheets("Ship").Cells(startingrow, 9) = cellh
startingrow = startingrow + 1
End If
Next i
End Sub

Fast Stack-Columns and Transpose

After few days learning VBA, I managed to get a simple macro to take some data from a sheet and transpose to another, then stack the columns together.
Macro
Sub pivotsourcedata()
Dim HeaderSelect As Range
Dim DataSelect As Range
Dim ID As Range
'Variabile Declaration for Progress bar
Dim x As Integer
Dim MyTimer As Double
For i = 1 To 7589
'Progress bar
Application.StatusBar = "Progress: " & i & " of 7589: " & Format(i / 7589, "0%")
'Copy ID Range
Sheets("Opps Closed FY15").Select
Range("A13").Offset(i, 0).Select
Set ID = Selection
'Copy Header Range
Range("EX13:HA13").Select
Set HeaderSelect = Selection
'Copy Data Range
Range("EX13:HA13").Offset(i, 0).Select
Set DataSelect = Selection
'Select ID and copy it to the next sheet and fill it down
ID.Copy
Sheets("Sheet1").Select
If i = 1 Then
Else
Selection.Resize(1, 1).Offset(0, 1).Select
End If
Selection.PasteSpecial Paste:=xlPasteAll, Operation:=xlNone, SkipBlanks:= _
False, Transpose:=True
Selection.Resize(HeaderSelect.Columns.Count).FillDown
'Select the Header, copy it in the adjacent column
Selection.Resize(1, 1).Select
Selection.Offset(0, 1).Select
Sheets("Opps Closed FY15").Select
HeaderSelect.Copy
Sheets("Sheet1").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:= _
False, Transpose:=True
'Same for the data, copy to the right of Header
Selection.Resize(1, 1).Select
Selection.Offset(0, 1).Select
Sheets("Opps Closed FY15").Select
DataSelect.Copy
Sheets("Sheet1").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:= _
False, Transpose:=True
'Stack the columns one over the other 3 by 3.
' take the 4th, 5th and 6th columns and stuck'em
' below 1st, 2nd and 3rd
If i = 1 Then
Else
Range("A1:C1").Offset(56 * (i - 1), 0).Resize(56, 3).Select
Dim PasteSelect As Range
Set PasteSelect = Selection
Range("D1:F56").Select
Selection.Cut Destination:=PasteSelect
Selection.Resize(1, 1).Offset(0, -1).Select
End If
Next i
Application.StatusBar = False
End Sub
As you can see for each of the 7589 times, I copy and transpose 3 times a range of 56 columns. This is taking a while, around 1.5h. Since I need to run it every week, I'm asking if I wrote badly some code portions...maybe I don't know I can seed it up in some areas...
any thoughts?
Update
After yours suggestions i get to tune up a bit the code, I'd like to know if there are others "imperfections"
Sub pivotsourcedata()
Dim OppsClosed As Worksheet
Set OppsClosed = Worksheets("Opps Closed FY15")
Dim Shadow2 As Worksheet
Set Shadow2 = Worksheets("Shadow2")
Dim ID As Range
Dim ID0 As Range
Set ID0 = OppsClosed.Range("A14")
Dim HeaderSelect As Range
Set HeaderSelect = OppsClosed.Range("EX13:HA13")
Dim DataSelect As Range
Set DataSelect = HeaderSelect
Dim PasteSelect As Range
Dim PasteSelect0 As Range
Set PasteSelect0 = Shadow2.Range("A1:C1").Resize(56, 3)
Dim CopySelect As Range
Set CopySelect = Shadow2.Range("D1:F56")
Dim Inizialize As Range
Set Inizialize = Shadow2.Range("D1:D1")
'Variabile Declaration for Progress bar
Dim x As Integer
Dim MyTimer As Double
'Set ScreenUpdating to False
Application.ScreenUpdating = False
For i = 1 To 7589
'Progress bar
Application.StatusBar = "Progress: " & i & " of 7589: " & Format(i / 7589, "0%")
'Copy ID Range
Set ID = ID0.Offset(i, 0)
'Copy Data Range
Set DataSelect = HeaderSelect.Offset(i, 0)
'Select ID and copy it to the next sheet and fill it down
ID.Copy
Shadow2.Select
If i = 1 Then
Range("A1").PasteSpecial Paste:=xlPasteAll, Operation:=xlNone, SkipBlanks:= _
False, Transpose:=True
Range("A1").Resize(HeaderSelect.Columns.Count).FillDown
Else
Range("D1").PasteSpecial Paste:=xlPasteAll, Operation:=xlNone, SkipBlanks:= _
False, Transpose:=True
Range("D1").Resize(HeaderSelect.Columns.Count).FillDown
End If
'Select the Header, copy it in the adiacent column
HeaderSelect.Copy
If i = 1 Then
Shadow2.Range("B1").PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:= _
False, Transpose:=True
Else
Shadow2.Range("E1").PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:= _
False, Transpose:=True
End If
'Same for the data, copy to the right of Header
DataSelect.Copy
If i = 1 Then
Shadow2.Range("C1").PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:= _
False, Transpose:=True
Else
Shadow2.Range("F1").PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:= _
False, Transpose:=True
End If
'Stack the columns one over the other 3 by 3.
' take the 4th, 5th and 6th columns and stuck'em
' below 1st, 2nd and 3rd
If i = 1 Then
Else
Set PasteSelect = PasteSelect0.Offset(HeaderSelect.Columns.Count * (i - 1), 0)
Shadow2.Range("D1:F56").Cut Destination:=PasteSelect
End If
Next i
Application.StatusBar = False660858
'Set ScreenUpdating to True
Application.ScreenUpdating = True
End Sub
Take a look at this link for several other things that you can turn off, such as formula recalculation: http://datapigtechnologies.com/blog/index.php/ten-things-you-can-do-to-speed-up-your-excel-vba-code/
I agree that the multiple selects are unnecessary and likely slowing down the code significantly. In many cases, they can simply be combined - as in using
Selection.Resize(1, 1).Offset(0, 1).Select
instead of
Selection.Resize(1, 1).Select
Selection.Offset(0, 1).Select
But also, why not reference your ranges explicitly using your counter value, and avoid using resize and offset so frequently?
Another thought is to see if you can remove the final operation that stacks the columns after they are pasted to a new sheet - would it be possible to rearrange your source data, perhaps at the top of your macro before you get into the loop? That way you would have to perform that stacking once instead of 7589 times. Or, alternatively, find a way to combine the columns after the end of the loop.
The answer to my question was: "Use arrays" :)
The code now is this:
Sub pivotsourcedata()
'Set ScreenUpdating to False
Application.ScreenUpdating = False
Application.StatusBar = True
Dim OppsClosed As Worksheet
Set OppsClosed = Worksheets("Opps Closed FY15")
Sheets.Add.Name = "Shadow2"
Dim Shadow2 As Worksheet
Set Shadow2 = Worksheets("Shadow2")
Dim ID As Range
Dim ID0 As Range
Set ID0 = OppsClosed.Range("A13")
Dim HeaderSelect As Range
Set HeaderSelect = OppsClosed.Range("FB1")
Dim DataSelect As Range
Set DataSelect = OppsClosed.Range("FC14")
Dim RowSize As Integer
OppsClosed.Activate
Dim lastrow, records, nHeader As Integer
lastrow = ActiveSheet.Cells(Rows.Count, 1).End(xlUp).Row - 13
nHeader = 56
records = lastrow * nHeader
'Stack DataSelect on column C of Shadow 2
ReDim TempTableData(1 To nHeader, 1 To lastrow) As Variant
ReDim TempTableHeader(1 To nHeader, 1 To lastrow)
ReDim FixedHeaders(1 To nHeader, 1 To 1)
ReDim Temp_Array1(1 To records, 1 To 1) As Variant
ReDim Temp_Array2(1 To records, 1 To 1) As Variant
FixedHeaders = OppsClosed.Range("FC1").Resize(1, nHeader)
FixedHeaders = Application.Transpose(FixedHeaders)
For j = 1 To lastrow
'Progress bar
Application.StatusBar = "Progress: " & j & " of " & lastrow & ": " & Format(j / lastrow, "0%")
For i = 1 To nHeader
TempTableData(i, j) = DataSelect.Offset(j - 1, i - 1)
TempTableHeader(i, j) = FixedHeaders(i, 1)
Next i
Next j
For j = 1 To nHeader
For i = 0 To lastrow - 1
Temp_Array1((i * nHeader) + j, 1) = TempTableData(j, i + 1)
Temp_Array2((i * nHeader) + j, 1) = TempTableHeader(j, i + 1)
Next i
Next j
Shadow2.Range("C1:C" & records).Value2 = Temp_Array1
Shadow2.Range("B1:B" & records).Value2 = Temp_Array2
'Copy and Replicate ID
ReDim TempTableID(1 To records, 1 To 1)
k = 1
For i = 1 To records
'Progress bar
Application.StatusBar = "Progress: " & i & " of " & records & ": " & Format(i / records, "0%")
DoEvents
'FixedID = OppsClosed.Range("A13").Offset(k, 0)
TempTableID(i, 1) = OppsClosed.Range("A13").Offset(k, 0)
variable = i / nHeader
If Fix(variable) = variable Then
k = k + 1
End If
Next i
Shadow2.Range("A1:A" & records).Value2 = TempTableID
Application.StatusBar = False
Application.ScreenUpdating = True
End Sub

Copy range to next free row in a different sheet

I need to copy a range (Sheet2 B2:S2), paste it on the same sheet on the first free row after row 7, paste the same data to the first empty row on Sheet1 and then clear the contents of the original range (Sheet2 B2:S2) ready for the next entry.
I have tried to use other posts but I can't figure out what to do.
Here is the macro that does the easy bit
Sub Macro2()
'
' Macro2 Macro
'
'
Sheets("Sheet2").Select
Range("B2:S2").Select
Selection.Copy
Range("B7").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Sheets("Sheet1").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Sheets("Sheet2").Select
Range("B2:S2").Select
Application.CutCopyMode = False
Selection.ClearContents
End Sub
It pastes over the last line. I need it to find the next free line when pasting.
You're so close! The issue is that you never increment the destination range object -- it's always set to Range("B7"). The following heavily-commented code should achieve what you're after:
Option Explicit
Public Sub MoveRowFrom2To1()
Dim shtSource As Worksheet, shtResult As Worksheet
Dim rngSource As Range, rngResult As Range
Dim lngLastRowOnSheet1 As Long, lngLastRowOnSheet2 As Long
'Set references up-front
Set shtSource = ThisWorkbook.Worksheets("Sheet2")
Set shtResult = ThisWorkbook.Worksheets("Sheet1")
'Identify the last occupied row on Sheet1 and Sheet2
lngLastRowOnSheet1 = LastRowNum(shtResult)
lngLastRowOnSheet2 = LastRowNum(shtSource)
'If the last occupied row is < 7, default to 6 so it writes to 7
If lngLastRowOnSheet2 < 7 Then
lngLastRowOnSheet2 = 6
End If
'Identify the Source data and Sheet2 Destination
Set rngSource = shtSource.Range("B2:S2")
Set rngResult = shtSource.Cells(lngLastRowOnSheet2 + 1, 2) '<~ column 2 is B
'Copy the Source data from Sheet2 to lower on Sheet2
rngSource.Copy
rngResult.PasteSpecial (xlPasteValues)
'Identify the Sheet1 Destination
Set rngResult = shtResult.Cells(lngLastRowOnSheet1 + 1, 2) '<~ column 2 is B
'Paste the Source data from Sheet2 onto Sheet1
rngResult.PasteSpecial (xlPasteValues)
'Clear the Source range in anticipation of a new entry
rngSource.ClearContents
End Sub
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'INPUT : Sheet, the worksheet we'll search to find the last row
'OUTPUT : Long, the last occupied row
'SPECIAL CASE: if Sheet is empty, return 0
Public Function LastRowNum(Sheet As Worksheet) As Long
If Application.WorksheetFunction.CountA(Sheet.Cells) <> 0 Then
LastRowNum = Sheet.Cells.Find(What:="*", _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious).Row
Else
LastRowNum = 0
End If
End Function
Try this, have tidied up by removing your select statements:
Sub Macro2()
Dim SourceRange, TargetRange1, TargetRange2 As Range
Dim RowToPaste As Long
'set range of source data
Set SourceRange = Sheets("Sheet2").Range("B2:S2")
'cater for chance that less than 7 rows are populated - we want to paste from row 8 as a minimum
If (Sheets("Sheet2").Range("B" & Rows.Count).End(xlUp).Row + 1) < 8 Then
RowToPaste = 8
Else
'Add 1 to the value of the last populated row
RowToPaste = Sheets("Sheet2").Range("B" & Rows.Count).End(xlUp).Row + 1
End If
'Set the address of the target 1 range based on the last populated row in column B
Set TargetRange1 = Sheets("Sheet2").Range("B" & RowToPaste)
'Copy Source to target 1
SourceRange.Copy Destination:=TargetRange1
'Cater for Sheet 1 being totally empty and set target row to 1
If Sheets("Sheet1").Range("A" & Rows.Count).End(xlUp).Row = 1 And _
Len(Sheets("Sheet1").Range("A1")) = 0 Then
RowToPaste = 1
Else 'set target row to last populated row + 1
RowToPaste = Sheets("Sheet1").Range("A" & Rows.Count).End(xlUp).Row + 1
End If
'Set the target 2 range based on the last empty row in column A
Set TargetRange2 = Sheets("Sheet1").Range("A" & RowToPaste)
'Paste the source to target 2
SourceRange.Copy Destination:=TargetRange2
'Clear the source data
SourceRange.ClearContents
End Sub

To copy number of values present in workbook1 ("A") to the work book 2 of coloumn B: VBA

I wanted to do like this:
Work Book1 (
Sheet1 has:
ColA:
AA
AA
AA
AB
AB
AB
AC
AC
AC
AC
Now I need to count how many are AA's, AB's, AC's and so on and represent their numbers in ColB of Work book B (Sheet1) like this:
ColA: ColB:
AA 3
AB 3
AC 4
Here in this second work book Col A is already mentoined so need to filter or add or change Col A just to update Col (B).
With the help of users here is the code modified so far: but I need your input thank you!
Code:
Sub foo()
Dim x As Workbook
Dim y As Workbook
'# Openning both workbooks first:
Set x = Workbooks.Open("C:\Users\ax1jk3\Desktop\Workbooks\Book2")
Set y = Workbooks.Open("C:\Users\ax1jk3\Desktop\Workbooks\Book1")
'Navigate to the first WOrkBook
Windows("Book1").Activate
'Find all the Rown in Range A that you need to copy
Sheets("Sheet1").Range("A1:A" & Sheets("Sheet1").Rows.Count).End(xlUp).Rows.Select
Selection.Copy
'Navigate to the Other WOrkBook
Windows("Book2").Activate
Sheets("Sheet2").Select
ActiveSheet.Paste
Application.CutCopyMode = False
'This will remove the Duplicates
ActiveSheet.Range("$A$1:$A$" & ActiveSheet.Rows.Count).End(xlUp).Rows.RemoveDuplicates Columns:=1, Header:=xlNo
Range("B1").Select
ActiveCell.FormulaR1C1 = "=COUNTIF([Book12]Sheet1!C1,RC[-1])"
Range("B1").Select
Selection.AutoFill Destination:=Range("B1:B" & Rows.Count).End(xlUp).Rows
Range("B1:B" & Rows.Count).End(xlUp).Rows.Select
Selection.Copy
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Application.CutCopyMode = False
'Close x:
x.Close
End Sub
Here's how I'd do it, using the RemoveDuplicates function:
'# Opening both workbooks first:
Set x = Workbooks.Open("C:\Users\ax1jk3\Desktop\Workbooks\Book2.xlsx")
Set y = Workbooks.Open("C:\Users\ax1jk3\Desktop\Workbooks\Book1.xlsx")
'Navigate to the first WorkBook
x.Sheets(1).Activate
'Copy-Paste column A to y.sheets(1)
lastRow_x = Range("A" & Rows.Count).End(xlUp).Row
Range("A1:A" & lastRow_x).Copy
'Paste and remove duplicates
y.Sheets(1).Activate
Range("A1").PasteSpecial xlPasteValuesAndNumberFormats
Range("A:A").RemoveDuplicates Columns:=1, Header:=xlNo 'if your column has a header, use xlYes
'Count number of occurences of each row from y in x
lastRow_y = Range("A" & Rows.Count).End(xlUp).Row
For each loopCell in Range("A1:A" & lastRow_y) 'A2 if you have a header
loopCell.Offset(0, 1) = Sheets(1).Evaluate("=COUNTIF([Book2.xlsx]Sheet1!A1:A" & lastRow_x & "," & loopCell.Address & ")")
next loopCell
'Close x:
x.Close SaveChanges:=xlNo
End Sub
I haven't tested it but it should be really quick!
From my own experience, I would avoid using the .copy feature. Instead I recommend using an array to identify a unique list of items.
'# Openning both workbooks first:
Set x = Workbooks.Open("C:\Users\ax1jk3\Desktop\Workbooks\Book2")
Set y = Workbooks.Open("C:\Users\ax1jk3\Desktop\Workbooks\Book1")
'Navigate to the first WOrkBook
Windows("Book1").Activate
Sheets("Sheet1").Select
'identify end of source tab
source_ROW = ActiveSheet.UsedRange.Row - 1 + ActiveSheet.UsedRange.Rows.Count
Do While Range("A" & source_ROW) = ""
source_ROW = source_ROW - 1
Loop
source_ROW_end = source_ROW
source_ROW_start = 3
'initialize unique value array
Dim unique_ARRAY() As String
ReDim unique_ARRAY(1 To 1)
unique_ARRAY(1) = Range("A" & source_ROW_start)
'identify unique list
For source_ROW = source_ROW_start To source_ROW_end
'initialize
source_record = Range("A" & source_ROW)
new_value = "dunno_yet"
For i = 1 To UBound(unique_ARRAY, 1)
If source_record = unique_ARRAY(i) Then
'value already exists in the array
new_value = "no"
'no need to continue searching
Exit For
End If
Next i
If new_value = "no" Then
'the source_record matched values already found in the array
'does nothing
Else
'a new source_record was found
'new_value = "yes"
'redimensionalize the array while preserving pre-existing values
ReDim Preserve unique_ARRAY(1 To UBound(unique_ARRAY) + 1)
'read the new value into the new upper bound of the array
unique_ARRAY(UBound(unique_ARRAY, 1)) = source_record
End If
Next source_ROW
'Navigate to the Other WOrkBook
Windows("Book2").Activate
Sheets("Sheet2").Select
'cycle through each item in the array
for i = 1 to UBound(unique_ARRAY)
'write values to book2
Range("A" & i) = unique_ARRAY(i)
Range("B" & i) = "=COUNTIF([Book1]Sheet1!C1,RC[-1])"
'convert formulas to values
Range("B" & i).Copy
Range("B" & i).PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
next i
'Close x:
x.Close
End Sub
You may also consider adapting the array to count how many times a value appears. Then you can eliminate .PasteSpecial at the end.