10
votes

Comment puis-je "Redim Conserver" un tableau 2D dans Excel 2007 VBA afin que je puisse ajouter des lignes, pas des colonnes, du tableau?

Je travaille avec un tableau dynamique dans Excel VBA. Le nombre de colonnes (m) est fixé, cependant, je ne sais pas combien de lignes (n) seront nécessaires.

Les documents d'aide indiquent que Redim Préserver MyARRAY (N, M) me permet de faire m plus grand, mais pas n. Cependant, je dois augmenter le nombre de lignes (n) tout en préservant mes données, pas de colonnes (m)!

Par exemple, je pourrais avoir un (5,20) matrice que je voudrais développer à (10,20) tout en préservant mes données.

Il semble que s'il y avait un moyen de transposer mon tableau, effectuez une préservation de Redim pour élargir le nombre de "colonnes", puis ré-transposez mon tableau, je pouvais accomplir ce que je veux.

est-ce la bonne façon de faire cela? Si oui, comment puis-je faire ça?

Y a-t-il un meilleur moyen d'accomplir ce que je veux?


0 commentaires

8 Réponses :


0
votes

aucun moyen de déterminer le nombre d'éléments dans la première dimension? Dommage. Pour une matrice bidimensionnelle avec une deuxième dimension fixe, vous voudrez peut-être envisager de le créer des types («Structs» dans d'autres langues). Cela vous permettra d'utiliser Regisim Preserve, et vous laisse toujours avec une manière raisonnable d'ajouter et d'accéder à des valeurs, bien que vous accédez maintenant à la deuxième dimension, car les membres nommés du type plutôt que sont des valeurs d'index.


0 commentaires

1
votes

a résolu ma propre question; Voici comment j'ai entendu mon problème. J'ai créé un tableau temporaire, copié le contenu de Myarray au tableau temporaire, a redimensionné myarray, puis copié le contenu du tableau temporaire à MyARRAY.

tempArray = myArray
ReDim myArray(1 To (UBound(myArray()) * 2), 1 To m)
For i = 1 To n
     For j = 1 To m
          myArray(i, j) = tempArray(i, j)
     Next j
Next i


1 commentaires

-1: Deux cycles imbriqués pour chaque refaire d'une matrice - pas une idée brillante du tout! Qu'est-ce qui va se passer si vous avez un tableau de 10 000 éléments?



12
votes

Une façon de faire ce que vous voulez, c'est utiliser un tableau 1-D contenant des tableaux 1-D au lieu d'un tableau 2-D. Ensuite, vous pouvez refaire la préservation de la matrice extérieure tout ce que vous voulez. Si vous retournez la matrice extérieure à partir d'une fonction, Excel fera la bonne chose et le contrariera à un tableau 2-D.

Par exemple, la fonction ci-dessous retourne un tableau 3x2 sur les cellules à partir de: xxx pré>

Ma réponse à ces questions peut également vous être utile: Passez une matrice multidimensionnelle dans Excel UDF dans VBA et VBA Coller une matrice 3 dimensionnelle dans une feuille P>

Bien sûr, si vous ne le retournez pas d'un UDF, vous devrez cérez-le vous-même. Un moyen facile de le faire sans écriture de code de boucle est de le faire: P>

Dim coerced
coerced = Application.Index(outer, 0, 0)


1 commentaires

Je n'ai pas fini par utiliser ou essayé cela parce que ma solution était assez bonne pour mes besoins de cette période. À première vue, cela ressemble à une façon plus élégante et efficace de faire ce que je voulais.



2
votes

Le mot "transpose" saute immédiatement à l'esprit. Vous pouvez simplement entrer des données dans la matrice 2D en retournant les colonnes et les lignes (c'est-à-dire transposez), vous permettant de créer efficacement N (maintenant le nombre de colonnes, mais de stocker des valeurs de ligne) plus grande lorsque vous avez besoin.

Pour référencer les valeurs, disons dans une double boucle, échangez les indices autour. Par exemple. Plutôt aller de i = 1 à n et j = 1 à m où votre valeur de référence (i, j), utilisez i = 1 à m et j = 1 à n.


