运行-当我指的是未命名的范围时出现错误“1004”
Run-time error '1004' when I'm referring to a range that is not named
我正在尝试在另一个工作簿中的 Excel 作品sheet 中放置一个下拉菜单,其中包含另一个作品sheet 中的选项。我正在使用 VBA,因为 我想根据另一个下拉菜单 自定义这些选项。我设法通过在源 sheet 中命名范围来做到这一点,但该文件是只读的,所以我无法保存名称来自动执行该过程。所以我试着只使用引用中的列名(比如 $B:$B,我只需要 B 列),但是当我 运行 宏停止时出现 运行-time error 1004 .
Private Sub Worksheet_Change(ByVal Target As Range)
Dim KeyCells As Range
Set KeyCells = Range("H6")
If Not Application.Intersect(KeyCells, Range(Target.Address)) Is Nothing Then
Call main
End If
End Sub
Private Sub main()
reason = Range("H6").Value
List = ""
If reason = "Project ID/Task ID" Then
List = "=PIDTID"
Else
List = "=Cost_Center"
End If
With Range("I6").Validation
.Delete
.Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, _
Operator:=xlBetween, Formula1:=List
.IgnoreBlank = True
.InCellDropdown = True
.InputTitle = ""
.ErrorTitle = ""
.InputMessage = ""
.ErrorMessage = ""
.ShowInput = True
.ShowError = True
End With
End Sub
这是我的宏,如您所见,main()
是在更改 H6 时调用的,因为那是我的其他下拉菜单所在的位置。然后,根据该单元格的值,List 被分配一个等于定义的名称的值,该名称引用其他作品中的范围sheet。
例如,如果 PIDTID 名称等于 ='[20190812_WP_and_CostCenters_Responsible.xls]Projects responsibles'!WBSName
,则脚本有效。请注意,WBSName 是为源 sheet 中的列 B 指定的名称。
如果我将 PIDTID 设置为 ='[20190812_WP_and_CostCenters_Responsible.xls]Projects responsibles'!$B:$B
,我将在
行收到错误
.Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, _
Operator:=xlBetween, Formula1:=List
Cost_Center
名称作用相同。
我想提一下,这些测试是在打开源文件的情况下完成的。如果我尝试关闭它,我会得到同样的错误。
有没有办法消除错误,或者我可以通过另一种方法在不命名的情况下引用其他工作簿的 sheet 中的单元格?我也想在不打开源文件的情况下工作。谢谢!
正如 JvdV 在评论中所写,这是因为您不能在列表引用另一个工作簿的地方使用数据验证,至少不能以简单的方式进行验证。
您可以通过使用此公式向可写工作簿添加命名范围来规避它(假设 Cost_Center
在 C 列中)
=IF(Sheet1!H6="PIDTID",OFFSET('[20190812_WP_and_CostCenters_Responsible.xls]Projects responsibles'!$B:$B,0,0),OFFSET('[20190812_WP_and_CostCenters_Responsible.xls]Projects responsibles'!$C:$C,0,0))
然后在您的数据验证/宏中使用这个命名范围。
缺点是源工作簿必须打开下拉菜单才能工作
"Is there a way to get rid of the error, or another way by which I can refer to cells in sheets of other workbooks without naming them? I would also like to work without having to open the source file. Thank you!"
让我试一试:)
根据 this 文档,您不能使用对另一个工作簿的引用(没有命名范围)。当然不是在封闭的工作簿中。参考@Gh3ttoKinG 他的回答:).
所以这可能会做得更聪明,但要做到这一点 无需打开 我考虑使用 ExecuteExcel4Macro
的工作簿。在@SiddharthRout 的 this 回答的帮助下,我们可以开始从已关闭的工作簿中提取信息:
Sub Test()
Dim wbPath As String, wbName As String
Dim wsName As String, cellRef As String
Dim Ret As String
Dim lr As Long
Dim arr() As String
wbPath = "C:\Users\....\SO\"
wbName = "SO.xlsx"
wsName = "Sheet1"
'Get the last row from B column, notice we need R1C1 notation for Excel4Macro
lr = ExecuteExcel4Macro("COUNTA('" & wbPath & "[" & wbName & "]" & wsName & "'!C2)")
'Let's use an array to fill our validation list with later on
ReDim arr(1 To lr)
For x = 1 To lr
arr(x) = ExecuteExcel4Macro("'" & wbPath & "[" & wbName & "]" & wsName & "'!R" & x & "C2")
Next x
'Join the array together to make a string which will be accepted in the validation list
With Range("I6").Validation
.Delete
.Add Type:=xlValidateList, Formula1:=Join(arr, ",")
.IgnoreBlank = True
.InCellDropdown = True
.InputTitle = ""
.ErrorTitle = ""
.InputMessage = ""
.ErrorMessage = ""
.ShowInput = True
.ShowError = True
End With
End Sub
有些事情我会尝试 "smoothen" 例如 COUNTA
不是获得 lr
变量的最佳方法,而且可能有一种方法可以提取完整的立即进入 arr()
变量范围。
不过,这可能会激发一些创意 ;)
编辑
另一种检索字符串数据最后一行的方法是使用 MATCH
,如下所示:
lr = ExecuteExcel4Macro("MATCH(""zzz"",'" & wbPath & "[" & wbName & "]" & wsName & "'!C2)")
我正在尝试在另一个工作簿中的 Excel 作品sheet 中放置一个下拉菜单,其中包含另一个作品sheet 中的选项。我正在使用 VBA,因为 我想根据另一个下拉菜单 自定义这些选项。我设法通过在源 sheet 中命名范围来做到这一点,但该文件是只读的,所以我无法保存名称来自动执行该过程。所以我试着只使用引用中的列名(比如 $B:$B,我只需要 B 列),但是当我 运行 宏停止时出现 运行-time error 1004 .
Private Sub Worksheet_Change(ByVal Target As Range)
Dim KeyCells As Range
Set KeyCells = Range("H6")
If Not Application.Intersect(KeyCells, Range(Target.Address)) Is Nothing Then
Call main
End If
End Sub
Private Sub main()
reason = Range("H6").Value
List = ""
If reason = "Project ID/Task ID" Then
List = "=PIDTID"
Else
List = "=Cost_Center"
End If
With Range("I6").Validation
.Delete
.Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, _
Operator:=xlBetween, Formula1:=List
.IgnoreBlank = True
.InCellDropdown = True
.InputTitle = ""
.ErrorTitle = ""
.InputMessage = ""
.ErrorMessage = ""
.ShowInput = True
.ShowError = True
End With
End Sub
这是我的宏,如您所见,main()
是在更改 H6 时调用的,因为那是我的其他下拉菜单所在的位置。然后,根据该单元格的值,List 被分配一个等于定义的名称的值,该名称引用其他作品中的范围sheet。
例如,如果 PIDTID 名称等于 ='[20190812_WP_and_CostCenters_Responsible.xls]Projects responsibles'!WBSName
,则脚本有效。请注意,WBSName 是为源 sheet 中的列 B 指定的名称。
如果我将 PIDTID 设置为 ='[20190812_WP_and_CostCenters_Responsible.xls]Projects responsibles'!$B:$B
,我将在
.Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, _
Operator:=xlBetween, Formula1:=List
Cost_Center
名称作用相同。
我想提一下,这些测试是在打开源文件的情况下完成的。如果我尝试关闭它,我会得到同样的错误。
有没有办法消除错误,或者我可以通过另一种方法在不命名的情况下引用其他工作簿的 sheet 中的单元格?我也想在不打开源文件的情况下工作。谢谢!
正如 JvdV 在评论中所写,这是因为您不能在列表引用另一个工作簿的地方使用数据验证,至少不能以简单的方式进行验证。
您可以通过使用此公式向可写工作簿添加命名范围来规避它(假设 Cost_Center
在 C 列中)
=IF(Sheet1!H6="PIDTID",OFFSET('[20190812_WP_and_CostCenters_Responsible.xls]Projects responsibles'!$B:$B,0,0),OFFSET('[20190812_WP_and_CostCenters_Responsible.xls]Projects responsibles'!$C:$C,0,0))
然后在您的数据验证/宏中使用这个命名范围。 缺点是源工作簿必须打开下拉菜单才能工作
"Is there a way to get rid of the error, or another way by which I can refer to cells in sheets of other workbooks without naming them? I would also like to work without having to open the source file. Thank you!"
让我试一试:)
根据 this 文档,您不能使用对另一个工作簿的引用(没有命名范围)。当然不是在封闭的工作簿中。参考@Gh3ttoKinG 他的回答:).
所以这可能会做得更聪明,但要做到这一点 无需打开 我考虑使用 ExecuteExcel4Macro
的工作簿。在@SiddharthRout 的 this 回答的帮助下,我们可以开始从已关闭的工作簿中提取信息:
Sub Test()
Dim wbPath As String, wbName As String
Dim wsName As String, cellRef As String
Dim Ret As String
Dim lr As Long
Dim arr() As String
wbPath = "C:\Users\....\SO\"
wbName = "SO.xlsx"
wsName = "Sheet1"
'Get the last row from B column, notice we need R1C1 notation for Excel4Macro
lr = ExecuteExcel4Macro("COUNTA('" & wbPath & "[" & wbName & "]" & wsName & "'!C2)")
'Let's use an array to fill our validation list with later on
ReDim arr(1 To lr)
For x = 1 To lr
arr(x) = ExecuteExcel4Macro("'" & wbPath & "[" & wbName & "]" & wsName & "'!R" & x & "C2")
Next x
'Join the array together to make a string which will be accepted in the validation list
With Range("I6").Validation
.Delete
.Add Type:=xlValidateList, Formula1:=Join(arr, ",")
.IgnoreBlank = True
.InCellDropdown = True
.InputTitle = ""
.ErrorTitle = ""
.InputMessage = ""
.ErrorMessage = ""
.ShowInput = True
.ShowError = True
End With
End Sub
有些事情我会尝试 "smoothen" 例如 COUNTA
不是获得 lr
变量的最佳方法,而且可能有一种方法可以提取完整的立即进入 arr()
变量范围。
不过,这可能会激发一些创意 ;)
编辑
另一种检索字符串数据最后一行的方法是使用 MATCH
,如下所示:
lr = ExecuteExcel4Macro("MATCH(""zzz"",'" & wbPath & "[" & wbName & "]" & wsName & "'!C2)")