By TomWhiteJnr le dimanche 08 octobre 2017
Publié dans Excel
Réponses 0
Aime 0
Vues 3.1K
Votes 0
J'ai une feuille de calcul dans un classeur contenant plus de 400 lignes, 8 colonnes et 160 plages fusionnées et j'ai gâché son apparence. J'ai cherché sur Internet les cellules fusionnées VBA Autofit. Aucune des URL n'est très utile. La macro sur ce site est sur la bonne voie mais : -
1) Je devrais identifier et saisir manuellement les 160 plages fusionnées.
J'ai ajouté une recherche de plages de cellules fusionnées.
2) Il utilise la première ligne pour effectuer des calculs de cellules fusionnées (Cellule ZZ1). J'utilise une police beaucoup plus grande sur la cellule A1 (Titre), ce qui entraîne des erreurs de calcul de la hauteur d'ajustement automatique fusionnée requise.
J'utilise une cellule 1 colonne à droite et 1 ligne sous les données. (Ctrl+Maj+Fin, ne trouve pas cette cellule)
3) Il recalcule toutes les cellules fusionnées afin de réduire la hauteur de deux lignes contenant à la fois des cellules fusionnées et normales, rendant les cellules normales illisibles.
Je modifie la hauteur de ligne uniquement lorsque la hauteur fusionnée requise dépasse la hauteur existante.
4) La méthode de copie des données dans les plages fusionnées vers la cellule ZZ1 est incorrecte, basée uniquement sur le texte de la plage fusionnée mais ne prenant pas en compte les différentes tailles de police dans les différentes cellules fusionnées.
J'ai corrigé la méthode de copie.
5) La macro est lente : environ 15+ secondes sur ma feuille de calcul.
Désactiver le rafraîchissement de l'écran et le réactiver à la fin de la macro réduit ce délai à 2 secondes.

J'ai réussi à trouver un autre défaut irritant. Ajuster automatiquement la feuille de calcul (avant de corriger les plages fusionnées) et déformer plusieurs lignes. Certaines cellules "normales", définies sur enveloppées, avaient leur hauteur augmentée et apparaissaient sous la forme d'une ligne (ou de deux lignes) de texte avec une ligne vide sous le texte. La recherche sur Internet a indiqué que cela est dû au fait qu'Excel modifie l'affichage pour s'adapter aux polices de l'imprimante. J'ai trouvé un "contournement", j'ai ajouté à la macro :
Augmentez la largeur des colonnes d'un petit pourcentage.
Ajuster automatiquement toutes les lignes de la feuille de calcul.
Effectuez des corrections à la hauteur des lignes pour tenir compte des plages fusionnées.
Rétablir la largeur de colonne aux tailles d'origine.
Cela a corrigé le problème, les lignes vides n'apparaissent plus !

Je pensais que tout était maintenant correct mais j'ai alors découvert un autre problème. Si je ferme le classeur et que je le rouvre à nouveau, les lignes vides sont de retour. J'ai regardé Fichier/Options et j'ai cherché sur Internet une méthode pour empêcher le classeur de mettre à jour l'affichage de l'écran lors de la fermeture/ouverture du classeur sans succès. J'ai dû ajouter Private Sub Workbook_Open() sur l'onglet "ThisWorkbook" avec un appel pour exécuter la macro lorsque le classeur est ouvert.


Option explicite

