XL 2010 Problème (aléatoire ?) avec Range(Cells(a,b),Cells(c,d))

TooFatBoy

XLDnaute Barbatruc
Bonjour,

Dans différentes macros de différents classeurs, j'ai un problème d'utilisation de Range avec des Cells.
Parfois la macro se déroule sans problème. Mais parfois la même macro plante.

Dans la dernière macro en date qui me pose souci, je tente de faire une copie d'une suite horizontale de 31 cellules d'une feuille "A1" d'un classeur "A", vers une suite horizontale de 31 cellules d'une feuille "B1" d'un classeur "B".
Le but est de copier une ligne de planning, d'un classeur vers un autre classeur.

la ligne qui plante est la suivante :
shSource.Range(Cells(LigEnCoursSource, ColNomsSource + 1), Cells(LigEnCoursSource, ColNomsSource + 31)).Copy shDest.Range(Cells(LigEnCoursDest, ColNomsDest + 1), Cells(LigEnCoursDest, ColNomsDest + 31))

j'ai aussi tenté :
shSource.Range(shSource.Cells(LigEnCoursSource, ColNomsSource + 1), shSource.Cells(LigEnCoursSource, ColNomsSource + 31)).Copy shDest.Range(shDest.Cells(LigEnCoursDest, ColNomsDest + 1), shDest.Cells(LigEnCoursDest, ColNomsDest + 31))

L'idéal serait de pouvoir faire la copie sans sélectionner le classeur "A" puis sa feuille "A1" pour faire le copier, puis sélectionner le classeur "B" puis sa feuille "B1" pour faire le coller, car (si je ne me trompe) ça fait perdre beaucoup de temps même avec le ScreenUpdating mis à FALSE.

Remarque :
shDest (le sheet de destination) est initialisé avec un "Set" : Set shDest = ThisWorkbook.Sheets(MoisAImporter)
Même principe pour le sheet source.
 
Solution
re
oui ca semble correcte
bien que c'est du tricotage en metant 16 et 24 directement
tu peux concatener aussi
shSource.Range("F"& 10+NbLigSource).Resize(1, NbJoursDuMois).Copy shDest.Range("F"& 10+NbLigDest)

enfin tu a compris l'essentiel je crois

Staple1600

XLDnaute Barbatruc
Bonsoir le fil

Pour recopier, il suffit simplement de connaitre la 1ère cellule de la plage où se fera la copie
Voir cet exemple basique (sur un classeur avec 2 feuilles)
VB:
Sub test() 'macro purement illustrative
Dim LigneEnCours&, ACopier As Range
LigneEnCours = Cells(1).Row 'exemple
Set ACopier = ActiveSheet.Cells(LigneEnCours, "A").Resize(31)
ACopier.Copy Sheets(2).Cells(Rows.Count, 1).End(xlUp)(2)
End Sub
La logique reste la même si il s'agit de deux fichiers distincts
(mais ils doivent être ouverts)
Je te laisse faire les adaptations
 

TooFatBoy

XLDnaute Barbatruc
Merci pour ta réponse. :)

Pardon, mais je ne comprends pas très bien ta première phrase.

Quant à ta proposition, certes ça doit fonctionner, mais il y a une des deux feuilles qui est active.
Est-ce que ça peut aussi fonctionner si aucune des deux feuilles n'est active ?

Mes deux classeurs sont bien ouverts. ;)
 

Staple1600

XLDnaute Barbatruc
Re

Dans ton exemple, tu redimensiones la plage de recopie
(or ce n'est pas utile)
<il suffit d'indiquer uniquement la première cellule qui commence la plage
Exemple: tu veux copier A1:A31 de la feuille 1 en C1:C31 de la feuille 2
Donc il suffit de dire à Excel
Sheets(1).Range("A1:A31").Copy Sheets(2).Range("C1")
 

TooFatBoy

XLDnaute Barbatruc
Ah, OK. Je comprends mieux dit comme ça. ;)
Ca va déjà simplifier la ligne de commande. Merci.

