【问题标题】:VBA Excel Range() with Cell argument带有 Cell 参数的 VBA Excel Range()
【发布时间】:2020-01-28 05:57:50
【问题描述】:

为什么以下方法不起作用:

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

Cells(1,1) 本质上应该与使用A1 相同,对吧?

(我意识到我可以做Cells(1,1).Value = 3,但我只是好奇为什么它不起作用。)

我阅读了 MSDN 条目,它显示第一个参数必须是 A1 样式,但这样的东西确实有效:

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

完全糊涂了。

【问题讨论】:

    标签: vba excel


    【解决方案1】:

    Range 与单个参数一起使用时,该参数被解释为范围名称。

    Range(Cells(1,1))
    

    和使用一样

    Range(Cells(1,1).Value)
    

    所以你会得到一个结果,只有Cells(1,1) 的值是A1 样式中的有效范围地址

    只有当传递两个范围参数时,它们才会被解释为范围的角。

    【讨论】:

    • 不错,但单元格(1,1).Address 示例可以更完整吗?
    • Range(Cells(1,1).Value) 在我的机器上引发错误。 Range(Cells(1,1).Address) 虽然有效。
    • @user3032689 'Cells(1,1).Value' 返回单元格中的值。 (如果该单元格值不是 A1 样式地址,'Range(Cells(1,1).Value)' 将引发错误)。否则,Cells(1,1).Address 返回字符串“$A$1”,这是 Range 的有效 A1 样式地址。
    【解决方案2】:

    当您想使用 Cells 属性来指定范围对象的参数时(如果我没记错的话 - 我已经有一段时间没有使用 VBA 了),那么您必须有效地提供两个参数。

    所以如果你想引用一个只有一个单元格的范围对象,那么你需要这样写:

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

    【讨论】:

    • 这只是令人困惑,因为它与他们自己的文档相矛盾,据我所知(说你必须使用 A1 样式作为第一个参数)。我想这只是你必须忍受的那些奇怪的设计决定之一。
    • 不完全是,如果你向下滚动文档,你会看到如果你使用 Cells 属性会有不同的条件......在该部分中它实际上并没有提到 A1 样式(显然是它与 Cells 属性有关)。
    • msdn.microsoft.com/en-us/library/office/ff836512.aspx 是它指定第一个参数要求的地方。我是 VBA 新手,所以我看错了条目吗?
    • msdn.microsoft.com/en-us/library/office/… 可能更有用,它解释了在范围对象中使用 Cells 属性。
    • Cells(1,1) = "hello world" ' 工作方式相同,代码更短
    【解决方案3】:

    而不是像这样引用单个单元格:

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

    你可以写:

     Range(Cells(1,1).Address)
    

    【讨论】:

      【解决方案4】:

      对于单个单元格更容易:使用默认的 Cells() 函数:

      Cells(1,1) = "hello world"
      

      或使用工作表的 Cells() 函数:

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

      对于一个范围,您必须使用两个参数,如此处给出的其他答案中所述。但优点是您可以将整个范围的字段设置为一个值。您可以在幕后处理不是“活动”的工作表。例如:

      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
      

      说明:

      Cells 函数接收:
      字符串参数 - 在其中指定 A1_And_Colon 样式范围
      两个单元格参数 - 范围的开始单元格和结束单元格。

      因此,要使用“单元格”设置范围,您需要将两个单元格用逗号分隔:

      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))"
      

      【讨论】:

        【解决方案5】:

        我写这个答案是因为我正在学习 VBA,我花了三天的大部分时间才弄清楚这里发生了什么,官方文档根本没有讨论这个话题。这个 QA 很好,但是从我今天的角度来看,信息有点分散。

        以下是我所知道的关于在 Range() 对象中使用 Cells() 属性来引用单个单元格区域的知识。我需要一直这样做!

        给定一个有效的 ws 对象...

        你认为这会奏效:

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

        它没有。您将收到运行时错误“1004”:对象“_Worksheet”的方法“范围”失败。

        @Woody_Pride 描述的明显解决方法是:

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

        不幸的是,不得不这样做是绝对令人恼火的,实际上并不是绝对必要的。

        你真正需要的是,正如@Willby 所断言的那样,尽管@chris_neilsen 的回答实际上解释了为什么会这样:

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

        这也可行,正如@pashute 所建议的那样(他的大部分解释都是错误的):

        ws.Cells(i,j)

        感谢在此页面上做出贡献的所有人;我觉得我现在终于掌握了全貌。

        【讨论】:

        • ws.Range(Cells(i,j).Address) 是引用单个单元格的一种非常糟糕的方式 - 它嵌入了对活动工作表的隐式引用,如果 ws 不活动,则会出错。而ws.Cells(i, j) 已经引用了所需的范围,所以整个事情毫无意义
        • @chrisneilsen 我编辑将ws.Range(Cells(i,j).Address) 更新为ws.Range(ws.Cells(i,j).Address)...感谢您的提醒。至于 ws.Cells(i, j) 我只是想弄清楚如何引用单个单元格,当我尝试编写 ws.Range(ws.Cells(i,j)) 和 I无法弄清楚为什么,因为文档似乎表明这应该有效。
        • 至于谁提供了解释但没有回答,OP问为什么以下不起作用,这正是我的回答。 OP还说他们知道如何正确地做到这一点,所以不需要重复
        • 例如,我只想能够将一条记录从一个地方复制到另一个地方; wsDestination.Range("A1") = wsSource.Range("A1") 有效,但我想在单元格引用中使用一个变量。文档说您可以使用 Cells(i, j) 样式引用来替换 R1C1 样式引用,但在这种情况下您不能。
        • 建议你问一个问题,详细说明你想要什么,你尝试了什么,它是如何失败的。我保证你会得到一个不涉及 Range(Cells(...).Address) 的答案
        【解决方案6】:

        我知道有时您需要一个范围来存储除值之外的其他属性。我会做一个函数来帮助你:

        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
        

        这样你可以编写更简洁的代码:

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

        【讨论】:

          【解决方案7】:

          使用“细胞”时,需要制定 Object.cells , 例如Application.cells(2,2) 或 activeWorksheet.cells

          【讨论】:

            猜你喜欢
            • 2014-05-23
            • 1970-01-01
            • 1970-01-01
            • 2020-03-28
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多