Всем привет! Недавно я собирал большое количество документов в Word с сайта с помощью скрипта. К сожалению, некоторые картинки и таблицы вышли за границы документов. Я бы хотел проверить все документы на данный баг, а исправить уже вручную. Пример файла с картинкой, которая выходит за границы выложил на файлообменник из-за большого веса: https://transfiles.ru/08dwe Вариант, который предложил GPT, но работает очень странно:
Код
Sub CheckShapesAndTablesOutOfMargins() Dim folderPath As String Dim fileSystem As Object Dim folder As Object
Application.ScreenUpdating = False
' Укажите путь к основной папке с подпапками folderPath = "C:\Users\"
' Создаем FileSystemObject для работы с файлами и папками Set fileSystem = CreateObject("Scripting.FileSystemObject") Set folder = fileSystem.GetFolder(folderPath)
' Обходим все подпапки Call CheckSubFolders(folder, fileSystem)
' Очистка Set fileSystem = Nothing Set folder = Nothing
Application.ScreenUpdating = True MsgBox "End" End Sub
Sub CheckSubFolders(parentFolder As Object, fileSystem As Object) Dim subFolder As Object
' Проходим по всем подпапкам в текущей папке For Each subFolder In parentFolder.Subfolders ' Формируем путь к документу Word в текущей подпапке Dim docPath As String docPath = subFolder.Path & "\" & subFolder.Name & ".docx"
' Проверяем, существует ли файл If fileSystem.FileExists(docPath) Then ' Вызываем функцию для проверки объектов, выходящих за поля If CheckFileForOutOfMarginObjects(docPath) Then Debug.Print "Найден объект, выходящий за границы полей в файле: " & docPath End If End If Next subFolder End Sub
Function CheckFileForOutOfMarginObjects(filePath As String) As Boolean Dim doc As Document Dim shape As InlineShape Dim floatShape As Shape Dim tbl As Table Dim cell As Cell Dim pageWidth As Single Dim leftMargin As Single Dim rightMargin As Single Dim topMargin As Single Dim bottomMargin As Single Dim foundOutOfMargin As Boolean Dim shapeLeft As Single Dim shapeRight As Single Dim shapeTop As Single Dim shapeBottom As Single Dim cellLeft As Single Dim cellRight As Single Dim cellTop As Single Dim cellBottom As Single
' Проверка каждой InlineShape For Each shape In doc.InlineShapes shapeLeft = shape.Range.Information(wdHorizontalPositionRelativeToPage) shapeRight = shapeLeft + shape.Width shapeTop = shape.Range.Information(wdVerticalPositionRelativeToPage) shapeBottom = shapeTop + shape.Height If shapeLeft < leftMargin Or shapeRight > pageWidth - rightMargin Or shapeTop < topMargin Or shapeBottom > pageWidth - bottomMargin Then foundOutOfMargin = True Exit For End If Next shape
' Проверка каждой плавающей Shape For Each floatShape In doc.Shapes If floatShape.Type = msoPicture Then shapeLeft = floatShape.Left + floatShape.Anchor.Paragraphs(1).Range.Information(wdHorizontalPositionRelativeToPage) shapeRight = shapeLeft + floatShape.Width shapeTop = floatShape.Top + floatShape.Anchor.Paragraphs(1).Range.Information(wdVerticalPositionRelativeToPage) shapeBottom = shapeTop + floatShape.Height If shapeLeft < leftMargin Or shapeRight > pageWidth - rightMargin Or shapeTop < topMargin Or shapeBottom > pageWidth - bottomMargin Then foundOutOfMargin = True Exit For End If End If Next floatShape
' Проверка каждой таблицы For Each tbl In doc.Tables For Each cell In tbl.Range.Cells cellLeft = cell.Range.Information(wdHorizontalPositionRelativeToPage) cellRight = cellLeft + cell.Width cellTop = cell.Range.Information(wdVerticalPositionRelativeToPage) cellBottom = cellTop + cell.Height If cellLeft < leftMargin Or cellRight > pageWidth - rightMargin Or cellTop < topMargin Or cellBottom > pageWidth - bottomMargin Then foundOutOfMargin = True Exit For End If Next cell If foundOutOfMargin Then Exit For Next tbl
' Закрываем документ без сохранения doc.Close False
' Возвращаем результат CheckFileForOutOfMarginObjects = foundOutOfMargin End Function
Вроде удалось победить с изображениями, но с таблицами все еще беда....
Код
Sub CheckPageBounds() Dim doc As Document Dim shape As shape Dim inlineShape As inlineShape Dim tbl As Table Dim overflowFound As Boolean Dim pageWidth As Single Dim pageHeight As Single Dim objLeft As Single Dim objTop As Single Dim objWidth As Single Dim objHeight As Single Dim cell As cell Dim msg As String
' Установка ссылки на активный документ Set doc = ActiveDocument overflowFound = False msg = ""
' Определение размеров страницы pageWidth = doc.PageSetup.pageWidth pageHeight = doc.PageSetup.pageHeight
' Проверка картинок и фигур For Each shape In doc.Shapes objLeft = shape.Left objTop = shape.Top objWidth = shape.Width objHeight = shape.Height
' Проверка выхода за границы страницы If objLeft < 0 Or objTop < 0 Or objLeft + objWidth > pageWidth Or objTop + objHeight > pageHeight Then overflowFound = True msg = msg & "Фигура на странице " & shape.Anchor.Information(wdActiveEndAdjustedPageNumber) & vbCrLf End If Next shape
' Проверка встроенных изображений For Each inlineShape In doc.InlineShapes objLeft = inlineShape.Range.Information(wdHorizontalPositionRelativeToTextBoundary) objTop = inlineShape.Range.Information(wdVerticalPositionRelativeToPage) objWidth = inlineShape.Width objHeight = inlineShape.Height
' Проверка выхода за границы страницы If objLeft < 0 Or objTop < 0 Or objLeft + objWidth > pageWidth Or objTop + objHeight > pageHeight Then overflowFound = True msg = msg & "Встроенное изображение на странице " & inlineShape.Range.Information(wdActiveEndAdjustedPageNumber) & vbCrLf End If Next inlineShape
' Вывод сообщения пользователю If overflowFound Then MsgBox "Следующие объекты выходят за границы листа документа:" & vbCrLf & msg, vbExclamation Else MsgBox "Все объекты в документе находятся в пределах листа.", vbInformation End If End Sub
В итоге победил историю тем, что таблицы выходили за края только с изображениями, поэтому оказалось достаточно этого:
Для одного открытого дока
Sub CheckPageBounds2() Dim doc As Document Dim inlineShape As inlineShape Dim overflowFound As Boolean Dim pageWidth As Single Dim pageHeight As Single Dim objLeft As Single Dim objTop As Single Dim objWidth As Single Dim objHeight As Single Dim msg As String
' Установка ссылки на активный документ Set doc = ActiveDocument overflowFound = False msg = ""
' Определение размеров страницы pageWidth = doc.PageSetup.pageWidth pageHeight = doc.PageSetup.pageHeight
' Проверка встроенных изображений For Each inlineShape In doc.InlineShapes objLeft = inlineShape.Range.Information(wdHorizontalPositionRelativeToTextBoundary) objTop = inlineShape.Range.Information(wdVerticalPositionRelativeToTextBoundary) ' Пробуем альтернативный метод objWidth = inlineShape.Width objHeight = inlineShape.Height
' Проверка выхода за границы страницы If objLeft < -1 Or objTop < -1 Or objLeft + objWidth > pageWidth Or objTop + objHeight > pageHeight Then overflowFound = True msg = msg & "Встроенное изображение на странице " & inlineShape.Range.Information(wdActiveEndAdjustedPageNumber) & vbCrLf End If Next inlineShape
' Вывод сообщения пользователю If overflowFound Then MsgBox "Следующие объекты выходят за границы листа документа:" & vbCrLf & msg, vbExclamation Else MsgBox "Все объекты в документе находятся в пределах листа.", vbInformation End If End Sub
Для доков в папке
Sub CheckBrokenImagesAndOutOfBounds() Dim folderPath As String Dim fileSystem As Object Dim folder As Object Dim docPath As String Dim msg As String Dim fileFound As Boolean Application.ScreenUpdating = False ' Укажите путь к основной папке с подпапками folderPath = "C:\\Новая папка" ' Создаем FileSystemObject для работы с файлами и папками Set fileSystem = CreateObject("Scripting.FileSystemObject") Set folder = fileSystem.GetFolder(folderPath) ' Обходим все подпапки Call CheckSubFolders(folder, fileSystem) ' Очистка Set fileSystem = Nothing Set folder = Nothing Application.ScreenUpdating = True MsgBox "End" End Sub Sub CheckSubFolders(parentFolder As Object, fileSystem As Object) Dim subFolder As Object ' Проходим по всем подпапкам в текущей папке For Each subFolder In parentFolder.Subfolders ' Формируем путь к документу Word в текущей подпапке Dim docPath As String docPath = subFolder.Path & "\" & subFolder.Name & ".docx" ' Проверяем, существует ли файл If fileSystem.FileExists(docPath) Then ' Вызываем функцию для проверки "сломанных" изображений и изображений, выходящих за границы If CheckFileForBrokenImagesAndOutOfBounds(docPath) Then Debug.Print "Найдена проблема в файле: " & docPath End If End If Next subFolder End Sub Function CheckFileForBrokenImagesAndOutOfBounds(filePath As String) As Boolean Dim doc As Document Dim foundProblem As Boolean
' Открываем документ Set doc = Documents.Open(filePath, ReadOnly:=True)
' Задержка для обеспечения полной загрузки документа DoEvents
' Вызываем функцию для проверки "сломанных" изображений If CheckImagesOutOfBounds(doc) Then foundProblem = True End If
' Закрываем документ без сохранения doc.Close False
' Возвращаем результат CheckFileForBrokenImagesAndOutOfBounds = foundProblem End Function
Function CheckImagesOutOfBounds(doc As Document) As Boolean Dim inlineShape As inlineShape Dim pageWidth As Single Dim pageHeight As Single Dim objLeft As Single Dim objTop As Single Dim objWidth As Single Dim objHeight As Single Dim overflowFound As Boolean
overflowFound = False
' Определение размеров страницы pageWidth = doc.PageSetup.pageWidth pageHeight = doc.PageSetup.pageHeight
' Проверка встроенных изображений For Each inlineShape In doc.InlineShapes objLeft = inlineShape.Range.Information(wdHorizontalPositionRelativeToTextBoundary) objTop = inlineShape.Range.Information(wdVerticalPositionRelativeToTextBoundary) ' Пробуем альтернативный метод objWidth = inlineShape.Width objHeight = inlineShape.Height
' Проверка выхода за границы страницы If objLeft < -1 Or objTop < -1 Or objLeft + objWidth > pageWidth Or objTop + objHeight > pageHeight Then overflowFound = True Exit For End If Next inlineShape
' Возвращаем результат CheckImagesOutOfBounds = overflowFound End Function