I'm quite new to Excel and completely new to this forum.
I have taken the code from the below forum and modified it to my need.
http://pressf1.pcworld.co.nz/showthread.php?90122-Creating-Macro-to-copy-and-paste-data-into-the-next-empty-column.
Sub copyTotals()
Dim TargetSht As Worksheet, SourceSht As Worksheet, SourceRow As Integer, SourceCells As Range
Set SourceSht = ThisWorkbook.Sheets("DUN - Jan")
Set TargetSht = ThisWorkbook.Sheets("DUN Jan - Jan,Feb,Mar,Apr")
Set SourceCells = SourceSht.Range("L36,N36")
If TargetSht.Range("C11").Value = "" Then
SourceRow = 1
ElseIf TargetSht.Range("C41") <> "" Then
MsgBox ("The sheet is full, you need to create a new sheet")
Else
SourceRow = TargetSht.Range("C41").End(xlUp).Row + 1
End If
SourceCells.Copy TargetSht.Cells(SourceRow, 3)
End Sub
The problem is that the values pasted have the formating of the source and i only want to paste the values.
Can someone please help me with this.
Use .Copy together with .PasteSpecial. Instead of:
SourceCells.Copy TargetSht.Cells(2, SourceCol)
Do this:
SourceCells.Copy
TargetSht.Cells(2, SourceCol).PasteSpecial xlPasteValues
Using the macro recorder yields this kind of thing. I use it a lot when stuck.
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
You don't need to copy and paste to do this (at least in Excel 2010 and above, I think). You just set the .Value of the range to equal itself. eg:
rng.Value = rng.Value
or
Sheet1.Range("A1:A10").Value = Sheet1.Range("A1:A10").Value
since .Value "Returns or sets a Variant value that represents the value of the specified range."
Note that this just works for values, not formats.
http://msdn.microsoft.com/en-us/library/office/ff195193(v=office.15).aspx
right click in the cell and select paste special then you can choose values only
edit: for macros its the same principle
use
.PasteSpecial xlPasteValues
like here
Set rng6 = .Range("A3").End(xlDown).Offset(0, 41)
rng6.Copy
ActiveSheet.Paste Destination:=Worksheets("Positions").Range("W2")
Related
I want to create an excel with a macro which does this:
It takes a values from one sheet and paste them in another sheet in the first empty Row. I currently have this and this does paste but then the formula, not the values. When I change Paste to Pastespecial it does not work anymore. Can anybody help me with this?
Sub CopyPasteSpecial()
Set wsA = Sheet3
Set wsW = Sheet5
wsA.Range("A3").Copy
Sheet5.Activate
Dim i As Integer
Application.ScreenUpdating = False
NumRows = Range("C5", Range("C5").End(xlDown)).Rows.Count
Range("C5").Select
For i = 1 To NumRows
ActiveCell.Offset(1, 0).Select
Next
Application.ScreenUpdating = True
ActiveSheet.Paste
The (accepted) answer of Sachin Kohli contains so many problems that it is too much to write in a comment. All of them causes errors that can be found thousend times on Stackoverflow.
(a) Don´t use Select and Activate - https://stackoverflow.com/a/10718179/7599798 - You have already a worksheet variable to sheet5 (wsW), so use it.
(b) Copying data (values) between ranges (=cells) can be done without Copy&Paste. This is much faster.
(c) When dealing with row and column numbers, use datatype Long, else you risk an overflow error in large sheets. Basically, use always Long instead of Integer - the data type Integer exists only for historic reasons.
(d) Always put Optiona Explicit at the top of your code and declare all variables. This will save you a lot of headaches because typos in variable names will be caught by the compiler.
Sub CopyPasteSpecial()
Dim wsA As Worksheet, wsW As Worksheet
Set wsW = ThisWorkbook.Sheets("Sheet2")
Set wsA = Sheet1
Set wsW = Sheet2
Dim lastRow As Long
lastRow = wsW.Cells(wsW.Rows.Count, "C").End(xlUp).Row
wsW.Cells(lastRow + 1, "C").Value = wsA.Range("A3").Value
End Sub
Try this below code for pasting as values & no need to iterate to get to the last empty row as well...
Sub CopyPasteSpecial()
Set wsA = Sheet3
Set wsW = Sheet5
wsA.Range("A3").Copy
Sheet5.Activate
Dim i As Integer
Application.ScreenUpdating = False
NumRows = Range("C5", Range("C5").End(xlDown)).Rows.Count
Range("C" & NumRows + 5).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
End Sub
Hope this Helps...
i have a little problem with VBA. I want to paste data from one sheet and specific range to another sheet and last empty cell. I need to paste Value, Number format and theme. Is there any macro to select last paste range and paste into this range theme? Or is there any macro which can paste all data without formulas?
My code:
Dim xScreenUpdating As Boolean
Dim xPasteSht As Worksheet
Dim xRg As Range
Dim xTxt As String
On Error Resume Next
Worksheets("KOPÍROVAT ASISTENT").Range("C1:G54").Copy
Set xPasteSht = Worksheets("Archiv")
xRg.Copy
xPasteSht.Cells(Rows.Count, 1).End(xlUp).Offset(0, 0).PasteSpecial xlPasteValuesAndNumberFormats, _
Operation:=xlNone, SkipBlanks:=False, Transpose:=False
End Sub
I'm not sure what .Offset(0,0) achieves - .Offset(1,0) is what you actually need to find the last empty cell. That aside, the following code snippet should give you what you want. Let me know how you go with it.
Sheets("KOPÍROVAT ASISTENT").Range("C1:G54").Copy
With Sheets("Archiv").Cells(Rows.Count, 1).End(xlUp).Offset(1, 0)
.PasteSpecial xlPasteValues
.PasteSpecial xlPasteFormats
Application.CutCopyMode = False
End With
I'm relatively new to VBA and have some code I wrote that seems like it should be straightforward but is not behaving as expected. I am trying to separate my primary WorkSheet (GAWi) into three other worksheets (LWi, WMi, & OTi) based on the first letter in column H. Basically if the first letter is "L" I want that row to be copied and pasted onto sheet LWi and then deleted from the original sheet. Then if it is W it goes onto WMi and if it is A it goes onto OTi. It is functioning properly for the first two If statements (placing items that begin with L & W onto the correct sheets), but for the last one items that begin with P and 0 are also being placed onto sheet OTi. I'm at a complete loss, it seems pretty easy and I can't figure out where I went wrong. Any advice would be much appreciated, also I'm sure this code is pretty unelegant by most standards so any tips on how to shorten it would also be welcomed-I've just started getting into VBA in the last couple weeks. Thank so much!
Sheets("GAWi").Select
Columns("H:H").Select
Dim lwr As Range
Set lwr = ActiveSheet.UsedRange
For i = lwr.Cells.Count To 1 Step -1
If Left(lwr.Item(i).Value, 1) = "L" Then
lwr.Item(i).EntireRow.copy
Sheets("LWi").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
ActiveCell.Offset(1, 0).Select
Sheets("GAWi").Select
lwr.Item(i).EntireRow.Delete
End If
If Left(lwr.Item(i).Value, 1) = "W" Then
lwr.Item(i).EntireRow.copy
Sheets("WMi").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
ActiveCell.Offset(1, 0).Select
Sheets("GAWi").Select
lwr.Item(i).EntireRow.Delete
End If
If Left(lwr.Item(i).Value, 1) = "A" Then
lwr.Item(i).EntireRow.copy
Sheets("OTi").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
ActiveCell.Offset(1, 0).Select
Sheets("GAWi").Select
lwr.Item(i).EntireRow.Delete
End If Next i
there's a main flaw in your logic: the use of UsedRange
despite being it a 2D range, its Item() property would act as if it were a 1D array with one row listed after another
so that were "A1:H10" (eight columns) the address of UsedRange, UsedRange.Item(1) would point to "A1", UsedRange.Item(8) would point to "H1" and UsedRange.Item(9) would point to "A2" …
so you have to loop through the cells of column H only
Then there's a coding flaw, which is the use of all those Select/Selection: get in the habit of always use explicit range reference qualified up to their parent worksheet and workbook
. This can be reached, for instance, with the use of With... End With construct
here's a possible code (explanations in comments):
Option Explicit
Sub TransferRows()
Dim i As Long
With Sheets("GAWi") ' reference "source" sheet
For i = .Cells(.Rows.Count, "H").End(xlUp).Row To 1 Step -1 ' loop backwards from referenced sheet column H last not empty cell row index to 1
Select Case UCase(.Cells(i, "H").Value) ' check for referenced sheet column H current row content
Case "L"
TransferRow Intersect(.UsedRange, .Rows(i)), Sheets("LWi") ' pass referenced sheet current row "used" range and "LWi" destination sheet to the helper sub
Case "W"
TransferRow Intersect(.UsedRange, .Rows(i)), Sheets("WMi") ' pass referenced sheet current row "used" range and "WMi" destination sheet to the helper sub
Case "A"
TransferRow Intersect(.UsedRange, .Rows(i)), Sheets("OTi") ' pass referenced sheet current row "used" range and "OTi" destination sheet to the helper sub
End Select
Next i
End With
End Sub
Sub TransferRow(sourceRng As Range, destSht As Worksheet)
With destSht
.Cells(.Rows.Count, 1).End(xlUp).Offset(1).Resize(, sourceRng.Columns.Count).Value = sourceRng.Value
End With
sourceRng.Delete xlUp
End Sub
As you see, other than the amendements due to the preface explanations I put in there:
the use of Select Case syntax instead of If Then End If
which I think is much clearer and would also correct a minor logic flaw of your orginal code: once a check is positive there's no need to run other ones (this you could have obtained by means of If - Then - ElseIf - Endif construct)
the use of a "helper" sub to demand the repetitive code to
which gives you much more control over your code and helps its maintenance
the use of Cells(Rows.Count, colIndex).End(xlUp) pattern
which is the most frequently used one to get the reference to the last not empty cell in some colIndex (be it a number or a letter) column
Thanks to HTH's great response I was able to clean up my code a bit and think I got it figured out. I opted to stick with the If Then Else If format since I am not too familiar with using Case yet. Here's the first section of it, I just repeated the copy, paste, delete row for each starting letter.
Set rng = Range("GAWi!H:H")
For k = rng.Cells.Count To 1 Step -1
If Left(rng.Item(k).Value, 1) = "W" Then
With rng.Item(k)
.EntireRow.copy
Sheets("WMi").Activate
ActiveCell.Offset(1, 0).PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
.EntireRow.Delete
End With
ElseIf Left(rng.Item(k).Value, 1) = "L" Then....
This is running well for my purposes but if anyone has more suggestions they are much appreciated.
I am looking to export a specific range of data from one workbook to a master workbook. I have already figured out how to overall copy from one to another but I'd like to modify my existing coding. Currently, the macro is taking all of row 2 from the workbook and copying it into this master file which is working great, however I am looking to do some more things in the master file so I need just columns A2:HD2 to copy and paste into the master sheet. Below is what we are using, can anyone help me figure out how to just get A2:HD2 and not all of row 2 into my master sheet?
Dim LN, Match As Integer
Dim wb As Workbook
Dim Name As String
Name = "Master sheet path here"
Application.ScreenUpdating = False
Sheets("LADB Bulk Upload").Select
LN = Range("A2").Value
Rows("2:2").Select
Selection.Copy
Set wb = Workbooks.Open(Filename:=Name)
If IsError(Application.Match(LN, ActiveSheet.Range("A:A"), 0)) Then
Range("A100000").End(xlUp).Select
ActiveCell.Offset(1, 0).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Else
Match = Application.Match(LN, wb.Sheets("Sheet1").Range("A:A"), 0)
Cells(Match, 1).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
End If
Application.CutCopyMode = False
ActiveWorkbook.Save
ActiveWorkbook.Close
Application.ScreenUpdating = True
Replace
Rows("2:2").Select
Selection.Copy
With
Range("A2:HD2").Copy
Ideally you should work with ranges instead of using Select. You'll find plenty of information about that elsewhere. That said, if the code works, and isn't especially slow, it hardly matters.
This code is refactored to copy only the A2:HD2 range, and without using Select
Option Explicit
Public Sub CopyA2HD2()
Dim mainWb As Workbook, mainWs As Worksheet, mainLr As Long, mainCol As Range
Dim thisWs As Worksheet, findTxt As String, foundCell As Variant
Set thisWs = ThisWorkbook.Worksheets("LADB Bulk Upload") 'Current file
Application.ScreenUpdating = False
On Error Resume Next 'Expected errors: File not found, and Sheet Name not found
Set mainWb = Workbooks.Open(Filename:="Master sheet path here")
If Err.Number = 0 Then 'If master file is found, and open, continue
Set mainWs = mainWb.Worksheets("Sheet1")
If Err.Number > 0 Then Exit Sub 'If "Sheet1" in master file is not found exit
mainLr = mainWs.Cells(mainWs.Rows.Count, "A").End(xlUp).Row 'Last row in master
Set mainCol = mainWs.Range(mainWs.Cells(1, "A"), mainWs.Cells(mainLr, "A"))
findTxt = thisWs.Range("A2").Value
foundCell = Application.Match(findTxt, mainCol, 0) 'Search column A in master
If Not IsError(foundCell) Then 'If text was found in master
Set foundCell = mainWs.Cells(foundCell, "A") 'Copy A2:HD2 to same row
Else
Set foundCell = mainWs.Cells(mainLr + 1, "A") 'Else, copy A2:HD2 to last row
End If
thisWs.Range("A2:HD2").Copy
foundCell.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone
foundCell.Select
Application.CutCopyMode = False
mainWb.Close SaveChanges:=True
End If
Application.ScreenUpdating = True
End Sub
A few notes about your code
As already mentioned, avoid using Select and Activate if possible
Use Option Explicit at the top of every module, so the compiler can catch missing variables
Don't use reserved keywords as variable names to avoid shadowing the built-in objects
Words like Name, Match, etc
Use Long variable type instead of Integer
According to MSDN VBA silently converts all Integers to Longs
Always refer to ranges explicitly: Rows("2:2") implicitly uses the ActiveSheet
It takes a lot of care and maintenance work to make sure that the expected sheet is active
Code indentation and proper vertical white-space will help visualize structure and flow clearer
I'm trying to take a range from one sheet and copy it to the next empty row in another sheet (basically, paste into the range A12:D12 for next empty row in the other sheet). The range will never change. I've seen a lot of questions like this, with people saying the answers work great, but I can't get it to work.
Very new to VBA. Here is the code I'm using:
Private Sub CommandButton1_Click()
Dim NextRow As Range
Set NextRow = Range("A" & Sheets("Sheet3").UsedRange.Rows.Count + 1)
Sheet1.Range("A12:D12").Copy
Sheet3.Activate
NextRow.PasteSpecial Paste:=xlValues, Transpose:=False
Application.CutCopyMode = False
Set NextRow = Nothing
End Sub
This runs but it doesn't actually paste any values into Sheet3. Is there something I'm missing? Is there a better way to do this?
Thanks!
You just had an issue in the second line defining NextRow.
Is there a better way to do this? It depends on your needs; personally I do not like to activate/select other cells during a VBA macro so e.g. I would get rid of the Sheet3.Activate. I would also copy the stuff 'manually' without using the clipboard to avoid changing the user's clipboard contents.
Private Sub CommandButton1_Click()
Dim NextRow As Range
Set NextRow = Sheet3.Range("A" & Sheet3.Rows.Count).End(xlUp).Offset(1, 0)
Sheet1.Range("A12:D12").Copy
Sheet3.Activate
NextRow.PasteSpecial Paste:=xlValues, Transpose:=False
Application.CutCopyMode = False
Set NextRow = Nothing
End Sub