Problème RANGE(cells(),cells())

Fermé
iadi06 Messages postés 21 Date d'inscription mercredi 20 février 2019 Statut Membre Dernière intervention 27 août 2022 - 20 févr. 2019 à 11:46
iadi06 Messages postés 21 Date d'inscription mercredi 20 février 2019 Statut Membre Dernière intervention 27 août 2022 - 2 mars 2019 à 10:25
Bonjour,

je suis novice dans la programmation VB / VBA. Et je rencontre des difficulté dans l'utilisation des range(cells(),cells()) qui fonctionne dans des cas et pas dans d'autres.

Voici ce que j'aimerais faire : copier une cellule d'une feuille dans une plage d'une autre feuille.

Voici le code qui bloque au premier range en gras :

Sub SequenceHorizontal()

Dim NbCol As Integer
Dim NbTache As Integer
Dim NbLigne As Integer
Dim NbCopy As Byte 'égale à la durée de la tâche
Dim DebutTache As Byte 'égale au jour (relatif à la séquence) de début de la tâche
Dim i As Byte 'variable pour boucle for
Dim EmptyCase As Byte 'variable qui sert à localiser la ligne vide pour pouvoir y copier la suite de la séquence

'Initialisation des tâches
NbLigne = 4
NbTache = 0
EmptyCase = 3
NbCopy = 1
NbCol = DebutTache + NbCopy

Application.ScreenUpdating = False 'Désactive la mise à jour écran qui permet d'optimiser la vitesse d'exécution du code
Sheets("SeqVert").Select

'Compte le nombre de tâche dans la séquence
Do
Cells(NbLigne, 3).Select
NbLigne = NbLigne + 1
NbTache = NbTache + 1

Loop Until IsEmpty(ActiveCell) 'Application.ActiveCell.CountBlank = 1

Cells(13, 1).Value = NbLigne
Cells(14, 1).Value = NbTache

'Copie la séquence en mode horizontal dans la feuille Séquence horizontale
For i = 4 To NbTache
Sheets("SeqVert").Select
NbCopy = Cells(i, 5).Value
DebutTache = Cells(i, 6).Value
EmptyCase = 3 'Réinitialise EmptyCase (variable qui sert à localiser la ligne vide pour pouvoir y copier la suite de la séquence)
Application.CutCopyMode = xlCopy
Cells(i, 3).Copy
If NbCopy > 1 Then 'Permet de copier la case plusieurs fois ou qu'une seule fois
Do
Sheets("SeqHor").Select
Range(Cells(EmptyCase, DebutTache), Cells(EmptyCase, DebutTache + NbCopy)).Select
ActiveSheet.Paste
EmptyCase = EmptyCase + 1
Loop Until IsEmpty(ActiveCell) = True

Else
Do
Sheets("SeqHor").Select
Cells(EmptyCase, DebutTache).Select
ActiveSheet.Paste
EmptyCase = EmptyCase + 1
Loop Until IsEmpty(ActiveCell) = True
End If
Application.CutCopyMode = False
Next i


End Sub



Pouvez-vous m'aider ?

Merci d'avance.

4 réponses

Patrice33740 Messages postés 8556 Date d'inscription dimanche 13 juin 2010 Statut Membre Dernière intervention 2 mars 2023 1 762
20 févr. 2019 à 12:52
Bonjour,

Puisque tu débutes en VBA, autant prendre quelques bonnes habitudes dès maintenant. Tu devrais revoir entièrement ton code.

1. Respecter certaines règles de nommage des variables, notamment l'emploi d'un préfixe qui identifie le type de variable : le code est plus lisible par tous. Plus d'explications ici : Conventions typographiques

2. La programmation exige beaucoup de rigueur, voici quelques conseils qui t'éviterons bien des déboires :
commences tous les modules par Option Explicit, cela oblige à déclarer toutes les variables, ça évite les ambigüités et ça limite les risques d'erreur.
• déclares les variables avec le type ad hoc (i.e. pas toutes en Variant)
• limites leur portée au strict nécessaire (i.e. locale, privée, publique ou globale) ;
• envisages tous les types potentiels de chaque variable pour éviter les erreurs ;
• dans le doute prévois un gestionnaire d"erreur ;
n'utilises jamais .Select, évites d'utiliser les objets actifs : Selection, Activecell, Activesheet, ... ;
• évites les références implicites(i.e. partielles), privilégies les références explicites (i.e. suffisamment complètes),
--- par exemple, au lieu de
= Cells(1,2)
écrire
= Worksheets(1).Cells(1,2).Value
,
donc, précises toujours la feuille pour un objet Range (Cells, Rows, ...) et la propriété cible (Value, Text, ...)
• n'hésites pas à utiliser des variables pour représenter les objets, ça facilite l'écriture et la lecture du code,
--- par exemple :
Set MaPlage = Me.Range("B2:C8")
;
• pour les mêmes raisons, n'hésites pas à utiliser aussi
With
et
End With
;
• évites d'utiliser des propriétés ou méthodes d'objet héritées qui pourraient ne pas exister,
--- par exemple, au lieu de :
Sheets(1).Range("A1")
écrire
Workheets(1).Range("A1")
,
en effet l'objet Range n'appartient pas à Sheet mais à Worksheet ;
• éviter d'utiliser le Presse-Papier, préfères la copie directe avec une destination
Source.Copy Destination
ou
bien, pour copier uniquement les valeurs :
Destination.valeur = Source.Valeur
.

