Яка різниця між .text, .value та .value2?


180

Я не прошу допомоги в будь-якому сценарії, але моє питання - для уточнення. Останнім часом я робив багато сценаріїв VB в Excel, тому в цьому питанні я справді посилаюся на 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

Я все ще трохи розгублений, бо коли я думаю про значення або value2, особливо після ваших відповідей, які ви надали, я думаю, що їх слід використовувати лише для цифр. Однак у своєму прикладі я говорю про суворо текст, що багато в чому стосується мого сценарію (текст у клітинках, тим більше цифри).


LCase (Target.Value) завершиться невдачею, якщо Target.Value не можна приєднати до рядка, оскільки LCase вимагає рядка для аргументу. Спершу слід перевірити VarType відповідно до моєї відповіді. Також зауважте, що ви можете використовувати UCase замість цього і порівнювати безпосередньо з "HLO": не так багато сенсу в роботі з літералом.
Вірсавія

Дякуємо за інформацію про VarType. Що стосується LCase або UCase для цього, то насправді не має значення, який я використовував. Деякі люди вводять його як hlo, а інші - як HLO. З того, що я бачив, здавалося, нижній регістр використовується частіше.
Кріс

Відповіді:


238

.Textдає вам рядок із зображенням того, що відображається на екрані для комірки. Використання .Text - це погана ідея, оскільки ви можете отримати ####

.Value2 дає базове значення комірки (може бути порожнім, рядком, помилкою, номером (подвійним) або булевим)

.Value дає вам те саме, що і .Value2, за винятком випадків, коли комірка була відформатована як валюта чи дата, вона дає вам валюту VBA (яка може скоротити десяткові знаки) або дату VBA.

Використання .Value або .Text зазвичай погана ідея, оскільки ви не можете отримати реальне значення з комірки, і вони повільніше, ніж .Value2

Для більш широкого обговорення дивіться мій Текст проти значення та значення2


6
Я, мабуть, використовую Format, щоб контролювати, як число перетворюється на рядок: var = Format (діапазон ("a1"). Value2, "#")
Чарльз Вільямс,

2
Я сподіваюся, що це не окреме питання, але: Що таке за замовчуванням? ОП нечітко стверджує, що залишити текст / значення / значення2 проблематично, але, безумовно, він за замовчуванням ставиться до одного з них?
Мартін Ф

3
До жаль , щоб розбудити цей oooooold пост, але я не в змозі побачити перевагу спонукання Dateв Double(використовуючи .Value2) , коли то , що вам потрібно це Date. Не .Valueварто віддавати перевагу над, .Value2коли ви дивитесь на Dateзначення? Зв'язана стаття також не дуже зрозуміла. Продуктивність, тому що немає конверсії? Звичайно, але тоді, якщо ваш код VBA працює з a Date, ви втратите цей край, виконуючи конверсію самостійно, неявно або явно ... (контекст - не соромтеся)
Матьє Гіндон

2
@ Mat's Mug - проблема полягає в тому, що в Excel не існує справжнього типу даних про дату - дати Excel та дати - це лише подвійні розміри, які залежать від того, який формат було застосовано або змінено користувачем, щоб відображатись як дати, часи чи валюти чи просто число. Таким чином, Value примушує подвійний Excel до дати VBA, але Value2 не робить ніякого примусу ... Для дат, примусових подвійний до дати, ймовірно, не завдає шкоди, доки код розуміє, що його залежність від змінного формату: профі і мінуси в будь-якому випадку - те, що нам дійсно потрібно, - це більш рідні типи даних Excel, щоб уникнути цієї проблеми.
Чарльз Вільямс

2
Коли я хочу , щоб встановити значення осередки рівного в іншу клітинку без перетворення типу (наприклад, без перетворення номера , який було збережено в вигляді тексту на ряд) Я використовую це: Format$(Range.Value2, Range.NumberFormat).
ChrisB

55

За винятком форми першої відповіді Вірсавія, крім інформації MSDN для:

.Value
.Value2
.Text

Ви можете проаналізувати ці таблиці для кращого розуміння відмінностей між проаналізованими властивостями.

введіть тут опис зображення


4
@Chris, використовуй .Valueяк стандартне властивість весь час - для тексту та цифр. Використовуйте, .Value2коли ви думаєте про дату та деякі цифри. І використовуйте .Textзавжди, якщо вам потрібно продовжувати форматувати все, що є у комірці / діапазоні. Отже, ваш приклад питання, якщо правильний!
Казімеж Явор

1
чому дата змінилася з 10:12 на 10:05? друкарський помилок?
Катрін

1
Я думаю, що саме час минув між створенням результатів і часом зйомки екрана
Казімір Явор

25

target.Valueдасть вам Variantтип

target.Value2також дасть вам 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)перш ніж спробувати явний примус.


11

Щодо конвенцій на 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

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 задушиться, порівнюючи повернене значення з рядком. Якщо до ваших даних застосоване певне форматування клітинок, тест може бути кращим вибором під час створення звіту.


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

введіть тут опис зображення

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.