Préambule
Cette discussion titrée Concaténer 1er onglet de plusieurs classeurs différents m'a donné l'envie d'écrire une nouvelle fonction nommée CopyRange.
Cette fonction est proche de la contribution Regrouper plusieurs feuilles sur une autre. (2003-2010) mais plus légère et plus ouverte quant à la source (possibilité de choisir la cellule de départ) et permettant également d'ajouter une colonne contenant un nom tel que celui du classeur ou de la feuille source.
Cette fonction permet d'importer une liste de données contenue dans une feuille et définie soit par un objet Range, un objet Worksheet ou un ListObject vers une feuille cible dont la plage de cellules commence en A1.
Son usage est surtout utile pour regrouper plusieurs liste de données en une seule.
Contraintes
Mis à part l'objet source, la fonction n'effectue aucune vérification sur les données sources, ni sur le nombre de colonnes, ni si l'orthographe des étiquettes de colonnes sont identiques aux données déjà présentes dans la feuille cible. Il y a donc lieu de faire cette vérification en amont.
Avant d'invoquer la fonction, il est donc important de
- supprimer s'il y a lieu, le filtre des données sources
- de veiller à ce que toutes les données sources soient de même nature (Plage classique ou tableau structuré)
- si la source est un objet type ListObject, outre le filtre, il y a lieu de désactiver la ligne des totaux
Les arguments
Obligatoires
objSource : Objet (Range, Worksheet ou ListObject)
TargetSheet : Objet Worksheet
Optionnels
AddLabel : String. Cet argument permet d'ajouter une colonne dont toutes les lignes copiées contiendront cette valeur (par exemple le nom de la feuille ou du classeur source)
ClearSheet : Boolean si TRUE, Supprime les cellules de TargetSheet
ValueOnly : Boolean si TRUE ne conserve que les valeurs
Code de la procédure
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
| Function CopyRange(objSource As Object, _
TargetSheet As Worksheet, _
Optional ClearSheet As Boolean, _
Optional AddLabel As String, _
Optional ValueOnly As Boolean) As Range
' Copie données contenues dans objSource vers TargetSheet
' Auhor : Philippe Tulliez www.magicoffice.be
' Date : 08/08/2019
' Version 1.1
' Arguments
' ObjSource - Source des données. Objet WorkSheet, ListObject ou Range
' TargetSheet - objet WorkSheet (Feuille cible)
' [AddLabel] - String
' [ClearSheet] - Boolean si TRUE, Supprime les cellules de TargetSheet
' [ValueOnly] - Boolean si TRUE ne conserve que les valeurs
' *** Déclaration ***
Dim rngTarget As Range, rngSource As Range
Dim flagExit As Boolean
' *** Attribution ***
With objSource
Select Case TypeName(objSource)
Case "Worksheet": Set rngSource = .Range("A1").CurrentRegion
Case "Range": If .Count = 1 Then Set rngSource = .CurrentRegion Else Set rngSource = objSource
Case "ListObject": Set rngSource = .Range
Case Else: flagExit = True
End Select
End With
'
If Not flagExit Then
Set rngTarget = TargetSheet.Range("A1").CurrentRegion
With rngTarget
If Not ClearSheet Then ClearSheet = .Rows.Count = 1
If ClearSheet Then
.Cells.Clear: Set rngTarget = .Cells(1, 1)
Else
Set rngTarget = .Cells(.Rows.Count + 1, 1)
End If
End With
' Exportation des données
With rngSource
.Offset(Abs(Not ClearSheet)).Resize(.Rows.Count + Not ClearSheet).Copy rngTarget
End With
' *** AddLabel
If Len(AddLabel) Then
With rngTarget
If .Row = 1 Then .Offset(ColumnOffset:=rngSource.Columns.Count).Value = "_SourceName_"
End With
With rngSource
rngTarget.Offset(0 + Abs(rngTarget.Row = 1), .Columns.Count).Resize(.Rows.Count - 1).Value = AddLabel
End With
End If
' *** ValueOnly
With rngTarget
Set CopyRange = .Range("A1").CurrentRegion
If ValueOnly Then .Value = .Value
End With
End If
' End Of Process
Set rngTarget = Nothing: Set rngSource = Nothing
End Function |
Classeur de démonstration
Le classeur au format xlsm a été testé avec la version 2010 et 2013.
Malgré le soin apporté à la programmation de cette procédure et aux multiples tests réalisés, il est possible qu'il subsiste un "bug" qui m'aurait échappé. N'hésitez pas à m'en faire part.
Vos remarques et réactions sont les bienvenues.
Partager