Qual è la differenza tra .text, .value e .value2?


180

Non sto chiedendo aiuto con alcun copione, ma la mia domanda è di chiarimento. Ultimamente ho fatto molti scripting VB in Excel, quindi mi riferisco davvero a Excel in questa domanda. Qual è la differenza tra .text, .value e .value2? Come quando dovrei usare target.text, target.value e target.value2? Non ho mai usato l'opzione value2 ma vorrei comunque sapere a cosa serve.

A volte se uso .text mi dà un errore e ho bisogno di usare .value quando sto solo controllando o manipolando il testo all'interno di una cella. Quindi a volte, quando penso che dovrei usare .value, ricevo un errore e devo usare .text. Di solito accetta o senza problemi, ma a volte fa la differenza. So che ci deve essere qualche logica in questo, ma non riesco a capirlo.

Ho anche scoperto che se lo lasci come target senza specificare .text o .value inizialmente funzionerà, ma poi qualcosa che qualcuno farà alla fine causerà un errore dello script, quindi è sempre meglio usare qualcosa. . Immagino che cosa sto chiedendo è se qualcuno può darmi una sorta di linea guida, regola empirica, su come usare correttamente ognuno e quando deve essere usato.

Grazie per la spiegazione ragazzi. Lo capisco meglio. Sono entrambe buone spiegazioni. Di seguito è riportato un piccolo esempio di alcuni dei miei codici che funzionano. Ho pensato che dovrebbe essere target.text, ma sarebbe un errore, quindi quando ho usato target.value ha funzionato.

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

Sono ancora un po 'confuso perché quando penso al valore o al valore2, specialmente dopo le risposte che hai fornito, penso che dovrebbero essere utilizzate solo per i numeri. Tuttavia, nel mio esempio sto parlando di solo testo, che è molto ciò a cui fa riferimento la mia sceneggiatura (testo nelle celle, più che numeri).


LCase (Target.Value) fallirà se Target.Value non è coercibile a una stringa poiché LCase richiede una stringa a un argomento. Dovresti controllare prima il VarType secondo la mia risposta. Nota anche che potresti usare UCase invece e confrontarlo direttamente con "HLO": non ha molto senso operare su un valore letterale.
Bathsheba,

Grazie per le informazioni su VarType. Per quanto riguarda LCase o UCase per questo, non importa davvero quale ho usato. Alcune persone lo digitano come hlo e altri lo digitano come HLO. Da quello che ho visto è apparso il caso minuscolo che veniva usato più spesso.
Chris,

Risposte:


238

.Textti dà una stringa che rappresenta ciò che viene visualizzato sullo schermo per la cella. Usare .Text è di solito una cattiva idea perché potresti ottenere ####

.Value2 ti dà il valore sottostante della cella (potrebbe essere vuoto, stringa, errore, numero (doppio) o booleano)

.Value ti dà lo stesso di .Value2 tranne se la cella è stata formattata come valuta o data ti dà una valuta VBA (che può troncare i decimali) o la data VBA.

Usare .Value o .Text è di solito una cattiva idea perché potresti non ottenere il valore reale dalla cella e sono più lenti di .Value2

Per una discussione più ampia, vedi il mio testo vs valore vs valore2


6
Probabilmente userei Format per controllare come il numero viene convertito in una stringa: var = Format (Range ("a1"). Value2, "#")
Charles Williams

2
Spero che questa non sia una domanda separata ma: qual è l'impostazione predefinita? L'OP afferma vagamente che tralasciare text / value / value2 è problematico, ma sicuramente per impostazione predefinita è uno di loro?
Martin F,

3
Mi dispiace svegliare questo post oooooold, ma non riesco a vedere il vantaggio di forzare a Datein Double(usando .Value2) quando ciò di cui hai bisogno è a Date. Non dovrebbe .Valueessere preferito rispetto a .Value2quando stai guardando un Datevalore? L'articolo collegato non lo rende neanche molto chiaro. Prestazioni perché nessuna conversione? Certo, ma se il tuo codice VBA funziona con un Date, allora perderai quel vantaggio eseguendo la conversione tu stesso, implicitamente o esplicitamente ... (contesto - sentiti libero di ponderare)
Mathieu Guindon

