【问题标题】:Calling VBA subroutine does not work when it is called from inside of another subroutine当从另一个子程序内部调用 VBA 子程序时,调用 VBA 子程序不起作用
【发布时间】:2017-06-21 17:45:30
【问题描述】:

我正在使用 VBA 尝试从主子例程调用一系列子例程。当我将所有子例程与类似于以下的代码组合在一起时,对于公式应该忽略的单元格,我会得到 #N/A。

Sub Main()

'Turn off autocalculation
    Application.Calculation = xlCalculationManual
    Application.DisplayStatusBar = False
'*********************************************************
'A bunch of other code
'*********************************************************

Call Sub_Routine1
Call Sub_Routine2
Call Sub_Routine3
Call Sub_Routine4
Call Sub_Routine5
Call Sub_Routine6
Call Sub_Routine7

'This is the sub routine that is not working correctly
Call Material_Formulas

'Turn back on the autocalculation function
    Application.Calculation = xlAutomatic

'*********************************************************
'A bunch of other code
'*********************************************************  
    Application.DisplayStatusBar = True
    Application.ScreenUpdating = True
    Application.EnableEvents = True

End Sub

当我从 Main 子例程中删除 Material_Formulas 子例程并使用以下脚本单独运行它时,它会按预期执行,如下图所示。

Private Sub Material_Formulas()

'Turn on manual calculation
Application.Calculation = xlCalculationManual
Dim lRow As Integer
Dim tiesMaterial As String
Dim result As String
lRow = Sheets("Material").Range("A2").End(xlDown).Row
lCol = Sheets("Material").Range("A2").End(xlToRight).Column

'Starts the count at column CU
endCount = lCol - 1    
    For c = 99 To endCount
        For r = 3 To lRow        
        tiesMaterial = Cells(r, 87).Value

        'Looks to see if the cells starting at CU2 contains a number and then iterates through each cell in row 3 to add a formula
        If tiesMaterial = "TIES MATERIAL" Then

            'Defines the unique ID and calendar year cells for the index-match-match function
            materialID = Sheets("Material").Cells(r, "CQ").Address(False, False)
            materialYear = Sheets("Material").Cells(2, c).Address(False, False)

            'Starting in cell CU3 it adds the formula =INDEX(BOM_Summary_Array,MATCH(CQ3,BOM_Summary_ID,0),MATCH(CU2,BOM_Summary_Head,0))
            Sheets("Material").Cells(r, c).Formula = "=INDEX(BOM_Summary_Array,MATCH(Material!" & materialID & ",BOM_Summary_ID,0),MATCH(Material!" & materialYear & ",BOM_Summary_Head,0))"                 
        End If

        Next r
    Next c     
'Turn on the auto calculation function
Application.Calculation = xlAutomatic
End Sub

我做错了什么?当我手动独立选择它时它如何运行良好,但当我将它与其他子例程结合时它会失败?

【问题讨论】:

  • 当您说 "fails" 时,您的意思是它什么都不做或抛出错误 ??
  • 单元格中的公式是什么,对吗?如果不是,正确的公式应该是什么?
  • 第 2 行实际日期中的年份是格式化为 yyyy 还是从 2012 年到 2021 年的整数?
  • 不应忽略具有#N/A 的单元格。在这些单元格中,假定启动公式的参数 (TIES MATERIAL ) 缺失,因此应跳过或忽略这些行。然后它们将具有原始值。上面的第二张图片应该是它的样子。在这两种情况下,它们都是数字,而不是日期格式。

标签: vba excel


【解决方案1】:

首先,您需要改进您的代码。我几乎可以保证这很可能是由于代码编写不佳而发生的。例如:

materialID = Sheets("Material").Cells(r, "CQ").Address(False, False)
materialYear = Sheets("Material").Cells(2, c).Address(False, False)

请注意,materialIDmaterialYear 永远不会被声明。这意味着它们属于 Variant 类型(出于这个确切原因,您需要将 Option Explicit 添加到代码模块的顶部)。变体的有趣之处在于,您猜对了,它们各不相同。 MaterialID 可以是 stringintlongdecimaldatearrayrange 等。我们可以假设范围将进入materialID,但我们无法确定。

另外,请注意讨厌的Sheets("Material")。这实际上是在说 ActiveWorkbook.Sheets("Material")`。限定您的参考资料,否则您几乎不知道实际上发生了什么。

在您的代码中很容易发生的情况是地址正确地以string 的形式进入materialID,但它是来自另一个工作簿的地址,其工作表名为“材料”。不太可能,但可能。

我们所知道的很可能是ActiveWorkbook 在某些方面发生了变化,很可能在Sub_Routine7 中(这里的旁注,您必须描述性地命名子例程,否则您的代码远未达到可维护性)。

祝你好运,但我强烈建议您在确定范围、声明所有变量并添加 Option Explicit 之前不要尝试调试情况。

【讨论】:

  • 感谢@Brandon!很抱歉,编号子例程不是它们的实际名称,它们是用于伪代码说明目的的误解。我最终通过添加对材料公式引用的活动工作簿页面的引用来使其工作。
最近更新 更多