ความแตกต่างระหว่าง. text, .value และ .value2 คืออะไร


180

ฉันไม่ได้ขอความช่วยเหลือจากสคริปต์ใด ๆ แต่คำถามของฉันสำหรับการชี้แจง เมื่อเร็ว ๆ นี้ฉันได้ทำ VB scripting ใน Excel เป็นจำนวนมากดังนั้นฉันจึงอ้างถึง Excel ในคำถามนี้ ความแตกต่างระหว่าง. text, .value และ .value2 คืออะไร เช่นเมื่อฉันควรใช้ target.text, target.value และ target.value2? ฉันไม่เคยใช้ตัวเลือก value2 แต่ยังต้องการทราบว่ามันใช้สำหรับอะไร

บางครั้งถ้าฉันใช้. text มันทำให้ฉันมีข้อผิดพลาดและฉันต้องใช้. value เมื่อฉันตรวจสอบหรือจัดการข้อความภายในเซลล์ แล้วบางครั้งเมื่อฉันคิดว่าฉันควรใช้. คุ้มค่าฉันได้รับข้อผิดพลาดและฉันต้องใช้. text โดยปกติจะยอมรับหรือไม่มีปัญหา แต่บางครั้งก็สร้างความแตกต่าง ฉันรู้ว่าต้องมีเหตุผลบางอย่างสำหรับเรื่องนี้ แต่ฉันไม่สามารถเข้าใจได้

ฉันยังพบว่าหากคุณเพิ่งปล่อยให้มันเป็นเป้าหมายโดยไม่ระบุ. text หรือ .value มันจะใช้งานได้ในตอนแรก แต่แล้วบางสิ่งบางอย่างที่บางคนทำในที่สุดจะทำให้สคริปต์ผิดพลาดดังนั้นจึงเป็นการดีที่สุดที่จะใช้. . ฉันเดาว่าสิ่งที่ฉันถามคือถ้ามีคนสามารถให้แนวทางบางอย่างกฎของหัวแม่มือเกี่ยวกับวิธีการใช้งานแต่ละอย่างถูกต้องและเมื่อจำเป็นต้องใช้

ขอบคุณสำหรับคำอธิบายพวก ฉันเข้าใจดีกว่า พวกเขาเป็นทั้งคำอธิบายที่ดี ด้านล่างเป็นตัวอย่างเล็ก ๆ ของรหัสของฉันที่ใช้งานได้ ฉันคิดว่ามันควรจะเป็น target.text แต่มันจะมีข้อผิดพลาดดังนั้นเมื่อฉันใช้ target.value มันก็ใช้ได้

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

ฉันยังสับสนอยู่เล็กน้อยเพราะเมื่อฉันนึกถึงคุณค่าหรือคุณค่า 2 โดยเฉพาะอย่างยิ่งหลังจากคำตอบที่คุณให้ไว้ฉันคิดว่าพวกเขาควรใช้ตัวเลขเท่านั้น อย่างไรก็ตามในตัวอย่างของฉันฉันกำลังพูดถึงข้อความที่เคร่งครัดซึ่งเป็นสิ่งที่สคริปต์ของฉันอ้างถึง (ข้อความในเซลล์มากกว่าตัวเลข)


LCase (Target.Value) จะล้มเหลวหาก Target.Value ไม่สามารถบังคับใช้กับสตริงได้เนื่องจาก LCase ต้องใช้สตริงเป็นอาร์กิวเมนต์ คุณควรตรวจสอบ VarType ก่อนตามคำตอบของฉัน นอกจากนี้โปรดทราบว่าคุณสามารถใช้ UCase แทนและเปรียบเทียบโดยตรงกับ "HLO": ไม่ได้มีจุดมากในการทำงานบนตัวอักษร
Bathsheba

ขอบคุณสำหรับข้อมูลเกี่ยวกับ VarType เท่าที่ LCase หรือ UCase สำหรับเรื่องนี้มันไม่สำคัญว่าจะใช้อันไหน บางคนพิมพ์เป็น hlo และบางคนพิมพ์เป็น HLO จากสิ่งที่ฉันเห็นมันปรากฏว่าตัวพิมพ์เล็กถูกใช้บ่อยกว่า
Chris

คำตอบ:


238

.Textให้สตริงที่แสดงถึงสิ่งที่ปรากฏบนหน้าจอสำหรับเซลล์ การใช้. Text มักเป็นความคิดที่ไม่ดีเพราะคุณสามารถรับ ####

.Value2 ให้ค่าพื้นฐานของเซลล์ (อาจว่างเปล่าสตริงข้อผิดพลาดตัวเลข (สองครั้ง) หรือบูลีน)

.Value ให้คุณเหมือนกับ. Value2 ยกเว้นว่าเซลล์ถูกจัดรูปแบบเป็นสกุลเงินหรือวันที่จะให้สกุลเงิน VBA (ซึ่งอาจตัดทอนทศนิยมตำแหน่ง) หรือวัน VBA

การใช้. Value หรือ. Text มักเป็นแนวคิดที่ไม่ดีเพราะคุณอาจไม่ได้รับคุณค่าที่แท้จริงจากเซลล์และจะช้ากว่า. Value2

