VBA copy.range dont understand why is not working - excel

I have a simple need to copy range from one sheet to another and I can do it differently, but I want to understand why this code dont work. Please, could you explain ?
Sub cioy()
Dim wb As Workbook
Dim sh1 As Worksheet
Dim sh2 As Worksheet
Set wb = ActiveWorkbook
Set sh1 = wb.Sheets("sh1")
Set sh2 = wb.Sheets("sh2")
sh2.Cells.ClearContents
sh1.Range(Cells(1, 1), Cells(12, 8)).Copy Destination:=sh2.Range(Cells(1, 1))
End Sub

it's because Range() property of Worksheet object would accept two Range parameters (the starting and ending range references of the wanted range) while you're giving only one (Range(Cells(1, 1)).
so you would code:
sh1.Range(Cells(1, 1), Cells(12, 8)).Copy Destination:=sh2.Cells(1, 1)
or:
sh1.Range(Cells(1, 1), Cells(12, 8)).Copy Destination:=sh2.Range("A1")
what above should fix the error
also, be aware that without an explicit Sheet reference, a Range object would implicitly take it as ActiveSheet, so your code would be the same as:
sh1.Range(ActiveSheet.Cells(1, 1), ActiveSheet.Cells(12, 8)).Copy Destination:=sh2.Cells(1, 1)
which may not be what you need if sh1 isn't the currently Active sheet.
hence you would more properly write:
sh1.Range(sh1.Cells(1, 1), sh1.Cells(12, 8)).Copy Destination:=sh2.Cells(1, 1)
or:
Range(sh1.Cells(1, 1), sh1.Cells(12, 8)).Copy Destination:=sh2.Cells(1, 1)
where you can notice you can omit the outer sheet reference, since using qualified Range references as parameters of a Range property leads the returned Range reference the same sheet as that of the two parameters ones
finally you could avoid all that burden by using the Range(string address, string address) notation of Range property and simply code:
sh1.Range("A1:H12").Copy Destination:=sh2.Cells(1, 1)
or:
sh1.Range("A1:H12").Copy Destination:=sh2.Range("A1")

Qualify your ranges with parent sheet name and you don't need Range wrapping Cells at end
Public Sub cioy()
Dim wb As Workbook
Dim sh1 As Worksheet
Dim sh2 As Worksheet
Set wb = ActiveWorkbook
Set sh1 = wb.Worksheets("sh1")
Set sh2 = wb.Worksheets("sh2")
sh2.Cells.ClearContents
With sh1
.Range(.Cells(1, 1), .Cells(12, 8)).Copy Destination:=sh2.Cells(1, 1)
End With
End Sub

Related

Write a dynamic sum formula vba that takes range from another sheet

screenshot of code
I am trying to calculate sum in cell "I13" of sheet2 with inputs based on the dynamic range.
Formula
range("I13").formula= "=sum('sheet1'!A1:A3)"
works but the range can be dynamic. For this I have used lr to identify the last row in the range
lr=cells(rows.count,1).end(xlup).row
Now, I want to modify the above formula such that in place of A3, it takes last cell. i.e. A&lr
Have tried using range("I13").formula= "=sum('sheet1'!A1:A"&lr)", but it results in error
Sub MMM()
Windows("Template.xlsx").activate
sheets("sheet1").select
range("a1").select
lr=cells(rows.count,1).end(xlup).row
sheets("sheet2").select
'this code works. But want dynamic range
'range("I13").formula = "= SUM('sheet1'!A1:A3)"
range("I13").formula = "= sum('sheet1'!A1:A&lr)"
End Sub
you can try to define the variable:
Option Explicit ' It should be used when you define variable
Sub MMM()
Dim lr as Range ' Define variable
Windows("Template.xlsx").activate
sheets("sheet1").select
range("a1").select
lr=cells(rows.count,1).end(xlup).row
sheets("sheet2").select
range("I13").formula = "= sum('sheet1'!A1:A&lr)"
End Sub
You have to join the string for the formula like this:
"=SUM('Sheet1'!A1:A" & lastRow & ")"
Alternatively:
If you set the whole range to be summed then you can use the Address of this range. The External-parameter returns the sheet name as well.
Sub MMM()
Dim wb As Workbook: Set wb = ThisWorkbook
Dim wsSource As Worksheet: Set wsSource = wb.Worksheets("Sheet1")
Dim wsTarget As Worksheet: Set wsTarget = wb.Worksheets("Sheet2")
Dim rgDataToSum As Range
With wsSource
Set rgDataToSum = .Range("A1", .Cells(.Rows.Count, 1).End(xlUp))
End With
wsTarget.Range("I13").Formula = "=SUM(" & rgDataToSum.Address(True, True, External:=True) & ")"
End Sub

