VBA - Copy only visible cells from sheet to another worksheet - excel

I have worksheet ("Formatted Data") and worksheet("Client_1 Data")
I run Macro which do following steps:
select worksheet("Fromatted Data")
autoFilter data in Column "C" with value "client_1"
copy selected columns from worksheet ("Formatted Data") and Paste data to worksheet("Client_1 Data")
What is my issue:
macro copy not only Data i filtered but all of them, veen if they are not visible.
My Macro Code:
Sub PRINT_AVIVA_ISA()
Sheets("Formatted Data").Select
ActiveSheet.Range("$A$1:$R$73").autofilter Field:=3, Criteria1:=Array( _
"client_1"), Operator:=xlFilterValues
Dim LastRow As Long, erow As Long
LastRow = Worksheets("Formatted Data").Cells(Rows.Count, 1).End(xlUp).Row
For i = 2 To LastRow
Worksheets("Formatted Data").Cells(i, 2).Copy
erow = Worksheets("Client_1 Data").Cells(Rows.Count, 1).End(xlUp).Row
Worksheets("Formatted Data").Paste Destination:=Worksheets("Client_1 Data").Cells(erow + 1, 1) ' --- account number
Worksheets("Formatted Data").Cells(i, 3).Copy
Worksheets("Formatted Data").Paste Destination:=Worksheets("Client_1 Data").Cells(erow + 1, 2) ' --- designation
Worksheets("Formatted Data").Cells(i, 4).Copy
Worksheets("Formatted Data").Paste Destination:=Worksheets("Client_1 Data").Cells(erow + 1, 3) ' --- fund name
Worksheets("Formatted Data").Cells(i, 5).Copy
Worksheets("Formatted Data").Paste Destination:=Worksheets("Client_1 Data").Cells(erow + 1, 4) ' --- fund code
Worksheets("Formatted Data").Cells(i, 7).Copy
Next i
End Sub
What i need:
put into my existing code something to copy only filtered data?
Thanks,
Peter.

The problem that you're running into is that you're looping through all of the cells in your 'formatted data' worksheet. The VBA code doesn't check to see if the cells have been filtered or not.
I'm attaching some code below that should do what you're attempting to do. I've made a few changes to clean it up a bit, such as storing sheets into their own variable so that you don't have to recurringly reference them directly.
Also, I opted to use direct value assignment as opposed to copy/paste. Assigning the value directly is usually quicker and has cleaner, more self-descriptive code. The tradeoff is that it doesn't copy over formatting. If you really need formatting, you can add it in once (either at the start or end of the routine, for the entire column).
See if you can adapt the below code and let us know if you need more help.
Sub PRINT_AVIVA_ISA()
Dim sData As Worksheet
Dim sClient As Worksheet
'Prevents the application from rendering graphical elements during processing
Application.ScreenUpdating = False
Set sData = Worksheets("Formatted Data")
Set sClient = Worksheets("Client_1 Data")
sData.Range("$A$1:$R$73").AutoFilter Field:=3, Criteria1:=Array( _
"client_1"), Operator:=xlFilterValues
LastRow = sData.Cells(Rows.Count, 1).End(xlUp).Row
Dim i As Long
For i = 2 To LastRow
If sData.Rows(i).Hidden = False Then
' Rather than add 1 to erow 4 times later, just calculate it here
erow = sClient.Cells(Rows.Count, 1).End(xlUp).Row + 1
sClient.Cells(erow, 1).Value = sData.Cells(i, 2).Value
sClient.Cells(erow, 2).Value = sData.Cells(i, 3).Value
sClient.Cells(erow, 3).Value = sData.Cells(i, 1).Value
End If
Next i
Application.ScreenUpdating = True
End Sub

Related

Error with copy paste due to merged column cells

