Copier un tableau

Bonjour tout le monde,

Je suis en train d'apprendre à utiliser Excel VBA et je bloque sur un petit problème. Je ne pense pas que cela soit compliqué mais je n'ai rien trouvé ni sur Internet, ni sur le didactiel de ce site.

Je cherche à copier coller un tableau sans connaitre à l'avance son nombre de ligne et de colonnes.

A l'heure actuelle, mon code est le suivant :

Sub update()

Dim table(number_of_line, number_of_column)

For j = 0 To number_of_column

For i = 0 To number_of_line

table(i, j) = Sheets("BASE TOTAL").Range("A" & i + 2)

Next

Next

End Sub

number_of_column fait bien sur référence au nombre de colonne de mon tableau

de même pour number_of_line

Mon nouveau tableau que je cherche à remplir s'appelle table et l'ancien tableau que je veux copier coller est situé sur la page "BASE TOTAL".

En l'occurrence (mais sa va changer au cours du temps), il s'agit d'un tableau 16 x 55.

Le problème que je rencontre est qu'à chaque occurrence du j (je parcours les colonnes), je dois "incrémenter la lettre" du range. Par exemple, pour tout i, je dois avoir la lettre A pour j =0, la lettre B, pour j = 1 etc... non ? Comment faire dans ce cas ?

Merci beaucoup pour votre aide, je débute tout juste VBA mais ayant quelques connaissances (vite fait) en java et C, sa ne devrait pas être trop dur.

Bonjour et bienvenu

Si j'ai compris utilises Cells(Ligne,Colonne) à la place de Range

Ce qui pourrait donner