Assigning range of cells results in Type Mismatch (Run-time Error 13)

I am trying to automate the population of a Vlookup formula, looking up values from one worksheet in another. There are two worksheets in the workbook, Suppliers and Products. The product code is looked up from the Products worksheet in the Suppliers worksheet.
This is the code:
Dim lastrow As Long
Sheets("Suppliers").Select
lastrow = ActiveSheet.UsedRange.Rows.Count
Dim SuppliersRnge As Range
Set SuppliersRnge = Range(Cells(2, 2), Cells(lastrow, 3))
' This next try was by declaring the first and last rows and columns in Suppliers sheet as variables and passing values to them (passing values not shown here)
' Set SuppliersRnge = .Range(.Cells(SupplierFirstRow, SupplierFirstColumn), .Cells(SupplierLastRow, SupplierLastColumn))
' This next try was by declaring the range as a static set of cells rather than using lastrow
' Set SuppliersRnge = Range("B2:C23")
' This next try was to pick cell references from currently active worksheet
' Set SuppliersRnge = .Range(.Cells(2, 2), .Cells(lastrow, 3))
' This next try was by fully qualifying the name of the worksheet from which the cell reference is drawn
' Set SuppliersRnge = Worksheets(Suppliers).Range(Cells(2, 2), Cells(lastrow, 3))
' Now switching to product sheet
Sheets("Products").Select
' Selecting cell in which vlookup will be added
Range("A4").Select
ActiveCell.FormulaR1C1 = "=VLOOKUP(RC[1],SuppliersRnge,2,FALSE)"
I am declaring SuppliersRnge as a range and using Set to pass to it the range of cells that need to be looked up.
I have tried to do it in five different ways (you will find four of the ways commented out above) with the same result, which is that the string SuppliersRnge literally gets used in the vlookup, resulting in a >#NAME? value where the result of the Vlookup should be.
When I run ?SuppliersRnge in the Immediate window, I get the Type Mismatch (Run-time Error 13).
If I run a Watch on the SuppliersRnge variable, it starts with a "Nothing" value then changes to a blank.
Any idea on where I might be going wrong? Thanks!
Formulas in VBA
Note the single quotes (around the worksheet name) which are only necessary if the worksheet name contains spaces, but it is good practice to use them always.
Option Explicit
Sub writeVLookupFormula()
Const sName As String = "Suppliers" ' Source
Const dName As String = "Products" ' Destination
Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
Dim sws As Worksheet: Set sws = wb.Worksheets(sName)
Dim sLast As Long: sLast = sws.UsedRange.Rows.Count
Dim srg As Range: Set srg = sws.Range(sws.Cells(2, 2), sws.Cells(sLast, 3))
Dim dws As Worksheet: Set dws = wb.Worksheets(dName)
' R1C1-style
Dim dFormula As String: dFormula = "=VLOOKUP(RC[1],'" & sName & "'!" _
& srg.Address(, , xlR1C1) & ",2,FALSE)"
dws.Range("A4").FormulaR1C1 = dFormula
' Or:
' ' A1-style
' Dim dFormula As String: dFormula = "=VLOOKUP(B4,'" & sName & "'!" _
' & srg.Address & ",2,FALSE)"
' dws.Range("A4").Formula = dFormula
End Sub

Fetching data from a different worksheet in Excel VBA

I'm trying to source data from a separate sheet in excel but the second reference to Ws_Names brings up Runtime Error 1004. How would I correctly source values for a range from another sheet?
Dim Ws_Names As Worksheet
Set Ws_Names = Worksheets("Names")
Dim Ws_Data As Worksheet
Set Ws_Data = Worksheets("Data")
Dim SubTechs As Long, Names_range As Range
SubTechs = Ws_Names.Cells(Rows.Count, 1).End(xlUp).Row 'this works
Set Names_range = Ws_Names.Range(Cells(1, 1), Cells(SubTechs, 2)) 'this doesn't work
It's because when you don't put a leading reference it assumes Activesheet
What
Set Names_range = Ws_Names.Range(Cells(1, 1), Cells(SubTechs, 2)) 'this doesn't work
Actually says is, and your current activesheet isn't Ws_Names
Set Names_range = Ws_Names.Range(Activesheet.Cells(1, 1), Activesheet.Cells(SubTechs, 2))
So the solution is
Set Names_range = Ws_Names.Range(Ws_Names.Cells(1, 1), Ws_Names.Cells(SubTechs, 2))

