VBA Select & Copy ignores first row - vba

I have a code I could use some help on. This script I wrote is meant to copy a range from the first row to the last row to another sheet. It works perfectly if there are more than 2 rows containing data, but if there is only 1 row (the first row), it ignores that data, does not copy it, and outputs an error.
Is there anything you can identify that might fix this code? I've searched endlessly with no results. Thanks!
Dim ws1 As Worksheet
Dim ws2 As Worksheet
Dim ws3 As Worksheet
Set ws1 = Worksheets("HCA")
Set ws2 = Worksheets("FormA")
Set ws3 = Worksheets("NamedRange")
ws3.Range("T1:U1").Select
Range(Selection, Selection.End(xlDown)).Select
Application.CutCopyMode = False
Selection.Copy
Sheets("FormA").Select
ws2.Range("AQ7").PasteSpecial

End(xlDown) will have undesirable effects when there is only one row being used. It's much more reliable to use xlUp from the bottom of your worksheet instead
Sub test()
Dim ws1 As Worksheet
Dim ws2 As Worksheet
Dim ws3 As Worksheet
Set ws1 = Worksheets("HCA")
Set ws2 = Worksheets("FormA")
Set ws3 = Worksheets("NamedRange")
With ws3
.Range(.Range("T1"), .Cells(.Rows.Count, "U").End(xlUp)).Copy
End With
ws2.Range("AQ7").PasteSpecial
End Sub

Replace,
ws3.Range("T1:U1").Select
Range(Selection, Selection.End(xlDown)).Select
Application.CutCopyMode = False
Selection.Copy
... with,
with ws3
.Range(.cells(1, "T"), .cells(.rows.count, "U").end(xlup)).copy
end with
When looking for the last non-blank cell, look from the bottom up; not from the top down.

Related

How to loop through sheet and copy some specific range

