Created
March 24, 2021 21:41
-
-
Save freakinbook/b7adca82e8312515e11d4e8a6d697c37 to your computer and use it in GitHub Desktop.
This VBA code replaces all the occurences of picture references as text for actual cross references.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Attribute VB_Name = "ChangeTextToRefs" | |
Dim picDic | |
Private Sub FindByRegexAndReplace(textToFind As String) | |
Attribute FindByRegexAndReplace.VB_ProcData.VB_Invoke_Func = "Normal.NewMacros.FindAndReplacePicRef" | |
Dim doc As Document | |
Dim range As range | |
Dim picNumber As String | |
Dim errorLog As String | |
Dim errorCount As Integer | |
On Error GoTo ErrorRef | |
errorCount = 0 | |
Set doc = ActiveDocument | |
Set range = doc.Content | |
With range.Find | |
.ClearFormatting | |
.Text = textToFind | |
.Forward = True | |
.Wrap = wdFindStop | |
.MatchWildcards = True | |
While .Execute | |
If .found Then | |
range.Select | |
picNumber = GetNumber(range.Text, ".") | |
Selection.InsertCrossReference ReferenceType:="Рисунок", ReferenceKind:= _ | |
wdOnlyLabelAndNumber, ReferenceItem:=picDic(picNumber), InsertAsHyperlink:=True, _ | |
IncludePosition:=False, SeparateNumbers:=False, SeparatorString:=" " | |
range.Collapse wdCollapseEnd | |
Selection.Collapse wdCollapseEnd | |
End If | |
Wend | |
End With | |
If errorCount > 0 Then | |
MsgBox (errorLog) | |
End If | |
ErrorRef: | |
If errorCount = 0 Then | |
errorLog = "Проблема с рисунками:" & vbNewLine & picNumber | |
Else | |
errorLog = errorLog & ", " & picNumber | |
End If | |
Options.DefaultHighlightColorIndex = wdYellow | |
Selection.range.HighlightColorIndex = wdYellow | |
errorCount = errorCount + 1 | |
Err.Clear | |
Resume Next | |
End Sub | |
Sub FindAndReplacePicRef() | |
Attribute FindAndReplacePicRef.VB_ProcData.VB_Invoke_Func = "Normal.NewMacros.FindAndReplacePicRef2" | |
Dim rawTitle As String | |
Dim picNumbers() As String | |
Dim regexTitle As String | |
Dim bookmarkCount As Integer | |
Dim i As Integer: i = 1 | |
Dim repeatNumber As String | |
Set picDic = CreateObject("Scripting.Dictionary") | |
rawTitle = InputBox("Введите пример ссылки на рисунок в тексте. Например:" & Chr(34) & "(Рисунок 13)" _ | |
& Chr(34), "Замена ссылок на рисунки в тексте") | |
If Trim(rawTitle & vbNullString) = vbNullString Then | |
Exit Sub | |
End If | |
myBookmarks = ActiveDocument.GetCrossReferenceItems("Рисунок") | |
bookmarkCount = UBound(myBookmarks) - LBound(myBookmarks) + 1 | |
ReDim picNumbers(bookmarkCount) | |
regexTitle = GetRefTitle(rawTitle) | |
repeatNumber = "" | |
Do While i <= bookmarkCount | |
Dim picName As String | |
picName = myBookmarks(i) | |
picNumbers(i) = GetNumber(picName, ".") | |
repeatNumber = picNumbers(i) | |
picDic.Add picNumbers(i), CStr(i) | |
On Error GoTo ErrorDictionary | |
i = i + 1 | |
Loop | |
On Error GoTo ErrorFindReplace | |
FindByRegexAndReplace regexTitle | |
Exit Sub | |
ErrorDictionary: | |
MsgBox "Найден повторяющийся номер рисунка: " & repeatNumber & _ | |
". Измените номер рисунка и попробуйте ещё раз.", vbOKOnly, _ | |
"Ошибка" | |
Exit Sub | |
ErrorFindReplace: | |
MsgBox "Ошибка при вставке ссылок. Обратитесь к разработчику.", vbOKOnly, _ | |
"Ошибка" | |
End Sub | |
Private Function GetNumber(s As String, delimeter As String) As String | |
Dim foundNumber As Boolean | |
Dim i As Long | |
Dim result As String | |
Dim currentChar As String | |
foundNumber = False | |
result = "" | |
For i = 1 To Len(s) | |
currentChar = Mid(s, i, 1) | |
If IsNumeric(currentChar) Then | |
foundNumber = True | |
result = result & currentChar | |
Else | |
If currentChar = delimeter And result <> "" Then | |
result = result & currentChar | |
Else | |
If foundNumber Then | |
Exit For | |
End If | |
End If | |
End If | |
Next i | |
If foundNumber Then | |
GetNumber = result | |
End If | |
End Function | |
Private Function GetRefTitle(s As String) As String | |
Dim last As Boolean | |
Dim i As Long | |
Dim trimmed As String | |
Dim number As String | |
Dim result As String | |
Dim pattern As String | |
Dim replacedNumber As String | |
Dim thisSymbol As String | |
trimmed = Trim(s) | |
trimmed = Replace(trimmed, "(", "") | |
trimmed = Replace(trimmed, ")", "") | |
last = True | |
number = "" | |
replacedNumber = "" | |
result = trimmed | |
pattern = "" | |
thisSymbol = "" | |
For i = Len(trimmed) To 1 Step -1 | |
thisSymbol = Mid(trimmed, i, 1) | |
If IsNumeric(thisSymbol) Then | |
number = thisSymbol & number | |
ElseIf IsDelimeter(thisSymbol) Then | |
If (last) Then | |
pattern = thisSymbol & "[0-9]*>" | |
number = thisSymbol & number | |
last = False | |
replacedNumber = number | |
ElseIf replacedNumber <> number Then | |
pattern = "[0-9]*" & pattern | |
End If | |
ElseIf IsSpace(thisSymbol) Then | |
If (last) Then | |
pattern = "[0-9]*>" | |
ElseIf replacedNumber <> number Then | |
pattern = "[0-9]*" & pattern | |
End If | |
Exit For | |
End If | |
Next i | |
pattern = "(" & pattern & ")" | |
result = Replace(result, number, pattern) | |
GetRefTitle = result | |
End Function | |
Private Function IsDelimeter(s As String) As Boolean | |
IsDelimeter = False | |
If s = "." Or s = "," Then | |
IsDelimeter = True | |
End If | |
End Function | |
Private Function IsSpace(s As String) As Boolean | |
IsSpace = False | |
If s = " " Then | |
IsSpace = True | |
End If | |
End Function |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment