VBA - Copying worksheet from one workbook to another (values, not formulas) - vba

Currently, I am copying the values and formats of a worksheet to a worksheet in another workbook as such:
workbooks("book1.xlsm").sheets(1).range(someRange).copy
with workbooks("book2.xlsm").sheets(1).range("A1")
.pasteSpecial xlPasteValues
.pasteSpecial xlPasteFormats
end with
I would like to use something like:
workbooks("book1.xlsm").sheet(1).copy after:=workbooks("book2.xlsm").sheet(1)
The problem is that some of the cells in sheet(1) of book1.xlsm have formulas. Using the second method pulls the formulas, and the resulting values are linked to the data in book2.xlsm
How can I use the second method, but have the values, not formulas, copied?
If not possible, what are some alternatives, aside from the first method, which I am currently using?

You can break the links after the copy operation:
Option Explicit
Sub copySheetValues()
With Workbooks("Book2")
Workbooks("Book1").Worksheets(1).Copy After:=.Worksheets(1)
Application.Wait Now + TimeValue("0:00:01") 'built-in replacement for "Sleep"
.BreakLink Name:=Workbooks("Book1.xlsm").FullName, Type:=xlLinkTypeExcelLinks
End With
End Sub
Note: both files need to be open in the same instance of the Excel application

Related

Copying and Pasting data using Cells / Row Column reference in VBA

I'm having difficulty copying and pasting data in Excel 2013 VBA using row column references.
Here's a snippet of my code that fails (creates an error message):
"Application Defined or object defined error"
Worksheets("Sheet2").Range(Cells(1, 1), Cells(3, 3)).Copy Worksheets("Sheet1").Range(Cells(1,1))
Here's an alternative version that works (copies the range A1:C3 from one worksheet to the other:
Worksheets("Sheet2").Range("A1:C3").Copy Worksheets("Sheet1").Range("A1")
Why am I fixated on the rows/columns method? Because I want to be able to copy and paste ranges where all of the row and column references are variables. This is for my personal knowledge.
Thanks in advance!
Cells on its own will refer to the ActiveSheet, you should watch your variable qualifications. Also here I have used CodeNames Worksheet.CodeName for the sheets which defends against user changing worksheet names.
I believe what you want is this...
Option Explicit
Sub Test()
Sheet2.Range(Sheet2.Cells(1, 1), Sheet2.Cells(3, 3)).Copy Sheet1.Cells(1, 1)
End Sub

How do I freeze the active row in excel with VBA?

Like the title says, I need to write a VBA code that copies the entire row i selected and pastes only the values so the results cannot be changed afterwards.
I have already managed to do this for the ActiveCell in the last file I worked on, but I only had to change one cell then. This is the code I used:
Sub Freeze()
ActiveCell.Copy
ActiveCell.PasteSpecial Paste:=xlPasteValues
End Sub
However, for this new file I have to copy the entire row and i don't want to select each individual cell. When I use this in the new file, it only works on the first cell. How can I make it work for the entire row?
Thanks.
Use the simple code below (try to avoid Selecting cells, and active cells if possible):
Sub Test()
Call Freeze(3, 7)
Call Freeze(4, 8)
End Sub
Sub Freeze(rowsource As Long, rowdest As Long)
Rows(rowsource).Copy
Rows(rowdest).PasteSpecial Paste:=xlPasteValues
End Sub
Paste:=xlPasteValues
You do not need to copy paste values unless you are trying to copy formats as well.
Try this. Replace the sheet names with the relevant sheet names. Also Replace X,Y with the relevant row numbers. If you are using multiple rows then change Rows(X) to Range("X:X") and similarly Range("Y:Y")
Thisworkbook.Sheets("Sheet1").Rows(X).Value = _
Thisworkbook.Sheets("Sheet2").Rows(Y).Value

How to paste value of a sheet using VBA?

