ERREUR dans copy

Bonjour,

Je bute sur un problème simple depuis 01H30.

Le problème ?

je veux copier une partie du contenu d'un fichier, soit une feuille de classeur, vers un autre fichier dans le même chemin d'accès ou même dossier.

Soution ? J'utilise "copy".

Workbooks("C:\Users\Folder1\Folder2\file1.xlsx").Worksheets("32").copy Workbooks("C:\Users\Folder1\Folder2\file2.xlsx").Worksheets("Feuil1")

J'ai volontairement changé Users, Folder1 et Folder2.

Les chemins d'accès absolus et fichiers source et destination sont bien déclarés car sans erreur. Je ne comprends pas...

Excel me dit ceci :

Erreur d'exécution 9:

L'indice n'appartient à la sélection.

Tout donnée déclarée est juste pourtant.

Bonsoir

macro a tester

Sub CopierFeuille()
    Dim wbSource As Workbook
    Dim wbDest As Workbook
    Dim wsSource As Worksheet
    Dim wsDest As Worksheet

    ' Ouvrir les fichiers
    Set wbSource = Workbooks.Open("C:\Users\Folder1\Folder2\file1.xlsx")
    Set wbDest = Workbooks.Open("C:\Users\Folder1\Folder2\file2.xlsx")

    ' Référencer les feuilles
    Set wsSource = wbSource.Worksheets("32")
    Set wsDest = wbDest.Worksheets("Feuil1")

    ' Copier la feuille entière dans le classeur de destination
    wsSource.Copy After:=wbDest.Worksheets(wbDest.Worksheets.Count)

    ' Ou pour copier des valeurs d'une plage spécifique
    ' wsSource.Range("A1:B10").Copy
    ' wsDest.Range("A1").PasteSpecial Paste:=xlPasteValues

    ' Fermer les fichiers si nécessaire
    ' wbSource.Close SaveChanges:=False
    ' wbDest.Close SaveChanges:=True
End Sub

Bonjour, Joco,

Votre solution marche. Merci. Il y aurait 2 solutions fonctionnant. La vôtre et la mienne.

A présent, j'essai de supprimer toute feuille de classeur n'étant pas conforme à une consigne de sélection donnée. Voici un petit bout de code :

    FileCopy pathIF1, pathOF
    Workbooks.Open pathOF
    NbSheets = Workbooks(Outputfilename).Sheets.Count
    For u = 1 To NbSheets
        If Workbooks(Outputfilename).Sheets(u).Name <> Outputsheetname Then
            Workbooks(Outputfilename).Sheets(u).Delete
        End If
    Next

Ici, c'est ma solution mais j'aurais pu prendre la vôtre. C'est pareil.

Ce que je veux faire ? supprimer toute feuille différente de la valeur contenue dans Outputsheetname, une variable de type integer pour l'instant, pour ne conserver qu'une feuille.

Problème ? Toujours la même chose.

Erreur d'exécution 9:

L'indice n'appartient à la sélection.

Pourtant les données saisies sont justes et le fichier ouvert.

Bonjour

A tester

FileCopy pathIF1, pathOF
Workbooks.Open pathOF
NbSheets = Workbooks(Outputfilename).Sheets.Count

For u = NbSheets To 1 Step -1
    If Workbooks(Outputfilename).Sheets(u).Name <> Outputsheetname Then
        Workbooks(Outputfilename).Sheets(u).Delete
    End If
Next u

Bonjour à tous,

Juste pour "expliquer" le correctif de Joco :

Quand vous itérez sur les feuilles de la première (1) à la dernière (disons 10). Votre "u" va prendre les valeurs, dans l'ordre : [1, 2, 3, 4, 5, 6, 7, 8, 9, 10].

Maintenant, si vous supprimez la feuille 2 par exemple, il n'y a plus que 9 feuilles dans le classeur. Donc quand votre u arrive à 10, il vous lève l'erreur (logique) : "l'indice n'appartient pas à la sélection" : en effet il n'y a plus de feuille numéro 10. Et plus vous supprimez de feuilles "avant la fin" et plus le problème sera levé plus tôt. C'est parce que NbSheets n'est pas réévalué à chaque boucle.

