0
votes

Excel transpose array de 2D - problème de mémoire

J'ai une macro VBA, où je souhaite écrire un tableau à une feuille Excel. Je reçois une erreur d'exécution "hors mémoire" sur certaines machines. Je peux le courir facilement sur mon PC de développement, mais mon client a des problèmes avec cela.

Ici, je définis mes valeurs matrices fortre> tableau: p>

Public Function TransP(var As Variant) As Variant
    Dim outP() As Variant, i As Long, j As Long
    ReDim outP(LBound(var, 2) To UBound(var, 2), LBound(var, 1) To UBound(var, 1))
    For i = LBound(outP) To UBound(outP)
      For j = LBound(var) To UBound(var)
        outP(i, j) = var(j, i)
      Next
    Next
    TransP = outP
End Function


5 commentaires

Vérification juste: votre client n'utilise pas MS Excel 2003?


Notez, ils utilisent Excel 2013 et UP.


Qu'est-ce que idxua ?


@TOM Désolé pour cela, j'ai effectivement effectué des petites corrections au code lorsque je l'ai posté, et je renommé Idxua à IDX ici sur Stackoverflow. Je n'ai pas remarqué que je ne l'ai pas changé dans tous les endroits. J'ai corrigé l'exemple de code maintenant.


@LAURANT C'est bon - je me demandais simplement si idxua pourrait être 0 qui pourrait provoquer une erreur. J'essaierais également d'éviter d'utiliser des valeurs sous forme de nom de variable - il est très proche de la syntaxe réelle et pourrait entraîner des erreurs erronées erronées.


4 Réponses :


0
votes

Je ne pense pas que ce soit la fonction Transp, car cela gère déjà tout dans une boucle. J'ai vécu le même genre de problème et cette erreur s'est produite lorsque j'ai essayé de transférer un grand réseau multidimensionnel sur une plage.

Ma solution consistait à créer une boucle et à faire environ 1000 lignes à chaque fois, mais cela dépend des clients PC, je suppose avec combien de rangées que vous pouvez faire.

prise en compte que var ne se termine pas sur une certaine taille, vous pouvez faire une boucle tandis que: xxx

dans Transp vous utilisez maintenant le bloc inférieur et supérieur de var , mais si vous ajoutez deux variables de la boucle, vous pouvez les utiliser pour seulement prendre un morceau de la matrice.


4 commentaires

Cela semble être un bon candidat ... Comment puis-je diviser le grand tableau en plus petits, sans passer les éléments et les copier un par-un?


J'ai changé la réponse pour inclure une façon de le faire, car c'était trop désordonné dans un commentaire.


Comment réécrireais-je la fonction Transp pour accepter les deux paramètres supplémentaires?


Vous créez le tableau OUTP basé sur le bloc d'accueil inférieur et supérieur de var . Vous pouvez plutôt utiliser les valeurs de i et max de la fonction principale.



0
votes

Je suppose que cela pourrait vous être dû ne pas spécifier la dimension dans votre fonction transp . Vous définissez également vos boucles avec les deux tableaux. Vous les avez dimensionnés de manière identique (bien que les dimensions commutées) - utilisez simplement le même pour définir votre pour boucle xxx


0 commentaires

1
votes

Votre méthode d'APPENDANT Éléments à Valeurs est inefficace car chaque fois qu'un élément est ajouté, un nouveau tableau est créé et les valeurs de l'existant copiées. Pendant ce temps deux fois, la mémoire est utilisée, et si un grand tableau est copié de cette manière, plusieurs fois de succession rapide, seul le ciel peut savoir quelles demandes sont placées sur la gestion du RAM.

La meilleure façon est de dimensionner la matrice plus grande que nécessaire (une fois), comptez le nombre d'éléments écrites et utiliser Redim Conserve pour réduire sa taille (une fois) lorsque vous avez terminé. .


9 commentaires

Le problème avec c'est que, au début, je n'ai aucune idée de la taille de la matrice.


Vous serez sûrement en mesure d'estimer 100 000 ou 1 million. Si même ce n'est pas possible, envisagez d'élargir le tableau qu'après que le million a été atteint, d'un million, etc. Comparez cet effort avec celui de copier un million d'éléments un million de fois. Un élément vierge prend très peu de mémoire.


Just redim Le tableau au nombre de lignes Vous avez dans votre pour en boucle et utilisez un compteur pour la position de la matrice. Ensuite, après le pour boucle Redim Conserve Le tableau à la valeur de votre compteur


@Tom Il y a une hiérarchie d'objet complexe, donc il n'y a pas qu'un seul pour la boucle. Il y en a plusieurs. Je voulais juste avoir les exemples de code aussi basiques que possible. C'est pourquoi je ne peux pas spécifier le nombre exact (ou même une estimation) du nombre de lignes que je vais avoir.


@Variatus et qu'est-ce qui se passerait si j'estime 1 million? Cela ne causerait-il pas la même erreur de mémoire si je redimensions à 1 million de lignes?


@LAURANT - Eh bien, alors vous connaissez vos critères de boucle. Ajoutez le max de chacun ensemble avant de commencer. En termes de taille maximale d'un tableau, jetez un coup d'œil à cette réponse Lien


@LAURANT S'il vous plaît n'oubliez pas le problème: votre tableau a atteint 1000 éléments. Pour ajouter un élément, vous créez un nouveau tableau avec 1001 éléments. Maintenant, vous copiez 1000 éléments de l'ancien vers le nouveau. Lorsque cela est fait, l'espace RAM de l'ancien tableau doit être libéré. Mais que se passe-t-il si un troisième tableau est créé avant que la copie du premier ait fini? Nous ne savons pas si c'est ce qui se passe mais si cela semble acrobatique. Le point est la création de nouveaux tableaux de succession rapide. Cela ne se produirait pas si l'expansion ne prend que tous les éléments de 1mn.


Merci pour les commentaires Guys, cela pourrait être une bonne option d'inclure dans la mise à jour du code, mais ce n'est pas la raison pour laquelle le code échoue.i mentionné dans mon message d'origine, que le code échoue à la partie où la gamme Excel est remplie. avec les données. Il pourrait également être que la fonction Transp provoque le problème. Pensez-vous que cela pourrait échouer, car toute la redimension est toujours verrouillée dans la mémoire?


C'est la présomption sur laquelle j'ai construit ma réponse.



2
votes

Vous pouvez également créer une boucle pour écrire votre rangée de la rangée de sortie par ligne, elle prendra plus de temps, mais vous ne serez probablement pas en sortie d'erreur de mémoire.

Dans le passé quand je suis sorti de Problèmes de mémoire avec des tableaux J'ai juste essayé d'effectuer des actions à l'aide de commandes Excel régulières, dans ce cas, vous pouvez simplement copier la plage et la pâte de valeurs transposées: p>

.PasteSpecial Paste:=xlPasteValues, Transpose:=True


0 commentaires