提问人:Chris 提问时间:6/28/2013 最后编辑:ΩmegaManChris 更新时间:1/7/2023 访问量:295960
.text、.value 和 .value2 之间有什么区别?
What is the difference between .text, .value, and .value2?
答:
target.Value
会给你一个类型Variant
target.Value2
也会给你一个类型,但 a 被强制为Variant
Date
Double
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)
除了 Bathsheba 的回答和 MSDN 信息之外:
您可以分析下表,以便更好地了解这三个属性之间的差异。
评论
.Value
.Value2
.Text
.Text
为您提供一个字符串,表示单元格屏幕上显示的内容。使用通常是一个坏主意,因为你可以得到.Text
####
.Value2
为您提供单元格的基础值(可以是空、字符串、错误、数字(双精度)或布尔值)
.Value
为您提供相同,除非单元格格式为货币或日期,否则它会为您提供VBA货币(可能会截断小数位)或VBA日期。.Value2
使用 or 通常是一个坏主意,因为您可能无法从单元格中获得真正的值,而且它们比.Value
.Text
.Value2
有关更广泛的讨论,请参阅我的文本 vs 价值 vs 价值 2
评论
Format$(Range.Value2, Range.NumberFormat)
关于 C# 中的约定。假设您正在读取包含日期的单元格,例如 2014-10-22。
使用时:
.Text
,您将获得日期的格式表示形式,如屏幕上的工作簿所示:
2014-10-22。此属性的类型始终是,但可能并不总是返回令人满意的结果。string
.Value
,编译器尝试将日期转换为对象: {2014-10-22 00:00:00} 很可能仅在读取日期时有用。DateTime
.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
.文本是格式化单元格的显示值; 。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 比 稍快。值或 .发短信。如果要查找错误,则 .text 将返回类似 text 的内容,并且可以与字符串进行比较,而 .值和 .Value2 将扼杀将其返回值与字符串进行比较。如果您对数据应用了一些自定义单元格格式,则 .在生成报表时,文本可能是更好的选择。#N/A
出于好奇,我想看看对.在对类似过程进行了大约 12 次尝试后,我看不到速度有任何显着差异,因此我总是建议使用 .我使用下面的代码运行了一些具有各种范围的测试。Value
Value2
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
评论
.Value2
Value2
几乎总是读取或写入 Excel 单元格或范围的最佳选择......来自 VBA。
Range.Value2 '<------Best way
以下各项都可用于从某个区域读取:
v = [a1]
v = [a1].Value
v = [a1].Value2
v = [a1].Text
v = [a1].Formula
v = [a1].FormulaR1C1
以下各项都可用于写入范围:
[a1] = v
[a1].Value = v
[a1].Value2 = v
[a1].Formula = v
[a1].FormulaR1C1 = v
要从大范围内读取多个值,或写入多个值,一次性完成整个操作比逐个单元格要快几个数量级:
arr = [a1:z999].Value2
如果 是 Variant 类型的变量,则上面的行实际上创建了一个 26 列宽和 999 行高的变体的 OLE SAFEARRAY 结构,并将 Variant 指向内存中的 SAFEARRAY 结构。arr
arr
[a1].Resize(UBound(arr), UBound(arr, 2).Value2 = arr
上面的一行将整个数组一次性写入工作表,无论数组有多大(只要它适合工作表)。
range 对象的默认属性是属性。因此,如果未为该范围指定任何属性,则默认情况下会以静默方式引用该属性。Value
Value
但是,是访问范围值的最快属性,读取它时返回真正的基础单元格值。它忽略数字格式、日期、时间和货币,并始终以 VBA Double 数据类型返回数字。由于尝试做更少的工作,它的执行速度比 .Value2
Value2
Value
另一方面,该属性检查单元格值是否具有“日期”或“时间”的数字格式,并在这些情况下返回 VBA Date 数据类型的值。如果您的 VBA 代码将使用 Date 数据类型,则使用该属性检索它们可能是有意义的。将VBA Date数据类型写入单元格将自动使用相应的日期或时间数字格式设置单元格的格式。和
将 VBA 货币数据类型写入单元格会自动将货币数字格式应用于相应的单元格。Value
Value
同样,检查单元格货币格式,然后
返回 VBA Currency 数据类型的值。这可能导致
精度损失,因为 VBA Currency 数据类型只能识别
小数点后四位(因为 VBA Currency 数据类型实际上只是一个 64 位整数,缩放为 10000),因此值四舍五入到四位,
至多。奇怪的是,这个精度被削减到只有两位小数
用于将 VBA 货币变量写入工作表范围时的位置。Value
Value
只读属性始终返回 VBA String 数据类型。返回的值是每个单元格中显示的内容的文本表示形式,包括“数字格式”、“日期”、“时间”、“货币”和“错误”文本。这不是将数值导入 VBA 的有效方法,因为需要隐式或显式强制。 当列太细时会返回 #######,当调整某些行高时,它会更慢。 与 和 相比,总是非常慢。但是,由于保留单元格值的格式化外观,因此可能很有用,特别是对于使用格式正确的文本值填充用户窗体控件。Text
Range.Text
Text
Text
Value
Value2
Text
Text
同样,两者始终以 VBA 字符串数据类型的形式返回值。如果单元格包含公式,则返回其 A1 样式表示形式并返回其 R1C1 表示形式。如果一个单元格有一个硬值而不是一个公式,那么两者都忽略所有格式,并返回真正的基础单元格值,就像做的那样......然后执行进一步的步骤,将该值转换为字符串。同样,这不是将数值导入 VBA 的有效方法,因为需要隐式或显式强制。但是,并且必须用于读取单元格
公式。它们应该用于将公式写入单元格。Formula
FormulaR1C1
Formula
FormulaR1C1
Formula
FormulaR1C1
Value2
Formula
FormulaR1C1
如果单元格 A1 包含具有货币数字格式的数值 100.25 $#,##0.00_);($#,##0.00) 请考虑以下几点:
MsgBox [a1].Value 'Displays: 100.25
MsgBox TypeName([a1].Value) 'Displays: Currency
MsgBox [a1].Value2 'Displays: 100.25
MsgBox TypeName([a1].Value2) 'Displays: Double
MsgBox [a1].Text 'Displays: $ 100.25
MsgBox TypeName([a1].Text) 'Displays: String
MsgBox [a1].Formula 'Displays: 100.25
MsgBox TypeName([a1].Formula) 'Displays: String
MsgBox [a1].FormulaR1C1 'Displays: 100.25
MsgBox TypeName([a1].FormulaR1C1) 'Displays: String
下一个:如何从 VBA 函数返回结果
评论