Автор 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 | ||
|
Нажимаю 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
44.3k7 gold badges65 silver badges115 bronze badges
asked Nov 5, 2014 at 17:00
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
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
Для того, чтобы перенести программный код на свой компьютер, наведите курсор мыши на поле с программным кодом, нажмите на одну из двух кнопкок в правом верхнем углу этого поля, скопируйте программный код и вставьте его в модуль проекта на своем компьютере (подробнее о том, как сохранить программный код макроса).
Другие материалы по теме:
Можно ли автоматизировать вытаскивание картинок из Ворда?
Есть документ ворд. В нем несколько рисунков. Задача: вытащить все картинки последовательно из этого документа и сохранить в соседней подпапке «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
Ага. Так и попробую. Спасибо!