.text
,.value
和 和有什么区别.value2
?比如什么时候应该使用target.text、target.value、target.value2?
6 回答
.Text
为您提供一个字符串,表示单元格屏幕上显示的内容。使用.Text
通常是一个坏主意,因为你可以得到####
.Value2
为您提供单元格的基础值(可以是空、字符串、错误、数字(双精度)或布尔值)
.Value
为您提供相同的内容,.Value2
除非单元格被格式化为货币或日期,否则它会为您提供 VBA 货币(可能会截断小数位)或 VBA 日期。
使用.Value
or.Text
通常是一个坏主意,因为您可能无法从单元格中获得真正的价值,而且它们比.Value2
有关更广泛的讨论,请参阅我的Text vs Value vs Value2
target.Value
会给你一个Variant
类型
target.Value2
也会给你一个Variant
类型,但 aDate
被强制为 aDouble
target.Text
尝试强制转换为 aString
并且如果底层Variant
不能强制转换为String
类型将失败
最安全的做法是
Dim v As Variant
v = target.Value 'but if you don't want to handle date types use Value2
VBA.VarType(v)
并在尝试显式强制之前检查变体的类型。
关于 C# 中的约定。假设您正在阅读一个包含日期的单元格,例如 2014-10-22。
使用时:
.Text
,您将获得日期的格式化表示,如屏幕上的工作簿所示:
2014-10-22。此属性的类型总是string
但可能并不总是返回令人满意的结果。
.Value
,编译器尝试将日期转换为DateTime
对象:{2014-10-22 00:00:00}很可能仅在读取日期时有用。
.Value2
, 为您提供单元格的真实基础值。在日期的情况下,它是一个日期序列:41934。此属性可以具有不同的类型,具体取决于单元格的内容。但是,对于日期连续剧,类型是double
.
因此,您可以在其中一个中检索和存储单元格的值dynamic
,var
或者object
但请注意,该值将始终具有某种您必须采取行动的先天类型。
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
.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 可能是更好的选择。
出于好奇,我想看看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