Macro to Copy Range and Paste Based on Cell Value - vba

I had created a macro to copy the data and paste into another sheet.
The cell reference where the data needs to be pasted is in the last column of table.
Range A2:E2 needs to be copied and paste at "A2" (mentioned in "H2")
The below code constantly gives and error "Object Required"
Google Doc Version of the Worksheet
Sub Reconcile()
Set i = Sheets("Data")
Set e = Sheets("Final")
Dim r1 As Range
Dim r2 As Variant
Dim j
j = 2
Set r1 = i.Range(Cells(j, 1), Cells(j, 5))
Set r2 = i.Cells("I" & j).Value
Do Until IsEmpty(i.Range("A" & j))
r1.Select
Selection.Copy
e.Range(r2).Select
Selection.Paste
j = j + 1
Loop
End Sub

Try the following code (in the sample sheet and in the description the target is in H column, not I as in sample VBA)
Sub Reconcile()
Set i = Sheets("Data")
Set e = Sheets("Final")
Dim r1 As Range
Dim r2 As Range
Dim j As Integer
j = 2
Application.ScreenUpdating = False
Application.EnableEvents = False
Application.Calculation = xlCalculationManual
Do Until IsEmpty(i.Range("A" & j))
Set r1 = i.Range(Cells(j, 1), Cells(j, 5))
Set r2 = e.Range(i.Range("H" & j).Value)
r2.Resize(1, 5).Value = r1.Value
j = j + 1
Loop
Application.ScreenUpdating = True
Application.EnableEvents = True
Application.Calculation = xlCalculationAutomatic
End Sub
EDIT:
I don't think you can achieve that without a loop, but I have edited the code to:
disable screen updates
disable events
disable formula calculation
assign range values instead of copy/paste
On my computer test with 18000 rows finished in less than 3 seconds.

You didn't dimension all your variables. Let me know if it doesn't fix your error:
Sub Reconcile()
Dim i as Worksheet
Dim e As Worksheet
Dim r1 As Range
Dim r2 As Variant
Dim j As Integer
Set i = Sheets("Data")
Set e = Sheets("Final")
j = 2
Set r1 = i.Range(Cells(j, 1), Cells(j, 5))
Set r2 = i.Cells("I" & j).Value
Do Until IsEmpty(i.Range("A" & j))
r1.Select
Selection.Copy
e.Range(r2).Select
Selection.Paste
j = j + 1
Loop
End Sub

Related

count row cell and copy and paste

I using my code for working with c# based macro soft
but i want do my macro only using VBA, not using c#
is it can do it? not using point?
Data in B2~Bxxxxx
my c# program do copy B2 cell value and paste another worksheets K3 cell
run macro under code
Sub CopyRows()
Application.ScreenUpdating = False
Application.EnableEvents = False
ActiveSheet.DisplayPageBreaks = False
Dim bottomL As Long
Dim x As Long
bottomL = Sheets("Total").Range("L" & Rows.Count).End(xlUp).Row: x = 1
Dim c As Range
Dim lr As Long
lr = Cells(Rows.Count, 1).End(xlUp).Row
For Each c In Sheets("Total").Range("K1:K" & bottomL)
If c.Value = "Inside" Then
c.EntireRow.Copy Worksheets("filter").Range("A" & Rows.Count).End(xlUp).Offset(1, 0)
x = x + 1
End If
Next c
End Sub
then my c# program do select b3 and copy to otherworksheet k3 cell then run macro then loop that process and end be cell on Bxxxxx
anyone know that working only using VBA?
Thanks and Sorry for my Bad English
In VBA make the full code like this:
Function CopyRows()
Application.ScreenUpdating = False
Application.EnableEvents = False
ActiveSheet.DisplayPageBreaks = False
Dim bottomL As Long
Dim x As Long
bottomL = Sheets("Total").Range("L" & Rows.Count).End(xlUp).Row
x = 1
Dim c As Range Dim lr As Long
lr = Cells(Rows.Count, 1).End(xlUp).Row
For Each c In Sheets("Total").Range("K1:K" & bottomL)
If c.Value = "Inside" Then
c.EntireRow.Copy
Worksheets("filter").Range("A" & Rows.Count).End(xlUp).Offset(1, 0)
x = x + 1
End If
Next c
End Function
Sub Main()
Dim bottomB As Long
Dim y As Long
bottomB = Range("B" & Rows.Count).End(xlUp).Row
For y = 2 To bottomB
Range("B" & 2).Copy Worksheets("Total").Range("K3")
CopyRows
Next
End Sub
Then only run Sub Main().
Thanks Wasif Hasan
I already using like this code i made
Sub dual()
Application.ScreenUpdating = False ActiveSheet.DisplayPageBreaks = False
Dim i As Long
Dim totalRows As Long
Dim lastRow As Long
Dim Number As Long
Dim nowRows As Long
Dim bottomL As Long
Dim x As Long
Dim c As Range
Dim lr As Long
bottomL = Sheets("Total").Range("L" & Rows.Count).End(xlUp).Row: x = 1
lr = Cells(Rows.Count, 1).End(xlUp).Row
With Worksheets("List")
'for looping
totalRows = .Cells(.Rows.Count, "B").End(xlUp).Row
'index of row to add from
lastRow = totalRows + 1 '<--| start pasting values one row below the last non empty one in column "B"
'data starts at row #2
For i = 2 To totalRows
If .Cells(i, 2).Value > 0 Then
Worksheets("List").Cells(i, "B").Copy
Worksheets("Total").Range("K3").PasteSpecial Paste:=xlPasteValues
lastRow = lastRow + Number
For Each c In Sheets("Total").Range("L1:L" & bottomL)
If c.Value = "Inside" Then
c.EntireRow.Copy Worksheets("filter").Range("A" & Rows.Count).End(xlUp).Offset(1, 0)
x = x + 1
End If
Next c
End If
Next i
End With Application.ScreenUpdating = True ActiveSheet.DisplayPageBreaks = True End Sub
but its lost many data at copy&paste
so it need wait paste done
so i using other program
is it any option to make waiting paste done?
Thnaks your Answer
If it is not necessary to copy and paste than try not to use that command. It is faster to just use cell1.Value = cell2.Value.
In your case you should declare a variable to count the total amount of columns in b. Then use a loop to go through b2 up to bx.
Example:
dim i as Integer
dim j as Integer
j = 3
For i = 2 to totalCount
Worksheet.Cells(2, i).Value = Worksheet2.Cells(11, j)
j = j + 1
Next i
In the above 2 = Column B and 11 = Column K