I want to copy paste values from 4 columns in one worksheet into 4 columns of another worksheet depending on whether the values in a single column are null or not.
Following is my code:
Private Sub CommandButton1_Click()
Dim lastrow As Long, erow As Long
lastrow = Worksheets("jun").Cells(Rows.Count, 1).End(xlUp).Row
erow = 20
For i = 8 To lastrow
If Worksheets("jun").Cells(i, 16).Value <> "" Then
Worksheets("jun").Cells(i, 16).Copy
Worksheets("jun").Paste Destination:=Worksheets("test").Cells(erow + 1, 1)
Worksheets("jun").Cells(i, 3).Copy
Worksheets("jun").Paste Destination:=Worksheets("test").Cells(erow + 1, 2)
Worksheets("jun").Cells(i, 2).Copy
Worksheets("jun").Paste Destination:=Worksheets("test").Cells(erow + 1, 3)
Worksheets("jun").Cells(i, 6).Copy
Worksheets("jun").Paste Destination:=Worksheets("test").Cells(erow + 1, 4)
erow = erow + 1
End If
Next i
End Sub
However this code produces an error when I try to paste the values into the second column of the test worksheet and I suspect this is because it is made of a merged column.
Following is the picture that shows the merged column. How could I combat this issue?
Having experimented slightly it appears .PasteSpecial Paste:=xlPasteValues will cause an error pasting into merged cells but .PasteSpecial Paste:=xlPasteValuesAndNumberFormats can paste into merged cells without that error
Try the updated sub below:
please note a slight alteration to the paste columns to take into account the merged column. I have also adjusted erow so it starts at 21 to avoid having to use 'erow + 1' for all entries
Private Sub CommandButton1_Click()
Dim lastrow As Long, erow As Long
With Worksheets("jun")
erow = 21
lastrow = .Cells(Rows.Count, 1).End(xlUp).Row
For i = 8 To lastrow
If .Cells(i, 16).Value <> "" Then
.Cells(i, 16).Copy
Worksheets("test").Cells(erow, 1).PasteSpecial Paste:=xlPasteValuesAndNumberFormats
.Cells(i, 3).Copy
Worksheets("test").Cells(erow, 2).PasteSpecial Paste:=xlPasteValuesAndNumberFormats
.Cells(i, 2).Copy
Worksheets("test").Cells(erow, 4).PasteSpecial Paste:=xlPasteValuesAndNumberFormats
.Cells(i, 6).Copy
Worksheets("test").Cells(erow, 5).PasteSpecial Paste:=xlPasteValuesAndNumberFormats
erow = erow + 1
End If
Next i
End With
End Sub
Is this the line causing the issue?
Worksheets("jun").Paste Destination:=Worksheets("test").Cells(erow + 1, 3)
It sounds like you're trying to paste in the third column but when you merge columns, the left most column becomes the primary. For example, you've merged B&C (cols 2 and 3) so any reference to 3 is now redundant. You'd either paste in to column 2 or 4. With that row, if you're trying to paste in to column D, you'd need to reference column 4, not 3.

How to Fix Run-time Error 424 "Object Required" in Excel VBA

I'm working on an Excel project where I am trying to produce certain rows from "Sheet 1" that contains a word called "external" in column C and then copy and paste that row into "Sheet 3"
I understand that there is a thing called "filter" but that is not an option.
This project is for my team at work that wants to be able to extract rows and columns that are shown as "external" and then be able to paste them and other information to another sheet that contains that information.
Private Sub CommandButton1_Click()
a = Worksheets("Sheet1").Cells(Rows.Count, 1).End(xlUp).Row
For i = 2 To a
If Worksheets("Sheet1").Cells(i, 3).Value = "External" Then
Worksheets("Sheet1").Rows(i).Copy
Worksheets("Sheet3").Activate
b = Worksheets("Sheet3").Cells(Row.Count, 1).End(xlUp).Row
Worksheets("Sheet3").Cells(b + 1, 1).Select
ActiveSheet.Paste
Worksheets("Sheet1").Activate
End If
Next
Application.CutCopyMode = False
ThisWorkbook.Worksheets("Sheet1").Cells(1, 1).Select
End Sub
The expected result was to display all rows that contained the word "External" in Sheet 1 Column C into a new sheet and have all its information displayed in Sheet 3.
Excel Worksheet for Reference:
First, declare all your variables. Next, you can try changing If Worksheets("Sheet1").Cells(i, 3).Value = "External" Then to If Worksheets("Sheet1").Range("C" & i).Text = "External" Then. See here:
Private Sub CommandButton1_Click()
Dim a As Long
Dim i As Long
Dim b As Long
a = Worksheets("Sheet1").Cells(Rows.Count, 1).End(xlUp).Row
For i = 2 To a
If Worksheets("Sheet1").Range("C" & i).Text = "external" Then
Worksheets("Sheet1").Rows(i).Copy
Worksheets("Sheet3").Activate
b = Worksheets("Sheet3").Cells(Rows.Count, 1).End(xlUp).Row
Worksheets("Sheet3").Cells(b + 1, 1).Select
ActiveSheet.Paste
Worksheets("Sheet1").Activate
End If
Next
Application.CutCopyMode = False
ThisWorkbook.Worksheets("Sheet1").Cells(1, 1).Select
End Sub

