.text,.value和.value2有什么区别?


179

我没有要求任何脚本的帮助,但我的问题是要澄清。最近,我在Excel中做了很多VB脚本编写工作,因此我在这个问题上确实指的是Excel。.text,.value和.value2有什么区别?就像我什么时候应该使用target.text,target.value和target.value2?我从未使用过value2选项,但仍然想知道它的用途。

有时,如果我使用.text,则会出现错误,并且仅在检查或操作单元格中的文本时需要使用.value。然后有时当我认为我应该使用.value时出现错误,我需要使用.text。通常,它接受一个问题或不提出任何问题,但有时确实会有所作为。我知道必须有一些逻辑,但是我似乎无法弄清楚。

我还发现,如果不指定.text或.value就将其保留为目标,则它最初会起作用,但随后某人做的某件事最终会导致脚本出错,因此始终最好在上面使用.something 。我想我要问的是,是否有人可以给我一些指导方针,即如何正确使用每项准则以及何时需要使用的准则。

谢谢你们的解释。我有点了解。它们都是很好的解释。以下是我的一些有效代码的小示例。我以为它应该是target.text,但是会出错,所以当我使用target.value时它可以工作。

If LCase(Target.Value) = LCase("HLO") And Target.Column = 15 Then
    Target.Value = "Higher Level Outage"
End If

我仍然有些困惑,因为当我想到value或value2时,尤其是在您提供了答案之后,我认为它们应该仅用于数字。但是,在我的示例中,我所指的是严格的文本,这是我的脚本所指的很多内容(单元格中的文本,而不是数字)。


如果Target.Value不可强制转换为字符串,则LCase(Target.Value)将失败,因为LCase要求参数使用字符串。您应该按照我的回答先检查VarType。另请注意,您可以改用UCase并直接与“ HLO”进行比较:对文字进行操作没有多大意义。
Bathsheba

感谢您提供有关VarType的信息。至于使用LCase还是UCase,我使用哪一个都没关系。有些人将其键入为HLO,其他人将其键入为HLO。从我看来,小写字母似乎经常使用。
克里斯

Answers:


236

.Text给您一个字符串,代表该单元屏幕上显示的内容。使用.Text通常不是一个好主意,因为您可以得到####

.Value2 为您提供单元格的基础值(可以为空,字符串,错误,数字(双精度)或布尔值)

.Value 为您提供与.Value2相同的功能,除非单元格的格式设置为货币或日期,否则它会为您提供VBA货币(可能会截断小数位)或VBA日期。

使用.Value或.Text通常不是一个好主意,因为您可能无法从单元格获取真实值,并且它们比.Value2慢。

有关更广泛的讨论,请参见我的文字vs价值vs Value2