Excel VBA Runtime Error 1004 while looping through sheets and extracting data

I'm writing an excel VBA script to loop through a set of 4 sheets, find a string at the top of a column of data, loop through all the data in that column and print the header and data in a summary tab.
I'm new to VBA and even after extensive research can't figure out why I'm getting Runtime error 1004 "Application-defined or object-defined error."
Here is the VBA code:
Private Sub CommandButton1_Click()
Dim HeaderList(1 To 4) As String, sheet As Worksheet, i As Integer, j As Integer, Summary As Worksheet
'Define headers to look for
HeaderList(1) = "Bananas"
HeaderList(2) = "Puppies"
HeaderList(3) = "Tigers"
'Loop through each sheet looking for the right header
For Each sheet In Workbooks("Tab Extraction Test.xlsm").Worksheets
i = i + 1
'Debug.Print i
'Debug.Print HeaderList(i)
Set h = Cells.Find(What:=HeaderList(i))
With Worksheets("Summary")
Worksheets("Summary").Cells(1, i).Value = h
End With
Col = h.Column
Debug.Print Col
Row = h.Row
Debug.Print Row
j = Row
'Until an empty cell in encountered copy the value to a summary tab
Do While IsEmpty(Cells(Col, j)) = False
j = j + 1
V = Range(Col, j).Value
Debug.Print V
Workbooks("Tab Extraction Test.xlsm").Worksheets("Summary").Cells(j, i).Value = V
Loop
Next sheet
End Sub
The error occurs at
Worksheets("Summary").Cells(1, i).Value = h
From other posts I thought this might be because I was trying to add something to a different cell than the one that was active in the current loop so I added a With statement but to no avail.
Thank you in advance for your help.
Following the comments above, try the code below.
Note: I think your Cells(Row, Col) is mixed-up, I haven't modified it yet in my answer below. I think Cells(Col, j) should be Cells(j, Col) , no ?
Code
Option Explicit
Private Sub CommandButton1_Click()
Dim HeaderList(1 To 4) As String, ws As Worksheet, i As Long, j As Long, Summary As Worksheet
Dim h As Range, Col As Long
'Define headers to look for
HeaderList(1) = "Bananas"
HeaderList(2) = "Puppies"
HeaderList(3) = "Tigers"
' set the "Summary" tab worksheet
Set Summary = Workbooks("Tab Extraction Test.xlsm").Worksheets("Summary")
'Loop through each sheet looking for the right header
For Each ws In Workbooks("Tab Extraction Test.xlsm").Worksheets
With ws
i = i + 1
Set h = .Cells.Find(What:=HeaderList(i))
If Not h Is Nothing Then ' successful find
Summary.Cells(1, i).Value = h.Value
j = h.Row
'Until an empty cell in encountered copy the value to "Summary" tab
' Do While Not IsEmpty(.Cells(h.Column, j))
Do While Not IsEmpty(.Cells(j, h.Column)) ' <-- should be
j = j + 1
Summary.Cells(j, i).Value = .Cells(j, h.Column).Value
Loop
Set h = Nothing ' reset range object
End If
End With
Next ws
End Sub
Try this one.
Private Sub CommandButton1_Click()
Dim HeaderList As Variant, ws As Worksheet, i As Integer, j As Integer, Summary As Worksheet
Dim lastRow As Long, lastCol As Long, colNum As Long
HeaderList = Array("Bananas", "Puppies", "Tigers", "Lions")
For Each ws In Workbooks("Tab Extraction Test.xlsm").Worksheets
lastCol = ws.Range("IV1").End(xlToLeft).Column
For k = 1 To lastCol
For i = 0 To 3
Set h = ws.Range(Chr(k + 64) & "1").Find(What:=HeaderList(i))
If Not h Is Nothing Then
lastRow = ws.Range(Chr(h.Column + 64) & "65536").End(xlUp).Row
colNum = colNum + 1
' The below line of code adds a header to summary page (row 1) showing which workbook and sheet the data came from
' If you want to use it then make sure you change the end of the follpowing line of code from "1" to "2"
' ThisWorkbook.Worksheets("Summary").Range(Chr(colNum + 64) & "1").Value = Left(ws.Parent.Name, Len(ws.Parent.Name) - 5) & ", " & ws.Name
ws.Range(Chr(h.Column + 64) & "1:" & Chr(h.Column + 64) & lastRow).Copy Destination:=ThisWorkbook.Worksheets("Summary").Range(Chr(colNum + 64) & "1")
Exit For
End If
Next i
Next k
Next ws
End Sub
Sometimes you have to remove blank sheets. Say you have 2k sheets because you combined a bunch of txt files into one workbook. But they're all in one column. So you loop through to do a text2columns. It does some of them but not all of them. It stops to give you run-time error 1004. Try removing blank sheets before looping through to do text2columns or something else.
Sub RemoveBlankSheets_ActiveWorkbook()
'PURPOSE: Delete any blanks sheets in the active workbook
'SOURCE: www.TheSpreadsheetGuru.com/the-code-vault
Dim sht As Worksheet
Application.ScreenUpdating = False
Application.DisplayAlerts = False
For Each sht In ActiveWorkbook.Worksheets
If WorksheetFunction.CountA(sht.Cells) = 0 And _
ActiveWorkbook.Sheets.Count > 1 Then sht.Delete
Next sht
Application.DisplayAlerts = True
Application.ScreenUpdating = True
End Sub

