【问题标题】:Why is my VB6 variant changing depending on when it is assigned?为什么我的 VB6 变体会根据分配时间而改变?
【发布时间】:2009-05-15 21:34:31
【问题描述】:

我是 VB6(以及任何形式的 Visual Basic)开发的新手,我遇到了一个问题。下面可能存在词汇错误,因为我在这里的帖子中将代码格式化为更具可读性,但问题的本质仍然存在。这是代码

我的问题是MsgBox 调用显示的值(第二组,引用变量scrWordresWord 的值)取决于我何时分配给变量scrWordresWord。如果我在上面显示的代码中未注释的第一个位置分配变量scrWordresWord,则代码底部的消息框将打印我不感兴趣的字符串(例如,第一个 messageBox 将产生一个类似于 srcws:resColNum:#) 的输出,或者看起来像是垃圾数据的输出。请注意,这意味着它将我在上一个消息框中使用的静态字符串分配给变量scrWord。这绝不是预期的行为,我不知道它是如何发生的。

另一方面,如果赋值是在消息框之前完成的,其中变量赋值在上面的代码中被注释,那么变量会打印一个不同的值,这有点像预期的,但不完全是(通常情况下,两个变量完全相同,或者一个是数字,但两者都应该是不同的字母字符串)。

我对这个问题感到困惑,我相信这与返回 Variant 数据类型的 GetData 调用有关。

谢谢, 埃文

新代码发布在下面。还是不行。

Dim srcWord As Variant
Dim resWord As Variant

Do While (BinsCol.GetData(grouprownum, 1) = binfromnum And nogroupfound = True)
    Dim groupmismatch As Boolean

    groupmismatch = False

    For j = 1 To FormHyst.GroupList.ListCount
                        
                        
        srcWord = sourceWS.Columns(j).GetData(i, 1)
        resWord = "hello, world"
                        

                        
        MsgBox ("srcws:" & srcWord & vbNewLine &_
                "resws:" & resWord & vbNewLine &_
                "test:" & (resWord <> srcWord))
    Next
Loop

在这个新代码中,srcWordresWord 都显示“hello, world”。

我仍然无法理解这种行为。

【问题讨论】:

  • 您是否尝试过使用调试器运行该代码。 VB6 调试器相当不错。这应该比在周围散布 MsgBox 调用更好地向您显示意外行为的来源。
  • 我正在编写一个 DLL 来扩展主机应用程序。我看到 VB6 调试器很好,但如果我必须运行主机应用程序,我不确定如何调试(否则,我对“GetData”的调用没有目标)
  • sourceWS 和 resultWS 对象是什么? Excel 工作表?
  • 另外你为什么要把所有的东西都放在括号里? scrWord = (sourceWS.Columns(columnnum).GetData(rownum, 1)) 应该只是 scrWord = sourceWS.Columns(columnnum).GetData(rownum, 1)
  • 那组外部括号是出于某种绝望的举动而添加的,我正在测试以确保它们保持平衡,然后将它们留在那里。 sourceWS 和 resultWS 是 Minitab 项目工作表对象。它们可与 Excel 工作表相媲美。在其列组件上调用的 GetData 函数返回一个变体类型。

标签: vb6 types


【解决方案1】:

正如您所说,您是 VB6 的新手,这里有一些一般性的想法和建议。

作为第一个建议:只要您不真的需要变体,就不要使用它们。使用您期望的具体数据类型。在MSDN 有一个解释变体如何在内部工作。比较变体时会发生隐式转换,因此如果您并不真正了解自己的数据,这就是一种赌博。

即使您的 GetData 函数返回 Variant,您也可以将返回值强制转换为该工作表列中的特定数据类型。因此,如果您的列仅包含字符串,请使用 CStr() 将其转换为字符串并将其放入字符串变量中。与数字相同,分为双精度或长变量。

您可能还想使用 VarType 函数来确定存储在 Variants 中的值的真实类型。

以下更多的是调试工作流程,但也许它可以帮助您找出问题:

  1. 启用选项显式以避免未声明/拼写错误的变量问题。 (如 DJ 所述)

  2. 在每一行之后生成调试输出,以确保您拥有您期望的值而不是其他值。如果无法通过调试或“Debug.Print”进行单步调试,那么也许您可以登录到外部日志文件或使用 MsgBox。

  3. 将您的源代码与外部组件依赖项解耦以进行测试。在您的情况下,尝试在不从外部网格读取数据的情况下重现问题(例如将变量设置为一些具体的字符串)。然后你就会知道问题出在你的编程逻辑上还是在你必须处理的数据上。

  4. 始终仔细检查您的外部数据源确实是您期望的数据源,而不是其他数据源。 (经常发生在我身上......)所以检查一下你的网格在 (i,j) 处保存了哪些数据,以及它是否与你获得的数据相匹配。

还有一点:字符串比较在 VB6 中区分大小写,只要您不将“选项比较文本”放在模块/类/表单的顶部即可。所以“你好世界”“你好世界”。

【讨论】:

    【解决方案2】:

    你的模块顶部有Option Explicit吗???

    你有一个错字:srcWord 应该是 scrWord

    【讨论】:

    • 注意,这是我的代码中的一个错字。但是,resWord 的显示方式仍然相同,并且显示明显随机的字符串(例如“resColNum:”)
    • 确保使用 Option Explicit 来捕获更多未声明的变量
    【解决方案3】:

    试试

    Dim srcWord As Variant Dim resWord As Variant Do While (BinsCol.GetData(grouprownum, 1) = binfromnum And nogroupfound = True) For columnnum = 1 To FormHyst.GroupList.ListCount scrWord = (sourceWS.Columns(columnnum ).GetData(rownum, 1)) resWord = (resultWS.Columns(columnnum + 3).GetData(grouprownum, 1)) MsgBox ("srcColNum:" & columnnum & vbNewLine & "srcRowNum:" & _ rownum) MsgBox ("resColNum:" & (columnnum + 3) & vbNewLine & "resRowNum:" & _ grouprownum) MsgBox ("srcws:" & srcWord) Next Loop

    以下没有任何意义

    MsgBox ("resws:" & resWord & vbNewLine & "test:" & (resWord <> srcWord))
    

    在 (resWord srcWord) 处你会得到“真”或“假”

    【讨论】:

    • 我打算显示字符串“true”或“false” 将 Dim 移到 while 循环之外似乎什么都不做
    • 删除另一个消息框显然没有效果。我将编辑我的问题正文以反映我的新代码。它被大大简化了,但仍然无法运行。 resWord 和 scrWord 都表现得像 volatile 字符串,它们在我的程序中由随机字符串组件加载和卸载。
    猜你喜欢
    • 1970-01-01
    • 2015-02-22
    • 2022-01-14
    • 1970-01-01
    • 1970-01-01
    • 2017-10-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多