6
我可能会使用Format来控制如何将数字转换为字符串:var = Format(Range(“ a1”)。Value2,“#”)
Charles Williams

2
我希望这不是一个单独的问题,而是:默认值是什么?OP模糊地声称遗漏text / value / value2是有问题的,但是可以肯定它默认为其中之一吗?
Martin F

3
很抱歉唤醒这篇文章,但是当您需要一个时,我没有看到将a强制Date转换为Double(使用.Value2)的优势Date。当您查看一个值时,不应该.Value被优先.Value2考虑Date吗?链接的文章也不是很清楚。性能是因为没有转化?当然可以,但是如果您的VBA代码正在使用Date,则您将无法
Mathieu Guindon

2
@Mat的杯子-问题是Excel没有真正的Date数据类型-excel日期和时间只是两倍,这取决于用户应用或更改的任何格式以显示为日期,时间或货币还是仅显示为数。因此,Value将Excel的Double强制为VBA日期,但是Value2没有进行任何强制...对于将Double强制为日期的日期,只要代码理解其依赖于可变格式,就可能不会造成任何损害:无论哪种方式都有弊端-我们真正​​需要的是更多本机Excel数据类型,以避免出现此问题。
查尔斯·威廉姆斯

2
当我想要设置的小区值等于另一个细胞未经类型转换(例如,而不转换存储为文本为数字的号码)我使用: Format$(Range.Value2, Range.NumberFormat)
ChrisB

55

除了第一个答案来自Bathsheba,MSDN信息除外:

.Value
.Value2
.Text

您可以分析这些表以更好地了解所分析属性之间的差异。

在此处输入图片说明


4
@Chris,始终将其.Value用作标准属性-用于文本和数字。使用.Value2时,你觉得日期和一些数字。.Text如果需要保留单元格/范围中所有内容的格式,请始终使用。因此,您的问题示例是否正确!
卡齐米兹·贾沃

1
为什么日期从10:12更改为10:05?错字?
卡特琳

1
我认为这只是在产生结果和制作屏幕快照之间经过的时间
Kazimierz Jawor

25

target.Value会给你一个Variant类型

target.Value2也会给你一个Variant类型,但是a Date被强制为aDouble

target.Text尝试强制转换为a String,如果基础Variant不可强制转换为String类型,则尝试将失败

最安全的事情是

Dim v As Variant
v = target.Value 'but if you don't want to handle date types use Value2

VBA.VarType(v)尝试使用显式强制之前,使用检查变体的类型。


11

关于C#中的约定。假设您正在读取包含日期的单元格,例如2014-10-22。

使用时:

.Text,您将获得日期的格式表示,如屏幕上的工作簿所示:
2014-10-22。此属性的类型始终是,string但可能并不总是返回令人满意的结果。

.Value,则编译器会尝试将日期转换为DateTime对象:{2014-10-22 00:00:00}最有可能仅在读取日期时有用。

.Value2,可为您提供单元格的实际基础价值。如果是日期,则为日期序列:41934。此属性可以具有不同的类型,具体取决于单元格的内容。对于日期序列,类型为double

所以,你可以检索和单元格的值存储在任dynamicvarobject但请注意,值将始终有某种先天型的,你将不得不在采取行动。

dynamic x = ws.get_Range("A1").Value2;
object  y = ws.get_Range("A1").Value2;
var     z = ws.get_Range("A1").Value2;
double  d = ws.get_Range("A1").Value2;      // Value of a serial is always a double

2

.Text是格式化单元格的显示值;.Value是单元格的值,可能会用日期或货币指标进行扩充;.Value2是去除了任何无关信息的原始基础值。

range("A1") = Date
range("A1").numberformat = "yyyy-mm-dd"
debug.print range("A1").text
debug.print range("A1").value
debug.print range("A1").value2

'results from Immediate window
2018-06-14
6/14/2018 
43265 

range("A1") = "abc"
range("A1").numberformat = "_(_(_(@"
debug.print range("A1").text
debug.print range("A1").value
debug.print range("A1").value2

'results from Immediate window
   abc
abc
abc

range("A1") = 12
range("A1").numberformat = "0 \m\m"
debug.print range("A1").text
debug.print range("A1").value
debug.print range("A1").value2

'results from Immediate window
12 mm
12
12

如果要处理单元格的值,则读取原始.Value2比.Value或.Text快一点。如果您要查找错误,则.Text将返回类似于#N/A文本的内容,并且可以将其与字符串进行比较,而.Value和.Value2将使将其返回的值与字符串进行比较会更加困难。如果对数据应用了一些自定义单元格格式,则在生成报告时,.Text可能是更好的选择。


0

出于好奇,我想看看对Value表现如何Value2。经过大约12次类似过程的试用后,我发现速度没有任何显着差异,因此我始终建议您使用Value。我使用下面的代码来运行各种范围的测试。

如果有人发现与性能有任何相反之处,请发表。

Sub Trial_RUN()
    For t = 0 To 5
        TestValueMethod (True)
        TestValueMethod (False)
    Next t

End Sub




Sub TestValueMethod(useValue2 As Boolean)
Dim beginTime As Date, aCell As Range, rngAddress As String, ResultsColumn As Long
ResultsColumn = 5

'have some values in your RngAddress. in my case i put =Rand() in the cells, and then set to values
rngAddress = "A2:A399999" 'I changed this around on my sets.



With ThisWorkbook.Sheets(1)
.Range(rngAddress).Offset(0, 1).ClearContents


beginTime = Now

For Each aCell In .Range(rngAddress).Cells
    If useValue2 Then
        aCell.Offset(0, 1).Value2 = aCell.Value2 + aCell.Offset(-1, 1).Value2
    Else
        aCell.Offset(0, 1).Value = aCell.Value + aCell.Offset(-1, 1).Value
    End If

Next aCell

Dim Answer As String
 If useValue2 Then Answer = " using Value2"

.Cells(Rows.Count, ResultsColumn).End(xlUp).Offset(1, 0) = DateDiff("S", beginTime, Now) & _
            " seconds. For " & .Range(rngAddress).Cells.Count & " cells, at " & Now & Answer


End With


End Sub

在此处输入图片说明

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.