looping through an entire column of values and if value matches, cut and paste it to another sheet

I have columns A, B, C, D, and E with data.
My goal is to start in cell A1, loop through every single record in column A while looking for a particular value "Grey". If the text in cells is equal to "Grey" then i want to cut and paste then entire row to a newly created sheet, starting in A1. here's what my code looks like ....
Dim n As Long
Dim nLastRow As Long
Dim nFirstRow As Long
Dim lastRow As Integer
ActiveSheet.UsedRange
Set r = ActiveSheet.UsedRange
nLastRow = r.Rows.Count + r.Row - 1
nFirstRow = r.Row
Worksheets("Original").Activate
With Application
.ScreenUpdating = False
Sheets.Add.Name = "NewSheet"
Sheets("Original").Select
Range("A1").Select
Set r = ActiveSheet.UsedRange
nLastRow = r.Rows.Count + r.Row - 1
nFirstRow = r.Row
With ActiveSheet
For n = nLastRow To nFirstRow Step -1
If .Cells(n, "A") = "Grey" Then
.Cells(n, "A").EntireRow.Cut Sheets("NewSheet").Cells(i, "A")
.Cells(n, "A").EntireRow.Delete
n = n + 1
End If
Next
End With
.ScreenUpdating = True
End With
So this macro creates a new sheet - however when it gets to a cell where the value is grey it gives me an error on this line....
.Cells(n, "A").EntireRow.Cut Sheets("NewSheet").Cells(i, "A")
Error says:
Application defined or object defined error.
Anyone have any idea why?
You need to declare i, and set it. As mentioned, the first time it occurs it's looking to paste in row 0, which doesn't exist.
Also, it's best to avoid using .Select/.Activate, and work directly with the data.
How does this work?
Sub t()
Dim r As Range
Dim n As Long, i As Long, nLastRow As Long, nFirstRow As Long
Dim lastRow As Integer
Dim origWS As Worksheet, newWS As Worksheet
Set origWS = Worksheets("Original")
Set newWS = Sheets.Add
newWS.Name = "NewSheet"
Set r = origWS.UsedRange
nLastRow = r.Rows.Count + r.Row - 1
nFirstRow = r.Row
i = 1
With Application
.ScreenUpdating = False
With origWS
For n = nLastRow To nFirstRow Step -1
If .Cells(n, "A") = "Grey" Then
.Cells(n, "A").EntireRow.Copy newWS.Cells(i, "A")
.Cells(n, "A").EntireRow.Delete
i = i + 1
End If
Next
End With
.ScreenUpdating = True
End With
End Sub
You also don't need to do n = n + 1 (unless I missed something).
Edit: Changed .Cut to .Copy, per OP's wish to keep formatting.
Or you may try something like this...
Sub CopyToNewSheet()
Dim sws As Worksheet, dws As Worksheet
Application.ScreenUpdating = False
Set sws = Sheets("Original")
On Error Resume Next
Set dws = Sheets("NewSheet")
dws.Cells.Clear
On Error GoTo 0
If dws Is Nothing Then
Sheets.Add(after:=sws).Name = "NewSheet"
Set dws = ActiveSheet
End If
sws.Rows(1).Insert
On Error Resume Next
With sws.Range("A1").CurrentRegion
.AutoFilter field:=1, Criteria1:="Grey"
.SpecialCells(xlCellTypeVisible).Copy dws.Range("A1")
.SpecialCells(xlCellTypeVisible).EntireRow.Delete
End With
dws.Rows(1).Delete
Application.ScreenUpdating = True
End Sub

VBA sumif with variable range

I'm new to VBA, so I have to ask you for a help.
Below, I got VBA code which should sum data from different sheet [AB] based on value from first column of active sheet. The number of rows and columns is variable, so cell adresses need to be absolute.
Sub sumif_test
Range("A1").Select
Selection.End(xlDown).Select
abc = ActiveCell.Row
Selection.End(xlUp).Select
Selection.End(xlToRight).Select
ActiveCell.Offset(1, 1).Select
Dim mycrit As Variant
Dim myval As Variant
Dim CritRng As Range
Dim SumRng As Range
Set CritRng = Worksheets("AB").Range("A:A")
Set SumRng = Worksheets("AB").Range("N:N")
c = ActiveCell.Column
r = ActiveCell.Row
For r = 2 To abc - 2
mycrit = Cells(r, 1).Address(RowAbsolute:=False, ColumnAbsolute:=False)
myval = Cells(r, c).Address(RowAbsolute:=False, ColumnAbsolute:=False)
myval = Application.WorksheetFunction.SumIf(CritRng, mycrit, SumRng)
Next r
End sub
With this code I don't get any result.
Try to avoid using select statements. Also learn to use the Application.ScreenUpdating property to speed up your code (This disables the screen refreshing between each write to the excel sheet and updates everything at the end making it much faster)
Sub sumif_test()
Dim ws As Worksheet
Dim NoCol As Integer, NoRow As Integer
Dim CritRng As Range, SumRng As Range
Application.ScreenUpdating = False
Set ws = Worksheets("AB")
With ws
NoRow = .Cells(.Cells.Rows.Count, 1).End(xlUp).Row
NoCol = .Cells(1, .Cells.Columns.Count).End(xlToLeft).Column
Set CritRng = .Range("A:A")
Set SumRng = .Range("N:N")
End With
For r = 2 To NoRow
Cells(r, NoCol) = WorksheetFunction.SumIf(CritRng, Cells(r, 1), SumRng)
Next r
Application.ScreenUpdating = True
End Sub
I've rewritten your code to avoid using the select statement. Please take a look at it and see if you can figure out what each part does.
You need ranges and you need to set them. In your code, if you write debug.print after myval like this:
For r = 2 To abc - 2
mycrit = Cells(r, 1).Address(RowAbsolute:=False, ColumnAbsolute:=False)
myval = Cells(r, c).Address(RowAbsolute:=False, ColumnAbsolute:=False)
myval = Application.WorksheetFunction.SumIf(CritRng, mycrit, SumRng)
debug.print myval
Next r
End sub
you would probably get some result in the immediate window. Ctrl+G.
In order to get some result try with:
For r = 2 To abc - 2
mycrit = Cells(r, 1).Address(RowAbsolute:=False, ColumnAbsolute:=False)
myval = Cells(r, c).Address(RowAbsolute:=False, ColumnAbsolute:=False)
myval = Application.WorksheetFunction.SumIf(CritRng, mycrit, SumRng)
Cells(r,c) = myval
Next r
End sub
Finally - 2 things - try to avoid usage of select and format your code :)
Here you may find some examples of sumif with VBA.