Sous Look4Merged()
Dim WSN As String 'Nom de la feuille de calcul
Dim sht As Worksheet 'Utilisé par "Set"
Dim LastRow As Long 'Dernière ligne dans toutes les colonnes avec des données
Dim LastRowCC As Long 'Dernière ligne dans la colonne actuelle avec des données
Dim LastColumn As Integer 'Numéro de la dernière colonne dans toutes les lignes avec des données
Dim CurrCol As Integer 'Numéro de la colonne actuelle
Dim Letter As String 'Convertir le nombre CurrCol en chaîne
Dim ILetter As String 'Colonne d'index un à droite de la dernière colonne
Dim ICell As String 'Cellule une colonne à droite et une ligne vers le bas dans la zone de données frpm. Utilisé pour calculer la hauteur fusionnée requise
Dim Crow As Long 'Numéro de ligne actuel
Dim TwN As Long 'Gestion des erreurs
Dim TwD As String 'Gestion des erreurs
Dim Mgd As Boolean 'Vrai/Faux test si la cellule est fusionnée
Dim MgdCellAddr As String 'Contient la plage fusionnée sous forme de chaîne
Dim MgdCellStart As String 'Lettre de début de la plage de cellules fusionnées Utilisée, par exemple, pour inspecter la colonne B pour les cellules fusionnées, ignorer toutes les cellules fusionnées commençant dans la colonne A et s'étendant jusqu'à la colonne B (déjà évaluée)
Dim MgdCellStart1 As String 'utilisé pour calculer MgdCellStart
Dim MgdCellStart2 As String 'utilisé pour calculer MgdCellStart
Dim OldHeight As Single 'Hauteur existante de toutes les lignes dans la plage fusionnée
Dim P1 As Integer 'Nombre de boucles/pointeur
Dim OldWidth As Single 'Largeur existante des cellules dans la plage fusionnée
Dim NewHeight As Single 'Hauteur requise de toutes les lignes dans la plage fusionnée. Mettre à jour les lignes individuelles proportionnellement si elles dépassent OldHeight
Dim C1 As Integer 'Nombre de colonnes de boucle
Dim R1 As Long 'Loop Row count/pointer
Dim Tweak As Single 'Petite augmentation de la largeur de la colonne pour résoudre le problème des lignes vides
Atténuer l'orange comme plage
En cas d'erreur GoTo TomsHandler

Application.ScreenUpdating = False 'BEAUCOUP plus rapide 15 secondes si l'écran mis à jour seulement 2 secondes est éteint.
Tweak = 1.04 'Augmente la largeur de la colonne de 4 % avant l'ajustement automatique de toutes les lignes.
WSN = ActiveSheet.Nom
Columns("A:A").EntireRow.Hidden = False

'Trouver la dernière ligne et colonne actives dans toute la feuille de calcul avec des données
Avec ActiveSheet.UsedRange
LastColumn = Range(Range("A1"), Cells(Rows.Count, Columns.Count)).Find(What:="*", LookIn:=xlValues, _
SearchOrder :=xlByColumns, SearchDirection :=xlPrevious).Column
LastRow = Range(Range("A1"), Cells(Rows.Count, Columns.Count)).Find(What:="*", LookIn:=xlValues, _
SearchOrder :=xlByRows, SearchDirection :=xlPrevious).Row
Terminer par
CurrCol = LastColumn + 1 'c'est-à-dire à droite de la dernière colonne
Si CurrCol < 27 Alors
ILetter = Chr$(CurrCol + 64) 'Colonne d'index
autre
ILettre = Chr$(Int((CurrCol - 1) / 26) + 64)
ILetter = ILetter & Chr$(CurrCol - Int((CurrCol - 1) / 26) * 26 + 64) 'Colonne d'index si double chiffre. Je n'ai pas pris la peine de triple lettre
Si fin

'Icell est situé à droite et en dessous des données. La cellule est utilisée pour calculer la hauteur requise pour s'adapter à la plage fusionnée
ICell = ILetter & LastRow + 1

'Augmente légèrement la largeur de la colonne pour résoudre le bogue d'habillage des lignes vides.
Range("A" & LastRow + 1).Select
Pour C1 = 1 à la dernière colonne
ActiveCell.ColumnWidth = ActiveCell.ColumnWidth * Tweak 'augmente légèrement la largeur de la colonne pour corriger le bogue
ActiveCell.Offset(0, 1).Range("A1").Select ' déplacer une cellule vers la droite
Suivant

'Ajustement automatique des lignes (ignore les lignes fusionnées) avec une largeur de colonne de 4 % supplémentaire pour éviter le bogue des lignes vides sur certaines lignes d'habillage
Cells.Select
Sélection.Rows.AutoFit
Set sht = Worksheets(WSN) 'nécessaire pour trouver la dernière entrée dans la colonne avec des données

Pour CurrCol = 1 à LastColumn
'convertir le numéro de la colonne actuelle en alpha (lettre simple ou double)
Si CurrCol < 27 Alors
Lettre = Chr$(CurrCol + 64)
autre
Lettre = Chr$(Int((CurrCol - 1) / 26) + 64)
Lettre = Lettre & Chr$(CurrCol - Int((CurrCol - 1) / 26) * 26 + 64)
Si fin
LastRowCC = sht.Cells(sht.Rows.Count, Letter).End(xlUp).Row 'trouve la dernière ligne dans la colonne actuelle

