【问题标题】:Variable not updating passed ByRef变量未更新通过 ByRef
【发布时间】:2018-07-12 19:26:47
【问题描述】:

我在所有模块中都使用了Option Explicit,这个让我摸不着头脑,也许是在调用方法中迷路了。

读取工作表并将特定数据组合到一个新工作簿、单个工作表中,变量 colData 应该增加列,并且它将被更新并传回与工作表一样多的次数(例如,复制 1-12 个月在第 1-12 列中给定年份,然后在第 13-24 列中复制下一年的第 1-12 个月等)

调用函数返回一个布尔值(这是随后的错误检查):

  'Attempt to load Total Revenue for the Import Sheet
  TotRevLoaded = Application.Run("modGetDataHelpers.loadTotRev", wsImport, rng, colData)

以下是函数中重要的部分: 'Sub 加载工作表中选定文件的总收入

Private Function loadTotRev(ByRef wsImport As Worksheet, ByRef rng As Range, ByRef colData As Long) As Boolean

'matchRow is called above and works


Dim k As Integer

    For k = 1 To 12
        'sets headers for the sheet
        wsData.Cells(1, colData) = strYear
        wsData.Cells(2, colData) = k
        'Copy Total Revenue in to row 3
        wsData.Cells(3, colData) = wsImport.Cells(matchRow, 2 + k).Value
        colData = colData + 1
    Next k
    loadTotRev = True 'Success in loading the total rev on sheet

End Function

函数中的 colData 更新为预期的 1-13,但是当离开函数并返回下一个工作表导入时,它始终为 1,因此 colData 的值在其引用地址处不会改变。

这应该很容易。变量正在转换为 ByVal,一旦离开函数范围,修改就会丢失。

我认为这可能是因为 () 中的 arg 换行,不。更改为 sub 并且没有分配,您可以删除这些。

我认为这可能是由于分配=,不。改为副。

因为它被传递给一个函数,不。更改为 Sub Public 和 Private。

因为调用者和修饰符在不同的模块中,所以不行

在解决方案上,我不想要一个全局变量或将所有辅助函数带入同一个模块范围(模块全局变量)。

【问题讨论】:

  • 您说的是 byRef,但如果您希望 colData 以更改后的值返回,则不应像 ByVal colData As Long 那样使用 byVal。
  • wsImport 是一个打开的工作簿,需要那个引用,它是在文件打开后分配的。 wsData 在代码工作簿(命名工作表)中。很好的收获,但它的意思是这样。 colData 是什么让我适应,总是重置为 1,它在返回时被初始化。
  • 我很抱歉另一个很好的问题,当我疯狂地更改代码时,这是一个糟糕的副本,这将是一个问题!已编辑。
  • 我不确定使用Application.Run 调用静态命名的函数的正当理由是什么(即,您没有调用从字符串和/或变量构建的函数名称)。将函数公开,如果您不希望它作为 UDF 公开,请为其模块指定 Option Private Module
  • 如果它需要在它所在的模块之外被调用,它应该是Public... 让一切Private 然后用Application.Run 绕过它只不过是一个聪明的黑客:我不会期望 Application.Run 甚至能够做到这一点。如果您的公共空间变得过于拥挤,请考虑使用类模块和对象来封装功能。更不用说在你重命名一个这样的私有方法之后你的代码是如何愉快地继续编译的,只是在运行时因为你忘记在调用站点更新该字符串而崩溃。

标签: vba excel


【解决方案1】:

经验丰富的 VBA 用户提供了很好的反馈,提供了很好的信息。

1) @TimWilliams:如果您打算传递参数 ByRef,请避免使用 Application.Run 调用 Private Functions/Subs,它会将这些转换为 ByVal。

http://www.tushar-mehta.com/publish_train/xl_vba_cases/1022_ByRef_Argument_with_the_Application_Run_method.shtml

2) @MathieuGuindon:完全避免使用 Application.Run,​​将 Functions/Subs 设为 Public,或者研究封装和保护类的实现,如果确实需要,请查看 Option Private Module

事实上,我确实通过反复试验找到了 make Public 解决方案,从而放弃了 Application.Run 调用,但原因是后来出现的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-09-28
    • 2019-12-20
    • 1970-01-01
    • 1970-01-01
    • 2018-10-07
    • 2014-03-31
    • 2023-03-05
    • 1970-01-01
    相关资源
    最近更新 更多