Parfois la macro passe sans soucis et me recopie donc bien toutes les lignes de mon planning source vers mon planning de destination, mais parfois elle plante.
As-tu une idée de pourquoi ?
 

Staple1600

XLDnaute Barbatruc
Re

Est-ce que tu as essayé ma macro illustrative au moins?
(Il suffit d'un classeur vierge avec deux feuilles
Et sur la feuille 1, tu saisis A1 en A puis tu recopies vers le bas jusqu'en A40 par exemple puis tu lances la macro
Observes alors ce qui se trouvera sur la feuille 2.
;)
 

patricktoulon

XLDnaute Barbatruc
re
le plantage est du au parent non précise quand tu utilise cells dans la codification du range

sheets("toto").range(cells(1,2),cells(4,7)) ---> PAS BIEN!!!!!

with sheets("toto"):.range(.cells(1,2),.cells(4,7)) .....:end with ----> BIEN!!!!!

1 ere hypothèse

le "." dans le code designe que c'est un enfant du with toto
le code interprete donc cells(1,2) comme etant un object range

sans le point VBA interprète automatiquement cells(1,2) comme cells(1,2).value
et comme il n'y a pas de point c'est la valeur de cells(1,2) du sheets actif

donc !!
imaginons que tu ai deux feuilles (toto et titi )
tu est sur titi actif et que en cells(1,2) tu ai "coucou" et que en cells(4,7) tu est "Marcel32"
et bien cette ligne ci dessous
sheets("toto").range(cells(1,2),cells(4,7)) ---> PAS BIEN!!!!!

ET BIEN VBA L’INTERPRÈTE COMME
sheets("toto").range(Coucou,Marcel32) ---> PAS BIEN!!!!!

tu vois mieux le shmilblik la

2d hypothèse
tu est sur titi actif

et bien cette ligne ci dessous
sheets("toto").range(cells(1,2),cells(4,7)) ---> PAS BIEN!!!!!

ET BIEN VBA L'INTERPRÈTE COMME
sheets("toto").range(sheets("titi").cells(1,2),sheets("titi").cells(4,7)) ---> PAS BIEN!!!!!

il est difficile de déterminer quelle est la bonne car l'erreur est bloquante IMPOSSIBLE DONC DE VÉRIFIER CAR LES 2 LOGIQUES SONT BONNES ;)
 

TooFatBoy

XLDnaute Barbatruc
re
le plantage est du au parent non précise quand tu utilise cells dans la codification du range

sheets("toto").range(cells(1,2),cells(4,7)) ---> PAS BIEN!!!!!

with sheets("toto"):.range(.cells(1,2),.cells(4,7)) .....:end with ----> BIEN!!!!!
C'est un peu ce que j'avais supposé, d'où ma seconde forme pour ma ligne de commande (avec laquelle j'ai tout de même des plantages, me semble-t-il) où je précise la feuille d'appartenance de chaque Cells.
Et tu réponds ainsi de façon très claire à la question que je sous-entendais, et que je me posais depuis... des années !

Le reste de ton explication est une pure merveille ! Il faut que je garde ça sous le coude pour le relire e temps en temps.
Merci infiniment !!!

Dans mon problème posé ici, quand j'utilise Range(Cells(a,b),Cells(c,d)) mon but est en fait d'utiliser une zone (un range) dont un point est la cellule Cells(a,b) et le point opposé est la cellule Cells(c,d).
Autrement dit, si a=5, b=10, c=15, d=20, alors pour moi
Range(Cells(5,10),Cells(15,20))
devait être la même chose que
Range("J5:T15")

J'ai souvent été obligé d'ajouter le nom de la feuille devant les Cells dans mes Range, mais sans vraiment comprendre pourquoi... alors qu'en fait c'est plutôt logique (oui, je sais, c'est facile à dire une fois qu'on a une explication bien claire ;)).
Merci encore pour ta réponse !!! :cool:
 
Dernière édition:

TooFatBoy

XLDnaute Barbatruc
Re