Sub update()
Dim table(number_of_line, number_of_column)
  For j = 0 To number_of_column
    For i = 0 To number_of_line
      table(i, j) = Sheets("BASE TOTAL").Cells(i + 2,[surligner=#FFFF80]j + 1)
    Next
  Next
End Sub

Bonjour et bienvenue sur le forum

Première remarque.

Il y a plusieurs façons de définir une plage de cellules.

Supposons que tu veuilles définir la plage de cellules qui va de la cellule B3 à la cellule D9.

Tu pourras la désigner au choix de 3 façons différentes :

Range(‘’B3:D9’’)

Range(cells(3, ‘’B ‘’),cells(9,’’D’’))

Range(cells(3,2),cells(9,4))

Dans ton cas, tu veux faire varier les lignes et les colonnes. Avec la méthode que tu as choisi pour parvenir à tes fins, tu n’as pas le choix. Il te faut utiliser la 3° façon.

Deuxième remarque

Tu veux copier un tableau, qui est supposons sur la Feuil1 et le coller ailleurs, supposons sur la Feuil2 au même endroit.

Copier les cellules une après l’autre n’est pas la solution la plus rapide mais elle est correcte.

Mais le nombre de colonnes importe peu. Il est plus important de connaitre les valeurs de la dernière ligne et de la dernière colonne. On suppose que les première ligne et colonne sont connues et fixes. Supposons que le tableau commence en A1.

On définit la dernière ligne avec l’instruction :

Last_Line = Range("A1").End(xlDown).Row

et la dernière colonne avec l’instruction :

Last_Column = Range("A1").End(xlToRight).Column

Maintenant, tu as tout pour faire ta boucle :

Sub Essai1()
    Last_Line = Range("A1").End(xlDown).Row
    Last_Column = Range("A1").End(xlToRight).Column
    For i = 1 To Last_Line
        For j = 1 To Last_Column
            Cells(i, j).Copy
            Sheets("Feuil2").Cells(i, j).PasteSpecial xlPasteValues
        Next j
    Next i
End Sub

Troisième remarque

Il serait plus judicieux et plus rapide pour la macro, dans ton cas, de copier l’ensemble de ton tableau et de le coller en une seule opération, sans boucle :

Sub essai2()
    Last_Line = Range("A1").End(xlDown).Row
    Last_Column = Range("A1").End(xlToRight).Column
    Range(Cells(1, 1), Cells(Last_Line, Last_Column)).Copy
    With Sheets("Feuil2")
        .Range(.Cells(1, 1), .Cells(Last_Line, Last_Column)).PasteSpecial xlPasteValues
    End With
End Sub

Bye !

Bonjour,

Avant toute chose, merci à tous les deux pour vos réponse.

Gmb, je n'ai pas tout saisi concernant tes remarques et j'aurais souhaité revenir sur 3 points.

Tu dis

Tu veux copier un tableau, qui est supposons sur la Feuil1 et le coller ailleurs, supposons sur la Feuil2 au même endroit.

En fait, je vais parcourir ce 1er tableau (Feuil1) plein de fois pour chercher des éléments particuliers et les coller dans un autre tableau qui existe déjà (Feuil3 par ex). Du coup, afin de réduire le temps de calcul, j'avais cru comprendre qu'il valait mieux copier coller ce tableau, mais sans avoir besoin de voir apparaitre sur une feuille particulière (Feuil2 si je suis tes notations) le nouveau tableau copier qui en pratique ne sert que d'intermédiaire pour les 2 autres tableaux existants. Du coup, est-ce quand même la bonne méthode que tu me proposes ?

Par ailleurs, tu dis

Il est plus important de connaitre les valeurs de la dernière ligne et de la dernière colonne

. Mais c'est la position de la dernière ligne et de la dernière colonne (ou de facon plus ou moins équivalente, le nombre de ligne et de colonne) qu'il est important de connaitre, non les valeurs de la dernière ligne et dernière colonne non ?

Enfin, concernant ta remarque, tu dis

Il serait plus judicieux et plus rapide pour la macro, dans ton cas, de copier l’ensemble de ton tableau et de le coller en une seule opération, sans boucle :

Je te crois sur parole mais je me demande, par curiosité, pk ce serait plus rapide sans boucle ? Car en pratique, il y a une boucle (voir même 2) mais qui sont faites implicitement avec la fonction Range(Cells(1, 1), Cells(Last_Line, Last_Column)) non ? Ce 3eme point, est le moins primordial en soi.

Merci pour tes réponses gmb

Bonjour

Tu écris dans ton premier message :

Je cherche à copier coller un tableau sans connaitre à l'avance son nombre de ligne et de colonnes.

Moi j’ai traduit cela en : je cherche à copier un tableau qui existe sur une feuille (Feuille que je suppose s’appeler ‘’Feuille 1’)’ et à le coller dans une autre feuille (que je suppose s’appeler Feuille 2)

Dans mon esprit et donc dans ma proposition, il n’y a pas de feuille intermédiaire.

Mais peut-être n’ai-je rien compris à ta demande.

Mais c'est la position de la dernière ligne et de la dernière colonne...qu'il est important de connaitre, non les valeurs de la dernière ligne et dernière colonne non ?

Là, je suis tout à fait d’accord avec toi, c’est ce que j’ai voulu dire en parlant de ‘’Valeur de la dernière ligne et de la dernière colonne. Désolé de m'être mal exprimé.

par curiosité, pk ce serait plus rapide sans boucle ?

La macro ne fait que faire, très vite, ce que tu ferais à la main beaucoup moins vite.

Alors, si tu dois copier un tableau à la main, comment vas-tu faire ? Deux solutions :

1 – Tu sélectionnes le tableau entier, tu le copies et le colles sur une autre feuille

2 – Tu sélectionnes une cellule du tableau, tu la copies et tu vas la coller sur autre feuille et tu recommences pour chacune des cellules du tableau.

A ton avis, quelle solution te permettra de finir le plus vite ?

On est bien d'accord concernant les 2 derniers points. Par contre pour le 1er point, je pense effectivement qu'il y a malentendu (j'ai du mal m'expliquer, excuse-moi). J'ai vu sur ce site (https://www.excel-pratique.com/fr/vba/tableaux_vba.php) qu'on gagnait beaucoup de temps en travaillant sur des tableaux "informels" plutôt que sur des sur tableaux excels.

Le but de mon travail est de créer un système qui actualise automatiquement une base de données. Du coup, je travaille sur 2 pages : une feuille ou il y a la base de données actuelle et une autre feuille ou on copie colle les données à mettre à jour. Je vais donc devoir considérer chaque ligne de ma feuille 2, comparer les chaines de caractères à la base de données et agir en conséquence (modification ou ajout) sur la base de données. En gros, sa fait beaucoup de boucle avec beaucoup de comparaison. C'est pour sa que je préférerais partir sur des tableaux "informels" afin de diminuer nettement le temps de calcul et donc je voudrais copier-coller la base de données (feuille 1) ainsi que les données à mettre à jour (feuille 2) pour améliorer le temps de calcul (mais en pratique, le rendu final est bien un tableau excel, je veux juste éviter de parcourir 5000 ligne d'un tableau excel pour faire 5 modif, autant utiliser directement un tableau informel).

Je ne sais pas si je suis clair, j'espère, sinon dis-moi ce qui manque de précision/clarté

Mais en conséquence, la solution que tu me proposais ne correspond pas...

Par ailleurs, je rencontre un autre problème (dois-je créer un nouveau post pour cela ?).

Il s'agit toujours du même projet. J'ai donc la base de données (tableau excel présent sur la 1ere feuille appelé BASE TOTAL) et un autre tableau excel (données à mettre à jour) sur la seconde feuille. Je crée donc 2 tableaux "informels" pour ces 2 tableaux (appelons les BASE et table).

Je m'intéresse aux colonnes y et z des tableaux table et BASE (respectivement). Je considère une cellule donnée de la colonne y et je compare sa valeur (chaine de caractères) aux valeurs (chaines de caractères) de toute les cellules de mon tableau BASE de la colonne z. Mon but étant de savoir si il y a des éléments égaux ou non pour déterminer s'il s'agit d'une modification ou d'un ajout (car le numéro client de la base de données ne change jamais, mais s'il s'agit d'un nouveau client alors son numéro n'existe pas).

Voila mon code (x : dernière ligne du tableau, ils commencent bien évidemment à 0 car ce sont des tableaux "informels", values représente une ligne donnée) :

Sub procedure(ByVal values As Integer)
Dim cel As Variant
Dim page As String

page = Sheets("Feuil2").cells(values, y).value

    Set cel = Worksheets("Feuil1").Range(cells(0, z), cells(x,z)).Find(what:="page", MatchCase:=False)

'Si pas de correspondance, nouveau client
If cel Is Nothing Then newclient

Else
oldclient

End If

End Sub

Mais malheureusement, cela ne marche pas et je ne sais pas pourquoi. Je n'arrive même pas à compiler d'ailleurs !!! Cela me dérange bc, je pense que c'est parce que j'utilise une procédure qui prend un argument en entrée (values) mais c'est la 1ere fois que j'utilise ce genre de procédure...

J'avais pensé à une autre solution en utilisant une boucle for (en j) et where + like, quelque chose dans le genre :

If "Worksheets("Feuil1").cells(j, z).value" Like "Worksheets("Feuil2").cells(values,y).value" Then oldclient

Else
newclient

End If

mais cela ne marche pas non plus et je crains que ce ne soit beaucoup plus long donc non intéressant.

Si tu peux encore m'aider sur ce problème, ce serait génial ! J'ai beau cherché sur internet, je n'arrive pas à trouver la solution. Merci d'avance pour tout conseil ou remarques

Bonjour

Essaie ce code :

Dim BDD, Table(), DerLn, DerCol, i, j

Sub Essai()

    Sheets("Destination").Cells(2, "B").CurrentRegion.Offset(1, 0).ClearContents
    With Sheets("BASE TOTAL")
        DerLn = .Range("A" & Rows.Count).End(xlUp).Row
        DerCol = .Cells(1, Columns.Count).End(xlToLeft).Column

        'On charge la variable tableau (Table)
        ReDim Table(DerLn - 1, DerCol)
        For i = 0 To DerLn - 2
            For j = 0 To DerCol
                Table(i, j) = .Cells(i + 2, j + 1).Value
            Next j
        Next i
    End With

    'On recopie sur la feuille 'Destination' à partir de la variable tableau
    With Sheets("Destination")
        For i = 0 To UBound(Table, 1)
            For j = 0 To UBound(Table, 2)

            'ici, on peut poser des conditions sur les cellules
            'de la Base, avant de les reporter sur la feuille
            'Destination

                .Cells(i + 2, j + 1).Value = Table(i, j)
            Next j
        Next i
    End With
End Sub

Bye !

Effectivement sa marche. En fait, ma méthode n'était vraiment pas loin de la tienne. La seul différence est que je calcule DerLn et DerCol dans une autre procédure en les déclarant global car je vais utiliser ces valeurs dans plusieurs procédures différentes.

Mais finalement, à l'aide de ton code et en bidouillant le mien, sa fonctionne finalement. Le pb était uniquement vis à vis de la page active vu que je travaille sur 2 feuilles excel.

Merci bc

Néanmoins, j'ai un petit souci. L'un des tableaux à copier comprend qq chose comme 700 lignes et 55 colonnes remplie de chaines de caractères et 65 000 lignes en plus (environ) qui ne contiennent pas de caractères mais une mise en page particulière (couleur) et donc ces lignes qui ne m'intéressent pas sont aussi copié dans mon tableau. Il faudrait donc modifier le code qui calcule DerLn pour que DerLn soit égal à 700 et non à 65 500. Comme sa, quand je rempli mon tableau, je ne m'intéresse plus aux lignes à partir de 701 !

Je vais voir si je peux trouver qq chose à ce sujet ! Mais si tu as une idée, je suis preneur

Merci bc en tout cas

Finalement, ta solution ne fonctionne pas si bien. C'est très étrange car à certains moment, la compilation marche très bien, je peux meme verifier que c'est bon avec des MsgBox par ex.

Et à d'autres moments (il suffit que je change le nom du tableau dans la procédure, ou que j'efface une ligne puis que je la recopie) sa bug totalement, pour les tableaux et sa me dit :

