【问题标题】:Excel VBA_ Method Range failed for Object Worksheet (Runtime Error 1004)Excel VBA_ 对象工作表的方法范围失败(运行时错误 1004)
【发布时间】:2020-10-15 12:49:51
【问题描述】:

我在不同的模块中编写了一些 vba 程序。然后,有一个用户窗体,在用户窗体中有这样的子,我称之为模块中的子

Sub uf2_imp_new_Click()
 Call a_xxx_delete '[Sub in Module A]
 Call a_xxx_import '[Sub in Module A]
 Call b_TransXXX    '[Sub in Module B]
 Call c_plist_reset_all '[Sub in Module C]
 Call c_xxx_listfrom_transANB '[Sub in Module C]
End Sub

执行时我在模块 C 子 c_xxx_listfrom_transANB 中收到运行时错误 1004“对象工作表的方法范围失败”:

Option Explicit
Sub c_xxx_listfrom_transANB()
 Dim wb As Workbook
 Dim ws_trans_anb As Worksheet
 Dim ws_plist As Worksheet
 Dim zeile_trans As Integer  
 Dim zeile_plist As Integer

 Set wb = ThisWorkbook
 Set ws_trans_anb = wb.Worksheets("Trans_XXX")       
 Set ws_plist = wb.Worksheets("PROJEKTLISTE")  

 letztezeile = ws_trans_anb.Cells(Rows.Count, 1).End(xlUp).Row

 For zeile_trans = 2 To letztezeile
  [...]
  ws_plist.Range(Cells(zeile_plist, 2), Cells(zeile_plist, 16)).Borders(xlEdgeBottom).LineStyle = xlContinuous
 Next
EndSub

发生错误时突出显示的行是

ws_plist.Range(Cells(zeile_plist, 2), Cells(zeile_plist, 16)).Borders(xlEdgeBottom).LineStyle = xlContinuous

有人知道如何解决这个问题吗?我几天前对模块 c 进行了编码,从未出现过错误。但是现在当通过用户表单调用 sub 时,它不再起作用了。而且很奇怪:我通过在 VBA 中单击“播放”来执行模块 C 中的 Sub,发生错误。但是当我在模块 C 中逐步执行 Sub 时,没有错误。这对我来说太多了.. :) 有人可以帮忙吗?

【问题讨论】:

  • ws_plist.Range(Cells 并不意味着 ws_plist.Range(ws_plist.Cells 所以你也需要像这样完全限定所有单元格引用
  • ws_plist.Range(Cells 实际上意味着ws_plist.Range(ActiveSheet.Cells - 所以当wsp_plistActiveSheet 相同时,它会起作用,而当它不是时,它不会。

标签: excel vba range runtime-error


【解决方案1】:

您的代码不精确。您正在计算一张纸(ActiveSheet)中的行数,然后在另一张纸中使用该数字。您还假设您定义的单元格与您使用它们的范围位于同一工作表上。结果不应该使 VBA 崩溃,但随后您将面临 VBA 无法按预期运行的情况。因此,如下所示提高精度。

Sub c_xxx_listfrom_transANB()
    ' 056
    
     Dim Wb             As Workbook
     Dim Ws_trans_anb   As Worksheet
     Dim Ws_plist       As Worksheet
     Dim zeile_trans    As Integer      ' should be Long
     Dim zeile_plist    As Integer      ' should be Long
     Dim Rng            As Range
    
     Set Wb = ThisWorkbook
     Set Ws_trans_anb = Wb.Worksheets("Trans_XXX")
     Set Ws_plist = Wb.Worksheets("PROJEKTLISTE")
    
     With Ws_trans_anb
        ' count the rows in the same worksheet where you define the last cell
        letztezeile = .Cells(.Rows.Count, 1).End(xlUp).Row
     End With
    
     For zeile_trans = 2 To letztezeile
     ' [...]
     With Ws_plist
        Set Rng = .Range(Cells(zeile_plist, 2), Cells(zeile_plist, 16))
         Rng.Borders(xlEdgeBottom).LineStyle = xlContinuous
     Next
End Sub

在上面的代码中,您将能够使用 F8 进入故障行并在崩溃发生之前检查组件。

您可能会发现zeile_plist 并不是您想的那样。逻辑上应该是zeile_trans,使用循环计数器?它可能是 0,这会产生现金。

我认为您需要处理变量命名。带有下划线的蛇形名称会使它们的可读性降低。您对小写的使用仅具有相同的效果。 ZeilePlistZeileTrans 将是一个改进。但是 Zeile 这个词并不是区分这些名称的原因。我可能会使用 ZplistZtrans,或许更有可能不落入你发现自己的陷阱。

【讨论】:

    【解决方案2】:

    正如 cmets 中所述,没有任何东西可以保证对 Cells() 的非限定调用将返回 ws_plist 上的范围。

    所以你的台词:

    ws_plist.Range(Cells(zeile_plist, 2), Cells(zeile_plist, 16)).Borders(xlEdgeBottom).LineStyle = xlContinuous
    

    应该变成:

    ws_plist.Range(ws_plist.Cells(zeile_plist, 2), ws_plist.Cells(zeile_plist, 16)).Borders(xlEdgeBottom).LineStyle = xlContinuous
    

    【讨论】:

    • 您能否详细说明ws_plist. 的“缺失”Rows.Count
    • Rows.Count 仅返回 ActiveSheet 的最大行数,无论是否使用,并且由于所有工作表上的行数都相同,因此是否对其进行限定并不重要。跨度>
    猜你喜欢
    • 2015-11-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多