VERSION 1.0 CLASS BEGIN MultiUse = -1 'True END Attribute VB_Name = "API_WordEditGuard" Attribute VB_GlobalNameSpace = False Attribute VB_Creatable = False Attribute VB_PredeclaredId = False Attribute VB_Exposed = False ' ========= Оболочка для редактирования документа в Мастере Текстов =================== ' Shared module version: 20220613 ' Tested in: ' Depends on: API_WordWrapper ' Required reference: Word Option Explicit ' Note: should synchronize with DocumentEditor Private Const ERROR_HIGHLIGHT_COLOR = wdViolet Private Const AUTOMATON_USER_NAME = "Мастер текстов" Private Const AUTOMATON_USER_INIT = "МТ" Private Const IGNORE_BM_PREFIX = "zIGNORE_" Private Const AUTO_COMMENT_PREFIX = "AR" Private document_ As Word.Document Private word_ As API_WordWrapper Private userName_ As String Private userInitials_ As String Private trackRevisions_ As Boolean Private includeHiddenText_ As Boolean Private includeFieldCodes_ As Boolean Private deletedTextMark_ As WdDeletedTextMark Private noProofing_ As Boolean Private Sub Class_Terminate() Set document_ = Nothing End Sub Public Function Init(target As API_WordWrapper) Set document_ = target.Document Set word_ = target End Function Public Function InitDoc(target As Word.Document) Set document_ = target Set word_ = Nothing End Function Public Property Get Document() As Word.Document Set Document = document_ End Property Public Property Get Wrapper() As API_WordWrapper Set Wrapper = word_ End Property Public Function BeginEdit(bTrackRevisions As Boolean) With document_ userName_ = .Application.UserName userInitials_ = .Application.UserInitials trackRevisions_ = .TrackRevisions includeHiddenText_ = .Range.TextRetrievalMode.IncludeHiddenText includeFieldCodes_ = .Range.TextRetrievalMode.IncludeFieldCodes deletedTextMark_ = .Application.Options.DeletedTextMark noProofing_ = .Range.NoProofing .ActiveWindow.View.ReadingLayout = False .Range.NoProofing = True .Application.ScreenUpdating = False End With Call HideIgnored Call ClearExistingFormat On Error Resume Next ' Срабатывает, если офис не 2013 и параметра Options.UseLocalUserInfo не существует With document_ .TrackRevisions = bTrackRevisions .Range.TextRetrievalMode.IncludeHiddenText = False .Range.TextRetrievalMode.IncludeFieldCodes = False .Application.Options.DeletedTextMark = wdDeletedTextMarkHidden .Application.UserName = AUTOMATON_USER_NAME .Application.UserInitials = AUTOMATON_USER_INIT .Application.Options.UseLocalUserInfo = True End With On Error GoTo 0 End Function Public Function EndEdit() If userName_ = vbNullString Then _ userName_ = VBA.Environ("username") On Error Resume Next With document_ .TrackRevisions = trackRevisions_ Call UnHideIgnored .Application.UserName = userName_ .Application.UserInitials = userInitials_ .Range.TextRetrievalMode.IncludeHiddenText = includeHiddenText_ .Range.TextRetrievalMode.IncludeFieldCodes = includeFieldCodes_ .Application.Options.DeletedTextMark = deletedTextMark_ .Range.NoProofing = noProofing_ .Application.ScreenUpdating = True Call .Application.ScreenRefresh End With End Function Public Function SaveAndShowDiff() Dim oldName$: oldName = document_.FullName Dim newName$: newName = oldName newName = VBA.Left(newName, VBA.Len(newName) - VBA.Len(".docx")) newName = newName & "_" & VBA.Format(VBA.Now(), "MMddhhmm") & ".docx" Call document_.SaveAs(newName) Dim iWrap As New API_WordWrapper: Call iWrap.OpenDocument(oldName) Call document_.Application.CompareDocuments(iWrap.Document, document_, _ Destination:=wdCompareDestinationNew, _ CompareFields:=False, _ RevisedAuthor:=AUTOMATON_USER_NAME) End Function Public Function BookmarkIgnored(target As Word.Range) As String Dim nIndex&: nIndex = document_.Bookmarks.Count + 1 Dim sBookmark$: sBookmark = IGNORE_BM_PREFIX & nIndex Do While document_.Bookmarks.Exists(sBookmark) nIndex = nIndex - 1 sBookmark = IGNORE_BM_PREFIX & nIndex Loop BookmarkIgnored = sBookmark If target.Bookmarks.Add(sBookmark, target) Is Nothing Then _ Call Err.Raise(vbObjectError) End Function ' ============== Private Function HideIgnored() ' Скрываем игнорируемые части текста Dim trackRev As Boolean: trackRev = document_.TrackRevisions document_.TrackRevisions = False Dim aBookmark As Word.Bookmark For Each aBookmark In document_.Bookmarks If IsBookmarkIgnored(aBookmark.Name) Then _ aBookmark.Range.Font.Hidden = True Next aBookmark document_.TrackRevisions = trackRev End Function Private Function UnHideIgnored() ' Отображаем игнорируемые части текста Dim trackRev As Boolean: trackRev = document_.TrackRevisions document_.TrackRevisions = False Dim aBookmark As Word.Bookmark For Each aBookmark In document_.Bookmarks If IsBookmarkIgnored(aBookmark.Name) Then _ aBookmark.Range.Font.Hidden = False Next aBookmark document_.TrackRevisions = trackRev End Function Private Function IsBookmarkIgnored(sBookmark$) As Boolean IsBookmarkIgnored = sBookmark Like IGNORE_BM_PREFIX & "*" End Function Private Function ClearExistingFormat() ' Очищаем форматирование в документе Dim trackRev As Boolean: trackRev = document_.TrackRevisions document_.TrackRevisions = False ' Очищаем выделение цветом ссылок на термины Dim rFind As Word.Range: Set rFind = document_.Range Dim nStart&: nStart = -1 With rFind.Find .Forward = True .Font.Hidden = False .Highlight = True .Format = True .MatchPhrase = False .MatchCase = False .MatchWholeWord = False .MatchWildcards = False End With Do While rFind.Find.Execute If rFind.HighlightColorIndex = ERROR_HIGHLIGHT_COLOR Then rFind.HighlightColorIndex = wdNoHighlight End If Call rFind.Collapse(wdCollapseEnd) If nStart = rFind.Start Then ' Гарантируем, что не зациклимся Debug.Print "Очистка текста зациклилась" Exit Do Else nStart = rFind.Start End If Loop Dim i&: i = 1 Do While True If i > document_.Comments.Count Then _ Exit Do If VBA.Left(document_.Comments(i).Range.Text, 2) = AUTO_COMMENT_PREFIX Then document_.Comments(i).Delete Else i = i + 1 End If Loop document_.TrackRevisions = trackRev End Function