สำหรับการสนทนาที่กว้างขวางยิ่งขึ้นดูข้อความของฉันกับค่าเทียบกับค่า 2


6
ฉันอาจจะใช้รูปแบบเพื่อควบคุมวิธีการแปลงจำนวนเป็นสตริง: var = รูปแบบ (ช่วง ("a1") ค่า 2, "#")
Charles Williams

2
ฉันหวังว่านี่ไม่ใช่คำถามแยกต่างหาก แต่: ค่าเริ่มต้นคืออะไร OP อ้างว่ามีการออกข้อความ / ค่า / ค่า 2 เป็นปัญหาอย่างชัดเจน แต่แน่นอนว่าเป็นค่าเริ่มต้นสำหรับหนึ่งในนั้น
มาร์ติน F

3
ขออภัยที่จะตื่นขึ้นโพสต์ oooooold นี้ แต่ผมไม่สามารถที่จะมองเห็นประโยชน์จากการบีบบังคับDateเป็นDouble(ใช้.Value2) Dateเมื่อสิ่งที่คุณต้องการเป็น ไม่ควร.Valueเป็นที่นิยมมากกว่า.Value2เมื่อคุณดูที่Dateค่าหรือไม่ บทความที่เชื่อมโยงไม่ได้ทำให้ชัดเจนเช่นกัน ประสิทธิภาพการทำงานเพราะไม่มีการแปลง? แน่นอน แต่ถ้ารหัส VBA ของคุณทำงานด้วย a Dateคุณจะสูญเสียการแปลงด้วยตนเองไม่ว่าจะโดยปริยายหรือโดยชัดแจ้ง ... (บริบท - รู้สึกปลอดน้ำหนัก)
Mathieu Guindon

2
@ Mat's Mug - ปัญหาคือ Excel ไม่มีประเภทข้อมูลวันที่จริง - วันที่และเวลาใน Excel เป็นเพียงสองเท่าที่ขึ้นอยู่กับรูปแบบใดก็ตามที่ผู้ใช้นำไปใช้หรือเปลี่ยนแปลงเพื่อให้ปรากฏเป็นวันที่เวลาหรือสกุลเงินหรือเพียง จำนวน. ดังนั้น Value กำลังบังคับใช้ Excel เป็นสองเท่าของวันที่ VBA แต่ Value2 ไม่ทำการข่มขู่ใด ๆ ... สำหรับวันที่การบังคับคู่กับวันที่อาจเป็นไปได้ที่จะไม่สร้างความเสียหายตราบใดที่โค้ดเข้าใจว่าขึ้นอยู่กับรูปแบบที่เปลี่ยนแปลงได้: pros และข้อเสียอย่างใดอย่างหนึ่ง - สิ่งที่เราต้องการจริงๆคือประเภทข้อมูล Excel ดั้งเดิมเพิ่มเติมเพื่อหลีกเลี่ยงปัญหานี้
ชาร์ลส์วิลเลียมส์

2
เมื่อฉันต้องการที่จะตั้งค่าในเซลล์เท่ากับเซลล์อื่นได้โดยไม่ต้องแปลงชนิด (เช่นโดยไม่ต้องแปลงหมายเลขที่เก็บไว้เป็นข้อความไปยังหมายเลข) Format$(Range.Value2, Range.NumberFormat)ฉันใช้นี้
ChrisB

55

ยกเว้นแบบฟอร์มคำตอบแรก Bathsheba ยกเว้นข้อมูล MSDN สำหรับ:

.Value
.Value2
.Text

คุณสามารถวิเคราะห์ตารางเหล่านี้เพื่อทำความเข้าใจความแตกต่างระหว่างคุณสมบัติที่วิเคราะห์ได้ดีขึ้น

ป้อนคำอธิบายรูปภาพที่นี่


4
@Chris ใช้.Valueเป็นคุณสมบัติมาตรฐานตลอดเวลาสำหรับข้อความและตัวเลข ใช้.Value2เมื่อคุณนึกถึงวันที่และตัวเลขบางตัว และใช้.Textเสมอหากคุณต้องการจัดรูปแบบของสิ่งที่คุณมีในเซลล์ / ช่วง ดังนั้นตัวอย่างคำถามของคุณถ้าถูกต้อง!
Kazimierz Jawor

1
ทำไมวันที่เปลี่ยนจาก 10:12 ถึง 10:05 typo?
Katrin

1
ฉันคิดว่ามันเป็นเวลาที่ผ่านไประหว่างการสร้างผลลัพธ์และเวลาในการทำสกรีนช็อต
Kazimierz Jawor

25

target.Valueจะให้Variantประเภทแก่คุณ

target.Value2จะให้Variantประเภทแก่คุณเช่นกัน แต่ a Dateถูกบังคับให้ aDouble

target.Textพยายามที่จะบีบบังคับให้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 คุณสมบัตินี้สามารถมีประเภทที่แตกต่างกันขึ้นอยู่กับเนื้อหาของเซลล์ สำหรับ serials วันที่แม้ว่าประเภทคือ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

หากคุณกำลังประมวลผลค่าของเซลล์ดังนั้นการอ่าน raw .Value2 แบบ raw นั้นจะเร็วกว่า. value หรือ. 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

ป้อนคำอธิบายรูปภาพที่นี่

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.