Skip to content

Instantly share code, notes, and snippets.

@freakinbook
Created March 24, 2021 21:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save freakinbook/b7adca82e8312515e11d4e8a6d697c37 to your computer and use it in GitHub Desktop.
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.
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