VBA Copy visible cells and paste as values - most efficient method - excel

I have an excel tool that uses feed from 11 different raw data files generated from reporting system to do some calculations on that data.
The process is very simple:
- open file
- filter contents
- copy filtered contents
- paste into another file (the summary tool's tab)
As the amounts of data and individual files rose I started getting more issues with memory.Hence my question - what is the most memory and speed efficient way to copy/paste these tables?
(...).SpecialCells(xlCellTypeVisible).Copy Destination:=(...) - I haven't found the way to include XLValues parameter for this (I want to minimise the resources taken up by copying formatting, there are no formulas)
using defined ranges for the copy/paste purpose (name range with xlCellTypeVisible parameter, converting to another range to get the values only and sending the range to destination) - that would require additional variables for the ranges
plain old Columns(...).SpecialCells(xlCellTypeVisible).Copy and Range.("A1").PasteSpecial Paste:=xlValues - this method has both "only visible cells" and "paste values only" bits that I'm looking for, but it uses the clipboard as a middleman and I guess this is eating up my memory
Maybe there is yet another method that I don't know of?
Appreciate any insights!

Fortunately there is a built-in feature for Autofilter to facilitate this. Say we start with:
and apply a filter to it with:
Sub Macro1()
Columns("A:B").AutoFilter
ActiveSheet.Range("$A$1:$B$8").AutoFilter Field:=2, Criteria1:=">50", Operator:=xlAnd
End Sub
==> The Autofilter has a Range property that allows: <==
Sub Kopy()
Dim rng As Range
Set rng = ActiveSheet.AutoFilter.Range
rng.Copy Sheets("Sheet2").Range("A1")
End Sub
The result on Sheet2 has
only the visible data from Sheet1
the header row
is not filtered
NOTE:
Looping is not required.Similar approach can be used for Tables.SpecialCells is not required.

Related

How do I copy a range including hidden cells(by filter)?

I know basically the same questions has previosly been asked and answered on many forums, including stack overflow, but none of the answers satisfy my requirements.
I want to press a button, which will copy a range of around 100 cells. I then want to press a different button, in a totally different workbook (which is in no way connected to the first workbook) and that will paste my copied range.
The issue is that I have a filter in my workbook, which will hide some of the cells in the range. These are not being copied but I need to copy the full range. (The reason I want to copy the full range is because the values need to align when I paste it)
My issue with all other given solutions are:
One solution is to remove the filter when I copy the range. This is not something I want to do as I don't know a way to restore the filter. If this is done before I paste the values, the copied range will "exit?" (it will no longer be copied). And due to the files not being connected, I can't perform any actions with the paste button.
Using a loop to copy the range as a array(Variant), This doesn't work since I can't "transfer" that variant to another workbook which is not connected. Or at least I don't know how to do that.
Is there any other method I can use?
It is a bit of a hack, but because both workbooks have access to the set of custom lists defined for Excel, you could create a custom list with the information needed to identify the source range from the target workbook. The code for the copy button would record the range address, sheet name, and workbook name of the selected range as follows:
Sub copy_range_info()
Application.AddCustomList Array("DeleteMe", Selection.Address, Selection.Parent.Name, Selection.Parent.Parent.Name)
End Sub
On the destination worksheet, the code to paste data would look like this:
Sub paste_range_from_other_workbook()
Dim last_list As Variant
last_list = Application.GetCustomListContents(Application.CustomListCount)
If last_list(1) = "DeleteMe" Then
Workbooks(last_list(4)).Worksheets(last_list(3)).Range(last_list(2)).Copy
ActiveCell.PasteSpecial xlPasteValues
Application.DeleteCustomList Application.CustomListCount
Else
MsgBox "You need to copy a range first using that special button"
End If
End Sub
Because this creates a custom list in Excel that will be permanent, I'm deleting it just before the "else" in the code above. It might be advisable to scan the custom list and delete any lists that begin with "DeleteMe" so if someone does a copy without a corresponding paste, it won't result in more than one custom list of this type.

Selecting a Named Range Cell Location EXCEL VBA

Basically I want to select a specific cell that my named range is referencing and not returning the Value. I want to mimic the below, but been having errors with selecting the cell address.
Range("AU8").Select
What I have been trying which hasn't been working.
ThisWorkbook.Names("Root").Select
ThisWorkbook.Names("Root").Cells(1,1).Select
Does anyone know how to fix this?
Use the .RefersToRange property of the Name Object. Like so:
ThisWorkbook.Names("Root").RefersToRange.Select
But the .Select method will fail if the sheet is not active. A better method is Application.Goto like so:
Application.Goto ThisWorkbook.Names("Root").RefersToRange
Side Note:
.Select is often a pointless and wasteful method that hinders the speed and accuracy of your macro scripts. Instead of relying on .Select and Selection, you can instead remove both, and directly reference the ranges that you want to interact with.
Comparison:
ThisWorkbook.Activate
Sheets("Sheet1").Activate
Range("B2").Select
Selection = "Input Text"
ThisWorkbook.Sheets("Sheet1").Range("B2") = "Input Text"
The last line does the same thing as the previous 4, but skips the steps of activating the workbook, sheet and range individually, which removes that screen jittering, and speeds up the execution of the script by massive amounts.

How to copy specific parts of a table from a sheet to another

I'm trying to get some details copied in Excel from Sheet 1 columns 1-5 to Sheet 2 columns 1-4, but only for lines that include text or values on sheet one under a specific column (in this case, Column 2). There are other columns in between, so I need to be able to use exact columns rather than A:D for example.
Example of what I'm trying to achieve:
I have tried using a simple IF function with A:A<>"" so it would include any rows that have any data in them, however this does not seem to copy as I need and occasionally based on my attempts i also get circular reference errors. Additionally, I’m not sure how to make sure this gets pasted at the bottom of a table that will expand with each addition.
I realize a probably easier option would be to simply copy Sheet 1 entirely and use a filter on row 1 to deselect Blanks on A:A, but the sheet has so much more info that it would be a waste, and additionally info is constantly added so I need something scale-able. It also occurred to me now that by doing this i would include info from the "header" and "footer", basically a frozen pane - which I do not need.
Could this be done via a simple function, or would it require a Macro?
Please keep in mind I'm rubbish at programming, just trying to make my life easier and learn as I go. A lot of excel forums help but still I'm no coder. I can understand to a pretty big degree what the code does and can adjust accordingly though :)
As suggested, this cannot be done with formulas. There are different ways to achieve this.. below is one approach:
Sub CopyFilteredRows()
Dim oSourceSheet As Worksheet: Set oSourceSheet = ThisWorkbook.Worksheets("Sheet3") ' Set your source sheet here
Dim oRng As Range: Set oRng = oSourceSheet.Range("A2:E" & oSourceSheet.Range("C" & oSourceSheet.Rows.Count).End(xlUp).Row)
' Set filter on column B
oRng.AutoFilter
oRng.AutoFilter 2, "<>"
' Copy to specified sheet
oRng.SpecialCells(xlCellTypeVisible).EntireRow.Copy ThisWorkbook.Worksheets("Sheet4").Range("A2") ' Change your destination sheet here
' Clear objects
Set oRng = Nothing
Set oSourceSheet = Nothing
End Sub
Paste the above UDF in a Module and then run it whenever you want to perform the copy. I suspect you would have to modify it a bit so that you can cater for your particular scenario but it should give you a start

