【问题标题】:Range() with Cells() Excel VBARange() 和 Cells() Excel VBA
【发布时间】:2020-03-28 10:29:43
【问题描述】:

我在应用循环以在电子表格中构建矩形时遇到问题,出现错误 1004,

运行时错误“1004”:
应用程序定义或对象定义的错误

在线:

Leftmargin = ThisWorkbook.Worksheets(2).Range(Cells(1, 1)).Left

我不知道为什么这不起作用。我还想使用其余参数切换到单元格功能,因为我需要循环超过 450 个位置来构建与卡片一样的矩形。我要求对该主题进行解释,以便我了解失败的原因。

Dim sh As Shape

Dim Leftmargin
Leftmargin = ThisWorkbook.Worksheets(2).Range(Cells(1, 1)).Left
Leftmargin = Leftmargin + 2

Set sh = ThisWorkbook.Worksheets(2).Shapes.AddShape( _
  Type:=msoShapeRoundedRectangle, _
  Left:=Leftmargin, _
  Top:=ThisWorkbook.Worksheets(2).Range("A1").Top + 2, _
  Width:=ThisWorkbook.Worksheets(2).Range("A1:E1").Width - 4, _
  Height:=ThisWorkbook.Worksheets(2).Range("A1:A10").Height - 4)

【问题讨论】:

  • 一个Range() 需要两个Cells() 你应该改用Cells()
  • Implicit ActiveSheet references: Cells 是一个成员调用,它隐含地限定于当前活动的任何工作表,或者你所在的工作表模块,如果那是不合格的成员调用所在的位置。基本上你不能做Sheet1.Range(Sheet2.Cells(...), Sheet2.Cells(...)),这就是当Sheet2处于活动状态并且你做Sheet1.Range(Cells(...), Cells(...))时发生的情况
  • @MathieuGuindon 虽然您对合格电话的看法是正确的,但 OP 的问题是,正如 Damian 上面所说,您不能将 one Range-typed 参数传递给 @ 987654333@.
  • @GSerg 是正确的。此外,这种未被检测到的唯一原因是通过将.Range 调用链接到Workbook.Worksheets(2) 引起的隐式后期绑定,该调用返回Object。通过将该Worksheet 对象拉入其自己的局部变量,OP 将恢复早期绑定和编译时检查,并获得智能感知/参数快速信息显示工具提示,显示.Range 属性预期的参数。是否应该重新提出问题?
  • @GSerg 这里是一个更合适的副本:stackoverflow.com/questions/17636170/…

标签: excel vba range cell


【解决方案1】:

Cells(1, 1) 已经是 Range 对象,指的是(假设这是在标准模块中)的单元格 A1(第 1 行,第 1 列),无论工作表恰好是 ActiveSheet

Leftmargin = ThisWorkbook.Worksheets(2).Range(Cells(1, 1)).Left

但您的意思是使用ThisWorkbook 的索引 2 处的工作表。将其拉入自己的局部变量中:

Dim sheet As Worksheet
Set sheet = ThisWorkbook.Worksheets(2)

现在您不再需要在任何需要获取该特定工作表的地方取消引用 ThisWorkbook.Worksheets(2):只需使用此变量即可。

所以Cells(1, 1) 变成了sheet.Cells(1, 1)——除了它仍然是已经是一个范围,所以成员调用要么是多余的,要么是格式错误的:

Leftmargin = sheet.Range(sheet.Cells(1, 1)).Left '<~ redundant or malformed range

当你将Range 对象传递给Worksheet.Range 属性时,你想给它2 个单元格:第一个是你想要的范围左上角的单元格;第二个是您想要的范围右下角的单元格...但是由于您使用的是 A1 并且您想要该单元格的 .Left 属性,您想要的可能就是这样:

Leftmargin = sheet.Cells(1, 1).Left + 2

Set sh = sheet.Shapes.AddShape( _
  Type:=msoShapeRoundedRectangle, _
  Left:=Leftmargin, _
  Top:=sheet.Range("A1").Top + 2, _
  Width:=sheet.Range("A1:E1").Width - 4, _
  Height:=sheet.Range("A1:A10").Height - 4)

...但是我不禁要问为什么要预先计算sh.Left,而不是其他属性...为什么不这样做并完全删除Leftmargin 变量?

Set sh = sheet.Shapes.AddShape( _
  Type:=msoShapeRoundedRectangle, _
  Left:=sheet.Range("A1").Left + 2, _
  Top:=sheet.Range("A1").Top + 2, _
  Width:=sheet.Range("A1:E1").Width - 4, _
  Height:=sheet.Range("A1:A10").Height - 4)

请注意,Worksheet.Cells(1, 1)Worksheet.Range("A1") 都指的是同一个单元格/范围。

【讨论】:

  • 请注意,Worksheet.Cells(1) 也指同一个单元格。也可以使用With sheet.Range("A1:E10") 来进一步减少冗余。
【解决方案2】:

在阅读了您的答案和相关链接(在这篇文章中)之后,我得出了适合我的结果:

Set sh1 = ThisWorkbook.Worksheets(1)
Set sh2 = ThisWorkbook.Worksheets(2)

Set sh = ThisWorkbook.Worksheets(2).Shapes.AddShape( _
Type:=msoShapeRoundedRectangle, _
Left:=sh2.Range(Cells(1, 1), Cells(1, 1)).Left + 2, _
Top:=sh2.Range(Cells(1, 1), Cells(1, 1)).Top + 2, _
Width:=sh2.Range(Cells(1, 1), Cells(1, 5)).Width - 4, _
Height:=sh2.Range(Cells(1, 1), Cells(10, 1)).Height - 4)

通过这种方式,我准备了整个语句来循环遍历整个项目列表,并为其创建卡片。

谢谢你, 迈克尔

【讨论】:

  • 我建议您重新阅读关于不合格的Cells 调用的部分,其中隐含地引用了 ActiveSheet 是什么。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-29
  • 2019-01-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多