J'ai une routine, qui consiste à remplir un calendrier avec tous les événements importants pour les marchés des matières premières pour chaque jour de la semaine suivante. J'ai une grille de calendrier disposée sur la page et j'ai dix cellules nommées pour chaque jour, c'est-à-dire lundi 1, lundi 2 et ainsi de suite (chaque jour ne va que jusqu'à 10 pour le moment, c'est-à-dire lundi 10), dans la colonne de chaque jour. En fait, les cellules ont une largeur de 2 cellules et une profondeur de 2 cellules. Souvent, il y a plus de 10 événements pour un jour donné. J'essaie de tester la plage nommée pour voir si elle existe, sinon je copie le format de la dernière cellule de la plage nommée et je nomme cette cellule le nom suivant dans la série.
J'ai seulement deux problèmes avec ce qui précède, le premier et le plus important est de savoir comment tester pour déterminer si un nom pour une plage nommée existe déjà. Je suis en train d'itérer à travers la liste entière de ThisWorkbook.Names, qui contient des milliers de plages nommées. Comme cette itération peut être exécutée plus de 100 fois lorsque le calendrier est généré, elle est très lente (comme on peut s'y attendre). Existe-t-il un meilleur moyen, plus rapide, de vérifier si un nom existe déjà en tant que plage nommée ?
Le deuxième problème est de savoir comment copier le formatage d'une cellule fusionnée de 4 cellules, puisque l'adresse n'apparaît toujours que dans la cellule du coin supérieur gauche et que le décalage de la plage ne fonctionne pas correctement. J'ai bidouillé pour obtenir ce code afin d'obtenir au moins la bonne plage pour le prochain groupe de cellules fusionnées de la colonne.
Set cCell = Range("Thursday" & CStr(y))
'even tho cCell is a 4 cell merged cell, cCell.Address returns the address of top left cell
Set destRange = Range(cCell.Address & ":" & cCell.offset(2, 0).offset(0, 1).Address)
L'enregistrement d'une macro pour faire glisser le formatage vers le bas, montre ce code.
Range("G22:H23").Select
Selection.AutoFill Destination:=Range("G22:H25"), Type:=xlFillFormats
Range("G22:H25").Select
Puisque Range("G22:H23") est identique à cCell, et Range("G22:H25") est identique à destRange. Le code suivant devrait fonctionner, mais ne fonctionne pas.
Set cCell = Range("Thursday" & CStr(y))
Set destRange = Range(cCell.Address & ":" & cCell.offset(2, 0).offset(0, 1).Address)
cCell.AutoFill Destination:=destRange, Type:=xlFillFormats
Application.CutCopyMode = False
cCell.offset(1, 0).Name = rangeName
Pour information, cela ne fonctionne pas non plus si je sélectionne cCell et utilise Selection.AutoFill.
Avez-vous une idée de la façon dont vous pouvez copier le formatage de cette cellule dans la colonne, une cellule à la fois, si nécessaire ?
Mise à jour :
Cela fonctionne maintenant pour copier le formatage d'une cellule fusionnée vers une autre de même taille. Pour une raison quelconque, le fait de définir destRange sur l'ensemble de la plage (la plage entière de copy cell et pastecell, comme l'indiquait l'enregistreur de macro) n'a pas fonctionné, mais le fait de définir destRange sur la plage de cellules nécessitant un formatage, puis d'effectuer une union de cCell et destRange a fonctionné et a permis de nommer plus facilement la nouvelle plage.
rangeName = "Friday" & CStr(y + 1)
priorRangeName = "Friday" & CStr(y)
namedRangeExist = CheckForNamedRange(rangeName)
If namedRangeExist = False Then
Set cCell = Range(priorRangeName)
Set destRange = Range(cCell.offset(1, 0).Address & ":" & cCell.offset(2, 0).offset(0, 1).Address)
cCell.AutoFill Destination:=Union(cCell, destRange), Type:=xlFillFormats
Application.CutCopyMode = False
destRange.Name = rangeName
End If
Mise à jour n°2
Il y a un problème avec le nommage des plages dans une boucle For (le code ci-dessous est exécuté dans une boucle For). La première fois que le nouveau nom de plage n'est pas trouvé, le fait de définir cCell sur le nom de la plage précédente et d'exécuter le code pour copier le format de cellule fusionné et nommer la nouvelle plage fonctionne bien. Voici le code
rangeName = "Thursday" & CStr(y + 1)
priorRangeName = "Thursday" & CStr(y)
namedRangeExist = DoesNamedRangeExist(rangeName)
If namedRangeExist = False Then
Set cCell = Range(priorRangeName)
Debug.Print "cCell:" & cCell.Address
Set cCell = cCell.MergeArea
Debug.Print "Merged cCell:" & cCell.Address
Set destRange = Range(cCell.offset(1, 0).Address & ":" & cCell.offset(2, 0).offset(0, 1).Address)
Debug.Print "Dest:" & destRange.Address
Debug.Print "Unioned:" & Union(cCell, destRange).Address
cCell.AutoFill Destination:=Union(cCell, destRange), Type:=xlFillFormats
Application.CutCopyMode = False
destRange.name = rangename
End If
donne les résultats suivants
cCell:$G$22
Fusionné cCell:$G$22:$H$23
Dest:$G$24:$H$25
Syndiqué:$G$22:$H$25
mais si plus d'une nouvelle plage nommée doit être créée la deuxième fois, ce code produit une zone de plage comme le montre le résultat ci-dessous.
cCell:$G$24:$H$25
Pourquoi l'adresse de cCell n'est affichée que dans la cellule supérieure gauche lors de la première exécution, alors que lors de la deuxième exécution, l'adresse de cCell est affichée dans toute la plage de cellules fusionnées ? Et parce que c'est le cas, la ligne de code suivante produit une erreur d'objet de plage.
Set cCell = cCell.MergeArea
En éliminant cette ligne de code et en modifiant le premier Set cCell en ceci ;
Set cCell = Range(priorRangeName).MergeArea
produit la même erreur. Je pourrais contourner ce problème en définissant un compteur et, s'il y en a plus d'un, contourner cette ligne de code, mais ce n'est pas la solution préférée.