9

Why does the following not work:

Range(Cells(1,1)).Value = 3

Cells(1,1) should essentially be the same thing as using A1 right?

(I realize that I could just do Cells(1,1).Value = 3, but I'm just curious as to why it doesn't work.)

I read the MSDN entry and it shows that the first argument must be A1 style, yet something like this does work:

Range(Cells(1,1), Cells(2,3)).Value = 2

Totally confused.

0

7 Answers 7

13

When Range is used with a single parameter, the parameter is is interpreted as a range name.

Range(Cells(1,1))

is the same as using

Range(Cells(1,1).Value)

So you will get a result only is the value of Cells(1,1) is a valid range address in A1 style

Only when passed two range parameters are they interpreted as the corners of a range.

Sign up to request clarification or add additional context in comments.

3 Comments

Good one, but could it be more complete with the cells(1,1).Address example?
Range(Cells(1,1).Value) throws an error on my machine. Range(Cells(1,1).Address) works though.
@user3032689 'Cells(1,1).Value' returns the value in the cell. (If that cell value is not an A1 style address, 'Range(Cells(1,1).Value)' will throw an error). Otherwise, Cells(1,1).Address returns the string "$A$1" which is a valid A1 style address for Range.
6

When you want to use the Cells property to specify the parameters of the range object (if I remember rightly - I've not been using VBA for some time), then you have to effectively supply two arguments.

So if you want to reference a range object that has only one cell, then you need to write:

Range(Cells(1, 1), Cells(1, 1)).value = "Hello World"

6 Comments

It's just confusing because it contradicts their own documentation, as far as I can tel(says you have to use A1 style as the first argument). I guess it's just one of those odd design decisions you have to live with.
Not exactly, if you scroll down the documentation you will see that there are different conditions if you are using the Cells property... In that section it does not in fact mention the A1 style (obviously as it is concerned with the Cells property).
msdn.microsoft.com/en-us/library/office/ff836512.aspx is where it specifies the first argument requirement. I'm new to VBA, so am I looking at the wrong entry?
msdn.microsoft.com/en-us/library/office/… might be more useful, it explains about using the Cells property in a range object.
Cells(1,1) = "hello world" ' works the same, shorter code
|
3

Instead of referring to a single cell like this:

Range(Cells(1,1), Cells(1,1))

You can write:

 Range(Cells(1,1).Address)

Comments

2

For a single cell its much easier: Use the default Cells() function:

Cells(1,1) = "hello world"

or use a Sheet's Cells() function:

Dim sht as Worksheet
Set sht = Sheets("myworksheet") ' or: = Sheets(1)
sht.Cells(1,1) = "hello world" 

For a range you'll have to use two params, as explained in the other answers given here. But the advantage is that you can set a whole range of fields to a value. And you can work on a sheet that isn't the 'Active one', behind the scenes. For example:

Const colRand = 4
Const colDiff = 5

Dim sht as Worksheet, rngHi As Range, rngRand As Range, rngDiff As Range
Set sht = Sheets("myworksheet") ' or: = Sheets(1)

Set rngHi = sht.Range(sht.Cells(1,1), sht.Cells(3,3)
rngHi = "hello world" 

Set rngRand = sht.Range(sht.Cells(1,colRand), sht.Cells(8,colRand) ' column 4, rows 1-8
rngRand = "=RAND()"

Set rngDiff = sht.Range(sht.Cells(2,colDiff), sht.Cells(8,colDiff) ' column 5, rows 2-8
' using FormulaR1C1 in case the sheet isn't set to use that type of formula
Set rngDiff.FormulaR1C1="=RC[-1] - R[-1]C[-1]" ' on previous columnn, diff between this row and previous row

Explanation:

The Cells function receives either:
a string parameter - in which you specify the A1_And_Colon Style range
or two Cell parameters - the beginning cell of the range and the end cell.

So to set the range with 'cells' you need to give both cells divided by a comma:

Range(Cells(1,1), Cells(1,1)) = "hello world"
Range(Cells(2,2), Cells(3,4)) = "you cannot square around, but you can round a square"
Sheets(1).Cells(5,5) = "=Round(Sqrt(5))"

Comments

1

I'm writing this answer because I'm learning VBA and it took me the better part of three days to figure out what was happening here, and the official documentation does not discuss this topic at all. This QA is good but the information is a bit scattered, from my perspective today.

Here's what I know about using the Cells() property inside a Range() object to reference a single-cell range. Which I need to do all the time!

Given a valid ws object...

You think this will work:

ws.Range(ws.Cells(i,j))

It doesn't. You'll get Run-time error '1004': Method 'Range' of object'_Worksheet' failed.

The obvious fix, as described by @Woody_Pride is:

ws.Range(ws.Cells(i,j), ws.Cells(i,j))

Unfortunately, having to do this is absolutely infuriating, and is not actually strictly necessary.

What you actually need is, as asserted by @Willby, although the explanation as to why this is the case is actually in the answer by @chris_neilsen:

ws.Range(ws.Cells(i,j).Address)

This will also work, as suggested by @pashute (who is wrong in most parts of his explanation):

ws.Cells(i,j)

Thank you to everyone who contributed on this page; I feel like I now, finally, have the entire picture.

8 Comments

ws.Range(Cells(i,j).Address) is a really bad way of referencing a single cell - it's got an embedded implicit reference to the Active Sheet which will error if ws is not active. And ws.Cells(i, j) already references the required range, so the whole thing is pointless
@chrisneilsen I edited to update ws.Range(Cells(i,j).Address) to ws.Range(ws.Cells(i,j).Address)... thanks for the reminder. As to ws.Cells(i, j) I'm just trying to figure out how to reference a single cell, and I kept getting errors when I tried to write ws.Range(ws.Cells(i,j)) and I couldn't figure out why, since the documentation SEEMS to indicate that that should work.
As for who provided an explanation but no answer the OP asked Why does the following not work which is exactly what I answered. The OP also said they knew how to do it correctly, so no need to repeat that
For example, I just want to be able to copy a record from one place to another; wsDestination.Range("A1") = wsSource.Range("A1") works, but I want to use a variable in the cell reference. The documentation says you can use a Cells(i, j) style reference to replace a R1C1 style reference, but in this context you can't.
Suggest you ask a Q with all the details of what you want, what you tried, how it failed. I gaurantee you'll get an answer that doesn't involve Range(Cells(...).Address)
|
0

I know sometimes you need a range for other properties other than value. What i would do is make a function to help you:

Public Function cellRange(ws As Worksheet, rowNum As Integer, colNum As Integer) As Range
    Set cellRange = ws.Range(ws.Cells(rowNum, colNum), ws.Cells(rowNum, colNum))
End Function

This way you can make cleaner code:

Set ws = ActiveWorkbook.Sheets("Sheet1")
cellRange(ws, 1, 3).Interior.Color = cellRange(ws, 1, 8).Interior.Color

Comments

-3

When using "cells", it is required to formulate Object.cells , e.g. Application.cells(2,2) or activeWorksheet.cells

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.