I am a newbie in VBA and I have this issue. I have this command button on my Excelsheet:
Command button:
Private Sub CommandButton1_Click()
Dim TestCell As String
TestCell = Range("A1").Value
TestCell = "Test"
End Sub
I wonder why this code doesn't work for me.
PS: Of course it works when I use: Range("A1").Value = "Test", but for some reason I need to use TestCell = Range("A1").Value (Variable used as cell reference).
Use Range variable if you want a reference to the cell instance. Then use it to read or write values.
Dim ws as Worksheet
Dim TestCell As Range
Set ws = Application.ActiveSheet
Set TestCell = ws.Range("A1")
TestCell.Value = "Test"
Related
A subroutine that I have used for a long time has stopped working for some reason. The simplified macro below causes a "run time error '6': Overflow" when I try to assign a value to a cell. The value in cell C2 is assigned to cValue but the error occurs when it is set in cell C3.
Private AWB As Workbook
Private cValue As Double
Sub Test()
Set AWB = ThisWorkbook
Sheets("Import").Select
Range("C2").Select
cValue = ActiveCell.Value
ActiveCell.Offset(1, 0).Select
ActiveCell.Value = cValue
End Sub
Sub Solution1()
'Set AWB = ThisWorkbook
With Worksheets("Import").Range("C2")
cValue = .Value2
.Offset(1, 0).Value2 = cValue
End With
End Sub
' *** <OR> ***
Sub Solution2()
With Worksheets("Import").Range("C2")
.Offset(1, 0).Value2 = .Value2
End With
End Sub
If you still run into trouble, try changing your cValue type to as variant.
Copy Cell Value
If you're dealing with the workbook containing this code, specify it with ThisWorkbook where ever you need it. If it's in a hundred procedures, do it a hundred times.
Using variables outside of procedures is kind of a last resort when you can't handle things differently, not to write fewer characters.
Qualify your objects by using variables (instead of using Select or any flavors of Active) to avoid long, unreadable expressions like e.g. ThisWorkbook.Sheets("Import").Range("C2").Offset(1).Value = ThisWorkbook.Sheets("Import").Range("C2").Value which you could actually use instead of the posted code (not recommended).
Option Explicit
Sub Test()
Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
Dim ws As Worksheet: Set ws = wb.Sheets("Import")
Dim sCell As Range: Set sCell = ws.Range("C2")
Dim dCell As Range: Set dCell = sCell.Offset(1)
dCell.Value = sCell.Value
End Sub
I would like to select multiple cells based on selection.
And here is my code:
Private Sub CommandButton1_Click()
Selection.EntireRow.Select
End Sub
I want to select the first four columns of rows in multiple cells, instead of the whole rows. How to achieve it?
this is my Excel worksheet
Select Rows of Non-Contiguous Range
Copy the codes into a standard module e.g. Module1.
In your command button click event use either of the procedure names in the following way:
Private Sub CommandButton1_Click()
selectRowsOfListObject
End Sub
or
Private Sub CommandButton1_Click()
selectRowsOfFirstFourColumns
End Sub
The first procedure will select only the rows of the selected cells in the first (structured) table in the ActiveSheet. Any cells outside the data of the table (DataBodyRange) will be ignored.
The second procedure will select all the row ranges of the selected cells in the first four columns, in the first four columns of the ActiveSheet. Any cells selected outside of the first four columns will be ignored
Each or both of the codes can be used with command buttons on any worksheet when they will refer to the worksheet 'containing' the command button.
If you want a command button on another worksheet to always refer to the first, you will rather have to create a reference to the first worksheet:
Instead of
Set ws = ActiveSheet
use e.g.
Set ws = wb.Worksheets("Sheet1")
To better understand the differences, you could add another command button for the second code and then test each of them.
The Code
Option Explicit
Sub selectRowsOfListObject()
Dim wb As Workbook
Set wb = ThisWorkbook
Dim ws As Worksheet
Set ws = ActiveSheet
Dim tbl As ListObject
Set tbl = ws.ListObjects(1)
If Selection.Worksheet.Name = ws.Name Then
If TypeName(Selection) = "Range" Then
Dim rng As Range
Set rng = Intersect(Selection, tbl.DataBodyRange)
If Not rng Is Nothing Then
Set rng = Intersect(rng.Rows.EntireRow, tbl.DataBodyRange.Rows)
End If
If Not rng Is Nothing Then
rng.Select
End If
End If
End If
End Sub
Sub selectRowsOfFirstFourColumns()
Dim wb As Workbook
Set wb = ThisWorkbook
Dim ws As Worksheet
Set ws = ActiveSheet
If Selection.Worksheet.Name = ws.Name Then
If TypeName(Selection) = "Range" Then
Dim rng As Range
Set rng = Intersect(Selection.Rows.EntireRow, _
ws.Columns(1).Resize(, 4))
If Not rng Is Nothing Then
rng.Select
End If
End If
End If
End Sub
Check this code:
Option Explicit
Sub Rows_Selection()
Dim rng As Range
Dim active_cells_adress, row_no As Variant
Dim final_selection_adress As String
Dim rng1 As String
Dim i As Integer
Selection.EntireRow.Select
Set rng = Selection
rng1 = rng.Address
final_selection_adress = ""
active_cells_adress = Split(rng1, "$")
For i = 2 To UBound(active_cells_adress)
row_no = Split(active_cells_adress(i), ",")
final_selection_adress = final_selection_adress + "A" & row_no(0) & ": D" & row_no(0) + ","
i = i + 1
Next
final_selection_adress = Left(final_selection_adress, Len(final_selection_adress) - 1)
Range(final_selection_adress).Select
End Sub
TL;DR:
I would like it so that the range A6:A? down is pasted into range B10:B?
I am trying to select a range of data to populate into another column. The range is coming from a table and is currently in range A6:A9, although this will extend.
The code that I am currently using is:
Sub Supplier_Names()
Dim wb As Workbook
Dim ws_Temp As Worksheet
Dim Supplier_Names As Range
Set wb = ThisWorkbook
Set ws_Temp = wb.Worksheets("Templates")
Set Supplier_Names = ws_Temp.Range("A6", Range("A6").End(xlDown))
ws_Temp.Range("B10") = Supplier_Names
End Sub
This works when I only select from range A6, but when I run it with the xlDown it does not enter any values into B10. It also does not come up with a debug box.
Any solutions would be great!
Cheers,
Using array is easy.
Sub Supplier_Names()
Dim wb As Workbook
Dim ws_Temp As Worksheet
Dim Supplier_Names As Range
Dim vDB As Variant
Set wb = ThisWorkbook
Set ws_Temp = wb.Worksheets("Templates")
With ws_Temp
Set Supplier_Names = ws_Temp.Range("A6", .Range("A6").End(xlDown))
vDB = Supplier_Names '<~~ use array
.Range("b10").Resize(UBound(vDB, 1)) = vDB
End With
End Sub
The following are the same. It doesn't matter which one is a character and which one is a range.
Dim rngDB As Range
Set rngDB = Range(Range("a1"), Range("a10"))
Set rngDB = Range("a1", "a10")
Set rngDB = Range("a1", Range("a10"))
Set rngDB = Range("a1:a" & 10)
Range("A1").End(xlDown) returns the default property which is Value.
So for example, your current range is A6:A9, if A9 has the word Test in it, your line becomes:
Set Supplier_Names = ws_Temp.Range("A6", "Test"). though it should be noted Excel/VBA seems smart enough to work out what you are wanting to do and does infact use the cell address reference)
You can use the Address property of Range to return the cell address that is found.
Like so:
Set Supplier_Names = ws_Temp.Range("A6", Range("A6").End(xlDown).Address)
Which would translate to:
Set Supplier_Names = ws_Temp.Range("A6", "$A$9")
I agree with #Dy.Lee answer that using an Array is a better way to do what you are wanting to do.
Like so:
Sub Supplier_Names()
Dim ws_Temp As Worksheet
Dim Supplier_Names_Array() As Variant
Set ws_Temp = ThisWorkbook.Worksheets("Templates")
With ws_Temp
Supplier_Names_Array = .Range("A6", .Range("A6").End(xlDown).Address)
.Range("B10").Resize(UBound(Supplier_Names_Array, 1)) = Supplier_Names_Array
End With
End Sub
http://www.cpearson.com/Excel/ArraysAndRanges.aspx is a great resource for learning about this method of using Arrays with the Worksheet.
I've introduced another range object to make it more readable:
Option Explicit
Sub Supplier_Names()
Dim wb As Workbook
Dim Temp As Worksheet
Dim Supp As Range
Dim Cust As Range
Set wb = ThisWorkbook
Set Temp = wb.Worksheets("Templates")
Set Supp = Temp.Range("A6")
Set Supp = Temp.Range(Supp, Supp.End(xlDown))
Set Cust = Temp.Range("B10")
Set Cust = Cust.Resize(Supp.Rows.Count, Supp.Columns.Count)
Cust.Value = Supp.Value
End Sub
Sub APnumbers()
Dim Currentcell As Range
ActiveWorkbook.Sheets(2).Activate
Set Currentcell = ActiveSheet.Range("BA5").Activate
End Sub
On second last line i am obtaining an error "Object required". Can you help?
As the comments from Dave and citizenkong suggest, you can do it differently without select and activate. Something like this should do the trick:
Sub APnumbers()
Dim Currentcell As Range
Dim ws as Worksheet: Set ws = ActiveWorkbook.Sheets(2)
Set Currentcell = ws.Range("BA5")
End Sub
I'm looking for a way to, instead of typing "ActiveCell.OffSet(1,1) over and over again in my vba code, define that as a variable, "x" and use that instead.
I have to use the dim command to do this but I"m not sure what the data type would be.
Suggestions?
When I test it using the code below I get Runtime Error 1004.
Private Sub CommandButton1_Click()
Dim i As Range
Set i = ActiveCell
ActiveSheet.Range(ActiveSheet.Range(i), ActiveSheet.Range(i).End(xlUp)).Select
End Sub
In response to your edit
Avoid the use of .Select/Activate and fully qualify your objects. INTERESTING READ
Your code can be written as
Private Sub CommandButton1_Click()
Dim ws As Worksheet
Dim rng1 As Range, rng2 As Range
'~~> Change as applicable
Set ws = ThisWorkbook.Sheets("Sheet1")
With ws
Set rng1 = ws.Range("A10")
Set rng2 = .Range(rng1, rng1.End(xlUp))
With rng2
Debug.Print .Address
'
'~~> Do something with the range
'
End With
End With
End Sub
If you still want to know what was wrong with your code then see this.
You have already defined your range. You do not need to add ActiveSheet.Range() again. Your code can be written as
Private Sub CommandButton1_Click()
Dim i As Range
Set i = ActiveCell
ActiveSheet.Range(i, i.End(xlUp)).Select
End Sub
EDIT
Followup from comments
Was ActiveSheet.Range() actually problematic or just redundant? – user3033634 14 mins ago
It is problematic. The default property of a range object is .Value
Consider this example which will explain what went wrong with your code
Sub Sample()
Dim ws As Worksheet
Dim rng As Range
Set ws = ThisWorkbook.Sheets("Sheet1")
With ws
Set rng = .Range("A1")
rng.Value = "Blah"
MsgBox rng '<~~ This will give you "Blah"
MsgBox rng.Value '<~~ This will give you "Blah"
MsgBox rng.Address '<~~ This will give you "$A$1"
MsgBox ws.Range(rng) '<~~ This will give you an error
'~~> Why? Becuase the above is evaluated to
'MsgBox ws.Range("Blah")
MsgBox ws.Range(rng.Address) '<~~ This will give you "Blah"
End With
End Sub
Dim x As Range
Set x = ActiveCell.OffSet(1,1)
EDIT: in response to your comment:
Private Sub CommandButton1_Click()
Dim i As Range
Set i = ActiveCell
ActiveSheet.Range(i, i.End(xlUp)).Select
End Sub