How to copy columns from one worksheet to another on excel with VBA?

I am trying to copy certain column from one worksheet to another but when I apply my code, I get no errors but also no results. I get blank paper. I applied this methodolgy on copying a certain row and it was copied to another worksheet perfectly.
This is regarding the successful attempt to copy row.
The code works just fine:
Sub skdks()
Dim OSheet As Variant
Dim NSheet As Variant
Dim i As Integer
Dim LRow As Integer
Dim NSLRow As Integer
OSheet = "Tabelle3" 'Old Sheet Name
NSheet = "Tabelle5" 'New Sheet Name
LRow = Sheets(OSheet).Cells(Rows.Count, 1).End(xlUp).row 'Last Row in Old Sheet
Sheets(OSheet).Activate
For i = 2 To LRow
'Finds last row in the New Sheet
If Sheets(NSheet).Cells(2, 1) = "" Then
NSLRow = 1
Else
NSLRow = Sheets(NSheet).Cells(Rows.Count, 1).End(xlUp).row
End If
'If cell has "certain # then..."
If Cells(i, 1).Value = Cells(13, 2).Value Then
Cells(i, 1).EntireRow.Copy
Sheets(NSheet).Cells(NSLRow + 1, 1).PasteSpecial Paste:=xlPasteValues
Application.CutCopyMode = False
End If
Next i
End Sub
This little piece of code is the failed attempt to copy column to another worksheet.
Sub trial()
Dim OSheet As Variant
Dim NSheet As Variant
Dim j As Integer
Dim LColumn As Integer
Dim NSLColumn As Integer
OSheet = "Tabelle2" 'Old Sheet Name
NSheet = "Tabelle5" 'New Sheet Name
LColumn = Sheets(OSheet).Cells(1, Columns.Count).End(xlToLeft).Column 'Last Column in Old Sheet
Sheets(OSheet).Activate
For j = 2 To LColumn
'Finds last column in the New Sheet
If Sheets(NSheet).Cells(1, 2) = "" Then
NSLColumn = 1
Else
NSLColumn = Sheets(NSheet).Cells(1, Columns.Count).End(xlToLeft).Column
End If
'If cell has "certain # then..."
If Cells(2, j) = Cells(13, 2) Then
Cells(2, j).EntireColumn.Copy
Sheets(NSheet).Cells(2, 2).PasteSpecial Paste:=xlPasteValues
Application.CutCopyMode = False
End If
Next j
End Sub
....
'If cell has "certain # then..."
If Cells(2, j) = Cells(13, 2) Then
debug.Print Cells(2, j).Address; " = "; Cells(13, 2).Address; " ---- COPY"
debug.print Cells(2, j).EntireColumn.address; Cells(2, j).EntireColumn.cells.count
debug.Print Sheets(NSheet).Cells(2, 2).Address
Cells(2, j).EntireColumn.Copy
Sheets(NSheet).Cells(2, 2).PasteSpecial Paste:=xlPasteValues
Application.CutCopyMode = False
End If
....
With the line If Cells(2, j) = Cells(13, 2) Then you compare the different cells from row 2 (B2, C2, D2, ...) with the value of cell "B13". If the value is the same you copy this column to the new worksheet.
Is there any equal value in your data? If yes you should get an error message with your code.
You try to copy the values of an entire column to the range starting with "B2". Of cause there is not enough space for this.
=> Either you reduce the source range or you start the destination range on row 1!
To add to the paste destination size, if you really want to paste the entire column, you either need to start at the beginning of the column or choose the entire column. Also, I think you want to make the paste column increase with your NSLColumn
If Cells(2, j) = Cells(13, 2) Then
Cells(2, j).EntireColumn.Copy
Sheets(NSheet).Columns(NSLColumn + 1).PasteSpecial Paste:=xlPasteValues
Application.CutCopyMode = False
End If

Row Counter Only Counting? Top Row

