【问题标题】:Reference a Sheet and Cell for use in Formula引用工作表和单元格以在公式中使用
【发布时间】:2018-11-06 13:14:00
【问题描述】:

我有一个工作簿,我想在第一个工作表 (B1) 中引用一个范围,以便在第二个工作表 (B3) 的单元格中输入公式。我的问题是第一个工作表的名称总是会改变,所以我想解决这个问题,我会根据公式可以使用的单元格引用创建一个变量。这是我目前所拥有的:

Sub GetCellAddress()

Dim Cell As Range
Dim CellAddress As String
Set Cell = ActiveWorkbook.Worksheets(1).Cells(1, 2)
CellAddress = Cell.Parent.Name & "!" & Cell.Address(External:=False)

With ActiveSheet
    Range("B3").Select
    ActiveCell.Formula = _
    "=CONCATENATE(""Balance Sheet"","" - "",MID(CellAddress,FIND("" "",CellAddress,FIND("","",CellAddress)+2)+1,256))"
End With

'MsgBox CellAddress

End Sub

虽然 MsgBox 将确认我拥有的 CellAddress 是 Sheet1!$B1$1 我似乎无法通过仅使用 CellAddress 在公式中传递此引用,因为我得到了#NAME?使用时出错。 如果我使用 Sheet1!R[-2]C 作为 ActiveCell.FormulaR1C1 语法,它可以正常工作,但正如我之前解释的那样,我希望代码解析工作表名称。要么我的语法错误,要么我的方法可能是在另一张表中引用范围的不正确方式。谁能告诉我哪里出错了。

【问题讨论】:

  • 我从未在外部或其他单元格地址中看到逗号(例如 , )。
  • 这是该单元格中带有逗号的字符串,即我正在获取日期的截至 2018 年 5 月 25 日星期五打印的最佳胡珀财务管理报告。
  • 如果使用'ActiveCell.FormulaR1C1 = _ "=CONCATENATE(""资产负债表"","" - "",MID(Sheet1!R[-2]C,FIND("" " ",Sheet1!R[-2]C,FIND("","",Sheet1!R[-2]C)+2)+1,256))"' 工作正常。

标签: excel excel-formula vba


【解决方案1】:

在尝试了上述解决方案后,我使用了以下语法:

 Sheets(2).Range("B3").Formula = "=CONCATENATE(""Balance Sheet"","" - "",
 MID(" & Sheets(1).Name & "!B1,FIND("" "", " & Sheets(1).Name & "!B1,
 FIND("","", " & Sheets(1).Name & "!B1)+2)+1,256))"

这似乎解决了我在引用工作表时遇到的问题。因此,只需在使用 @asleedawg 的 Index 方法时将引号放在正确的位置即可。

如果工作表名称中有空格,则必须小心。如果是,则在引用工作表名称的双引号周围添加一个单引号。

【讨论】:

  • 请注意,使用工作表索引与使用工作表名称一样危险。正如用户可以更改工作表的名称一样,他们也可以更改工作表的位置,从而更改其索引(例如,通过拖动工作表选项卡)。最安全的方法是使用CodeName
  • 真的,@Chris 这可能会发生,但我知道我的客户和特定项目不太可能......但是,我明白你的意思,并会考虑改变公式。
  • @Martin - 感谢您发布完整的答案。(您将能够在 2 天内接受它 - 不要忘记也 ▲ Upvote 任何答案很有帮助。至于 Chris 的评论,他是正确的 - 我没有考虑拖动选项卡以重新排序更改索引号。可以通过以下方式阻止用户添加/编辑/删除工作表:Review > 保护工作簿 > (仅应检查“结构”) > 确定(不需要密码)。我将编辑我的答案添加更多信息。
  • 刚刚意识到,在研究和测试CodeName 方法后,您只能从该特定工作簿中的模块中引用它。因为我让用户从 Personal.xlsb 宏运行宏(这是因为工作簿在发送到我的客户端时都不同),所以引用 CodeName 将不起作用,但 Index 和 Sheet Name 方法将起作用。
【解决方案2】:

我怀疑问题可能是由于单元格地址的语法造成的。如果您从“Sheet1”中的“工作表空间”引用单元格 A1,您应该得到:

='sheet space'!A1

当工作表名称中包含空格时,请注意工作表名称包含在“'”中。当工作表名称是单个单词时,“'”会自动格式化,但仍然是有效的参考(即='Sheet1'!A1 是有效的)

试试:

CellAddress = "'" & Cell.Parent.Name & "'!" & Cell.Address(External:=False)

【讨论】:

  • 嗨@Yeile,我得到的只是'Sheet1'!$B$1而不是Sheet1$B$1,但公式仍然不喜欢这个变量。
  • @MartinHewittTayler,您的公式很复杂,因此很难确定您的错误原因。你可以试试ActiveCell.Formula = CellAddress 看看你是否得到一个有效的引用(即ActiveCell 返回CellAddress 的值,而不是错误)?告诉我结果!
  • 使用您的代码运行时,单元格地址为 'Sheet1'!$B$1,但是,如果您看到我的最新帖子,我已经通过使用工作表的索引解决了语法错误。
  • 好的先生,很高兴您的问题已经解决。请考虑 Chris 对您的回复的评论,CodeName 然后使用索引会很强大
【解决方案3】:

使用工作表索引号而不是名称:

据我了解,您的问题至少有一部分是您需要能够引用工作表,即使工作表的名称有时会发生变化。

您可以参考工作表的索引号而不是其名称。

这个临时子将在即时窗口中列出您现有工作表的名称和索引号:Ctrl + G

Sub CheckIdx()
   Dim ws as Worksheet
   For Each ws In Sheets
     Debug.Print ".Index=" & ws.Index,".Name=" & ws.Name,".CodeName=" & ws.CodeName
   Next ws
End Sub

名称改变时索引号不会改变。

如果您有一个名为“数据”且索引号为 3 的工作表,您可以按名称引用它:

Sheets("data")

...或者,按数字:

Sheets(3)

编辑:

正如@Chris 指出的那样,工作表Index 数字确实会发生变化,例如,如果工作表选项卡的顺序发生变化。

这可以通过protecting the workbook(有或没有密码)来防止,方法是点击:

  • ReviewProtect Workbook(只应检查“结构” )确定

  • 密码不是必需的,但是是可选的。 Protecting the workbook structure 阻止用户添加、移动、删除或隐藏/取消隐藏工作表,并且与protecting the worksheet不同相同,因此仍可以编辑单元格等。


另一种方法是使用worksheet CodeName property 而不是Index。从技术上讲,这可以也可以改变,但不太可能。

我已将CheckIdx 函数(上图)更新为包含CodeName,所以如果你想走这条路。

【讨论】:

  • 嗨@ashleedawg,尝试了 Index 方法,语法为 ActiveCell.Formula = _ "=CONCATENATE(""Balance Sheet"","" - "",MID(Sheets(1)!$ B$1,FIND("" "",Sheets(1)!$B$1,FIND("","",Sheets(1)!$B$1)+2)+1,256))" 但仍然有一个应用程序-定义或对象定义的错误。也许我的语法错了??
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-22
相关资源
最近更新 更多