Tu trouveras ici un excellent cours VBA gratuit pour débutants (et plus si affinités ...),
même si, pour simplifier les explications, il n'applique pas toujours les conseils précédents :
ftp://ftp-developpez.com/bidou/Cours/VBA/formationVBA.pdf


1
iadi06 Messages postés 21 Date d'inscription mercredi 20 février 2019 Statut Membre Dernière intervention 27 août 2022
20 févr. 2019 à 13:00
Merci, Patrice33740 pour tous ces bons conseils.

Je vais tâcher de les utiliser dans ce même code.

Si je comprends bien, mon code engendre une erreur à cause d'un problème de syntaxe et donc je dois le reprendre dans son intégralité. Je vais essayer, merci.
0
Patrice33740 Messages postés 8556 Date d'inscription dimanche 13 juin 2010 Statut Membre Dernière intervention 2 mars 2023 1 762
Modifié le 20 févr. 2019 à 13:57
Commences par supprimer les .select
Définit des objets Worksheet et/ou Range et agit dessus sans les sélectionner.
Au lieu d'une boucle, pour trouver la première ligne libre, utilises .End()
0
iadi06 Messages postés 21 Date d'inscription mercredi 20 février 2019 Statut Membre Dernière intervention 27 août 2022
21 févr. 2019 à 10:45
Par contre,

Voilà ce que j'aimerais faire : copier une cellule d'une feuille dans une plage d'une autre feuille.

Mais je n'ai pas dit qu'en fait, je souhaite que si la case de destination est non vide, le programme copie dans la ligne du dessous (si celle-ci également est non vide), il copiera dans la cellule en dessous.

Voilà pourquoi j'ai mis une boucle.

Je travaille sur le sujet là.

Dès que j'ai revu tous les problèmes de syntaxe et autres, je poste le code.
0
Patrice33740 Messages postés 8556 Date d'inscription dimanche 13 juin 2010 Statut Membre Dernière intervention 2 mars 2023 1 762
21 févr. 2019 à 11:13
Avec .End(xlUp).Offset(1), la case de destination est toujours vide, pas besoin de boucle !
0
iadi06 Messages postés 21 Date d'inscription mercredi 20 février 2019 Statut Membre Dernière intervention 27 août 2022
24 févr. 2019 à 00:30
J'ai avancé sur le code. Malheureusement, j'ai toujours la même erreur : "Erreur 1004".

Public Sub SequenceHorizontal()

Dim intNbCol As Integer
Dim intNbTache As Integer
Dim intNbLigne As Integer
Dim bytNbCopy As Byte 'égale à la durée de la tâche
Dim bytDebutTache As Byte 'égale au jour (relatif à la séquence) de début de la tâche
Dim I As Byte 'variable pour boucle for
Dim bytEmptyCase As Byte 'variable qui sert à localiser la ligne vide pour pouvoir y copier la suite de la séquence
Dim rCopRange As Range
Dim rDestRange As Range


'Initialisation des tâches
intNbLigne = 4
intNbTache = 0
'bytEmptyCase = 3
bytNbCopy = 1
intNbCol = bytDebutTache + bytNbCopy
Dim sError As String

Application.ScreenUpdating = False 'Désactive la mise à jour écran qui permet d'optimiser la vitesse d'exécution du code
Worksheets("SeqVert").Activate

'Compte le nombre de tâche dans la séquence
If Me.Cells(4, 3) <> 0 Then
Do
Me.Cells(intNbLigne, 3).Select
intNbLigne = intNbLigne + 1
intNbTache = intNbTache + 1
Loop Until IsEmpty(ActiveCell)

Else
sError = MsgBox("Merci de renseigner les séquences", vbExclamation + vbOKOnly)
End If


'Ligne à supprimer, sert à vérifier si le code est ok.
Me.Cells(13, 1).Value = intNbLigne
Me.Cells(14, 1).Value = intNbTache

'Copie la séquence en mode horizontal dans la feuille Séquence horizontale
For I = 4 To intNbTache
bytNbCopy = Me.Cells(I, 5).Value
bytDebutTache = Me.Cells(I, 6).Value

If bytNbCopy > 1 Then 'Permet de copier la case plusieurs fois ou qu'une seule fois

Set rCopRange = Me.Cells(I, 3)
Set rDestRange = Worksheets("SeqHor").Range(Cells(I, bytDebutTache), Cells(I, bytDebutTache + bytNbCopy))
Worksheets("SeqVert").rCopRange.Copy Worksheets("SeqHor").rDestRange.End(xlUp).Offset(1, 0)

Else
Set rCopRange = Me.Cells(I, 3)
Set rDestRange = Worksheets("SeqHor").Cells(I, bytDebutTache)
Worksheets("SeqVert").rCopRange.Copy Worksheets("SeqHor").rDestRange.End(xlUp).Offset(1, 0)

End If
Application.CutCopyMode = False
Next I


End Sub
0