2
@ Mat's Mug - il problema è che Excel non ha un vero tipo di dati Date - le date e le ore di Excel sono solo doppie che dipendono dal formato che è stato applicato o modificato dall'utente per apparire come date, ore o valuta o solo un numero. Quindi Value sta costringendo un doppio di Excel a una data VBA ma Value2 non sta eseguendo alcun tipo di coercizione ... Per le date che coprono il doppio di una data probabilmente non sta causando alcun danno, a condizione che il codice capisca che dipende da un formato variabile: pro e contro in entrambi i casi - ciò di cui abbiamo veramente bisogno sono più tipi di dati Excel nativi per evitare questo problema.
Charles Williams,

2
Quando voglio impostare un valore di cella uguale ad un'altra cella senza conversione di tipo (per esempio, senza convertire un numero memorizzato come testo in un numero) Io uso questo: Format$(Range.Value2, Range.NumberFormat).
ChrisB,

55

Tranne il primo modulo di risposta Bathsheba, ad eccezione delle informazioni MSDN per:

.Value
.Value2
.Text

è possibile analizzare queste tabelle per una migliore comprensione delle differenze tra le proprietà analizzate.

inserisci qui la descrizione dell'immagine


4
@Chris, usa sempre .Valuecome proprietà standard- per testo e numeri. Utilizzare .Value2quando si pensa alla data e ad alcuni numeri. E usa .Textsempre se hai bisogno di mantenere la formattazione di qualsiasi cosa tu abbia nella cella / intervallo. Quindi, il tuo esempio di domanda se corretto!
Kazimierz Jawor,

1
perché la data è cambiata dalle 10:12 alle 10:05? errore di battitura?
Katrin,

1
Penso che sia trascorso solo il tempo tra la generazione dei risultati e il tempo di fare una schermata
Kazimierz Jawor,

25

target.Valueti darà un Varianttipo

target.Value2ti darà anche un Varianttipo ma a Dateè costretto a aDouble

target.Texttenta di forzare a Stringe fallirà se il sottostante Variantnon è coercibile a un Stringtipo

La cosa più sicura da fare è qualcosa di simile

Dim v As Variant
v = target.Value 'but if you don't want to handle date types use Value2

E controlla il tipo di variante usando VBA.VarType(v)prima di tentare una coercizione esplicita.


11

Per quanto riguarda le convenzioni in C #. Supponiamo che tu stia leggendo una cella che contiene una data, ad esempio 22-10-2014.

Quando si usa:

.Text, otterrai la rappresentazione formattata della data, come mostrato nella cartella di lavoro sullo schermo:
22-10-2014 . Il tipo di questa proprietà è sempre stringma potrebbe non restituire sempre un risultato soddisfacente.

.Value, il compilatore tenta di convertire la data in un DateTimeoggetto: {2014-10-22 00:00:00} Molto probabilmente utile solo durante la lettura delle date.

.Value2, ti dà il valore reale e sottostante della cella. Nel caso delle date, è una data seriale: 41934 . Questa proprietà può avere un tipo diverso a seconda del contenuto della cella. Per i serial di data, tuttavia, il tipo è double.

Quindi puoi recuperare e archiviare il valore di una cella in entrambi dynamic, varoppure objectnotare che il valore avrà sempre una sorta di tipo innato su cui dovrai agire.

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 è il valore visualizzato della cella formattata; .Value è il valore della cella eventualmente aumentato con gli indicatori di data o valuta; .Value2 è il valore sottostante grezzo rimosso da qualsiasi informazione estranea.

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

Se stai elaborando il valore della cella, leggere .Value2 non elaborato è leggermente più veloce di .Value o .Text. Se stai individuando errori, allora .Text restituirà qualcosa come #N/Atesto e può essere confrontato con una stringa mentre .Value e .Value2 si strozzeranno confrontando il loro valore restituito con una stringa. Se hai applicato una formattazione di cella personalizzata ai tuoi dati, allora .Text potrebbe essere la scelta migliore durante la creazione di un rapporto.


0

Per curiosità, volevo vedere come si Valueesibiva contro Value2. Dopo circa 12 prove su processi simili, non ho riscontrato differenze significative nella velocità, quindi consiglierei sempre di usarlo Value. Ho usato il codice seguente per eseguire alcuni test con vari intervalli.

Se qualcuno vede qualcosa di contrario per quanto riguarda le prestazioni, si prega di pubblicare.

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

inserisci qui la descrizione dell'immagine

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.