Copy and paste data between workbooks depending on drop-down choice

Just a quick one, I have coded a piece of VBA that copies and pastes data between two workbooks. However, I would like to be able to copy specific data across rather than the entire table. So workbook "x" I would like to filter column 'L' by a choice of a drop down box in workbook "y" - field "P14".
how would I do this, so that whatever the user chooses it filters and pastes that data into workbook y.
Code below for what I've done so far:
Private Sub CommandButton1_Click()
Dim x As Workbook
Dim y As Workbook
Dim p As String
Set p = y.Worksheets("Title").Cells(14, "P").Value
Set x = Workbooks.Open("C:\Users\name\Desktop\Project
Autonetics\CoreData")
'x.Worksheets("Xero").Range("L1").AutoFilter Field:=1, Criteria:="p"
With Xero
.AutoFilterMode = False
With .Range("L:L")
.AutoFilter Field:=1, Criteria:="p"
.SpecialCells (xlCellTypeVisible)
End With
End With
Set y = ThisWorkbook
x.Worksheets("Xero").Range("A1:L100000").Copy
Application.DisplayAlerts = False
y.Worksheets("Costings").Range("A1").PasteSpecial
x.Close
End Sub
Here is something for you to work with. Personally I'm not such a On Error fan, but it would be legitimate use inside to check for a returned error when using SpecialCells.
Private Sub CommandButton1_Click()
Dim wb1 As Workbook, wb2 As Workbook
Dim sht1 As Worksheet, sht2 As Worksheet
Dim lc As Long, lr As Long
Dim rng As Range, str As String
'Set your two workbooks
Set wb1 = ThisWorkbook
Set wb2 = Workbooks.Open("C:\Users\name\Desktop\ProjectAutonetics\CoreData")
'Set your two worksheets
Set sht1 = wb1.Worksheets("Title")
Set sht2 = wb2.Worksheets("Xero")
'Get your criteria ready
str = sht1.Range("P14").Value
'Get your range to filter ready
With sht2
lr = .Cells(.Rows.Count, 12).End(xlUp).Row
lc = .Cells(1, .Columns.Count).End(xlToLeft).Column
Set rng = .Range(.Cells(1, 1), .Cells(lr, lc))
End With
'Apply filter and act if any hits
rng.AutoFilter 12, str
If rng.SpecialCells(12).Cells.Count > rng.Rows(1).Cells.Count Then
rng.SpecialCells(12).Copy sht1.Cells(1, 1)
End If
'Close your second workbook
wb2.Close False
End Sub
I been quite extensive in the hope you can clearly see what is going on in this code.
Good luck.

Combobox not adding defined named range

I have two comboboxes set in sheet1. I need to add the list of sheets to combobox one, which works fine. I need to add the first column of sheet2 to combobox two with the first cell as the name (called "Name"). This code worked for my UserForm, with Me instead of Sheet1, but using either doesn't work for me.
I'm getting an "Object doesnt support this property or method" error.
Thanks,
Private Sub Workbook_Open()
Dim refSheet As Worksheet
Set refSheet = ActiveWorkbook.Sheets(2)
Dim oSheet As Excel.Worksheet
For Each oSheet In ActiveWorkbook.Sheets
Sheet1.ComboBox1.AddItem oSheet.Name
Next oSheet
Dim lastrow As Long
lastrow = refSheet.Cells(Rows.Count, 1).End(xlUp).Row
With refSheet.Columns(1)
Range(Cells(1, 1), Cells(lastrow, 1)).Select
Selection.CreateNames Top:=True
End With
Sheet1.ComboBox2.RowSource = "Name"
End Sub
Refer to the sheet:
lastrow = refSheet.Cells(Rows.Count, 1).End(xlUp).Row
should be:
lastrow = refSheet.Cells(refSheet.Rows.Count, 1).End(xlUp).Row
When you use "With" here:
With refSheet.Columns(1)
Range(Cells(1, 1), Cells(lastrow, 1)).Select
Selection.CreateNames Top:=True
End With
you should actually use it with the dots:
With refSheet.Columns(1)
.Range(.Cells(1, 1), .Cells(lastrow, 1)).Select
Selection.CreateNames Top:=True
End With
(Notice the dots prior to range and cells)
Not using dots in the "With" block refers to the ActiveSheet

Resources