My code is supposed to select all of the items in A-H from the top of the sheet to the bottom most row containing text in the J column. However, now all it does is select the top row. This code has worked fine elsewhere for other purposes, but when I run it here it only selects the top row.
Here is the code and what it currently does. The commented out bit does the same when it is ran in the place of the other finalrow =statement.
Option Explicit
Sub FindRow()
Dim reportsheet As Worksheet
Dim finalrow As Integer
Set reportsheet = Sheet29
Sheet29.Activate
'finalrow = Cells(Rows.Count, 10).End(xlUp).Row
finalrow = Range("J1048576").End(xlUp).Row
If Not IsEmpty(Sheet29.Range("B2").Value) Then
Range(Cells(1, 1), Cells(finalrow, 8)).Select
End If
End Sub
This is the excerpt of code with a row counter that works.
datasheet.Select
finalrow = Cells(Rows.Count, 1).End(xlUp).Row
''loop through the rows to find the matching records
For i = 1 To finalrow
If Cells(i, 1) = item_code Then ''if the name in H1 matches the search name then
Range(Cells(i, 1), Cells(i, 9)).Copy ''copy columns 1 to 9 (A to I)
reportsheet.Select ''go to the report sheet
Range("A200").End(xlUp).Offset(1, 0).PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False ''find the first blank and paste info there
datasheet.Select ''go back to the data sheet and continue searching
End If
Next i
You can try this:
Option Explicit
Sub FindRow()
' always use Longs over Integers
Dim finalrow As Long: finalrow = 1
' you might not need this line tbh
Sheet29.Activate
With Sheet29
' custom find last row
Do While True
finalrow = finalrow + 1
If Len(CStr(.Range("J" & finalrow).Value)) = 0 Then Exit Do
Loop
' Len() is sometimes better then IsEmpty()
If Len(CStr(.Range("B2").Value)) > 0 Then
.Range(.Cells(1, 1), .Cells((finalrow - 1), 8)).Select
End If
End With
End Sub

Excel formula only bring over row in other worksheet if cell in column A is not blank

I have two worksheets in one Excel workbook, and I only want to take the lines that have data in the cell (from worksheet1 into worksheet2) if Column A has data in it. My formula in worksheet 2 is =IF('Raw Data'!A2<>"", 'Raw Data'!A2,), but I actually don't want it to bring in the row at all if there is no data as shown in Rows 3 and 5. Right now it is bringing the whole row in:
In
you see that it is still bringing the row into worksheet 2 if there is no data. Any ideas how to only bring in the rows with the data?
Sub DataInCell()
Dim rw As Long
rw = 2
' Select initial sheet to copy from
Sheets("Raw Data").Select
' Find the last row of data - xlUp will check from the bottom of the spreadsheet up.
FinalRow = Cells(Rows.Count, 1).End(xlUp).Row
' For loop through each row
For x = 2 To FinalRow
If Cells(x, 1).Value <> 0 Then
Range("A" & x & ":C" & x).Copy
Sheets("Sheet1").Select
NextRow = Cells(Rows.Count, 1).End(xlUp).Row + 1 'Continue incrementing through the rows.
Cells(NextRow, 1).Select ' Find the next row.
ActiveSheet.Cells(NextRow, "A").PasteSpecial xlPasteAll ' Paste information.
Sheets("Raw Data").Select 'Reselect sheet to copy from. Probably uneccessary.
End If
Next x
End Sub
After you update the sheet names on the 3rd and 4th line, you will see that the code carries over the entire row. You can modify using Range(Cells, Cells) if you want partial ranges.
Option Explicit
Sub Non_Blanks()
Dim ms As Worksheet: Set ms = ThisWorkbook.Sheets("Sheet1") '<-- Master Sheet
Dim ns As Worksheet: Set ns = ThisWorkbook.Sheets("Sheet2") '<-- New Sheet
Dim i As Long, MoveMe As Range, LR As Long
For i = 2 To ms.Range("B" & ms.Rows.Count).End(xlUp).Row
If ms.Range("A" & i) = "*" Then
If Not MoveMe Is Nothing Then
Set MoveMe = Union(MoveMe, ms.Range("A" & i))
Else
Set MoveMe = ms.Range("A" & i)
End If
End If
Next i
If Not MoveMe Is Nothing Then
LR = ns.Range("A" & ns.Rows.Count).End(xlUp).Offset(1).Row
MoveMe.EntireRow.Copy
ns.Range("A" & LR).PasteSpecial xlPasteValuesAndNumberFormats
End If
End Sub

Resources