So I would like my code to loop through sheets, depend on sheet name I would like to copy different range (if sheet will not be listed i want just to skip it) (lets say i know number/adress of the columns i would like to copy (number of rows might be different, depends on the orginal file i got) and i would like to copy all of these ranges one under another into sheet called check_data with additional column to the right saying from which sheet this part is comming from. I'm stuck sometimes this part of code works but it seems like it doesnt loop through the sheets.
So far i got this (but im totally new to vba)
Sub Copy_data()
Dim wb As Workbook
Dim ws1 As Worksheet
Dim ws2 As Worksheet
Dim ws3 As Worksheet
Set wb = ActiveWorkbook
Set ws1 = wb.Sheets("A")
Set ws2 = wb.Sheets("B")
Set ws3 = wb.Sheets("Check_data")
For Each ws In Worksheets
If ws.Name = "A" Then
ws1.Activate
ws1.Range("A1:Q1").Select
ws1.Range(Selection, Selection.End(xlDown)).Select
Selection.Copy
ws3.Select
If ws3.Range("A1") = "" Then
ws3.Range("A1").Select
ActiveSheet.Paste
Else
Selection.End(xlDown).Offset(1, 0).Select
ActiveSheet.Paste
End If
ElseIf ws.Name = "B" Then
ws2.Activate
ws2.Range("A1:Q1").Select
ws2.Range(Selection, Selection.End(xlDown)).Select
Selection.Copy
ws3.Select
If ws3.Range("A1") = "" Then
ws3.Range("A1").Select
ActiveSheet.Paste
Else
Selection.End(xlDown).Offset(1, 0).Select
ActiveSheet.Paste
End If
Else
End If
Next ws
End Sub
Thanks for any suggestions
A couple of things here. Always fully specify both the workbook and worksheets with objects, and preprend methods like Sheets with those objects, like this:
Dim wb As Workbook
Dim ws1 As Worksheet
Dim ws2 As Worksheet
Set wb = ThisWorkbook
ws1 = wb.Sheets("A")
ws2 = wb.Sheets("Check_data")
ws1.Range("A1:Q1").Select
ws1.Range(Selection, Selection.End(xlDown)).Select
Selection.Copy
...and same thing when you are ready to paste, except that you need to explicitly activate the sheet that you are pasting into:
ws2.Activate
If ws2.Range("A1") = "" Then
ws2.Range("A1").Select
Selection.Paste
Else
Selection.End(xlDown).Offset(1, 0).Select
Selection.Paste
End If
Obviously, this isn't your entire code snippet rewritten, but it's the direction that you want to head in.

Set current worksheet as a variable in order to work with formulas easier

I want to set my current active worksheet as a variable in order to be able to use vlookups easier without having issues. The reason that I want to do that is because I run this macro daily and each day the active worksheet has new name (the new date). Now inside my macro I use ActiveSheet but I use a lot of vlookups and go back and forth so it crushes.. I will provide the beginning of the code so as to be more clear.. All I need is a way to set the current active book as a variable. This way, even if the active worksheet changes, the old current worksheet will be saved as a variable
Application.DisplayAlerts = False
ActiveSheet.Cells.Copy
Worksheets.Add.Name = ActiveSheet.Name & "_Daily_RCCP"
With ActiveSheet
.Cells.PasteSpecial xlValues
.Cells.PasteSpecial xlFormats
End With
Application.DisplayAlerts = True
As you can see the active worksheet changes two times.. So, I want to set the last active worksheet as a variable
To draw out what #ScottCraner mentioned in comment.
Dim ws1 as Worksheet
Set ws1 = ActiveSheet
Worksheets.Add.Name = ws1.Name & "_Daily_RCCP"
Dim ws2 as Worksheet
Set ws2 = ActiveSheet 'bc adding a sheet automatically makes it active
ws1.Cells.Copy
With ws2.Cells
.PasteSpecial xlValues
.PasteSpecial xlFormats
End With
'n.b. - i would personally avoid copying all the cells in a worksheet
'instead copying the usedrange or some defined range
I would like to slightly rewrite Scott Holtzman answer:
Dim ws1 as Worksheet, ws2 as Worksheet
Set ws1 = ActiveSheet
'here you add a sheet and directly assign it to a variable
Set ws2 = Worksheets.Add.Name = ws1.Name & "_Daily_RCCP"
ws1.Cells.Copy
With ws2.Cells
.PasteSpecial xlValues
.PasteSpecial xlFormats
End With
Also take notice that each sheet has 2 names: the tab name the user sees (.Name), and the other name you can only see from VBE (.CodeName).
Actually, if you put some code behind Sheet1 (CodeName), you can also refer to it using Me (current class object), exactly like you can use ThisWorkbook to designate the workbook containing the code.
You could therefore rewrite the above this way:
Dim ws2 as Worksheet
'here you add a sheet and directly assign it to a variable
Set ws2 = Worksheets.Add.Name = Sheet1.Name & "_Daily_RCCP"
'No need for an extra variable ws1 since we use the CodeName
sheet1.Cells.Copy
With ws2.Cells
.PasteSpecial xlValues
.PasteSpecial xlFormats
End With
or if the code is behind Sheet1:
Dim ws2 As Worksheet
Set ws2 = Worksheets.Add
ws2.Name = Me.Name & "_Daily_RCCP"
'No need for an extra variable ws1 since we use Me
Me.Cells.Copy
ws2.PasteSpecial xlPasteValuesAndNumberFormats

VBA - Copy data from one sheet to another

I'm trying to copy data from sheet "DATEV_RAB_UNVERBINDLICH", Range D2:D to sheet "Ready to upload", Range B2:B.
I would like find data to the last row and then copy them into the other sheet. I have this code:
Sub CopyInvoiceNo()
Dim ws, ws1 As Worksheet
Dim lastrow As Long
lastrow = .Cells(.Rows.Count, "D").End(xlUp).Row
Set ws = Sheets("DATEV_RAB_UNVERBINDLICH")
Set ws1 = Sheets("Ready to upload")
ws.Range("D2" & lastrow).Copy
ws1.Range("B4").PasteSpecial xlPasteValues
ws1.Activate
End Sub
But I receive error msg Invalid or unqualified reference. Could you advise me, what do I do wrong, please?
Two errors in your code
At line 3, this is not the correct way to define multiple variable types in the same line. You have to define each of them.
At line 10, lets say your lastrow is "20". It would set the range to "D220", which is also not what you want.
Sub CopyInvoiceNo()
Dim ws As Worksheet, ws1 As Worksheet
Dim lastrow As Long
Set ws = Sheets("DATEV_RAB_UNVERBINDLICH")
Set ws1 = Sheets("Ready to upload")
lastrow = ws.Cells(Rows.count, 4).End(xlUp).Row
ws.Range("D2:D" & lastrow).Copy
ws1.Range("B4").PasteSpecial xlPasteValues
ws1.Activate
End Sub
I also changed to define the variables and its values at the start of the code. The lastrow bit didn't code here too after a bit of testing. Now it works for me at least.

cutting from one page to another without select

I am trying to copy from one worksheet to another, and the .End property should work with the Range value, but the error saying it isn't! The developer docs haven't helped, so I'm not sure what to do.
Code below, the .End(xlup) is what's throwing the error.
Dim inputcells As Range
Sheets(1).Range("B8:F8").Cut
With Worksheets(2).Range("C1000")
.End (xlUp)
.Offset(1, 0).PasteSpecial xlPasteValues
End With
This will do it,
Sheets(1).Range("B8:F8").Cut Destination:=Sheets(2).Cells(Sheets(2).Rows.Count, "C").End(xlUp).Offset(1)
If you are trying to paste special values with "Cut" it will not work, you can only paste special with "Copy"
One way to get around that is to set the ranges then make the range equal the other range.
Sub Button1_Click()
Dim sh1 As Worksheet
Dim sh2 As Worksheet
Dim CrNg As Range
Dim LstRw As Long
Dim PrNg As Range
Set sh1 = Sheets(1)
Set sh2 = Sheets(2)
Set CrNg = sh1.Range("B8:F8")
With sh2
LstRw = .Cells(.Rows.Count, "C").End(xlUp).Row + 1
Set PrNg = .Range(.Cells(LstRw, "C"), (.Cells(LstRw, "G")))
End With
PrNg.Value = CrNg.Value
End Sub
You can clear CrNg at the end if you want.
Use Copy rather than Cut:
Sub ljsh()
Sheets(1).Range("B8:F8").Copy
Sheets(2).Range("C1000").End(xlUp).Offset(1, 0).PasteSpecial xlPasteValues
End Sub

copy paste data from a different workbook to current worksheet

I am basically stuck. I have a code which allows me to browse a file, once the file is selected it copies all the data in that file and then allows me to select a worksheet, from any workbook that is open at that time. Once the worksheet is selected [this is where i get stuck] i want it to paste it into j7. instead it doesn't do that, baring in mind i will be changing the file name everyday as it has the current days date on it.
here is my code:
Sub Macro4()
'
' Macro4 Macro
'
'
Range("A1").Select
Dim fileStr As String
fileStr = Application.GetOpenFilename()
If fileStr = "False" Then Exit Sub
Workbooks.Open fileStr
Range("A2").Select
Range(Selection, Selection.End(xlToRight)).Select
Range(Selection, Selection.End(xlDown)).Select
Selection.Copy
Window.Sheets(Array("Forecast_workings")).Select{**this is where i want to be able to select a worksheet from any open workbook and it will paste the data in cell J7 of that worksheet.**
Range("J7").Select
Application.CutCopyMode = False
Range("C16:C27").Select
Selection.Copy
Range("E16").Select
ActiveSheet.Paste
Application.CutCopyMode = False
Range("G16:G27").Select
Selection.Copy
Range("C16").Select
ActiveSheet.Paste
Application.CutCopyMode = False
Range("O16").Select
End Sub
I can see lot of errors in your code.
First things first. You avoid the use of .Select. INTERESTING READ
If I understand you correctly then to get the name of the sheet which user selects at runtime, you can use Application.InputBox with Type:=8. This will return a range and from that you can use .Parent.Name to get the name of the worksheet.
Is this what you are trying?
Your code can be written as (UNTESTED)
Sub Macro4()
Dim fileStr As String
Dim wb As Workbook, thiswb As Workbook
Dim ws As Worksheet, thisws As Worksheet
Dim Lcol As Long, LRow As Long
Dim Ret As Range
'~~> Set an object for thisworkbook and worksheet
Set thiswb = ThisWorkbook
'~~> Change this to the sheet from where you want to copy
Set thisws = thiswb.Sheets("Sheet1")
'~~> Let user choose a file
fileStr = Application.GetOpenFilename()
If fileStr = "False" Then Exit Sub
'~~> Set an object for workbook opened and it's worksheet
Set wb = Workbooks.Open(fileStr)
On Error Resume Next
Set Ret = Application.InputBox("Select a cell from the sheet you want to choose", Type:=8)
On Error GoTo 0
If Ret Is Nothing Then Exit Sub
Set ws = wb.Sheets(Ret.Parent.Name)
With thisws
'~~> Find Last column in row 2
Lcol = .Cells(2, .Columns.Count).End(xlToLeft).Column
'~~> Find last cell in Col 1
LRow = .Range("A" & .Rows.Count).End(xlUp).Row
'~~> Copy your range directly to new worksheet selected
.Range(.Cells(2, 1), .Cells(LRow, Lcol)).Copy ws.Range("J7")
.Range("C16:C27").Copy ws.Range("E16")
.Range("G16:G27").Copy ws.Range("C16")
Application.CutCopyMode = False
End With
End Sub
when working with multiple workbooks, dont use range() but wb.range(), where wb is defined with the set function.
Also activesheet can be tricky. Preferably name the sheet you are using sheets("whatever").
And for last, to copy things dont use activate/select, just do as this:
wb.sheets("whatever").range() thisworkbook.sheets("watever2").range("").
I also saw you dont use application.enableevents=false/true, so events will trigger like crazy and your activesheet (or cell) will change like crazy if you have code in worksheet_change section.