Je sais que vous pouvez facilement prendre une plage de cellules et les insérer dans un tableau de variants, mais je souhaite travailler avec un tableau de chaînes (car il s'agit d'un tableau à une dimension et utilise moins de mémoire qu'un tableau de variants).
Est-il possible de convertir automatiquement une plage en tableau de chaînes?
En ce moment, j'utilise une fonction qui prend la plage et enregistre les valeurs dans un tableau variant, puis convertit le tableau variant en tableau de chaînes. Cela fonctionne bien, mais je cherche un moyen de passer directement de la plage au tableau de chaînes. Toute aide serait grandement appréciée.
Function RangeToArray(ByVal my_range As Range) As String()
Dim vArray As Variant
Dim sArray() As String
Dim i As Long
vArray = my_range.Value
ReDim sArray(1 To UBound(vArray))
For i = 1 To UBound(vArray)
sArray(i) = vArray(i, 1)
Next
RangeToArray = sArray()
End Function
UPDATE: On dirait qu'il n'y a aucun moyen de sauter l'étape consistant à jeter les données dans un tableau variable avant de le convertir en tableau de chaînes à une dimension. Une honte si c'est vrai (même si cela ne prend pas beaucoup d'effort, j'aime ultra-optimiser alors j'espérais qu'il y avait un moyen de sauter cette étape). Je vais fermer la question dans quelques jours si aucune solution ne se présente. Merci pour les commentaires utiles, les gars!
UPDATE2: La réponse va à Simon qui a fait de gros efforts (tout le monde l’a fait) et qui a tout à fait souligné qu’il était en effet impossible de passer d’un rang à l’autre. Merci tout le monde.
Que diriez-vous...
Public Function RangeToStringArray(theRange As Excel.Range) As String()
' Get values into a variant array
Dim variantValues As Variant
variantValues = theRange.Value
' Set up a string array for them
Dim stringValues() As String
ReDim stringValues(1 To UBound(variantValues, 1), 1 To UBound(variantValues, 2))
' Put them in there!
Dim columnCounter As Long, rowCounter As Long
For rowCounter = UBound(variantValues, 1) To 1 Step -1
For columnCounter = UBound(variantValues, 2) To 1 Step -1
stringValues(rowCounter, columnCounter) = CStr(variantValues(rowCounter, columnCounter))
Next columnCounter
Next rowCounter
' Return the string array
RangeToStringArray = stringValues
End Function
En fait, vous pouvez aller directement d'une plage à un tableau en utilisant les fonctions Split, Join et un délimiteur ne figurant pas dans le texte.
En supposant que vous ayez déjà attribué une plage de valeurs 1D en tant que SrcRange
Dim Array() As String: Array = Split(Join(Application.Transpose(SrcRange), "#"), "#")
Function RangeToStringArray(myRange as range) as String()
ReDim strArray(myRange.Cells.Count - 1) As String
Dim idx As Long
Dim c As Range
For Each c In myRange
strArray(idx) = c.Text
idx = idx + 1
Next c
RangeToStringArray = strArray
End Function
Si cela ne vous dérange pas de modifier le contenu du presse-papiers, alors:
COPIER la plage dans le presse-papiers avec la méthode Copy:
MyTargetRange.Copy
Copiez le contenu du presse-papiers dans une variable chaîne (recherchez sur ce site ou ailleurs des fonctions permettant de transférer des chaînes vers/depuis le presse-papiers).
SPLIT la chaîne dans un tableau variant:
MyStringArray = Split(MyClipboardText, vbCrLf)
FACULTATIF: le tableau comportera un élément vide supplémentaire car il y aura toujours un retour supplémentaire (vbCrLf) à la fin du texte que vous venez de copier dans le Presse-papiers. Pour supprimer simplement redimensionner le tableau:
Redim Preserve MyStringArray(Ubound(MyStringArray) - 1)
Très simple et rapide !!!
Les inconvénients sont que le Presse-papiers peut changer lorsque vous vous y attendez le moins (lors d'un nouveau calcul) et qu'il ne produit que des tableaux de chaînes (pas de Doubles ni d'autres types de valeurs numériques).
Cela serait extrêmement utile si vous travaillez avec beaucoup de fonctions répétitives (des milliers) qui utilisent les mêmes données (des milliers de points de données). La première fois que votre fonction est appelée, effectuez tous les calculs intermédiaires sur les plages de données dont vous avez besoin, mais enregistrez les résultats dans des variables statiques. Enregistrez également une copie de chaîne de vos plages d’entrée via le presse-papiers. À chaque appel suivant de votre fonction, convertissez les plages de saisie en texte, à nouveau via le Presse-papiers, et comparez-les avec la copie enregistrée. S'ils sont identiques, vous pourrez peut-être éviter des calculs préliminaires.
Les plages nommées utilisées dans VBA sont déjà des tableaux. Alors commencez par créer une plage nommée, puis faites référence à cette plage et supprimez-la. Par exemple:
ThisWorkbook.Names.Add Name:="test_array", RefersTo:=Sheet1.Range("A4:B10")
a = Sheet1.Range("test_array")
ThisWorkbook.Names("test_array").Delete