web-dev-qa-db-fra.com

Écriture d'un tableau dans une plage. Obtenir uniquement la première valeur du tableau

J'essaie d'écrire un tableau dans une plage et j'ai essayé plusieurs façons, mais quoi qu'il arrive, je ne reçois toujours que la PREMIÈRE valeur du tableau.

Voici le code:

Option Explicit

Sub test()

    ActiveWorkbook.Worksheets("Sheet1").Cells.Clear

    Dim arrayData() As Variant
    arrayData = Array("A", "B", "C", "D", "E")

    Dim rngTarget As Range
    Set rngTarget = ActiveWorkbook.Worksheets("Sheet1").Range("A1")

    'this doesn't work
    rngTarget.Resize(UBound(arrayData, 1), 1).Value = arrayData

    Dim rngTarget2 As Range
    Set rngTarget2 = ActiveWorkbook.Worksheets("Sheet1").Range(Cells(1, 5), Cells(UBound(arrayData, 1), 5))
    'this doesn't work either
    rngTarget2.Value = arrayData

End Sub

Ce que je m'attends à voir, c'est:

(Col A)     (Col E)
A           A
B           B
C           C
D           D
E           E

Ce que je vois en fait, c'est:

(Col A)     (Col E)
A           A
A           A
A           A
A           A
A           A

Qu'est-ce que je fais mal ici?

J'ai essayé de suivre les suggestions de Chip Pearson, telles que trouvées ICI

Mais pas de chance ...

D'accord, donc en ajoutant dans la deuxième partie de ce problème:

J'ai un tableau 1D avec 8 061 éléments que je passe à la fonction suivante en tant que telle:

Call writeArrayData7(strTabName, arrayBucketData, 7)

Sub writeArrayData7(strSheetName As String, arrayData As Variant, intColToStart As Integer)

    Dim lngNextRow As Long
    lngNextRow = 1 ' hard-coded b/c in this instance we are just using row 1

    ' Select range for data
    Dim rngData As Range
    Set rngData = Sheets(strSheetName).Range(Cells(lngNextRow, intColToStart), Cells(lngNextRow - 1 + UBound(arrayData, 1), intColToStart))

    ' Save data to range
    Dim arrayDataTransposed As Variant
    arrayDataTransposed = Application.Transpose(arrayData)
    rngData = arrayDataTransposed

End Sub

Donc, lorsque je lance ceci, la fonction de transposition se convertit correctement en un:

Array(1 to 8061, 1 to 1)

La plage semble être une seule colonne avec 8 061 cellules dans la colonne G.

Mais j'obtiens l'erreur suivante:

Run-time error '1004':
Application-defined or object-defined error

L'erreur est lancée sur la ligne suivante:

rngData = arrayDataTransposed

--- MISE À JOUR ---

Donc, une chose que j'ai omise de mon exemple de code (b/c, honnêtement, je ne pensais pas que cela importait) était que le contenu de mon tableau était en fait des formules. Voici la ligne que j'utilise dans le code live réel:

arrayData(i) = "=IFERROR(VLOOKUP($D" + CStr(i) + "," + strSheetName + "!$D:$F,3,FALSE),"")"

Eh bien, ce que j'ai trouvé (avec l'aide d'Excel Hero), c'est que l'instruction ci-dessus n'avait pas les doubles ensembles de guillemets requis pour une chaîne, j'ai donc dû y changer à la place:

arrayBucketData(i) = "=IFERROR(VLOOKUP($D" + CStr(i) + "," + strSheetName + "!$D:$F,3,FALSE),"""")"

Je peux noter cela jusqu'au codage bonehead tard dans la nuit.

Cependant, une autre chose que j'ai apprise est que lorsque je suis retourné pour exécuter le code complet, il a fallu FOREVER pour coller le tableau dans la plage. Ce serait normalement une tâche très simple et se produirait rapidement, donc j'étais vraiment confus.

Après beaucoup de débogage, j'ai trouvé que le problème était dû au fait que je désactivais toutes les alertes/calculs/etc. et quand j'ai collé dans ces formules, la feuille strSheetName n'était pas encore là b/c I suis en train de développer ce code séparé du fichier principal. Apparemment, cela ouvre une boîte de dialogue lorsque vous collez le code, mais si vous avez tous ces éléments désactivés, vous ne pouvez pas le voir, mais cela ralentit VRAIMENT tout. Il faut environ 6 minutes pour coller la plage si ces onglets ne sont pas là, et s'ils existent, cela prend quelques secondes (peut-être moins). En tout cas, pour affiner un peu plus le code, j'ai simplement ajouté une fonction qui vérifie la feuille requise et si elle n'existe pas, elle ajoute l'onglet en tant qu'espace réservé afin que le processus entier ne ralentisse pas à une analyse.

Merci à tous pour leur aide! J'espère que cela aide quelqu'un d'autre sur la route.

8
gotmike

Faites ceci:

arrayData = Array("A", "B", "C", "D", "E")

[a1].Resize(UBound(arrayData)) = Application.Transpose(arrayData)

Le bit important est la fonction Transpose ().

Mais il est préférable de travailler avec des tableaux 2D dès le départ si vous prévoyez de les écrire dans la feuille de calcul. Tant que vous les définissez comme des lignes dans le premier rang et des colonnes dans le second, aucune transposition n'est requise.

23
Excel Hero

Cette:

Sub test()

    ActiveWorkbook.Worksheets("Sheet1").Cells.Clear

    Dim arrayData(1 To 5, 1 To 1) As Variant
    arrayData(1, 1) = "A"
    arrayData(2, 1) = "B"
    arrayData(3, 1) = "C"
    arrayData(4, 1) = "D"
    arrayData(5, 1) = "E"

    Dim rngTarget As Range
    Set rngTarget = ActiveWorkbook.Worksheets("Sheet1").Range("A1:A5")
    rngTarget = arrayData

End Sub

produira:

enter image description here

4
Gary's Student

Si je peux développer la réponse acceptée, je propose:

[a1].Resize(UBound(arrayData) - LBound(arrayData) + 1) = Application.Transpose(arrayData)

Ce serait le moyen sûr. Cela fonctionnera peu importe si vous déclarez votre variable de tableau comme:

Dim arrayData(0 to 2) 

ou

Dim arrayData(1 to 3) 

La réponse acceptée ne fonctionne que dans le deuxième cas.

La méthode proposée peut être utile si la taille du tableau est inconnue et que vous déclarez votre tableauData comme:

Dim arrayData()
0
Przemyslaw Remin