Copiar/pegar de una rango de celdas variable en VBA
flavinou
-
gbinforme Mensajes publicados 14930 Fecha de registro Estado Colaborador Última intervención -
gbinforme Mensajes publicados 14930 Fecha de registro Estado Colaborador Última intervención -
Bonjour, voici une version corrigée et optimisée de votre macro VBA, en conservant le comportement demandé: sélectionner la colonne C entre les lignes g et h selon les critères dans la colonne E et copier les valeurs vers la colonne I, tout en restant lisible et efficace.
Notez les principaux changements:
- Utilisation d’objets Range correctement déclarés.
- Éviter les Selects répétés et les chaînes de conditions confuses.
- Recherche des bornes g et h avec des boucles simples et propres.
- Copie des valeurs sans utiliser le clipboard lorsque possible.
- Gestion des feuilles par index ou nom et nettoyage des variables.
Code proposé:
Sub Nom()
Dim wsParams As Worksheet
Dim wsName As Worksheet
Dim a As Variant, b As Variant
Dim g As Long, h As Long
Dim i As Long, j As Long
Dim cVal As Variant, eVal As Variant
Set wsParams = Sheets("Paramètres")
Set wsName = Sheets("Name")
' Récupérer les bornes à partir des cellules S3 et T3
a = wsParams.Range("S3").Value
b = wsParams.Range("T3").Value
' Recherche de g: première ligne à partir de 2 où E(i) >= a
g = 0
For i = 2 To 500
cVal = wsName.Range("E" & i).Value
If Not IsEmpty(cVal) Then
If cVal >= a Then
g = i
Exit For
End If
End If
Next i
If g = 0 Then
MsgBox "Aucune valeur >= a trouvée dans la plage E2:E500.", vbExclamation
Exit Sub
End If
' Recherche de h: dernière ligne où E(j) <= b et suivante croissante
h = g
For j = g + 1 To 500
eVal = wsName.Range("E" & j).Value
If eVal <= b Then
h = j
Else
Exit For
End If
Next j
' Vérifier que g et h sont valides
If g > 0 And h >= g Then
Dim srcRng As Range
Set srcRng = wsName.Range("C" & g & ":C" & h)
Dim dest As Range
Set dest = wsName.Range("I2")
' Copier les valeurs sans modifier les formats
dest.Resize(srcRng.Rows.Count).Value = srcRng.Value
Else
MsgBox "Impossible de déterminer les bornes g et h.", vbExclamation
Exit Sub
End If
End Sub
Instructions rapides:
- Le code recherche g comme la première ligne i où E(i) >= S3 (a).
- Puis il étend h tant que E(j) <= T3 (b).
- Il copie les valeurs de C[g] à C[h] vers I2 en tant que valeurs (pas de formats).
Si vous préférez toujours utiliser le presse-papiers (comme dans votre version), remplacez la section de copie par:
srcRng.Copy
dest.PasteSpecial xlPasteValues
Mais la version sans presse-papiers est plus fiable et rapide.
Souhaitez-vous que je ajuste le code pour gérer dynamiquement la fin des données (au lieu de 500) ou pour inclure des protections supplémentaires (types mismatches, erreurs de feuille, etc.) ?
Notez les principaux changements:
- Utilisation d’objets Range correctement déclarés.
- Éviter les Selects répétés et les chaînes de conditions confuses.
- Recherche des bornes g et h avec des boucles simples et propres.
- Copie des valeurs sans utiliser le clipboard lorsque possible.
- Gestion des feuilles par index ou nom et nettoyage des variables.
Code proposé:
Sub Nom()
Dim wsParams As Worksheet
Dim wsName As Worksheet
Dim a As Variant, b As Variant
Dim g As Long, h As Long
Dim i As Long, j As Long
Dim cVal As Variant, eVal As Variant
Set wsParams = Sheets("Paramètres")
Set wsName = Sheets("Name")
' Récupérer les bornes à partir des cellules S3 et T3
a = wsParams.Range("S3").Value
b = wsParams.Range("T3").Value
' Recherche de g: première ligne à partir de 2 où E(i) >= a
g = 0
For i = 2 To 500
cVal = wsName.Range("E" & i).Value
If Not IsEmpty(cVal) Then
If cVal >= a Then
g = i
Exit For
End If
End If
Next i
If g = 0 Then
MsgBox "Aucune valeur >= a trouvée dans la plage E2:E500.", vbExclamation
Exit Sub
End If
' Recherche de h: dernière ligne où E(j) <= b et suivante croissante
h = g
For j = g + 1 To 500
eVal = wsName.Range("E" & j).Value
If eVal <= b Then
h = j
Else
Exit For
End If
Next j
' Vérifier que g et h sont valides
If g > 0 And h >= g Then
Dim srcRng As Range
Set srcRng = wsName.Range("C" & g & ":C" & h)
Dim dest As Range
Set dest = wsName.Range("I2")
' Copier les valeurs sans modifier les formats
dest.Resize(srcRng.Rows.Count).Value = srcRng.Value
Else
MsgBox "Impossible de déterminer les bornes g et h.", vbExclamation
Exit Sub
End If
End Sub
Instructions rapides:
- Le code recherche g comme la première ligne i où E(i) >= S3 (a).
- Puis il étend h tant que E(j) <= T3 (b).
- Il copie les valeurs de C[g] à C[h] vers I2 en tant que valeurs (pas de formats).
Si vous préférez toujours utiliser le presse-papiers (comme dans votre version), remplacez la section de copie par:
srcRng.Copy
dest.PasteSpecial xlPasteValues
Mais la version sans presse-papiers est plus fiable et rapide.
Souhaitez-vous que je ajuste le code pour gérer dynamiquement la fin des données (au lieu de 500) ou pour inclure des protections supplémentaires (types mismatches, erreurs de feuille, etc.) ?
1 respuesta
-
Hola,
Evita los selects puestos por el registrador pero innecesarios.
Así es como lo corregiría:Sub Nom() Dim a As Range Dim b As Range Dim i As Integer Dim j As Integer With Sheets("Paramètres") Set a = .Range("S3") Set b = .Range("T3") End With With Sheets("Name") For i = 2 To 500 If Range("E" & i) >= a Then Exit For End If Next i For j = i To 500 If Range("E" & j).Value >= Range("E" & i).Value Then If Range("E" & j).Value <= b Then If Range("E" & j + 1).Value <= Range("E" & j).Value Then Exit For End If End If End If Next j End With Range("C" & i & ":C" & j).Copy Range("I2").PasteSpecial Paste:=xlPasteValues Application.CutCopyMode = False End Sub
--
Siempre zen
La perfección se alcanza, no cuando ya no hay nada que añadir, sino cuando ya no hay nada que quitar. Antoine de Saint-Exupéry