What is the best way to cut and paste a column with a defined name to a new worksheet, and why doesn't my code work?

I am attempting to efficiently copy columns of data from one worksheet to a second worksheet in Excel using VBA, starting with a defined name for the column.
I am unsure why my code doesn't work. I cannot emphasis enough, how little I know about coding. I am attempting to teach myself VBA in order to manipulate vast quantities of data in Excel.
Function SortDataC()
'cuts and pastes columns from the unsorted worksheet to the sorted worksheet
Worksheets("UnsortedData").Range("DeltaModScore").Copy Destination:=Worksheets("SortedData").Columns(1)
End Function
DeltaModScore is the column header. If I look in defined named it is present on the sheet UnsortedData with workbook scope. Thus, I assume I have screwed up the syntax somewhere?
I have used the term Sheets("UnsortedData").Range..... as well as Worksheets.... as you see above. I've been basically searching the web for code examples and trying to get them to work with my data. Inevitably, I end up with errors I have much difficulty fixing. I hope this is something simple someone can point out.
You only require the single top left cell of a destination to complete a Copy & Paste.
SUB SortDataC()
'COPIES and pastes columns from the unsorted worksheet to the sorted worksheet
Worksheets("UnsortedData").Range("DeltaModScore").Copy _
Destination:=Worksheets("SortedData").Cells(1, "A")
End SUB
Functions are intended to return a value. If you simply want to complete an operation, a sub procedure is more appropriate.

Excel Filtering and Copying in VBA

I'm working on a VBA script that pulls a range of dates from Access, then filters the data and creates a chart based on the filtered data. The filtered data will be going to a separate sheet where the chart will be pulling its data from . I can get data out of Access with a SQL statement, but my AutoFilter in Excel is erroring out. Here is what I have...
Sheet3.Range("F4:F500").AutoFilter(, "Riveter 01").Copy Destination:=Sheet2.Range("A5")
It gives an app-defined or object-defined error and I can't figure out why. Is this the proper way or is there an easier way?
PS: This filter will happen with 22 unique machines so I was planning on running a loop for each machine. If that is not the fastest or proper way please let me know.
You need to split this into two parts. Filter and then copy/ paste. See below:
With Sheet3
.AutoFilterMode = False
With .Range("F4:F500")
.AutoFilter Field:=1, Criteria1:="Riveter 01"
.SpecialCells(xlCellTypeVisible).Copy Destination:=Sheet2.Range("A5")
End With
End With
to remove the filter:
On Error Resume Next
Sheet3.ShowAllData
On Error GoTo 0
On Error Resume Next is for when there is no filter present to skip the error. Please note the use of Sheet3 and Sheet2 for those looking for a generic solution.
I think that you have to do this in 2 separate steps:
filter the data
copy the filtered data to another sheet
The answer here has an excellent example of how to do this: Autofilter Macro, then copy visible data ONLY and paste to next available row

Resources