Pour CRow = 1 Vers LastRowCC
Plage (Lettre & Crow).Sélectionnez
Mgd = ActiveCell.MergeCells 'La cellule est-elle dans la plage fusionnée
Si Mgd = Vrai Alors 'Si Vrai, alors c'est
'Quelle est l'adresse de la plage fusionnée ? extraire un seul/double chiffre pour le début de la plage
MgdCellAddr = ActiveCell.MergeArea.Address
MgdCellStart1 = Milieu (MgdCellAddr, 2, 1)
MgdCellStart2 = Milieu (MgdCellAddr, 3, 1)
Si MgdCellStart2 = "$" Alors
MgdCellStart = MgdCellStart1
autre
MgdCellStart = MgdCellStart1 & MgdCellStart2
Si fin
If MgdCellStart = Letter Then 'Est la première colonne de la cellule fusionnée égale à la colonne actuelle
Avec feuilles (WSN)
AncienneLargeur = 0
Set oRange = Range(MgdCellAddr) 'set oRange sur la plage fusionnée détectée
Pour C1 = 1 à oRange.Columns.Count
OldWidth = OldWidth + .Cells(1, oRange.Column + C1 - 1).ColumnWidth 'Accumule les largeurs de colonne pour la plage de cellules (avec 4 % ajoutés)
Suivant
AncienneHauteur = 0
Pour R1 = 1 à oRange.Rows.Count
OldHeight = OldHeight + .Cells(CRow, oRange.Row + R1 - 1).RowHeight 'Accumule la hauteur de ligne existante pour la plage de cellules
Suivant
oRange.MergeCells = Faux
.Range(Letter & CRow).Copy Destination:=Range(ICell) 'Copie le texte ET la taille de la police, pas uniquement les valeurs
.Range(ICell).WrapText = True 'enveloppe ICell
.Columns(ILetter).ColumnWidth = OldWidth 'modifier la largeur de la colonne contenant ICell pour imiter la plage existante
.Rows(LastRow + 1).EntireRow.AutoFit ' Ajuste automatiquement la ligne ICell, prête à mesurer la hauteur fusionnée requise
oRange.MergeCells = True 'Réinitialise la plage fusionnée à fusionnée
oRange.WrapText = True 'et habillage
'Mesurer la hauteur requise pour la plage fusionnée
NouvelleHauteur = .Rows(LastRow + 1).RowHeight
'La nouvelle hauteur requise dépasse-t-elle l'ancienne hauteur existante
Si NouvelleHauteur > AncienneHauteur Alors
Pour R1 = CRow à CRow + oRange.Rows.Count - 1
'Augmente chaque ligne de la plage au prorata
Plage(ILetter & R1).RowHeight = Plage(ILetter & R1).RowHeight * NewHeight / OldHeight
Suivant
autre
'espace suffisant dans la cellule fusionnée
Si fin
CRow = CRow + oRange.Rows.Count - 1 'autrement sur une plage multiligne, descendra jusqu'à la 2ème ligne de la plage et répétera le calcul en arrivant à "Suivant"
.Range(ICell).Clear 'Zap ICell prêt pour le prochain calcul
.Range(ICell).ColumnWidth = 8.1 'Ranger la largeur de la colonne
Terminer par
Si fin
Si fin
Suivant
Suivant

'Réinitialiser la largeur de la colonne en supprimant 4 % ajoutés (nécessaire pour remédier à l'erreur d'habillage)
Range("A" & LastRow + 1).Select
Pour C1 = 1 à la dernière colonne
ActiveCell.ColumnWidth = ActiveCell.ColumnWidth / Tweak 'réduit la largeur de la colonne à l'original
ActiveCell.Offset(0, 1).Range("A1").Select ' une cellule à droite
Suivant
Plage("A1").Sélectionnez

Application.ScreenUpdating=True 'réactiver la mise à jour
Exit Sub

TomsHandler :
Application.ScreenUpdating=True 'réactiver la mise à jour
TwN = numéro d'erreur
TwD = Err.Description
MsgBox "Besoin de gérer l'erreur " & TwN & " " & TwD
Arrêter
Reprendre
End Sub

Est-il possible d'empêcher Excel de modifier l'apparence de l'affichage à l'écran lors de la fermeture/rouverture du classeur ?
Voir l'article complet