Все картинки vba word

Автор RuR, 03 апреля 2020, 16:42

Для выделения всех рисунков (картинок) типа «Shape» я использую это:
ActiveDocument.Shapes.SelectAll

Как выделить все рисунки типа «InlineShape»?

Я выделяю все рисунки, чтобы затем в программе «Word» (вручную, без макроса) их оформить.



Администратор

  • Administrator
  • Сообщения: 2,253
  • Записан

В VBA нет инструмента для одновременного выделения всех рисунков типа «InlineShape», можно выделить только один рисунок.
Но можно двигаться по всем рисункам и можно обрабатывать каждый рисунок отдельно.
Но некоторые действия, какие юзер может делать в ворде, нельзя сделать в VBA. Поэтому заранее не известно, возможно ли применить к рисунку нужное оформление с помощью VBA.

Sub Макрос()

    Dim рис As InlineShape

        ‘ Движение по всем рисункам с типом «InlineShape».
    For Each рис In ActiveDocument.InlineShapes
        ‘ Отображение высоты рисунка в окне View — Immediate Window.
        Debug.Print рис.Height
    Next рис

   End Sub


Есть методы:
ConvertToInlineShape
ConvertToShape

Возможен ли перевод из InlineShape в Shape, выделение всех картинок с помощью ActiveDocument.Shapes.SelectAll, форматирование вручную, обратный перевод в InlineShape?



Администратор

  • Administrator
  • Сообщения: 2,253
  • Записан

Вот так можно перевести все рисунки типа «InlineShape» в рисунки типа «Shape»:

Макрос

Sub Макрос()

    Dim i As Long

       ‘ Движение по всем рисункам с типом «InlineShape» от последнего к первому.
        ‘ От первого к последнему не двигаемся, т.к. будет сбиваться
        ‘ порядковая нумерация рисунков типа «InlineShape».
        ‘ Т.к. после превращения рисунка типа «InlineShape» в «Shape»
        ‘ исчезнет рисунок типа «InlineShape».
    For i = ActiveDocument.InlineShapes.Count To 1 Step -1
        ActiveDocument.InlineShapes(i).ConvertToShape
    Next i

   End Sub

[свернуть]

Вот так можно перевести все рисунки типа «Shape» в рисунки типа «InlineShape»:

Макрос

Sub Макрос()

    Dim i As Long

       ‘ Движение по всем рисункам с типом «Shape» от последнего к первому.
        ‘ От первого к последнему не двигаемся, т.к. будет сбиваться
        ‘ порядковая нумерация рисунков типа «Shape».
        ‘ Т.к. после превращения рисунка типа «Shape» в «InlineShape»
        ‘ исчезнет рисунок типа «Shape».
    For i = ActiveDocument.Shapes.Count To 1 Step -1
        ActiveDocument.Shapes(i).ConvertToInlineShape
    Next i

   End Sub

[свернуть]


После превращения картинок типа «InlineShape» в картинки типа «Shape», все картинки документа оказываются на первом листе друг на друге в куче.



Администратор

  • Administrator
  • Сообщения: 2,253
  • Записан

Не обращайте на это внимание. Выделите рисунки, примените оформление и снова превратите их в InlineShape.


Спасибо, теперь все заработало!


  • Форум по VBA, Excel и Word

  • Word

  • Макросы в Word

  • Word VBA Макросы: Как выделить все рисунки (объекты) типа «InlineShape»?

Студворк — интернет-сервис помощи студентам

Всем привет.

Потребовалось выделить все картинки в очень большом файле Word, чтобы центровать их и поместить в рамку. Хочу просто выделить все картинки скриптом.
VBA не пользовался ранее.
Нашел вроде текст скрипта, но выдает ошибку.
Word 2007.
Выполняю следующую последовательность действий:
С помощью комбинации Alt+F11, Ctrl+G Перехожу в Visual basic в поле Immediate и пишут код

Visual Basic
1
2
3
Sub selectAllShapes()
   ActiveDocument.Shapes.SelectAll
End Sub

Нажимаю Enter — выдает ошибку Compile error: Invalid in Immediate pane
Что не так? Какие то проблемы при выделении, нужно что-то установить, код некоррктный?

Заранее спасибо всем за помощь.