rreur 9: L'indice n'appartient pas à la selection

en surlignant sa :

ReDim base(number_of_line_in_the_database - 3, number_of_column_in_the_database - 1)

Il ne s'agit pas d'un problème de taille du tableau, j'en suis sur j'ai vérifié plusieurs fois les bornes !

Voila mon code à tout hasard :

Dim number_of_column As Integer
Dim number_of_line As Integer
Dim number_of_column_in_the_database As Integer
Dim number_of_line_in_the_database As Integer

'determine le nombre de colonnes et lignes des feuilles BASE TOTAL et Nuevos informaciones
Sub number()

'Number of lines and columns in the database
With Sheets("BASE TOTAL")
        number_of_line_in_the_database = .Range("A" & Rows.Count).End(xlUp).Row
        number_of_column_in_the_database = .cells(2, Columns.Count).End(xlToLeft).Column

End With

'Number of lines and columns in the sheet Nuevos informaciones
With Sheets("Nuevos informaciones")
        number_of_line = .Range("A" & Rows.Count).End(xlUp).Row
        number_of_column = .cells(2, Columns.Count).End(xlToLeft).Column

End With

'begin the updating'
creationtable
creationbase

End Sub

'procedure which copies the new sheet Nuevos informaciones in a tab, called table, so as to reduce the time of calcul
Sub creationtable()