Une solution courante pour contourner ce problème est celle que vous a donné Joco : itérer depuis la fin vers le début, ainsi votre u va faire [10, 9, 8, 7… 1].

Et là, si vous supprimez la feuille numéro 9 par exemple, et bien ça ne pose plus de problème car la suivante sera toujours la 8 (c'est la 10, que vous avez déjà checké, qui sera décalée en position 9).

Voilà, en espérant que ce long laïus vous aidera à y voir plus clair.


PS : pour supprimer les feuilles sans avoir le MsgBox d'alerte il faut utiliser Application.DisplayAlerts=False [code de suppression] Application.DisplayAlerts=True.

Messieurs,

J'ai déjà vu ça par le passé. Préférer le parcours d'une boucle comme suit :

For u = NbSheets To 1 Step -1

plutôt que :

For u = 1 To NbSheets

ne garantit pas d'obtenir le même résultat. Vous avez bien raison.

Je n'ai jamais cherché à comprendre pourquoi car cela me paraissait absurde.

Mathématiquement, le résultat à obtenir est identique.

Intuitivement, parcourir un intervalle dans un sens ou dans un autre revient à avoir connaissance de lui-même.

Ex : je dispose d'une fonction intégrable sur [a,b], avec a<b. Selon que l'on inverse les bornes d'intégration de notre intégrale, le résultat obtenu est le même.

image

g(b)−g(a) = - (g(a)−g(b)) avec la g la primitive.

Je vais méditer tout cela... Merci de votre aide.

N'hésiter pas à argumenter encore...

Oui bien entendu, avec un certain niveau d'abstraction on peut dire que c'est équivalent. Mais c'est dans la pratique, dans l'implémentation, que tout bascule. Puisque Excel exécute les instructions "au fur et à mesure", ce raisonnement ne tient pas. Comme je le disais, la suppression des feuilles "à la volée" (càd dans la boucle de recherche) casse la théorie en modifiant les indices de feuilles durant l'éxécution. C'est un cas d'école quand on apprend à programmer.

Voici ci-après une implémentation plus "mathématique" en deux étapes : d'abord un parcours des feuilles, et sauvegarde des pointeurs (on n'utilise pas les indices car sinon le problème reste entier) vers les feuilles à supprimer dans une liste. Puis une deuxième boucle sur cette liste de pointeurs (càd les objets worksheet) pour les supprimer.

Public Sub Exemple()
  ' creation de la liste des feuilles a supprimer
  Dim feuillesASuppr As Collection: Set feuillesASuppr = New Collection

  Dim ws As Worksheet
  For Each ws In ThisWorkbook.Worksheets
    ' pour l'exemple, on supprime les feuilles dont le nom contient "SupprimeMoi"
    If ws.Name Like "*SupprimeMoi*" Then
      ' ajout de la feuille (ws) dans la liste
      feuillesASuppr.Add ws
    End If
  Next ws

  Application.DisplayAlerts = False
  Application.ScreenUpdating = False
  ' parcours de la liste et suppression des feuilles retenues
  For Each ws In feuillesASuppr
    ws.Delete
  Next ws

  Application.DisplayAlerts = True
  Application.ScreenUpdating = True
End Sub

Comme vous pouvez le constater cette implémentation est invariante par permutation : qu'importe l'ordre des feuilles (qui n'est meme plus spécifié avec For Each), le résultat sera le meme.

Il faut bien faire attention à la traduction d'un modèle théorique à la pratique : il y a souvent soit des étapes à ajouter, soit des conditions à respecter pour éviter les "pièges".

Je comprends maintenant. C'est bon pour moi. On a dû aborder ce point par le passé mais je ne m'en souviens plus trop.

Le problème c'est que j'ai parfois du mal à sortir de l'ancrage de la théorie comme si c'était quelque chose d'immuable, comme si la réalité matérielle ou physique de ce qui existe devait obéir aux modèles ou abstractions. Cela est vrai dans certaines conditions comme vous le rappeliez.

Ça viendra avec la pratique, ce sont des automatismes.

Bonne journée et au plaisir de pouvoir vous aider.

Bon courage dans votre travail...

Rechercher des sujets similaires à "erreur copy"