0 commentaires

5
votes

Si vous êtes développeur - quelle est la différence entre les rangées et les colonnes? Utilisation du tableau (N, 2) (si vous avez 2 colonnes) est identique à la matrice (2, N) - pour laquelle vous pouvez

N = ubound(arr)
FOR i=1 to N
    GetColumn1Value = arr(i, 1)
    GetColumn2Value = arr(i, 2)
NEXT i


3 commentaires

Eh bien, la différence est que je pourrais avoir besoin de changer les deux dimentis. Ou je ne sais pas quelle dimension sera affectée.


@Ster, si vous utilisez le mot-clé conserve, vous pouvez redimensionner uniquement la dernière dimension de la matrice et vous ne pouvez pas modifier le nombre de dimensions du tout. msdn.microsoft.com/en-us/library/Office/gg251578. ASPX La règle est valable non seulement pour Office 2013 et plus tard, comme dans le lien ci-dessus, mais pour tout bureau à partir de 2003 (je n'ai pas d'expérience avec les versions plus anciennes).


Je suis pleinement conscient de cette limitation. Ce que je voulais dire, c'est que je ne peux pas simplement transposer le tableau à chaque fois ou être heureux avec possibilité de ne changer que la dernière taille de la dimension.



7
votes

Une manière dont vous pourriez vous sover, il est en effet par une double transposition avec une modification du nombre de colonnes entre les deux. Cela ne fonctionnera toutefois que pour les tableaux bidimensionnels. Il est fait comme suit: xxx

bien sûr m et n peut être déduit comme suit: xxx

Vous utilisez donc la fonctionnalité transposée intégrée d'Excel elle-même. Comme mentionné dans les commentaires du code, cela ne fonctionnera pas pour des matrices d'ordre supérieur.


2 commentaires

Merci. Je suis surpris à quelle vitesse c'est rapide. 0.08sek pour 16200 lignes * 14 colonnes = 226000 valeurs (2x transpose, 1x Redim)


Hmm, je reçois une erreur de décalage de type lorsque j'exécute la première ligne de code. Cela doit-il être exécuté sur une plage de feuille de calcul réelle plutôt qu'une variable de matrice de 2 dimensions?



0
votes

la forcer ou la trancher ne semble pas fonctionner avec l'index (ou la correspondance (index (lorsque je veux filtrer une matrice (W / O Loops) en fonction de plusieurs critères, lorsque la taille des données s'étend sur 2 ^ 16 rangées (~ 92000 rangées).

Run-Time error '13':

Type Mismatch


0 commentaires

0
votes

Un tableau avec 2 dimensions, où le nombre de colonnes est fixe et que le nombre de lignes est dynamique, peut être créé comme suit:

Sub my2DimArray()
Dim Arr2D() As String
Dim NumberOfCol As Long, NumberOfRow As Long
Dim FirstCol As Long, FirstRow As Long, LastCol As Long, LastRow As Long
Dim I As Long, J As Long, X As Long
Dim tmpValue As String, tmpValue2 As String, tmpValue3 As String

'if cells with values start in A1
With ActiveSheet.UsedRange
    NumberOfCol = .Columns.Count
    NumberOfRow = .Rows.Count
End With

'if cells with values starts elsewhere
With ActiveSheet.UsedRange
    FirstCol = .Column
    FirstRow = .Row
    LastCol = .Column + .Columns.Count - 1
    LastRow = .Row + .Rows.Count - 1
End With

J = 1

For I = 1 To NumberOfRow 'or For I = FirstRow to LastRow
tmpValue = Cells(I, 1).Value 'or tmpValue = Cells(I, FirstCol).Value
    If Len(tmpValue) > 0 Then
        ReDim Preserve Arr2D(NumberOfCol, 1 To J)
            For X = 1 To NumberOfCol 'or For X = FirstCol to LastCol
                Arr2D(X, J) = Cells(I, X).Value
            Next X
        J = J + 1
    End If
Next I

End Sub


0 commentaires