【问题标题】:Len function not giving correct valueLen 函数没有给出正确的值
【发布时间】:2020-06-12 21:21:38
【问题描述】:

我很难让 Len() 函数给出正确的数字长度。

有困难的代码部分在这里:

Spec = Len(Range("J8")) - x
intermit = Range("I8") - Range("J8")
Low = Len(intermit)

MsgBox "Lower Spec: " & intermit & " Length: " & Low

intermit = Range("I8") + Range("J8")
High = Len(WorksheetFunction.Text(intermit, 0))
MsgBox "Upper Spec: " & intermit & " Length: " & High

范围("I8") = 0.0140

范围(“J8”)= 0.0002

消息框应该显示以下内容:

低规格:0.0138 长度:6

规格上限:0.0142 长度:6

但是他们正在显示:

低规格:0.0138 长度:8

规格上限:0.0142 长度:8

我尝试将间歇变量转换为文本,但它会返回为 0。我不知道函数计数的额外 2 个字符是从哪里来的。

【问题讨论】:

  • 您的单元格中显示的值是否可能不是单元格中保存的 实际 值?单元格格式可以使它们不同...
  • 如果我将这些值复制到I8 和J8,输出为:"Lower Spec: 0.0138 Length: 6" 和"Upper Spec: 0.0142 Length: 1"...
  • 问题远不止您所显示的 - 我无法使用提供的代码重现 8 输出。
  • *和数字输入
  • @TimWilliams 单元格的格式一般。我做了一个临时的。显示数字和长度的消息框,它显示是正确的。 (0.014 和 5)

标签: excel vba


【解决方案1】:

不要使用WorksheetFunction.Text 将Variant/Double 转换为String;它的正确格式字符串应该是 "@",而不是 0 - 但您不需要涉及工作表函数,VBA 标准库已经提供了一个 VBA.Conversion 模块,它为您提供了一堆转换函数,包括CStr.

但是,Len 函数存在于 VBA.Strings 模块中,这表明字符串转换无论如何都是隐式的 - 使用适当的转换函数使该转换显式并没有什么坏处,特别是考虑到我们正在处理假设单元格值实际上是数值,则似乎是未声明的变量,在运行时将是 Variant/Double。

我无法使用提供的代码和值重现问题。这对我有用:

Dim intermitLow As Double
intermitLow = Sheet2.Range("I8").Value - Sheet2.Range("J8").Value
Debug.Print intermitLow, Len(CStr(intermitLow))

Dim intermitHigh As Double
intermitHigh = Sheet2.Range("I8").Value + Sheet2.Range("J8").Value
Debug.Print intermitHigh, Len(CStr(intermitHigh))

I8=0.014(OP 中不重要的尾随零令人担忧)和 J8=0.0002 的输出:

 0.0138        6 
 0.0142        6 

请注意,我使用正确的 Worksheet 对象明确限定了 Range 成员调用,此处为 Sheet2(请参阅 CodeName: Sheet1 了解有关工作表代码名称的所有信息)。如果您的代码是在标准模块中编写的,那么不合格的Range 调用是implicit ActiveSheet references,即它指的是当时碰巧处于活动状态的任何工作表,这使得代码比它更脆弱需要 - 虽然,这似乎不是问题,因为我们正在使用预期值。

考虑只读取一次单元格值 - 无需每次都再次点击工作表:

Dim value1 As Double 'todo use a meaningful name
'note: possible type mismatch on assignment depending on the data type of .Value
value1 = Sheet2.Range("I8").Value

Dim value2 As Double 'todo use a meaningful name
'note: possible type mismatch on assignment depending on the data type of .Value
value2 = Sheet2.Range("J8").Value

Dim intermitLow As Double
intermitLow = value1 - value2
Debug.Print intermitLow, Len(CStr(intermitLow))

Dim intermitHigh As Double
intermitHigh = value1 + value2
Debug.Print intermitHigh, Len(CStr(intermitHigh))

避免在过程范围内为不同目的重复使用变量/标识符,并始终声明所有变量(在每个模块的顶部都有Option Explicit迫使您这样做)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-11-10
    • 1970-01-01
    • 1970-01-01
    • 2013-07-30
    • 1970-01-01
    • 2015-06-18
    • 1970-01-01
    • 2023-01-22
    相关资源
    最近更新 更多