I have always used following to make a sheet to contain only values:
Sheets("NameOfTheTab").Activate
Cells.Select
Selection.Copy
Selection.PasteSpecial Paste:= xlPasteValues
But this is not safe, if someone/event change the selection, the program runs into random behaviour. How can can I get rid of this pattern?
Well, for one thing, you can avoid selecting the cells, just directly copy them:
Sheets("NameOfTheTab").Activate
Cells.Copy
Cells(1,1).PasteSpecial Paste:= xlPasteValues
Although this might not be the fastest way, depending on your sheet/actual problem.
You should always avoid using select method, beacuse it is not reliable. The sub below is a sample to copy data from a worksheet and paste only values to another one. This sample sub assumes you are running this macro from your target workbook if not change ThisWorkbook to your target workbook.
Sub copy_paste_only_values()
'will copy all cells in your tab that contain data
ThisWorkbook.Worksheets("NameOfTheTab").Cells.Copy
'will paste only values to your target worksheet
ThisWorkbook.Worksheets("NameOfTheTargetTab").Range("A1")._
PasteSpecial Paste:=xlPasteValues
'empty the clipboard
Application.CutCopyMode = False
End Sub

Excel to replace formulas with values

I have an Excel workbook (1) with around 9 sheets that is pulling in and manipulating data from a second workbook (2).
After pulling in the data from workbook (2) I need to be able to replace the formulas in workbook (1) to the resulting values that the formulas have produced, from here I will then save the workbook (1) with the results.
Is there a macro that can do this for me?
On your new workbook some basic code such as:
Sub Value()
Dim ws As Worksheet
For Each ws In ActiveWorkbook.Sheets
ws.UsedRange.Value = ws.UsedRange.Value
Next
End Sub
While the OP is dated, I want to make note of a non-loop method that is useful. In certain scenarios, loops can really slow down the code execution. To replace formulas in a cell --without a loop-- try:
With Sheets("example").Range("A1:C1000")
.value = .value
End With
You can revise the reference as necessary, but the execution is seamless, fast, and as a bonus - prevents range highlighting that cannot be cleared if you pursued the .copy + .pastespecial xlPasteValues approach.
What seems to work for me is to use concatenate()
So, for example, the formula I have referencing a cell from another sheet is:
=arrayformula(iferror(index('To Be Processed'!X:X,small(if($A$1='To Be
Processed'!$Y2,row('To Be Processed'!X:X)),row((2:2))),"")))
and if I change to the formula to:
=concatenate(arrayformula(iferror(index('To Be
Processed'!X:X,small(if($A$1='To Be Processed'!$Y2,row('To Be
Processed'!X:X)),row((2:2))),""))))
and it puts in the text value from the reference cell into my second sheet.
Which may or may not be helpful depending on how you populate your sheets--I'm not very good with VBA, though, which means I do more things manually :)

Run time Error - 438

I have the following code in which I am trying to copy data from one sheet to another in same workbook. When I run the code I get Runtime error -438
Sub Copy()
Sheets("Sheet1").Range("A1:D20").Copy
Sheets("Sheet2").Activate
Range("E1").Select
ActiveSheet.Paste
Application.CutCopyMode = False
End Sub
Try the following code. You should not rely on Activate and Select.
Sub ZCopy()
Sheets("Sheet1").Range("A1:D20").Copy
Sheets("Sheet1").Paste Destination:=Worksheets("Sheet2").Range("E1")
Application.CutCopyMode = False
End Sub
Interesting Reads
MSDN
How to avoid using Select in Excel VBA macros
Do you have a particular need for copy and paste? This can be slow and inefficient. If you're just copying data from one sheet to another, you can set the values of one range equal to the values of another range and avoid the whole thing.
Sheets("Sheet2").Range("E1:H20").Value = Sheets("Sheet1").Range("A1:D20").Value
This will set the range from cells E1:H20 on Sheet2 to the same values as those in the range A1:D20 on Sheet1, which is effectively a copy and paste. I should add that this will work only for the values themselves.
If there is specific formatting (or formulas) that you need copied and pasted, this method won't work.