В данной статье хочу показать 4 способа как экспортировать (сохранить) все изображения из Word документа в файлы в указанную папку на диске с помощью макроса VBA. Обращаю внимание, что речь идет про сохранение не авто-фигур и т.п., а импортированных изображений, которые входят в ворде в коллекцию InlineShapes объекты которой и будем сохранять.

Способ 1. Сохранение изображений из Word в формате EMF

Это самый короткий и быстрый способ экспортировать все изображения из Word-а. Формат изображений EMF (Microsoft Enhanced Metafile) — это медиа-формат, который Microsoft придумал на замену формату WMF. Однако, этот формат не всем приложениям понятен, в этом и минус этого способа.

ExportImages "C:Мои документыfile.doc", "C:Export"

Sub ExportImages(DocFile As String, ExportPath As String)
  ' Открываем документ
  Set Wrd = CreateObject("Word.Application")
  Set Doc = Wrd.Documents.Open(DocFile)
  ' Цикл по картинкам в документе
  For i = 1 To Doc.InlineShapes.Count
    FileName = ExportPath & "img" & CStr(i) & ".emf"
    SaveInlineShape FileName, Doc.InlineShapes(i)
  Next i
  ' Закрываем документ
  Doc.Close
  Wrd.Quit False
End Sub

Sub SaveInlineShape(FileName As Variant, iShape As InlineShape)
Dim vData() As Byte
  ' Открываем файл для записи
  Open FileName For Binary Access Write As #1
  ' Записываем данные
  vData = iShape.Range.EnhMetaFileBits
  Put #1, 1, vData
  ' Закрываем файл
  Close #1
End Sub

Способ 2. Распаковка Word файла как архива

Суть идеи в том, что если файл в формате docx, то он будет представлять собой архив, который содержит множество файлов, в т.ч. и папку с изображениями, которые есть в нем. На случай, если файл не в формате docx, макрос открывает его и пересохраняет в формат docx и потом распаковывает его во временную папку.

ExportImages "C:Мои документыfile.doc", "C:Export"

