'---------------------------------------------------------------------------------------
' Titre : SuiviX
' Auteur : Skoobi
' Date : 27/04/2010
' Sujet : Suivi des modifications des cellules, feuilles et codes VBA
'---------------------------------------------------------------------------------------
'++++++++ déclarations gestion cellule +++++++++
Dim DerLig As Long, DerCol As Long
Dim Lig As Long, Col As Long, PlageAddress As String, StateUndo As Boolean, UndoDo As Boolean
Dim LastChange As String
Dim NewSel As Range, ModeCutCopy As Byte, AdressCutCopy As String
Dim ListCutCopy() As Variant, StopFormat As Boolean
Dim SaveDetect As Boolean, DetectDeplace As Byte, OpSh As String, CloseDetect As Boolean
Dim XLAInstalled As Boolean
Dim AutreClasseur As String
Dim ListDest() As Variant 'v2.21
Private WithEvents AppSuiviX As Application
'Permet de détecter la suppression de module via le menu ou clic droit pour avertir l'utilisateur
Private WithEvents EvntDelModuleMenu As CommandBarEvents, WithEvents EvntDelModulePopUp As CommandBarEvents
'&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
'&&&&&&&&&&&&&&&&&&&&&&&&&&&& Partie gestion du fichier SuiviX.xla &&&&&&&&&&&&&&&&&&&&&&&&&
'&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
Private Sub Workbook_Open()
'vérifie que le fichier est installé et non ouvert comme un fichier ordinaire
Set AppSuiviX = Application
On Error Resume Next
XLAInstalled = AddIns("SuiviX_v2.1").Installed
If Err.Number > 0 Then
MsgBox "Ce fichier est une macro complémentaire à installer via Outils>Macros complémentaire", vbCritical
ThisWorkbook.Close
Exit Sub
End If
'création des menus et contrôles
Call P_InitMenu
SuiviCellNon = True
End Sub
Private Sub Workbook_BeforeClose(Cancel As Boolean)
Call P_DelMenu
End Sub
'&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
'&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& Partie gestion des fichiers ouverts &&&&&&&&&&&&&&&&&&&&&&&&&&
'&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
Private Sub AppSuiviX_WorkbookBeforeClose(ByVal Wb As Workbook, Cancel As Boolean)
If Wb.Name = ThisWorkbook.Name Then Exit Sub '!!!! A activer pour le xla !!!!
CloseDetect = True
End Sub
Private Sub AppSuiviX_WorkbookBeforeSave(ByVal Wb As Workbook, ByVal SaveAsUI As Boolean, Cancel As Boolean)
If Wb.Name = ThisWorkbook.Name Then Exit Sub ' !!!! A activer pour le xla !!!!
'############# met à jour la feuille de suivi VBA si actif ###########
If SuiviVBAOui(Wb) Then
Set WbX = Wb
Call P_VBACompare
Call P_FeuilSuiviPleine("SuiviX>>HistVBA", 2000, Wb)
End If
'############# met à jour la feuille de suivi cellule si actif ###########
If SuiviCellNon Then Exit Sub
'############# détection format de feuille ###########
If NbSh = Wb.Sheets.Count And Not NomSh Like "SuiviX>>Hist*" Then 'pour détecter la suppression/création d'une feuille
Call FormatCell: Call CommentCell: Call FusCell
SaveDetect = True
End If
'############# détection opération de feuille ###########
Call OperationsFeuil
If Not SuiviCellNon Then Call P_FeuilSuiviPleine("SuiviX>>HistCell", 500, Wb)
End Sub
Private Sub AppSuiviX_WorkbookDeactivate(ByVal Wb As Workbook)
If CloseDetect Then
CloseDetect = False
Exit Sub
End If
'Si on effectue une modification de code et que l'on active un autre fichier, "WorkbookDeactivate"
'fait la mise à jour dans la feuille de suivi avant de passer à cet autre fichier.
If SuiviVBAOui(Wb) Then
Set WbX = Wb
Call P_VBACompare
Call P_FeuilSuiviPleine("SuiviX>>HistVBA", 2000, Wb)
End If
End Sub
Private Sub AppSuiviX_WorkbookOpen(ByVal Wb As Workbook)
'La condition suivante permet de tout de suite prendre en charge le suiviVBA du fichier actif lors de l'installation
'de l'utilitaire (pas nécessaire de fermer et ouvrir ce fichier).
If Not XLAInstalled And Wb.Name = ThisWorkbook.Name Then Call P_EtatVBA1_2 '!!!! A activer pour le xla !!!!
If Wb.Name = ThisWorkbook.Name Then Exit Sub
'Cette condition permet de lancer le code que si d'autres fichiers ne sont pas actuellement ouvert.
'En effet, comme l'événement "WorkbookDeactivate" va désactiver un fichier déjà ouvert, "WorkbookActivate"
'sera appelé pour se fichier tout de suite après.
If Workbooks.Count = 1 Then Call AppSuiviX_WorkbookActivate(Wb)
End Sub
Private Sub AppSuiviX_WorkbookActivate(ByVal Wb As Workbook)
Dim CtlDelModuleMenu As CommandBarControl, CtlDelModulePopUp As CommandBarControl
Dim Test As String
On Error Resume Next
Test = Wb.Sheets("SuiviX>>HistCell").Name
If Err.Number = 0 Then
SuiviCellNon = False
If Application.CutCopyMode = 0 Then Call P_InitVariables(Wb.ActiveSheet): Call P_InitVarOp
'############# détection coupe/copie cellule #############
If Application.CutCopyMode <> 0 Then Call VarCutCopy
Else
SuiviCellNon = True
If Application.CutCopyMode = 0 Then
Set PlageSel = Selection
AutreClasseur = ActiveWorkbook.Name & "." & ActiveWorkbook.ActiveSheet.Name
End If
End If
On Error GoTo 0
If ActiveWorkbook.VBProject.Protection = vbext_pp_locked Then
MsgBox "Le code VBA de ce fichier est protégé! processus interrompu.", vbCritical, "SuiviVBA"
Exit Sub
End If
Call P_EtatVBA1_2
'>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
'>>>>>>>>>>>>>>>>>>>>>> Gestion suppression module dans VBE >>>>>>>>>>>>>>>>>>>>>>>>>
'>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Set CtlDelModuleMenu = Application.VBE.CommandBars(1).Controls(1).Controls(8)
Set CtlDelModulePopUp = Application.VBE.CommandBars(14).Controls(8)
Set EvntDelModuleMenu = Application.VBE.Events.CommandBarEvents(CtlDelModuleMenu)
Set EvntDelModulePopUp = Application.VBE.Events.CommandBarEvents(CtlDelModulePopUp)
End Sub
Private Sub EvntDelModuleMenu_Click(ByVal CommandBarControl As Object, handled As Boolean, CancelDefault As Boolean)
Dim g As Byte, d As Byte, NomVBE As String
With Application.VBE
g = InStr(1, .MainWindow.Caption, "-") + 2
d = InStr(1, .MainWindow.Caption, "[") - 2
NomVBE = Mid(.MainWindow.Caption, g, d - g + 1)
If NomVBE <> ActiveWorkbook.Name Then
CancelDefault = True
MsgBox "Il faut sélectionnez un module du fichier actif: " & ActiveWorkbook.Name, vbExclamation, "Suppression de module"
ElseIf SuiviVBAOui(ActiveWorkbook) Then
Call P_DeleteModule(.SelectedVBComponent)
CancelDefault = True
Application.ScreenUpdating = True 'sinon excel ne s'affiche pas correctement
End If
End With
End Sub
Private Sub EvntDelModulePopUp_Click(ByVal CommandBarControl As Object, handled As Boolean, CancelDefault As Boolean)
Dim g As Byte, d As Byte, NomVBE As String
With Application.VBE
g = InStr(1, .MainWindow.Caption, "-") + 2
d = InStr(1, .MainWindow.Caption, "[") - 2
NomVBE = Mid(.MainWindow.Caption, g, d - g + 1)
If NomVBE <> ActiveWorkbook.Name Then
CancelDefault = True
MsgBox "Il faut sélectionnez un module du fichier actif: " & ActiveWorkbook.Name, vbExclamation, "Suppression de module"
ElseIf SuiviVBAOui(ActiveWorkbook) Then
Call P_DeleteModule(.SelectedVBComponent)
CancelDefault = True
Application.ScreenUpdating = True 'sinon excel ne s'affiche pas correctement
End If
End With
End Sub
'>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
'>>>>>>>>>>>>>>>>>>>>>> Gestion suppression module dans VBE >>>>>>>>>>>>>>>>>>>>>>>>>
'>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Private Sub AppSuiviX_SheetActivate(ByVal Sh As Object)
'If SuiviCellNon Then Exit Sub
If SuiviCellNon And Application.CutCopyMode = 0 Then
Set PlageSel = Selection
AutreClasseur = ActiveWorkbook.Name & "." & Sh.Name
ElseIf Not SuiviCellNon Then
'############# détection coupe/copie cellule #############
If Not SuiviFeuilNon(Sh) And Application.CutCopyMode <> 0 And Not NomSh Like "SuiviX>>Hist*" Then
Call VarCutCopy
' Else: AutreClasseur = ""
ElseIf Application.CutCopyMode = 0 Then
AutreClasseur = ""
End If
'############# détection format de feuille ###########
'pour détecter la suppression/création d'une feuille et la sauvegarde car sinon est écrit 2 fois dans la feuille de suivi
If Not SuiviFeuilNon(Sh) And NbSh = ActiveWorkbook.Sheets.Count And Not SaveDetect And Not NomSh Like "SuiviX>>Hist*" And Not PlageSel Is Nothing Then Call FormatCell: Call CommentCell: Call FusCell
'############# détection opération de feuille ###########
'on vérifie que la feuille de suivi VBA n'a pas été créée
If Not AjoutShVBA Then
Call OperationsFeuil
Else: AjoutShVBA = False
End If
If Not SuiviCellNon Then Call P_FeuilSuiviPleine("SuiviX>>HistCell", 50, ActiveWorkbook)
If Application.CutCopyMode = 0 Then Call P_InitVariables(Sh)
SaveDetect = False: DetectDeplace = 0
'on initialise l'état opération de feuille
OpSh = ""
End If
End Sub
Private Sub AppSuiviX_SheetChange(ByVal Sh As Object, ByVal Target As Range)
Dim i As Long
If SuiviCellNon Then Exit Sub
If SuiviFeuilNon(Sh) Or Sh.Name Like "SuiviX>>Hist*" Then Exit Sub
Application.EnableEvents = False
'############# détection coupe/copie de cellule(s) ###########
'coupe/colle
If ModeCutCopy = 2 Then
Call MajHistCColle("coupe/colle cellule(s)")
'copie/colle
ElseIf ModeCutCopy = 1 Then
Call MajHistCColle("copie/colle cellule(s)")
Else
Set PlageSel = Selection
NbLig = Selection.Rows.Count
NbCol = Selection.Columns.Count
'############# intervention sur ligne ###########
If Selection.Count = Sh.Rows(Selection.Row).Columns.Count * NbLig Then
'ici, permet de voir qu'il s'agit d'une insertion
If Sh.UsedRange.Cells(Sh.UsedRange.Count).Row > DerLig Then
Call MajHist1(OpInsSupLigCol, "insertion ligne", NomSh, Selection.Address(0, 0))
'ici, permet de voir qu'il s'agit d'une suppression
ElseIf Sh.UsedRange.Cells(Sh.UsedRange.Count).Row < DerLig Then
Call MajHist1(OpInsSupLigCol, "suppression ligne", NomSh, Selection.Address(0, 0))
End If
'############# intervention sur colonne ############
ElseIf Selection.Count = Sh.Columns(Selection.Column).Rows.Count * NbCol Then
'ici, permet de voir qu'il s'agit d'une insertion
If Sh.UsedRange.Cells(Sh.UsedRange.Count).Column > DerCol Then
Call MajHist1(OpInsSupLigCol, "insertion colonne", NomSh, Selection.Address(0, 0))
'ici, permet de voir qu'il s'agit d'une suppression
ElseIf Sh.UsedRange.Cells(Sh.UsedRange.Count).Column < DerCol Then
Call MajHist1(OpInsSupLigCol, "suppression colonne", NomSh, Selection.Address(0, 0))
End If
Else
'############# intervention sur 1 cellule ############
'Cette variable permet de détecter un déplacement de cellule(s) car celà déclenche l'événement "Change"
'2 fois de suite puis l'événement "Selection"
DetectDeplace = DetectDeplace + 1
If Target.Count = 1 Then
'détection de insertion/suppression d'une plage de cellules avec décalage
Call DetecInsSuppCell(Sh)
'sinon opération sur les cellules:
If LastChange <> "I" And LastChange <> "S" Then
If Target.Count = Selection.Count Then
If IsEmpty(Target.Value) And Not IsEmpty(TempValue) Then
Call MajHist1(True, "Cellule vidée", NomSh, Target.Address(0, 0), "<vide>", IIf(TempValue Like "=*", "'" & TempValue, TempValue))
ElseIf Target.HasFormula Or TempValue Like "=*" Then
If Target.FormulaLocal <> TempValue Then
Call MajHist1(True, "Cellule modifiée", NomSh, Target.Address(0, 0), "'" & Target.FormulaLocal, IIf(IsEmpty(TempValue), "<vide>", "'" & TempValue))
End If
ElseIf Target.Value <> TempValue Then
Call MajHist1(True, "Cellule modifiée", NomSh, Target.Address(0, 0), Target.Value, IIf(IsEmpty(TempValue), "<vide>", TempValue))
End If
'Détection déplacement de la cellule
If DetectDeplace = 2 Then
With ActiveWorkbook.Sheets("SuiviX>>HistCell")
Call MajHist1(True, "Déplacement de cellule", NomSh, .[C2].Value & " vers " & Target.Address(0, 0), IIf(Target.HasFormula, "'" & Target.FormulaLocal, Target.Value), "<inconnu>")
DetectDeplace = 0
.Range("A3:H3").Delete shift:=xlShiftUp
End With
End If
'La donnée est auto remplie:
ElseIf Target.Count <> Selection.Count Then
Call MajHist1(True, "Cellule auto-remplie", NomSh, Target.Address(0, 0), IIf(Target.HasFormula, "'" & Target.FormulaLocal, Target.Value), "<inconnu>")
End If
End If
'############# intervention sur plusieurs cellules ############
ElseIf Target.Count > 1 Then
'détection de insertion/suppression d'une plage de cellules avec décalage
Call DetecInsSuppCell(Sh)
'sinon opération sur les cellules:
If LastChange <> "I" And LastChange <> "S" Then
If PlageSel.Address = Selection.Address Then
LastChange = "R"
If Target.Count = Selection.Count Then
For i = 1 To Target.Count
If IsEmpty(Target(i).Value) And Not IsEmpty(ListTemp(i)) Then
Call MajHist1(True, "Cellule vidée", NomSh, Target(i).Address(0, 0), "<vide>", IIf(ListTemp(i) Like "=*", "'" & ListTemp(i), ListTemp(i)))
ElseIf Target(i).HasFormula Or ListTemp(i) Like "=*" Then
If Target(i).FormulaLocal <> ListTemp(i) Then
Call MajHist1(True, "Cellule modifiée", NomSh, Target(i).Address(0, 0), "'" & Target(i).FormulaLocal, IIf(IsEmpty(ListTemp(i)), "<vide>", "'" & ListTemp(i)))
End If
ElseIf Target(i).Value <> ListTemp(i) Then
Call MajHist1(True, "Cellule modifiée", NomSh, Target(i).Address(0, 0), Target(i).Value, IIf(IsEmpty(ListTemp(i)), "<vide>", ListTemp(i)))
End If
Next
End If
'Détection déplacement des cellules
If DetectDeplace = 2 Then
With ActiveWorkbook.Sheets("SuiviX>>HistCell")
For i = 1 To Target.Count
Call MajHist1(True, "Déplacement de cellule", NomSh, .Range("C" & 1 + Target.Count).Value & " vers " & Target(i).Address(0, 0), IIf(Target(i).HasFormula, "'" & Target(i).FormulaLocal, Target(i).Value), "<inconnu>")
Next
.Range("A" & Target.Count + 2 & ":H" & Target.Count * 2 + 1).Delete shift:=xlShiftUp
End With
DetectDeplace = 0
'Les données sont auto remplies:
ElseIf Target.Count <> Selection.Count Then
For i = 1 To Target.Count
Call MajHist1(True, "Cellule auto-remplie", NomSh, Target(i).Address(0, 0), IIf(Target(i).HasFormula, "'" & Target(i).FormulaLocal, Target(i).Value), "<inconnu>")
Next
End If
End If
End If
End If
End If
End If
If Not SuiviCellNon Then Call P_FeuilSuiviPleine("SuiviX>>HistCell", 500, ActiveWorkbook)
ModeCutCopy = 0
Application.CutCopyMode = 0
Call P_InitVariables(Sh)
Application.EnableEvents = True
End Sub
Private Sub AppSuiviX_SheetSelectionChange(ByVal Sh As Object, ByVal Target As Range)
'If SuiviCellNon Then Exit Sub
If SuiviCellNon And Application.CutCopyMode = 0 Then
Set PlageSel = Selection
AutreClasseur = ActiveWorkbook.Name & "." & Sh.Name
ElseIf Not SuiviCellNon Then
'on met la procédure d'opérations de feuille au cas où on fait des modifications dans cette feuille
'après un renommage de cette dernière.
'############# détection opération de feuille ###########
'on vérifie que la feuille de suivi VBA n'a pas été créée
If Not AjoutShVBA Then
Call OperationsFeuil
Else: AjoutShVBA = False
End If
If SuiviFeuilNon(Sh) Or Sh.Name Like "SuiviX>>Hist*" Then Exit Sub
'############# détection coupe/copie cellule #############
If Application.CutCopyMode <> 0 Then
Call VarCutCopy
Else
AutreClasseur = ""
'############# modifications formats de cellules ############
If LastChange <> "I" And LastChange <> "S" And Not SaveDetect Then Call FormatCell
If Not SaveDetect Then
Call CommentCell: Call FusCell
End If
'on vérifie si toute les feuilles ont été sélectionnées -> message
If Target.Count = Cells.Count Then
MsgBox "SuiviX ne gère pas toutes les cellules de la feuille!", vbExclamation, "SuiviX"
Sh.[A1].Select
Else
'"P_InitVariables" déplacé ici car en mode coupe/copie, si la cellule de déstination n'est choisi qu'au bout de la
'2eme sélection, cela ne va plus.
Call P_InitVariables(Sh)
End If
End If
If Not SuiviCellNon Then Call P_FeuilSuiviPleine("SuiviX>>HistCell", 50, ActiveWorkbook)
LastChange = "": DetectDeplace = 0
Application.EnableEvents = False: SaveDetect = False
NbLig = Selection.Rows.Count: NbCol = Selection.Columns.Count
DerLig = Sh.UsedRange.Cells(Sh.UsedRange.Count).Row: DerCol = Sh.UsedRange.Cells(Sh.UsedRange.Count).Column
'Call P_InitVariables(Sh)
'on initialise l'état opération de feuille
OpSh = ""
Application.EnableEvents = True
End If
End Sub
Private Function SuiviFeuilNon(Feuil As Worksheet) As Boolean
Dim Pos As Integer
With ActiveWorkbook
On Error Resume Next
Pos = WorksheetFunction.Match(Feuil.Name, .Sheets("SuiviX>>HistCell").Range("J2:J" & .Sheets("SuiviX>>HistCell").[J65536].End(xlUp).Row), 0)
If Err.Number > 0 And Not Feuil.Name Like "SuiviX>>Hist*" And Not .Sheets("SuiviX>>HistCell").[M2] Then SuiviFeuilNon = True
On Error GoTo 0
End With
End Function
Private Sub VarCutCopy()
Dim i As Long, j As Long
Dim nCol As Long, nLig As Long 'v2.21
If PlageSel.Count = 1 Then
ReDim ListDest(1 To 1) 'v2.21
ListDest(1) = IIf(Selection.HasFormula, "'" & Selection.FormulaLocal, Selection.Value) 'v2.21
AdressCutCopy = PlageSel.Address(0, 0)
ReDim ListCutCopy(1 To 1): ListCutCopy(1) = PlageSel.Address(0, 0)
Else
If Selection.Count <= PlageSel.Count Then 'v2.21
nCol = PlageSel.Columns.Count 'v2.21
nLig = PlageSel.Rows.Count 'v2.21
ReDim ListDest(1 To Selection.Resize(nLig, nCol).Count) 'v2.21
For i = 1 To Selection.Resize(nLig, nCol).Count 'v2.21
ListDest(i) = IIf(Selection.Resize(nLig, nCol)(i).HasFormula, "'" & Selection.Resize(nLig, nCol)(i).FormulaLocal, Selection.Resize(nLig, nCol)(i).Value) 'v2.21
Next 'v2.21
Else 'v2.21
ReDim ListDest(1 To Selection.Count) 'v2.21
For i = 1 To Selection.Count 'v2.21
ListDest(i) = IIf(Selection(i).HasFormula, "'" & Selection(i).FormulaLocal, Selection(i).Value) 'v2.21
Next 'v2.21
End If 'v2.21
ReDim ListCutCopy(1 To PlageSel.Count)
For i = 1 To PlageSel.Count
ListCutCopy(i) = PlageSel(i).Address(0, 0)
Next
End If
ModeCutCopy = Application.CutCopyMode
End Sub
Private Sub DetecInsSuppCell(Feuille As Worksheet)
Dim Test As String
On Error Resume Next
'détection de insertion/suppression d'une plage de cellules avec décalage horizontal
Test = CellD.Address
If Err.Number > 0 Then
On Error GoTo 0
LastChange = "I"
Call MajHist1(OpInsSupCel, "insertion cellule, décalage droite", Feuille.Name, Selection.Address(0, 0))
ElseIf CellD.Column < 256 Then
LastChange = "S"
Set NewSel = Selection(1)
Call MajHist1(OpInsSupCel, "suppression cellule ,décalage gauche", Feuille.Name, Selection.Address(0, 0))
Else
'détection de insertion/suppression d'une plage de cellules avec décalage vertical
On Error Resume Next
Test = CellB.Address
If Err.Number > 0 Then
On Error GoTo 0
LastChange = "I"
Call MajHist1(OpInsSupCel, "insertion cellule, décalage bas", Feuille.Name, Selection.Address(0, 0))
ElseIf CellB.Row < 65536 Then
LastChange = "S"
Set NewSel = Selection(1)
Call MajHist1(OpInsSupCel, "suppression cellule, décalage haut", Feuille.Name, Selection.Address(0, 0))
'si pas d'insertion/suppression de cellule(s)
Else: LastChange = ""
End If
End If
End Sub
'############# commentaires de cellules ############
Private Sub CommentCell()
'la condition permet de prendre en compte un renommage de feuille
'suivi d'un changement de format sur la cellule active.
If Not PlageSel.Comment Is Nothing Then
'si ajout
If TextComment = "" Then
Call MajHist1(OpCommentCel, "ajout commentaire cellule", IIf(OpSh = "r" And NameSh <> NomSh, NomSh, NameSh), PlageSel.Address(0, 0), PlageSel.Comment.Text, "<vide>")
'si modification
ElseIf TextComment <> PlageSel.Comment.Text Then
Call MajHist1(OpCommentCel, "modification commentaire cellule", IIf(OpSh = "r" And NameSh <> NomSh, NomSh, NameSh), PlageSel.Address(0, 0), PlageSel.Comment.Text, TextComment)
End If
'si suppression
ElseIf TextComment <> "" And PlageSel(1).Comment Is Nothing Then
Call MajHist1(OpCommentCel, "suppression commentaire cellule", IIf(OpSh = "r" And NameSh <> NomSh, NomSh, NameSh), PlageSel.Address(0, 0), "<vide>", TextComment)
End If
End Sub
'############# cellules fusionnées ############
Private Sub FusCell()
'la condition permet de prendre en compte un renommage de feuille
'suivi d'un changement de format sur la cellule active.
'cellules fusionnées
If (PlageFus = False And PlageSel.MergeCells) Or (IsNull(PlageFus) And PlageSel.MergeCells) Then
Call MajHist1(OpFusCel, "cellules fusionnées", IIf(OpSh = "r" And NameSh <> NomSh, NomSh, NameSh), PlageSel.Address(0, 0))
'cellules dé-fusionnées
ElseIf (PlageFus = True And Not PlageSel.MergeCells) Or (IsNull(PlageFus) And Not PlageSel.MergeCells) Then
Call MajHist1(OpFusCel, "cellules dé-fusionnées", IIf(OpSh = "r" And NameSh <> NomSh, NomSh, NameSh), PlageSel.Address(0, 0))
End If
End Sub
Private Sub MajHist1(OpSuivi As Boolean, OpName As String, Feuil As String, OpAdresse As String, Optional NCont As Variant, Optional ACont As Variant)
If Not OpSuivi Then Exit Sub
With ActiveWorkbook.Sheets("SuiviX>>HistCell")
If Not IsEmpty(.Range("A2").Value) Then .Range("A2:H2").Insert: .Range("A2:H2").Clear
.Range("A2").Value = OpName
.Range("B2").Value = Feuil
.Range("C2").Value = "'" & OpAdresse
If Not IsMissing(NCont) Then .Range("D2").Value = NCont
If Not IsMissing(ACont) Then .Range("E2").Value = ACont
Call P_AutDaTi("SuiviX>>HistCell")
End With
End Sub
Private Sub MajHistCColle(OpName As String)
Dim i As Long, x As Long, Lig As Long, Col As Long, LastLig As Long
If Not OpCColle Then Exit Sub
With ActiveWorkbook.Sheets("SuiviX>>HistCell")
'Si une cellule de déstination
If Selection.Count = 1 Then
If Not IsEmpty(.Range("A2").Value) Then .Range("A2:H2").Insert: .Range("A2:H2").Clear
.Range("A2").Value = OpName
' .Range("B2").Value = IIf(NomSh <> ActiveWorkbook.ActiveSheet.Name, NomSh & " vers " & ActiveWorkbook.ActiveSheet.Name, NomSh)
If AutreClasseur <> "" Then
.Range("B2").Value = AutreClasseur & " vers " & ActiveWorkbook.ActiveSheet.Name
ElseIf NomSh <> ActiveWorkbook.ActiveSheet.Name Then
.Range("B2").Value = NomSh & " vers " & ActiveWorkbook.ActiveSheet.Name
Else: .Range("B2").Value = NomSh
End If
.Range("C2").Value = AdressCutCopy & " vers " & Selection.Address(0, 0)
Selection.Copy .Range("D2")
If Selection.HasFormula Then .Range("D2").Value = "'" & Selection.FormulaLocal
' .Range("E2").Value = "<inconnu>"
.Range("E2").Value = ListDest(1) 'v2.21
Call P_AutDaTi("SuiviX>>HistCell")
'Si plusieurs cellules de déstination
Else
'Si le nbre des cellules de déstination est égal aux nbre de cellules sources
If Selection.Count = PlageSel.Count Then
For i = 1 To Selection.Count
If Not IsEmpty(.Range("A2").Value) Then .Range("A2:H2").Insert: .Range("A2:H2").Clear
.Range("A2").Value = OpName
' .Range("B2").Value = IIf(NomSh <> ActiveWorkbook.ActiveSheet.Name, NomSh & " vers " & ActiveWorkbook.ActiveSheet.Name, NomSh)
If AutreClasseur <> "" Then
.Range("B2").Value = AutreClasseur & " vers " & ActiveWorkbook.ActiveSheet.Name
ElseIf NomSh <> ActiveWorkbook.ActiveSheet.Name Then
.Range("B2").Value = NomSh & " vers " & ActiveWorkbook.ActiveSheet.Name
Else: .Range("B2").Value = NomSh
End If
.Range("C2").Value = ListCutCopy(i) & " vers " & Selection(i).Address(0, 0)
Selection(i).Copy .Range("D2")
If Selection(i).HasFormula Then .Range("D2").Value = "'" & Selection(i).FormulaLocal
' .Range("E2").Value = "<inconnu>"
.Range("E2").Value = ListDest(i) 'v2.21
Call P_AutDaTi("SuiviX>>HistCell")
Next
'Si le nbre des cellules de déstination sont supérieures aux cellules sources
Else
'Si le nbre de colonnes de cellules déstination sont <= aux nbre de colonnes de cellules sources
If Selection.Columns.Count <= PlageSel.Columns.Count Then
x = 0
Do
For i = 1 To PlageSel.Count
x = x + 1
If Not IsEmpty(.Range("A2").Value) Then .Range("A2:H2").Insert: .Range("A2:H2").Clear
.Range("A2").Value = OpName
' .Range("B2").Value = IIf(NomSh <> ActiveWorkbook.ActiveSheet.Name, NomSh & " vers " & ActiveWorkbook.ActiveSheet.Name, NomSh)
If AutreClasseur <> "" Then
.Range("B2").Value = AutreClasseur & " vers " & ActiveWorkbook.ActiveSheet.Name
ElseIf NomSh <> ActiveWorkbook.ActiveSheet.Name Then
.Range("B2").Value = NomSh & " vers " & ActiveWorkbook.ActiveSheet.Name
Else: .Range("B2").Value = NomSh
End If
.Range("C2").Value = ListCutCopy(i) & " vers " & Selection(x).Address(0, 0)
Selection(i).Copy .Range("D2")
If Selection(x).HasFormula Then .Range("D2").Value = "'" & Selection(x).FormulaLocal
' .Range("E2").Value = "<inconnu>"
.Range("E2").Value = ListDest(x) 'v2.21
Call P_AutDaTi("SuiviX>>HistCell")
Next
Loop Until x = Selection.Count
'Si le nbre de colonnes de cellules déstination sont > aux nbre de colonnes de cellules sources
ElseIf Selection.Columns.Count > PlageSel.Columns.Count Then
x = 1
Do
For Lig = 1 To PlageSel.Rows.Count
Do
For Col = 1 To PlageSel.Columns.Count
LastLig = Selection(x).Row
If Not IsEmpty(.Range("A2").Value) Then .Range("A2:H2").Insert: .Range("A2:H2").Clear
.Range("A2").Value = OpName
' .Range("B2").Value = IIf(NomSh <> ActiveWorkbook.ActiveSheet.Name, NomSh & " vers " & ActiveWorkbook.ActiveSheet.Name, NomSh)
If AutreClasseur <> "" Then
.Range("B2").Value = AutreClasseur & " vers " & ActiveWorkbook.ActiveSheet.Name
ElseIf NomSh <> ActiveWorkbook.ActiveSheet.Name Then
.Range("B2").Value = NomSh & " vers " & ActiveWorkbook.ActiveSheet.Name
Else: .Range("B2").Value = NomSh
End If
.Range("C2").Value = PlageSel(Lig, Col).Address(0, 0) & " vers " & Selection(x).Address(0, 0)
PlageSel(Lig, Col).Copy .Range("D2")
If Selection(x).HasFormula Then .Range("D2").Value = "'" & Selection(x).FormulaLocal
' .Range("E2").Value = "<inconnu>"
.Range("E2").Value = ListDest(x) 'v2.21
Call P_AutDaTi("SuiviX>>HistCell")
x = x + 1
Next
Loop While LastLig = Selection(x).Row
Next
Loop Until x > Selection.Count
End If
End If
End If
End With
AutreClasseur = ""
End Sub
Private Sub FormatCell()
Dim Texte As String
With ActiveWorkbook.Sheets("SuiviX>>HistCell")
'-------- opération couleur de fond ---------
If OpCoulFond Then
If CoulFond <> PlageSel.Interior.ColorIndex Or (IsNull(CoulFond) And Not IsNull(PlageSel.Interior.ColorIndex)) Then
If Not IsEmpty(.Range("A2").Value) Then .Range("A2:H2").Insert: .Range("A2:H2").Clear
.Range("D2").Interior.ColorIndex = PlageSel.Interior.ColorIndex
If Not IsNull(CoulFond) Then
.Range("E2").Interior.ColorIndex = CoulFond
Else: .Range("E2").Value = "<multiple couleur de fond>"
End If
Texte = "couleur de fond,"
End If
End If
'-------- opération couleur de police ---------
If OpCoulPol Then
If CoulPolice <> PlageSel.Font.ColorIndex Or (IsNull(CoulPolice) And Not IsNull(PlageSel.Font.ColorIndex)) Then
If Texte = "" Then
If Not IsEmpty(.Range("A2").Value) Then .Range("A2:H2").Insert: .Range("A2:H2").Clear
End If
.Range("D2").Font.ColorIndex = PlageSel.Font.ColorIndex: .Range("D2").Value = "<nouvelle couleur>"
If Not IsNull(CoulPolice) Then
.Range("E2").Font.ColorIndex = CoulPolice: .Range("E2").Value = "<ancienne couleur>"
Else: .Range("E2").Value = .Range("E2").Value & "<multiple couleur police>"
End If
Texte = Texte & "couleur police,"
End If
End If
'-------- MAJ feuille de suivi ---------
If Texte <> "" Then
Texte = Left(Texte, Len(Texte) - 1)
.Range("A2").Value = Texte
'la condition permet de prendre en compte un renommage de feuille
'suivi d'un changement de format sur la cellule active.
.Range("B2").Value = IIf(OpSh = "r" And NameSh <> NomSh, NomSh, NameSh)
.Range("C2").Value = PlageSel.Address(0, 0)
Texte = ""
Call P_AutDaTi("SuiviX>>HistCell")
End If
End With
End Sub
Private Sub OperationsFeuil()
Dim NewListSh() As Variant, PosSh As Long
Application.EnableEvents = False
'on initialise l'état
OpSh = ""
'on écrit la nouvelle disposition dans NewListSh
With ActiveWorkbook
ReDim NewListSh(1 To .Sheets.Count)
For i = 1 To .Sheets.Count
NewListSh(i) = .Sheets(i).Name
Next
'---------- détection création de feuille ----------
If .Sheets.Count > NbSh Then
OpSh = "c"
Call MajHist1(OpFeuil, "Création feuille", .ActiveSheet.Name & " devant " & NomSh, "")
'---------- détection suppression de feuille ----------
ElseIf .Sheets.Count < NbSh Then
'on vérifie si la feuille de suivi "SuiviX>>HistCell" a été supprimé, dans ce cas on repasse "SuiviCellNon" à vrai
If NomSh = "SuiviX>>HistCell" Then
SuiviCellNon = True
Application.EnableEvents = True
Exit Sub
End If
OpSh = "s"
Call MajHist1(OpFeuil, "Suppression feuille", NomSh, "")
Set PlageSel = Nothing
Else
'---------- renommage de feuille ----------
'si le nom stocké dans la variable NomSh n'est pas trouvé dans la nouvelle disposition (NewListSh),
'alors il s'agit d'un renommage.
On Error Resume Next
PosSh = WorksheetFunction.Match(NomSh, NewListSh, 0)
If Err.Number > 0 Then
On Error GoTo 0
'on cherche la position de la feuille renommée au cas où elle a également été déplacée!
'de la nouvelle liste NewListSh dans l'ancienne liste ListSh
For i = LBound(NewListSh) To UBound(NewListSh)
On Error Resume Next
PosSh = WorksheetFunction.Match(NewListSh(i), ListSh, 0)
If Err.Number > 0 Then
ISh = i
Exit For
End If
Next
OpSh = "r"
Call MajHist1(OpFeuil, "Renommage feuille", NomSh & " en " & .Sheets(ISh).Name, "")
'on vérifie que la feuille est suivi pour les opérations de cellule pour mettre à jour la feuille Hist si nécessaire
On Error GoTo 0
On Error Resume Next
PosSh = WorksheetFunction.Match(NomSh, .Sheets("SuiviX>>HistCell").Range("J2:J" & .Sheets("SuiviX>>HistCell").[J65536].End(xlUp).Row), 0)
If Err.Number = 0 Then
On Error GoTo 0
.Sheets("SuiviX>>HistCell").Range("J" & PosSh + 1).Value = .Sheets(ISh).Name
End If
'on met à jour les variables au cas où la feuille a également été déplacée!
NomSh = .Sheets(ISh).Name
ListSh(ISh) = NomSh
End If
On Error GoTo 0
End If
'---------- déplacement de feuille ----------
If OpSh <> "s" And OpSh <> "c" Then
For i = 1 To .Sheets.Count
If .Sheets(i).Name <> ListSh(i) Then
'on cherche l'emplacement de la feuille
PosSh = WorksheetFunction.Match(NomSh, NewListSh, 0)
If PosSh < .Sheets.Count Then
Call MajHist1(OpFeuil, "Déplacement feuille", NomSh & " devant " & .Sheets(PosSh + 1).Name, "")
Else: Call MajHist1(OpFeuil, "Déplacement feuille", NomSh & " en dernier", "")
End If
Exit For
End If
Next
End If
'---------- ATTENTION -------------
'La MAJ variables ce fait dans les procédures qui appelent ce code, en tenir compte au cas où
End With
Application.EnableEvents = True
End Sub