.text, .value和.value2之间的区别是什么?如何时应瞄准。文本、目标。价值和目标。Value2被使用?
目标。Value会给你一个Variant类型
目标。Value2也会给你一个Variant类型,但是Date被强制为Double类型
目标。文本试图强制转换为字符串,如果底层变体不能强制转换为字符串类型,则会失败
最安全的做法是
Dim v As Variant
v = target.Value 'but if you don't want to handle date types use Value2
在尝试显式强制之前,使用VBA.VarType(v)检查变量的类型。
. text为您提供一个字符串,表示单元格在屏幕上显示的内容。使用.Text通常是一个坏主意,因为你可能会得到####
.Value2给出了单元格的底层值(可以是空的,字符串,错误,数字(double)或布尔值)
. value会给你与. value2相同的结果,除了如果单元格被格式化为货币或日期,它会给你一个VBA货币(可能会截断小数位)或VBA日期。
使用.Value或.Text通常是一个坏主意,因为你可能无法从单元格中获得真正的值,而且它们比.Value2慢
有关更广泛的讨论,请参阅我的文本vs值vs Value2
关于c#中的约定。假设您正在读取一个包含日期的单元格,例如2014-10-22。
当使用:
.Text,你将得到日期的格式化表示,如屏幕上的工作簿所示: 2014-10-22。此属性的类型始终是字符串,但可能并不总是返回令人满意的结果。
如果编译器试图将日期转换为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
.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
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
如果arr是一个Variant类型的变量,上面的行实际上创建了一个宽26列、高999行的OLE SAFEARRAY结构,并将Variant arr指向内存中的SAFEARRAY结构。
[a1].Resize(UBound(arr), UBound(arr, 2).Value2 = arr
上面的代码行将整个数组一次性写入工作表,无论数组有多大(只要它适合工作表)。
范围对象的默认属性是Value属性。因此,如果没有为范围指定属性,则默认情况下将静默引用Value属性。
然而,Value2是访问范围值的最快属性,读取时它返回真实的底层单元格值。它忽略数字格式、日期、时间和货币,并始终将数字作为VBA Double数据类型返回。由于Value2尝试做更少的工作,因此它的执行速度略快于Value。
The Value property, on the other hand, checks if a cell value has a Number Format of Date or Time and will return a value of the VBA Date data type in these cases. If your VBA code will be working with the Date data type, it may make sense to retrieve them with the Value property. And writing a VBA Date data type to a cell will automatically format the cell with the corresponding date or time number format. And writing a VBA Currency data type to a cell will automatically apply the currency Number Format to the appropriate cells.
类似地,Value检查单元格货币格式,然后 返回VBA Currency数据类型的值。这可能会导致 精度损失,因为VBA货币数据类型只识别 小数点后四位(因为VBA Currency数据类型实际上只是一个按10000缩放的64位整数),因此值四舍五入到四位, 最多。奇怪的是,这个精度被缩减到了小数点后两位 使用Value将VBA Currency变量写入工作表范围时的位置。
The read-only Text property always returns a VBA String data type. The value returned by Range.Text is a textual representation of what is displayed in each cell, inclusive of Number Formats, Dates, Times, Currency, and Error text. This is not an efficient way to get numerical values into VBA as implicit or explicit coercion is required. Text will return ####### when columns are too thin and it will slow down even more when some row heights are adjusted. Text is always VERY slow compared to Value and Value2. However, since Text retains the formatted appearance of cell values, Text may be useful, especially for populating userform controls with properly formatted text values.
Similarly, both Formula and FormulaR1C1 always return values as a VBA String data type. If the cell contains a formula then Formula returns its A1-style representation and FormulaR1C1 returns its R1C1 representation. If a cell has a hard value instead of a formula then both Formula and FormulaR1C1 ignore all formatting and return the true underlying cell value exactly like Value2 does... and then take a further step to convert that value to a string. Again, this is not an efficient way to get numerical values into VBA as implicit or explicit coercion is required. However, Formula and FormulaR1C1 must be used to read cell formulas. And they should be used to write formulas to cells.
如果单元格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
推荐文章
- .text, .value和.value2之间的区别是什么?
- 从c#读取Excel文件
- 检查单元格是否包含子字符串
- 在Excel中从公式返回空单元格
- 熊猫:在excel文件中查找表格列表
- 检查一个字符串是否包含另一个字符串
- 循环通过文件夹中的文件使用VBA?
- VBA有字典结构吗?
- 将公式应用到Excel中的整个列的快捷方式
- VBA调试在哪里。打印日志到?
- 在现有Excel值中添加前导0 /0到一定长度
- 如何在Office VBA编辑器中注释和取消注释代码块
- 如何从一个VBA函数返回一个结果
- 如何在Excel中创建包含双引号的字符串或公式?
- 使用Pandas对同一工作簿的多个工作表进行pd.read_excel()