Sub ExportImages(DocFile As String, ExportPath As String)
  ' Создаем временную папку
  TmpPath = ExportPath & "tmp"
  Set FSO = CreateObject("Scripting.FileSystemObject")
  If Not FSO.FolderExists(TmpPath) Then FSO.CreateFolder (TmpPath)
  ' Открываем документ и пересохраняем во временную папку в формате docx (на случай если он был какого-то другого формата)
  DocXFile = TmpPath & "1.docx"
  Set Wrd = CreateObject("Word.Application")
  Set Doc = Wrd.Documents.Open(DocFile)
  Doc.SaveAs FileName:=DocXFile, FileFormat:=wdFormatXMLDocument
  Doc.Close: Wrd.Quit False
  ' Переименовываем файл в zip
  ZipFile = TmpPath & "1.zip"
  Name DocXFile As ZipFile
  ' Распаковываем файлы
  Set objShell = CreateObject("Shell.Application")
  Set FilesInZip = objShell.NameSpace(ZipFile).items
  objShell.NameSpace(TmpPath).CopyHere (FilesInZip)
  ' Получаем список картинок, которые теперь находятся в wordmedia
  Set sFolder = FSO.GetFolder(TmpPath & "wordmedia")
  For Each FileItem In sFolder.Files
    FileCopy FileItem.Path, ExportPath & "" & FileItem.Name
  Next FileItem
  ' Удаляем временную папку и всё ее содержимое
  Shell "cmd /c rd /S/Q """ & TmpPath & """"
End Sub

Способ 3. Сохранение файла в HTML

Принцип похож на 2-й способ. При сохранении в html формат создается папка, содержащая картинки и другие вложенные файлы и всё, что нужно, это взять из нее изображения. Минус в том, что изображения выгружаются по несколько раз в разных форматах.

ExportImages "C:Мои документыfile.doc", "C:Export"

Sub ExportImages(DocFile As String, ExportPath As String)
  ' Создаем временную папку
  TmpPath = ExportPath & "tmp"
  Set FSO = CreateObject("Scripting.FileSystemObject")
  If Not FSO.FolderExists(TmpPath) Then FSO.CreateFolder (TmpPath)
  ' Открываем файл и пересохраняем во временную папку в формате HTML
  Set Wrd = CreateObject("Word.Application")
  Set Doc = Wrd.Documents.Open(DocFile)
  Doc.SaveAs TmpPath & "tmp.html", FileFormat:=wdFormatHTML
  Doc.Close: Wrd.Quit False
  ' Получаем список файлов в папке с вложениями tmp.files
  Set sFolder = FSO.GetFolder(TmpPath & "tmp.files")
  For Each FileItem In sFolder.Files
    If FSO.GetExtensionName(FileItem.Name) = "jpg" Or _
       FSO.GetExtensionName(FileItem.Name) = "gif" Or _
       FSO.GetExtensionName(FileItem.Name) = "png" Then
      ' Копируем только картинки
      FileCopy FileItem.Path, ExportPath & "" & FileItem.Name
    End If
  Next FileItem
  ' Удаляем временную папку и всё ее содержимое
  Shell "cmd /c rd /S/Q """ & TmpPath & """"
End Sub

Способ 4. Экспорт изображений в формате BMP с использованием буфера обмена

Суть этого метода в том, чтобы скопировать картинку в буфер обмена и затем, используя API функции сохранить из буфера картинку в файл. Одно из преимуществ этого метода в том, что можно сохранить только одну конкретную картинку из Word документа, а не все подряд.

Private Declare Function IsClipboardFormatAvailable Lib "user32" (ByVal wFormat As Integer) As Long
Private Declare Function OpenClipboard Lib "user32" (ByVal hwnd As Long) As Long
Private Declare Function GetClipboardData Lib "user32" (ByVal wFormat As Integer) As Long
Private Declare Function CloseClipboard Lib "user32" () As Long
Private Declare Function OleCreatePictureIndirect Lib "olepro32.dll" (PicDesc As uPicDesc, RefIID As GUID, ByVal fPictureOwnsHandle As Long, IPic As IPicture) As Long
Private Declare Function CopyImage Lib "user32" (ByVal handle As Long, ByVal un1 As Long, ByVal n1 As Long, ByVal n2 As Long, ByVal un2 As Long) As Long
Const CF_BITMAP = 2
Const IMAGE_BITMAP = 0
Const LR_COPYRETURNORG = &H4
Private Type GUID
  Data1 As Long
  Data2 As Integer
  Data3 As Integer
  Data4(0 To 7) As Byte
End Type
Private Type uPicDesc
  Size As Long
  Type As Long
  hPic As Long
  hPal As Long
End Type

ExportImages "C:Мои документыfile.doc", "C:Export"

Sub ExportImages(DocFile As String, ExportPath As String)
  ' Открываем документ
  Set Wrd = CreateObject("Word.Application")
  Set Doc = Wrd.Documents.Open(DocFile)
  ' Цикл по картинкам в документе
  For i = 1 To Doc.InlineShapes.Count
    Doc.InlineShapes(i).Range.CopyAsPicture
    Clip2File ExportPath & "" & CStr(i) & ".bmp"
  Next i
  ' Закрываем документ
  Doc.Close
  Wrd.Quit False
End Sub

' Процедуры для работы с буфером обмена

Public Function Clip2File(OutputPath As String)
  Dim strOutputPath As String, oPic As IPictureDisp
  Set oPic = GetClipPicture()
  If Not oPic Is Nothing Then
    SavePicture oPic, OutputPath
    Clip2File = OutputPath
  Else
    Clip2File = ""
    MsgBox "Unable to retrieve bitmap from clipboard"
  End If
End Function

Private Function GetClipPicture() As IPicture
Dim h As Long, hPicAvail As Long, hPtr As Long, hPal As Long, hCopy As Long
  hPicAvail = IsClipboardFormatAvailable(CF_BITMAP)
  If hPicAvail <> 0 Then
    h = OpenClipboard(0&)
    If h > 0 Then
      hPtr = GetClipboardData(CF_BITMAP)
      hCopy = CopyImage(hPtr, IMAGE_BITMAP, 0, 0, LR_COPYRETURNORG)
      h = CloseClipboard
      If hPtr <> 0 Then Set GetClipPicture = CreatePicture(hCopy, 0, CF_BITMAP)
    End If
  End If
End Function

Private Function CreatePicture(ByVal hPic As Long, ByVal hPal As Long, ByVal lPicType) As IPicture
  Dim r As Long, uPicInfo As uPicDesc, IID_IDispatch As GUID, _
  IPic As IPicture
  Const PICTYPE_BITMAP = 1
  With IID_IDispatch
    .Data1 = &H7BF80980
    .Data2 = &HBF32
    .Data3 = &H101A
    .Data4(0) = &H8B
    .Data4(1) = &HBB
    .Data4(2) = &H0
    .Data4(3) = &HAA
    .Data4(4) = &H0
    .Data4(5) = &H30
    .Data4(6) = &HC
    .Data4(7) = &HAB
  End With
  With uPicInfo
    .Size = Len(uPicInfo)
    .Type = PICTYPE_BITMAP
    .hPic = hPic
    .hPal = 0
  End With
  r = OleCreatePictureIndirect(uPicInfo, IID_IDispatch, True, IPic)
  Set CreatePicture = IPic
End Function

У каждого из способов экспорта картинок есть свои плюсы и минусы. Самые быстрые в плане производительности скорее всего 1-й и 4-й способы. У 3-го способа есть плюс — сохраняет в файлы не только вставленные картинки, но так же и автофигуры, диаграммы и т.д. Какой из способов удобнее всего для вас — решайте сами.

Формулировка задачи:

1)Как получить список всех картинок что есть в документе?
2)Как бы перетащить такой найденный объект-картинку в PowerPoint презентацию? Мне говорили что есть какой-то метод для «переприсваивания» чтоли.
И по первому и по второму вопросу гуглил, но нужной информации найти не смог, знаю что существует специальный объект или объекты через которые и можно пройтись по всем картинкам в документе, но не помню как к нему добираться

Код к задаче: «Поиск картинок в документе Word»

textual

Sub test1234()
 
    Dim PPAppl As Object
    Dim m As Variant
    
    'создать новый объект
    Set PPAppl = CreateObject("PowerPoint.Application")
    
    'выбрать тип новых создаваемых листов в PowerPoint
    Dim Layout As Integer
    Layout = 2
    
    
    With PPAppl
        .Visible = True 'показать PowerPoint
        .Presentations.Add 'создать в PowerPoint презентацию
        
    'пройтись по всех картинках
    For i = 1 To ActiveDocument.InlineShapes.Count
        .ActivePresentation.Slides.Add i, Layout 'добавить новый лист
        ActiveDocument.InlineShapes(i).Select 'выбрать i-ую картинку
    Next i
    End With
End Sub

Полезно ли:

9   голосов , оценка 3.667 из 5

So for my particular application, I want to be able to select an image after I’ve copied it in from Excel, and then insert a caption.

I can successfully copy images using:

docapp.Selection.Range.PasteSpecial DataType:=wdPasteEnhancedMetafile, Placement:=wdInLine

However, I’m having a lot of difficult just selecting the recently copied image so I can use

Selection.InsertCaption

What’s the best way to select images?

Deduplicator's user avatar

Deduplicator

44.3k7 gold badges65 silver badges115 bronze badges

asked Nov 5, 2014 at 17:00

johnzilla's user avatar

Ok, I’m an idiot and have solved my own problem. It’s not the prettiest code but it works:

The key is to use document.InlineShapes.Select:

Public Sub Chart2Word(chto As Chart, doc1 As Word.Document, docapp As Word.Application, _
                     Optional Title As Variant)
    Dim objpic As Word.InlineShape


    docapp.Activate
    chto.CopyPicture

    docapp.Selection.MoveEnd wdStory
    docapp.Selection.Move
    docapp.Selection.ParagraphFormat.Alignment = wdAlignParagraphCenter

    docapp.Selection.Range.PasteSpecial DataType:=wdPasteEnhancedMetafile, Placement:=wdInLine

    doc1.InlineShapes(doc1.InlineShapes.Count).Select
    Label = Me.Range("LabelName").value
    If Not IsMissing(Title) Then

        docapp.Selection.InsertCaption Label:=Label, Title:=": " + Title
    End If

answered Nov 5, 2014 at 17:23

johnzilla's user avatar

johnzillajohnzilla

3386 silver badges21 bronze badges

1

Вы не вошли. Пожалуйста, войдите или зарегистрируйтесь.

Выделить макросом несколько рисунков

Страницы 1

Чтобы отправить ответ, вы должны войти или зарегистрироваться

Сообщений [ 4 ]

1 28.09.2017 06:50:46

  • Выделить макросом несколько рисунков
  • Alex_Gur
  • Модератор
  • Неактивен
  • Откуда: Москва
  • Зарегистрирован: 28.07.2011
  • Сообщений: 2,758
  • Поблагодарили: 492

Тема: Выделить макросом несколько рисунков

В файле Word имеется несколько рисунков в формате обтекание «перед текстом». Нужно выделить совместно рисунки с определенными номерами (например, 1, 3, 4, 7) и сдвинуть их.
Данный макрос выделяет только один рисунок с номером 1:

Sub Pict1()
    Dim selPic As Object
    'В переменную selPic записываем все рисунки документа, находящиеся не в тексте.
    Set selPic = ActiveDocument.Shapes
    'Выделяется рисунок с номером 1.
    selPic(1).Select
    'Рисунки нужно сдвинуть.
    Selection.ShapeRange.IncrementLeft 0.65
    Selection.ShapeRange.IncrementLeft 0.65
End Sub

Как выделить несколько рисунков с определенными номерами?
Их, вероятно, нужно включить в переменную selPic. Как это сделать?

Удобной и приятной работы в Word!
Перевести спасибо на Яндекс кошелёк — 41001162202962; на WebMoney — R581830807057.

2 Ответ от Alex_Gur 28.09.2017 07:15:37

  • Выделить макросом несколько рисунков
  • Alex_Gur
  • Модератор
  • Неактивен
  • Откуда: Москва
  • Зарегистрирован: 28.07.2011
  • Сообщений: 2,758
  • Поблагодарили: 492

Re: Выделить макросом несколько рисунков

Спасибо. Нашел приемлемое решение в внешняя ссылка

Sub SelectShapeRange()
    ActiveDocument.Shapes.Range(Array(1, 3, 4, 7)).Select
    Selection.ShapeRange.IncrementLeft 0.65
    Selection.ShapeRange.IncrementLeft 0.65
End Sub

Удобной и приятной работы в Word!
Перевести спасибо на Яндекс кошелёк — 41001162202962; на WebMoney — R581830807057.

3 Ответ от Alex_Gur 28.09.2017 07:35:46

  • Выделить макросом несколько рисунков
  • Alex_Gur
  • Модератор
  • Неактивен
  • Откуда: Москва
  • Зарегистрирован: 28.07.2011
  • Сообщений: 2,758
  • Поблагодарили: 492

Re: Выделить макросом несколько рисунков

Еще вопрос в связи с этим.
Пусть выделен некоторый рисунок в формате обтекание «перед текстом».
Как узнать его номер в коллекции Shapes?

Удобной и приятной работы в Word!
Перевести спасибо на Яндекс кошелёк — 41001162202962; на WebMoney — R581830807057.

4 Ответ от Fck_This 28.09.2017 13:19:24

  • Выделить макросом несколько рисунков
  • Fck_This
  • генерал-полковник
  • Неактивен
  • Откуда: Минск, Беларусь
  • Зарегистрирован: 13.07.2016
  • Сообщений: 648
  • Поблагодарили: 97

Re: Выделить макросом несколько рисунков

Alex_Gur пишет:

Еще вопрос в связи с этим.
Пусть выделен некоторый рисунок в формате обтекание «перед текстом».
Как узнать его номер в коллекции Shapes?

Никогда не обращался к фигурам через VBA, но чисто логически у shapes в совокупности есть count и каждому shapes соответствует определённый ID. Если по порядку спрашивать их ID через For i = 1 To … .Count, то i будет номером.

Спасибо можно перевести на WebMoney-кошелёк R378231864568 или на Яндекс-деньги 410015093172871

Сообщений [ 4 ]

Страницы 1

Чтобы отправить ответ, вы должны войти или зарегистрироваться

Похожие темы

  • Как выделить объекты?
  • Как выделить картинку из Shape?
  • Как выделить все перекрестные ссылки?
  • Выделить текст, но не печатать выделение
  • Не выделить постоянную часть гиперссылки
  • Найти и выделить текст цветом
  • Выделить все вхождения стиля с заданным именем
  • Как выделить все абзацы начинающиеся с определенного символа ?
Информация о материале
Категория: Макросы Word

Опубликовано: 05 июня 2016

Если в документе Word необходимо удалить все картинки, то если картинок немного, можно это сделать вручную, а если много, то можно быстро удалить их при помощи достаточно простого макроса VBA.

Для разового удаления ненужной картинки вполне подходят стандартные методы, для удаления же всех картинок в активном документе Word лучше подойдет макрос VBA, который найдет и удалит каждую картинку документа. Макрос работает одинаково в любой версии.

Sub AllImgDelete()
'Удаление всех картинок в активном документе
Dim Img As InlineShape
    For Each Img In ActiveDocument.InlineShapes
        Img.Delete
    Next Img
End Sub

Для того, чтобы перенести программный код на свой компьютер, наведите курсор мыши на поле с программным кодом, нажмите на одну из двух кнопкок knopka_view_source в правом верхнем углу этого поля, скопируйте программный код и вставьте его в модуль проекта на своем компьютере (подробнее о том, как сохранить программный код макроса).

Другие материалы по теме:

Можно ли автоматизировать вытаскивание картинок из Ворда?

Есть документ ворд. В нем несколько рисунков. Задача: вытащить все картинки последовательно из этого документа и сохранить в соседней подпапке «pics». Чтобы потом можно было бы к ним обращаться по их номерам в соответствии с их нумерацией в документе.

8 ответов

248

15 ноября 2012 года

Dmitry2064

590 / / 06.12.2006

ОК. Я выбрал вариант сохранения как html и потом тащу сохраненные картинки из папки .files к себе. А потом этот временный html кокаю. Не полный «автомат», ну да ладно.

Спасибо за ссылку.

275

15 ноября 2012 года

pashulka

985 / / 19.09.2004

Производите вышеописанные действия программно и будет Вам «автомат»

248

15 ноября 2012 года

Dmitry2064

590 / / 06.12.2006

Производите вышеописанные действия программно и будет Вам «автомат»

Да, так и делаю: макрос сохраняет док как html. Потом из его подпапки с картинками все копируется в папку с нужным документом в подпапку pics. Потом опять открывается исходный документ, и в процессе расстановки тегов при «натыкании» на картинку выскакивает окно выбора файла, где я тыкаю в нужную картинку и ее путь вписывается в тело будущего html-документа. Проблемка в том, что при первичном временном сохранении как html, в папке оказываются картинки с их превьюшками и приходится переключаться в Тоталкоммандер, что бы уточнить, как кую картинку именно надо выбрать. А если бы можно было напрямую из ворда сохранять, то можно сразу было бы и ссылку формировалаь на нужную картинку. Т.е. чтобы совсем без участия пользователя прописывать все картинки. Вот это было бы красиво.

275

15 ноября 2012 года

pashulka

985 / / 19.09.2004

Дык, можно просто анализировать файл *.htm и искать там тэг(и) <IMG SRC=… ибо первый IMG соответствует первой картинке, второй IMG, соответственно, второй и т.д.

P.S. Впрочем, если Вас это не устраивает, то можно попробовать и другие варианты.

248

17 ноября 2012 года

Dmitry2064

590 / / 06.12.2006

Дык, можно просто анализировать файл *.htm и искать там тэг(и) <IMG SRC=… ибо первый IMG соответствует первой картинке, второй IMG, соответственно, второй и т.д.

P.S. Впрочем, если Вас это не устраивает, то можно попробовать и другие варианты.

Как раз устраивает. Только не соображу: надо построчно парсить текст hml-дока и искать указанный тег? (через open … for input file as #1?). Но тогда надо как-то сделать счетчик, чтобы искать не всегда одно и тоже, а по счету найденных вхождений картинок. Правильная мысль?

275

20 ноября 2012 года

pashulka

985 / / 19.09.2004

Имелось ввиду, что можно получить весь текст hml файла, а затем просто использовать VB(A) функцию InStr()

248

20 ноября 2012 года

Dmitry2064

590 / / 06.12.2006

Ага. Так и попробую. Спасибо!

Like this post? Please share to your friends:
  • Все использованные формулы в excel
  • Все инструменты word 2007
  • Все индикаторы в excel
  • Все индексы россии скачать в excel
  • Все иконки стали word