Est-ce que tu as essayé ma macro illustrative au moins?
(Il suffit d'un classeur vierge avec deux feuilles
Et sur la feuille 1, tu saisis A1 en A puis tu recopies vers le bas jusqu'en A40 par exemple puis tu lances la macro
Observes alors ce qui se trouvera sur la feuille 2.
;)
J'ai regardé ta macro et il m'a fallu pas mal de temps pour comprendre ce qu'elle faisait...

Je dois pouvoir utiliser ton idée du Resize (de 29, ou 30, ou 31 pour les colonnes) et la cumuler avec un Offset pour copier la bonne ligne et un autre offset pour coller dans la bonne ligne.
En espérant que ça ne ralentisse pas la macro. ;)

Merci pour ton aide.
 

patricktoulon

XLDnaute Barbatruc
re
Autrement dit, si a=5, b=10, c=15, d=20, alors pour moi
Range(Cells(5,10),Cells(15,20))
devait être la même chose que
Range("J5:T15")

oui et non ;):p
ca dépend en fait ,ca n'est valable uniquement sur sheets actif
oui je sais ;)le fait que VBA soit permissif en terme de syntaxe provoque en même temps incompréhension

comme je disais
sheets actif titi
sheets(toto").Range(Cells(5,10),Cells(15,20))
PAS BON!!!!!!

Range(Cells(5,10),Cells(15,20)) oui sur sheets actif ça marche car vba attribut le même parent a "range" cells1,cells2
 

TooFatBoy

XLDnaute Barbatruc
Oui, quand je lis ce que tu écris, j'ai l'impression de comprendre.
Mais de là à ce que ça devienne une évidence et instinctif pour moi, il va falloir pas mal de temps je pense... ;)

Est-ce qu'il ne faudrait pas mettre .Address ou un .Value pour éviter tout litige ???
Dans mon cas ça donnerait ceci :
Sheets("Toto").Range(Cells(5,10).Address,Cells(15,20).Address)

Si c'est la feuille Titi qui est active,
Sheets("Toto").Range(Cells(5,10),Cells(15,20))
est-ce la même chose que
Sheets("Toto").Range(Sheets("Titi").Cells(5,10),Sheets("Titi").Cells(15,20))
ou encore
Sheets("Toto").Range(ActiveSheet.Cells(5,10),ActiveSheet.Cells(15,20))

Comme tu le vois, je ne pige pas encore très bien quand c'est l'adresse qui est utilisée et quand c'est le contenu de la cellule qui est utilisé... Désolé.
 
Dernière édition:

patricktoulon

XLDnaute Barbatruc
sheets("Toto").Range(Cells(5,10).address,Cells(15,20).address)
;) :p :p :p :p
et non !!!!
la encore on a un soucis de syntaxe

soit tu l'exprime en string soit en object range
j'explique
un range s'exprime de 4 facon courantes et la méthode resize

les methode primaires
EN STRING
Range("A1:C10")

en argument cells object range/cells
Range(cells(1,1),cells(10,3))


en string ET !!! argument cells (la colonne exprimée en string )
Range(cells(1,"A"),cells(10,"C"))

sous forme Abrégé de evaluate
[A1:C10]

avec resize
cells(1,1).resize(10,3)

mais TOUJOURS : si .parent devant l'un alors .parent a tout les object constituant la formulation




perso quand je formule un range avec cells je le fait dans un with
exemple
with sheets("toto"):set ma plage= .range(.cells(1,1),.cells(10,3)):end with

et encore!!! tout ca n'est valable que pour un range contiguë

pour ce qui est de
Si c'est la feuille Titi qui est active,
sheets("Toto").Range(Cells(5,10),Cells(15,20))
est-ce la même chose que
Sheets("Toto").Range(Sheets("Titi").Cells(5,10),Sheets("Titi").Cells(15,20))
ou encore
Sheets("Toto").Range(ActiveSheet.Cells(5,10),ActiveSheet.Cells(15,20))

oui c'est ca et ces 3 formulation ne sont pas bonnes
 
Dernière édition:

Discussions similaires

Réponses
8
Affichages
861

Statistiques des forums

Discussions
314 782
Messages
2 112 920
Membres
111 701
dernier inscrit
aelbachiri