Dim table()

ReDim table(number_of_line - 3, number_of_column - 1)
        For j = 0 To number_of_column - 1
            For i = 0 To number_of_line - 3
                table(i, j) = cells(i + 3, j + 1)
            Next i
        Next j

End Sub

'procedure which copies the sheet BASE TOTAL in a tab, called base, so as to reduce the time of calcul
Sub creationbase()

Dim base()

ReDim base(number_of_line_in_the_database - 3, number_of_column_in_the_database - 1)
        For j = 0 To number_of_column_in_the_database - 1
            For i = 0 To number_of_line_in_the_database - 3
                base(i, j) = cells(i + 3, j + 1)
            Next i
        Next j

End Sub

Je ne comprend pas pk j'ai erreur 9 qui apparait de temps en temps sans raison...

Bonjour

Tu écris :

Je ne comprend pas pk j'ai erreur 9 qui apparait de temps en temps sans raison...

Je suis désolé mais sans fichier, je ne peux pas t'aider.

Bye !

Qu'appelle tu fichier ? L'ensemble du code, les données excel ou les 2 ?

Il parle de ton fichier Excel avec données j'en suis convaincue!

Les données étant confidentiel, j'ai recrée de fausses données excel. Mais du coup, j'ai fait des tableaux très petit (2 lignes et 55 colonnes pour la 1ere feuille, 1 ligne et 55 colonnes pour la 2nd feuille).

j'espère que sa ira ! Besoin du code en entier ou pas ?


Prenez plutôt ce fichier là ! Il y a les données et le code en VBA !

edit : fichier supprimé

Bonjour à tous

Bonjour Barthe

bonjour Saniafe

@Barthe

Tu écris :

Qu'appelle tu fichier ? L'ensemble du code, les données excel ou les 2 ?

Un fichier est un classeur ; il comprend les feuilles de calcul et si il y en a, les macros VBA

Les documents joints à ton dernier message ont l'air d'être ce que je souhaite.

Je regarderai cela demain.

A bientôt.

Bonjour gmb,

c'est bien ce que je pensais.

Super ! Merci pour ton aide

Depuis le début du post, en parcourant des forums et avec l'aide d'autres personnes j'ai réussi à améliorer mon code (je te met ici la version finale, ayant fait qq modifs depuis ce matin). Globalement, tout tourne assez bien, notamment le remplissage des tableaux (pb initial) se fait bien.

Le seul souci est que ponctuellement, une erreur 9 "Sub ou fonction non définie" empêche la compilation du programme. Cette erreur surligne toujours en jaune un ReDilm !

J'espère que tu trouveras le pb car coder un code qui ne marche que ponctuellement, c'est pas génial :p

Bon week-end sinon

edit : fichier supprimé

Bonjour

Tu écris :

J'espère que tu trouveras le pb car coder un code qui ne marche que ponctuellement, c'est pas génial :p

Je suis désolé mais je ne trouve pas.

Bye !

Ce n'est pas grave, merci énormément pour ton aide ! Merci aussi aux autres m'ayant aidé par ailleurs

Pour le moment sa compile donc je ne vais pas me plaindre !

Merci à tout le monde pour votre aide

Rechercher des sujets similaires à "copier tableau"