VBA search column for strings and copy row to new worksheet

Not really good at VBA here. Found and edited some code that I believe can help me.
I need this code to search 2 columns (L and M) for any string in those columns that ends with _LC _LR etc... Example: xxxxxxxx_LC .
If the cell ends with anything in the array, I need the row to be copied to a new sheet. Here is what I have:
Option Explicit
Sub Test()
Dim rngCell As Range
Dim lngLstRow As Long
Dim keywords() As String
Dim maxKeywords As Integer
maxKeywords = 6
ReDim keywords(1 To maxKeywords)
maxKeywords(1) = "_LC"
maxKeywords(2) = "_LR"
maxKeywords(3) = "_LF"
maxKeywords(4) = "_W"
maxKeywords(5) = "_R"
maxKeywords(6) = "_RW"
lngLstRow = ActiveSheet.UsedRange.Rows.Count
For Each rngCell In Range("L2:L, M2:M" & lngLstRow)
For i = 1 To maxKeywords
If keywords(i) = rngCell.Value Then
rngCell.EntireRow.Copy
Sheets("sheet1").Select
Range("L65536, M65536").End(xlUp).Offset(1, 0).Select
Selection.PasteSpecial xlPasteValues
Sheets("Results").Select
End If
Next i
Next
End Sub
Okay, the issue I think is with your variable declarations. Before I continue, I will echo #GradeEhBacon's comment that if you can't read this and understand what's going on, you may want to take some time to learn VBA before running.
This should work, AFAIK. You didn't specify which sheet has what info, so that may have to be tweaked. Try the below, and let me know what is/isn't working:
Sub Test()
Dim rngCell As Range
Dim lngLstRow As Long
Dim keywords() As String, maxKeywords() As String
Dim totalKeywords As Integer, i&
Dim ws As Worksheet, resultsWS As Worksheet
Set ws = Sheets("Sheet1")
Set resultsWS = Sheets("Results")
totalKeywords = 6
ReDim keywords(1 To totalKeywords)
ReDim maxKeywords(1 To totalKeywords)
maxKeywords(1) = "_LC"
maxKeywords(2) = "_LR"
maxKeywords(3) = "_LF"
maxKeywords(4) = "_W"
maxKeywords(5) = "_R"
maxKeywords(6) = "_RW"
lngLstRow = ws.UsedRange.Rows.Count 'Assuming "Sheet1" is what you want to get the last range of.
Dim k& ' create a Long to use as Column numbers for the loop
For k = 12 To 13 ' 12 is column L, 13 is M
With ws 'I'm assuming your Ranges are on the "Sheet1" worksheet
For Each rngCell In .Range(.Cells(1, k), .Cells(lngLstRow, k))
For i = LBound(maxKeywords) To UBound(maxKeywords)
If maxKeywords(i) = Right(rngCell.Value, 3) or maxKeywords(i) = Right(rngCell.Value, 2) Then
' rngCell.EntireRow.Copy
' ws.Range("L65536, M65536").End(xlUp).Offset(1, 0).PasteSpecial xlPasteValues
resultsWS.Cells(65536, k).End(xlUp).Offset(1, 0).EntireRow.Value = rngCell.EntireRow.Value
End If
Next i
Next rngCell
End With
Next k
End Sub
This might be what you are looking for:
==================================================
Option Explicit
Sub Test()
Dim rngCell As Range
Dim lngLstRow As Long
Dim keywords() As String
Dim maxKeywords, i, j, k As Integer
maxKeywords = 6
ReDim keywords(1 To maxKeywords)
keywords(1) = "_LC"
keywords(2) = "_LR"
keywords(3) = "_LF"
keywords(4) = "_W"
keywords(5) = "_R"
keywords(6) = "_RW"
lngLstRow = ActiveSheet.UsedRange.Rows.Count
For j = 1 To lngLstRow
For i = 1 To maxKeywords
If keywords(i) = Right(Sheets("Results").Range("L" & j).Value, Len(keywords(i))) Or _
keywords(i) = Right(Sheets("Results").Range("M" & j).Value, Len(keywords(i))) Then
k = k + 1
Rows(j & ":" & j).Copy
Sheets("sheet1").Select
Range("A" & k).Select
ActiveSheet.Paste
End If
Next i
Next j
End Sub