Je ne demande de l'aide pour aucun scénario, mais ma question concerne des éclaircissements. Dernièrement, je faisais beaucoup de VB scripts dans Excel. Je me réfère donc vraiment à Excel dans cette question. Quelle est la difference entre .text, .value et .value2? Comme quand devrais-je utiliser target.text, target.value et target.value2? Je n'ai jamais utilisé l'option value2, mais j'aimerais tout de même savoir à quoi elle sert.
Parfois, si j'utilise .text, cela me donne une erreur et je dois utiliser .value lorsque je ne fais que vérifier ou manipuler le texte dans une cellule. Parfois, lorsque je pense que je devrais utiliser .value, j'obtiens une erreur et je dois utiliser .text. Habituellement, il accepte l’un ou l’autre problème, mais parfois cela fait une différence. Je sais qu'il doit y avoir une certaine logique à cela, mais je n'arrive pas à comprendre.
J'ai aussi découvert que si vous le laissez simplement comme cible sans spécifier .text ou .value, cela fonctionnera initialement, mais ensuite, quelque chose que quelqu'un fera provoquera éventuellement une erreur du script, il est donc toujours préférable d'utiliser un .somlement dessus. . Je suppose que ce que je demande, c'est si quelqu'un peut me donner une sorte de ligne directrice, une règle de base, sur la manière d'utiliser correctement chacune d'entre elles et à quel moment.
Merci pour l'explication les gars. Je le comprends un peu mieux. Ce sont deux bonnes explications. Vous trouverez ci-dessous un petit exemple d'une partie de mon code qui fonctionne. Je pensais que cela devrait être target.text, mais cela provoquerait une erreur, donc lorsque j’utilisais target.value, cela fonctionnait.
If LCase(Target.Value) = LCase("HLO") And Target.Column = 15 Then
Target.Value = "Higher Level Outage"
End If
Je suis encore un peu confus parce que lorsque je pense à valeur ou valeur2, en particulier après vos réponses que vous avez fournies, je pense qu’elles ne devraient être utilisées que pour des nombres. Cependant, dans mon exemple, je parle strictement de texte, ce qui est en grande partie ce à quoi mon script fait référence (texte dans les cellules, davantage que les chiffres).
.Text
vous donne une chaîne représentant ce qui est affiché à l'écran pour la cellule. Utiliser .Text est généralement une mauvaise idée car vous pourriez obtenir ####
.Value2
vous donne la valeur sous-jacente de la cellule (vide, chaîne, erreur, nombre (double) ou booléen)
.Value
vous donne la même chose que .Value2, sauf que la cellule a été formatée en devise ou en date, elle vous donne une devise VBA (qui peut tronquer les décimales) ou une date VBA.
L'utilisation de .Value ou .Text est généralement une mauvaise idée car vous risquez de ne pas obtenir la valeur réelle de la cellule et ils sont plus lents que .Value2.
Pour une discussion plus approfondie, voir mon Texte vs Valeur vs Valeur2
target.Value
vous donnera un type Variant
target.Value2
vous donnera aussi un type Variant
mais un Date
sera forcé à un Double
target.Text
tente de contraindre un String
et échouera si le Variant
sous-jacent n'est pas contraint à un type String
La chose la plus sûre à faire est quelque chose comme
Dim v As Variant
v = target.Value 'but if you don't want to handle date types use Value2
Et vérifiez le type de la variante à l'aide de VBA.VarType(v)
avant de tenter une coercition explicite.
Concernant les conventions en C #. Supposons que vous lisiez une cellule contenant une date, par exemple. 2014-10-22.
En utilisant:
.Text
, vous obtiendrez la représentation formatée de la date, comme indiqué dans le classeur à l'écran:
2014-10-22. Le type de cette propriété est toujours string
mais ne donne pas toujours un résultat satisfaisant.
.Value
, le compilateur tente de convertir la date en un objet DateTime
: {2014-10-22 00:00:00} Très probablement utile uniquement lors de la lecture de dates.
.Value2
, vous donne la valeur réelle sous-jacente de la cellule. Dans le cas des dates, il s’agit d’une publication en série: 41934. Cette propriété peut avoir un type différent selon le contenu de la cellule. Pour les publications en série, cependant, le type est double
.
Ainsi, vous pouvez récupérer et stocker la valeur d'une cellule dans dynamic
, var
ou object
, mais notez que la valeur aura toujours une sorte de type inné sur lequel vous devrez agir. .
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 est la valeur affichée de la cellule mise en forme; .Valeur est la valeur de la cellule éventuellement complétée par des indicateurs de date ou de devise; .Value2 est la valeur sous-jacente brute débarrassée de toute information superflue.
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
Si vous traitez la valeur de la cellule, la lecture de la valeur brute .Value2 est légèrement plus rapide que .Value ou .Text. Si vous localisez des erreurs, alors .Text retournera quelque chose comme #N/A
sous forme de texte et peut être comparé à une chaîne, tandis que .Value et .Value2 s'étoufferont en comparant leur valeur renvoyée à une chaîne. Si un formatage de cellule personnalisé est appliqué à vos données, alors .Text peut être le meilleur choix lors de la création d'un rapport.
Par curiosité, je voulais voir comment Value
fonctionnait contre Value2
. Après environ 12 essais de processus similaires, je ne voyais aucune différence significative de vitesse, donc je recommanderais toujours d'utiliser Value
. J'ai utilisé le code ci-dessous pour exécuter des tests avec différentes gammes.
Si quelqu'un voit quelque chose de contraire à la performance, merci de poster.
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