Not As Easy As You’d Think…
One would think that saving something as a picture file (png, jpg, etc…) inside Excel with VBA would be a pretty straightforward exercise. Unfortunately, the “Save as Picture” functionality only exists for saving images of Charts (called exporting). This leaves saving pictures of shapes, icons, and cell ranges void of any VBA automation.
However, with a little bit of creativity, we can utilize the chart object to store our desired image and use the chart object’s Export function to create the image file that we can manually generate by right-clicking and selecting Save as Picture…
In this article I’ll walk you through the basic concept of what the VBA code is doing and also go through two VBA macro examples pertaining to saving shapes/icons and cell ranges in various file formats.
Methodology
Not many people know this but Charts can actually store shapes/objects inside of them. For example, if you have ever copied a textbox and pasted it while a chart is selected, you’ll notice the textbox object appears to be grouped with the chart. Meaning, if you move the chart to a different location, the textbox would move right along with it. What is actually occurring is the textbox is getting embedded within the chart and is essentially now a component of the chart object (think legend, chart title, chart series, axis, etc…).
Notice that the chart object is selected while selecting the textbox? This indicates the textbox has been embedded into the chart object.
The fact that charts in Excel can absorb other objects is what we will be utilizing to workaround the fact that shapes and other objects cannot be saved as a picture in VBA.
Before we dive into the VBA code, the concept the macro will be utilizing will be to isolate the object you want to save as a picture file and also generating a blank/empty chart object.
With those two objects in place, the VBA code will simply paste the desired object into the Chart Object (kind of like converting it into a chart!).
With this concept in mind, let’s take a look at the VBA code I’ve proposed to get this job done!
Save Shape As A PNG File [VBA Code]
Hopefully the following VBA macro is easily to follow along, but I’ll outline essentially the steps it is doing so you can customize it accordingly if needed.
-
Determine if a shape is selected, if not, don’t proceed. Store the selected shape to a variable (ActiveShape)
-
Generate a Chart Object that is the exact same size as the selected shape
-
Remove the chart’s Fill and Border to make the background transparent
-
Copy the selected shape and Paste it into the Chart Object
-
Export the Chart Object as a PNG file and save to the user’s desktop
-
Delete the chart so it appears like nothing has occurred to the user
Sub SaveShapeAsPicture()
‘PURPOSE: Save a selected shape/icon as a PNG file to computer’s desktop
‘SOURCE: www.thespreadsheetguru.com
Dim cht As ChartObject
Dim ActiveShape As Shape
Dim UserSelection As Variant
‘Ensure a Shape is selected
On Error GoTo NoShapeSelected
Set UserSelection = ActiveWindow.Selection
Set ActiveShape = ActiveSheet.Shapes(UserSelection.Name)
On Error GoTo 0
‘Create a temporary chart object (same size as shape)
Set cht = ActiveSheet.ChartObjects.Add( _
Left:=ActiveCell.Left, _
Width:=ActiveShape.Width, _
Top:=ActiveCell.Top, _
Height:=ActiveShape.Height)
‘Format temporary chart to have a transparent background
cht.ShapeRange.Fill.Visible = msoFalse
cht.ShapeRange.Line.Visible = msoFalse
‘Copy/Paste Shape inside temporary chart
ActiveShape.Copy
cht.Activate
ActiveChart.Paste
‘Save chart to User’s Desktop as PNG File
cht.Chart.Export Environ(«USERPROFILE») & «Desktop» & ActiveShape.Name & «.png»
‘Delete temporary Chart
cht.Delete
‘Re-Select Shape (appears like nothing happened!)
ActiveShape.Select
Exit Sub
‘ERROR HANDLERS
NoShapeSelected:
MsgBox «You do not have a single shape selected!»
Exit Sub
End Sub
Save Range As A JPG File [VBA Code]
Hopefully the following VBA macro is easily to follow along, but I’ll outline essentially the steps it is doing so you can customize it accordingly if needed.
-
Determine if a cell range is selected, if not, don’t proceed.
-
Copy/Paste the range as a picture and store the picture to a variable (ActiveShape)
-
Generate a Chart Object that is the exact same size as the selected shape
-
Remove the chart’s Fill and Border to make the background transparent
-
Copy the selected shape and Paste it into the Chart Object
-
Export the Chart Object as a PNG file and save to the user’s desktop
-
Delete the generated chart & picture so it appears like nothing has occurred to the user
Sub SaveRangeAsPicture()
‘PURPOSE: Save a selected cell range as a JPG file to computer’s desktop
‘SOURCE: www.thespreadsheetguru.com
Dim cht As ChartObject
Dim ActiveShape As Shape
‘Confirm if a Cell Range is currently selected
If TypeName(Selection) <> «Range» Then
MsgBox «You do not have a single shape selected!»
Exit Sub
End If
‘Copy/Paste Cell Range as a Picture
Selection.Copy
ActiveSheet.Pictures.Paste(link:=False).Select
Set ActiveShape = ActiveSheet.Shapes(ActiveWindow.Selection.Name)
‘Create a temporary chart object (same size as shape)
Set cht = ActiveSheet.ChartObjects.Add( _
Left:=ActiveCell.Left, _
Width:=ActiveShape.Width, _
Top:=ActiveCell.Top, _
Height:=ActiveShape.Height)
‘Format temporary chart to have a transparent background
cht.ShapeRange.Fill.Visible = msoFalse
cht.ShapeRange.Line.Visible = msoFalse
‘Copy/Paste Shape inside temporary chart
ActiveShape.Copy
cht.Activate
ActiveChart.Paste
‘Save chart to User’s Desktop as PNG File
cht.Chart.Export Environ(«USERPROFILE») & «Desktop» & ActiveShape.Name & «.jpg»
‘Delete temporary Chart
cht.Delete
ActiveShape.Delete
‘Re-Select Shape (appears like nothing happened!)
ActiveShape.Select
End Sub
I Hope This Helped!
Hopefully, I was able to explain how you can use VBA to create image files in Excel. If you have any questions about this technique or suggestions on how to improve it, please let me know in the comments section below.
About The Author
Hey there! I’m Chris and I run TheSpreadsheetGuru website in my spare time. By day, I’m actually a finance professional who relies on Microsoft Excel quite heavily in the corporate world. I love taking the things I learn in the “real world” and sharing them with everyone here on this site so that you too can become a spreadsheet guru at your company.
Through my years in the corporate world, I’ve been able to pick up on opportunities to make working with Excel better and have built a variety of Excel add-ins, from inserting tickmark symbols to automating copy/pasting from Excel to PowerPoint. If you’d like to keep up to date with the latest Excel news and directly get emailed the most meaningful Excel tips I’ve learned over the years, you can sign up for my free newsletters. I hope I was able to provide you some value today and hope to see you back here soon! — Chris
Import the URLDownloadToFile function and use it directly. The following is an entire module code sheet, including the declarations section at the top. The routine expects a list of the full img src URLs in column A starting at row 2. e.g.: http://www.staples.no/content/images/product/491215_1_xnm.jpg
Option Explicit
#If VBA7 And Win64 Then
Private Declare PtrSafe Function URLDownloadToFile Lib "urlmon" _
Alias "URLDownloadToFileA" ( _
ByVal pCaller As LongPtr, _
ByVal szURL As String, _
ByVal szFileName As String, _
ByVal dwReserved As LongPtr, _
ByVal lpfnCB As LongPtr _
) As Long
Private Declare PtrSafe Function DeleteUrlCacheEntry Lib "Wininet.dll" _
Alias "DeleteUrlCacheEntryA" ( _
ByVal lpszUrlName As String _
) As Long
#Else
Private Declare Function URLDownloadToFile Lib "urlmon" _
Alias "URLDownloadToFileA" ( _
ByVal pCaller As Long, _
ByVal szURL As String, _
ByVal szFileName As String, _
ByVal dwReserved As Long, _
ByVal lpfnCB As Long _
) As Long
Private Declare Function DeleteUrlCacheEntry Lib "Wininet.dll" _
Alias "DeleteUrlCacheEntryA" ( _
ByVal lpszUrlName As String _
) As Long
#End If
Public Const ERROR_SUCCESS As Long = 0
Public Const BINDF_GETNEWESTVERSION As Long = &H10
Public Const INTERNET_FLAG_RELOAD As Long = &H80000000
Sub dlStaplesImages()
Dim rw As Long, lr As Long, ret As Long, sIMGDIR As String, sWAN As String, sLAN As String
sIMGDIR = "c:folder"
If Dir(sIMGDIR, vbDirectory) = "" Then MkDir sIMGDIR
With ActiveSheet '<-set this worksheet reference properly!
lr = .Cells(Rows.Count, 1).End(xlUp).Row
For rw = 2 To lr
sWAN = .Cells(rw, 1).Value2
sLAN = sIMGDIR & Chr(92) & Trim(Right(Replace(sWAN, Chr(47), Space(999)), 999))
Debug.Print sWAN
Debug.Print sLAN
If CBool(Len(Dir(sLAN))) Then
Call DeleteUrlCacheEntry(sLAN)
Kill sLAN
End If
ret = URLDownloadToFile(0&, sWAN, sLAN, BINDF_GETNEWESTVERSION, 0&)
.Cells(rw, 2) = ret
Next rw
End With
End Sub
A value of 0 is column B indicates success (e.g. ERROR_SUCCESS).
How to save an Excel Range as an Image file (JPG)? Today’s post is inspired by my readers emails. In some of my previous emails I considered other Excel Image scenarios such as Adding Images to Excel using VBA or using the Excel Camera Tool to create an image snapshot in Excel. However today I stumbled across a different scenario: Saving an Excel Range as an Image File.
Let us start with an example. The easiest way to create an image in Excel is to Select an Excel Range, next hit the Copy button from Home ribbon and finally by clicking Paste with Picture.
Seems at first like we are just one step away from saving the image as an image file right?
Wrong! Only problem being… there is no Save As Image button easily available in Excel!
Of course you might say – why no copy and paste to MS Paint or another Image Editor? Yes that is always an option. But let me show you a much better and dedicated tool for taking Snapshots in any Windows application. Next I will show a way to achieve the task above with a simple VBA Macro.
Snipping Tool
One way is to use the almighty Microsoft Snipping Tool which is great for creating image snapshots and saving them as images (PNG files).You can see how the Snipping Tool works easily.
The problem however is that the Snipping Tool is not very precise and often detailed Excel Range images are cumbersome to achieve. This is where as usually we can use a bit of Visual Basic for Applications to automate this task…
Excel to Image with VBA
Now let us create an Image from an Excel Range like a pro. First copy the Excel VBA code below to an existing or new VBA Module:
Sub SelectedRangeToImage() Dim tmpChart As Chart, n As Long, shCount As Long, sht As Worksheet, sh As Shape Dim fileSaveName As Variant, pic As Variant 'Create temporary chart as canvas Set sht = Selection.Worksheet Selection.Copy sht.Pictures.Paste.Select Set sh = sht.Shapes(sht.Shapes.Count) Set tmpChart = Charts.Add tmpChart.ChartArea.Clear tmpChart.Name = "PicChart" & (Rnd() * 10000) Set tmpChart = tmpChart.Location(Where:=xlLocationAsObject, Name:=sht.Name) tmpChart.ChartArea.Width = sh.Width tmpChart.ChartArea.Height = sh.Height tmpChart.Parent.Border.LineStyle = 0 'Paste range as image to chart sh.Copy tmpChart.ChartArea.Select tmpChart.Paste 'Save chart image to file fileSaveName = Application.GetSaveAsFilename(fileFilter:="Image (*.jpg), *.jpg") If fileSaveName <> False Then tmpChart.Export Filename:=fileSaveName, FilterName:="jpg" End If 'Clean up sht.Cells(1, 1).Activate sht.ChartObjects(sht.ChartObjects.Count).Delete sh.Delete End Sub
What does the VBA Macro do? The Sub will do the following
-
Copy the selected Excel Range and paste it as a Picture
-
Copy the Picture to an empty Chart
-
Ask for the destination file name
-
Save the Chart as a JPG image
Now you may as Why not use VBA to save the pasted Picture as an Image file?. Well, you can’t (not so straight forward at least). The workaround above works pretty well however.
Using the Excel to Image VBA
First select the Excel Range you want to save as an Image. To run the VBA Macro click the Macros button to open the Macros window.
All that is left is to select the VBA Macro from the Macro window and to hit Run.
There may a short pause for the macro to process the image, shortly after the Save As file dialog should appear. Simply select your destination file name and hit Save and that is it!
Save Excel as Static Image Workbook
As usual I am leaving the best for last. Say you want to share an Excel Workbook as readonly. You can try protecting the Password Protecting your Excel documents but the safety is limited if you want to protect your underlying formulas.
What better way to protect your formulas then to send an Excel Workbook with print screen images of each and every Worksheet? The VBA Macro will additionally save the copy of your file as an XLSX file which means all VBA Macros will be removed as well.
Excel to Static Image Workbook VBA
Below the VBA code snippet to create a copy of your Workbook where every Worksheet is an image copy of the original.
Sub SaveStaticImageWorkbook() Dim ws As Worksheet, wb As Workbook, fDialog As FileDialog Application.DisplayAlerts = False Set wb = Workbooks.Add wb.Sheets(1).Name = "Tmp123" For Each ws In ThisWorkbook.Worksheets ws.Copy After:=wb.Sheets(wb.Sheets.Count) Next ws 'Remove Sheet1 wb.Sheets("Tmp123").Delete For Each ws In wb.Worksheets ws.Range(ws.Cells(1, 1), ws.Cells.SpecialCells(xlLastCell)).Copy ws.Select ws.Cells(1, 1).Select ws.Pictures.Paste ws.Range(ws.Cells(1, 1), ws.Cells.SpecialCells(xlLastCell)).Clear Next ws Set fDialog = Application.FileDialog(msoFileDialogSaveAs) fDialog.Title = "Save Static Workbook" fDialog.InitialFileName = ThisWorkbook.Path If fDialog.Show = -1 Then wb.SaveAs fDialog.SelectedItems(1) End If wb.Close SaveChanges:=False Application.DisplayAlerts = True End Sub
Great right? I have noticed that in most cases the Image Workbook might however be a bit larger than the original file which has its slight downside. Then again this will depend heavily on the type of Workbook (more formatting larger file size).
Let me know what you think!
Хитрости »
1 Май 2011 182172 просмотров
Получили по почте файл-прайс с изображениями товара и эти картинки нужны в отдельной папки, а не на листе? Например для загрузки на сайт. Или для других целей. Подобной команды в Excel нет. Вставить картинки можно, а вот обратно к сожалению никак. Хорошо, если картинок штук 10, а если 100? А если таких книг много? И из всех надо сохранить картинки? Решил поделиться кодами, которые могут сохранять картинки из листа Excel в папку.
Если не знаете как применять коды Visual Basic for Applications, то настоятельно рекомендую к прочтению эти статьи:
Что такое макрос и где его искать?
Что такое модуль? Какие бывают модули?
Если хотите использовать один из нижеприведенных кодов, то следует создать стандартный модуль, скопировать нужные код и вставить его в этот модуль.
- Сохранение выделенной картинки в файл
- Сохранение всех картинок из всех выбранных файлов Excel в папку
- Сохранить выделенный диапазон в картинку
- Сохраняем все картинки с листа в папку с записью в ячейки имен картинок
- Сохранить картинки с листа с именами картинок из ячеек
Все, что потребуется это выделить объект/картинку и выполнить нижеприведенный код:
Sub Save_Sel_Object_As_Picture() Dim sName As String, oObj As Object, wsTmpSh As Worksheet If VarType(Selection) <> vbObject Then MsgBox "Выделенная область не является объектом!", vbCritical, "www.excel-vba.ru" Exit Sub End If Application.ScreenUpdating = False Application.DisplayAlerts = False Set oObj = Selection: oObj.Copy Set wsTmpSh = ThisWorkbook.Sheets.Add sName = ActiveWorkbook.FullName & "_" & ActiveSheet.Name & "_" & oObj.Name With wsTmpSh.ChartObjects.Add(0, 0, oObj.Width, oObj.Height).Chart .ChartArea.Border.LineStyle = 0 .Parent.Select .Paste .Export Filename:=sName & ".gif", FilterName:="GIF" .Parent.Delete End With wsTmpSh.Delete Application.ScreenUpdating = True Application.DisplayAlerts = True End Sub
Если необходимо сохранить не только картинки, но и другие объекты, то необходимо в коде в строке: If oObj.Type = 13 Then изменить цифру. В коде комментариями указано, какая цифра какой тип обозначает. Так же можно изменить и расширение итогового файла с «.gif» на «.jpg». Достаточно найти расширение gif в коде(в двух местах) и заменить их на jpg. Если ни один объект не выделен, то ничего не произойдет.
Сохранение всех картинок из всех выбранных файлов Excel в папку
Sub Save_Object_As_Picture() Dim avFiles, li As Long, oObj As Object, wsSh As Worksheet, wsTmpSh As Worksheet Dim sImagesPath As String, sBookName As String, sName As String Dim wbAct As Workbook Dim IsForEachWbFolder As Boolean avFiles = Application.GetOpenFilename("Excel Files(*.xls*),*.xls*", , "Выбрать файлы", , True) If VarType(avFiles) = vbBoolean Then Exit Sub IsForEachWbFolder = (MsgBox("Сохранять картинки каждой книги в отдельную папку?", vbQuestion + vbYesNo, "www.excel-vba.ru") = vbYes) If Not IsForEachWbFolder Then sImagesPath = Environ("userprofile") & "desktopimages" '" If Dir(sImagesPath, 16) = "" Then MkDir sImagesPath End If End If On Error Resume Next Application.ScreenUpdating = False Application.DisplayAlerts = False Set wsTmpSh = ThisWorkbook.Sheets.Add For li = LBound(avFiles) To UBound(avFiles) Set wbAct = Workbooks.Open(avFiles(li), False) 'создаем папку для сохранения картинок If IsForEachWbFolder Then sImagesPath = wbAct.Path & "" & wbAct.Name & "_images" If Dir(sImagesPath, 16) = "" Then MkDir sImagesPath End If End If sBookName = wbAct.Name For Each wsSh In Sheets For Each oObj In wsSh.Shapes If oObj.Type = 13 Then '13 - картинки '1 - автофигуры '3 - диаграммы oObj.Copy sName = ActiveWorkbook.Name & "_" & wsSh.Name & "_" & oObj.Name With wsTmpSh.ChartObjects.Add(0, 0, oObj.Width, oObj.Height).Chart .ChartArea.Border.LineStyle = 0 .Parent.Select .Paste .Export Filename:=sImagesPath & sName & ".jpg", FilterName:="JPG" .Parent.Delete End With End If Next oObj Next wsSh wbAct.Close 0 Next li Set oObj = Nothing: Set wsSh = Nothing wsTmpSh.Delete Application.DisplayAlerts = True Application.ScreenUpdating = True MsgBox "Объекты сохранены", vbInformation, "www.excel-vba.ru" End Sub
Код позволяет выбрать одну или несколько книг Excel и сохраняет все картинки со всех листов выбранных книг. При запуске кода предлагается выбрать файлы Excel, картинки из которых надо сохранить. После этого появится запрос: «Сохранять картинки каждой книги в отдельную папку?»
- Да — для каждой книги будет создана своя папка images, в которую будут сохранены картинки с именами вида: ИмяКниги_ИмяЛиста_ИмяФигуры
- Нет — на рабочем столе пользователя будет создана папка images, в которую будут сохранены картинки с именами вида: ИмяКниги_ИмяЛиста_ИмяФигуры
Если необходимо сохранить не только картинки, но и другие объекты, то необходимо в коде в строке: If oObj.Type = 13 Then изменить цифру. В коде комментариями указано, какая цифра какой тип обозначает. Так же можно изменить и расширение итогового файла с «.jpg» на «.gif». Достаточно найти расширение jpg в коде(в двух местах) и заменить их на gif. В данном коде я намеренно сделал сохранение в формат jpg, чтобы можно было сравнить с предыдущим кодом и увидеть как правильно менять расширение(формат) файла.
Сохранить выделенный диапазон в картинку
Данные код сохраняет выделенный на листе диапазон в картинку.
Sub Range_to_Picture() Dim sName As String, wsTmpSh As Worksheet If TypeName(Selection) <> "Range" Then MsgBox "Выделенная область не является диапазоном!", vbCritical, "www.excel-vba.ru" Exit Sub End If Application.ScreenUpdating = False Application.DisplayAlerts = False With Selection .CopyPicture Set wsTmpSh = ThisWorkbook.Sheets.Add sName = ActiveWorkbook.FullName & "_" & ActiveSheet.Name & "_Range" With wsTmpSh.ChartObjects.Add(0, 0, .Width, .Height).Chart .ChartArea.Border.LineStyle = 0 .Parent.Select .Paste .Export Filename:=sName & ".gif", FilterName:="GIF" .Parent.Delete End With End With wsTmpSh.Delete Application.ScreenUpdating = True Application.DisplayAlerts = True End Sub
Просто выделяем диапазон, который необходимо сохранить как картинку и запускаем код. Картинка будет сохранена в папку с активной книгой.
СОХРАНЯЕМ ВСЕ КАРТИНКИ С ЛИСТА В ПАПКУ С ЗАПИСЬЮ В ЯЧЕЙКИ ИМЕН КАРТИНОК
Код ниже сохраняет все картинки на активном листе в папку
images
, которая создается в папке с книгой Excel, картинки из которой сохраняются. Если папки
images
нет — она будет создана. Картинкам даются имена
«img1», «img2», «img3»
и т.д. Картинки из ячеек удаляются, а на их место записывается имя картинки. Актуально, наверное, для тех, кто из таких файлов делает потом выгрузки в интернет-магазины и пр.
Sub Save_Object_As_Picture() Dim li As Long, oObj As Shape, wsSh As Worksheet, wsTmpSh As Worksheet Dim sImagesPath As String, sName As String sImagesPath = ActiveWorkbook.Path & "images" '" If Dir(sImagesPath, 16) = "" Then MkDir sImagesPath End If On Error Resume Next Application.ScreenUpdating = False Application.DisplayAlerts = False Set wsSh = ActiveSheet Set wsTmpSh = ActiveWorkbook.Sheets.Add For Each oObj In wsSh.Shapes If oObj.Type = 13 Then li = li + 1 oObj.Copy sName = "img" & li With wsTmpSh.ChartObjects.Add(0, 0, oObj.Width, oObj.Height).Chart .ChartArea.Border.LineStyle = 0 .Parent.Select .Paste .Export Filename:=sImagesPath & sName & ".jpg", FilterName:="JPG" .Parent.Delete End With oObj.TopLeftCell.Value = sName oObj.Delete 'удаляем картинку с листа End If Next oObj Set oObj = Nothing: Set wsSh = Nothing wsTmpSh.Delete Application.DisplayAlerts = True Application.ScreenUpdating = True MsgBox "Объекты сохранены в папке: " & sImagesPath, vbInformation, "www.excel-vba.ru" End Sub
В коде все так же, как в кодах выше(можно сохранять другие объекты, можно изменить формат сохраняемых картинок). Только при этом в ячейку, в которой была картинка записывается имя, с которым эта картинка была сохранена в папку на компьютере. Сама картинка при этом удаляется. Если удалять не надо, то необходимо просто удалить строку:
oObj.Delete ‘удаляем картинку с листа
Если необходимо записать в ячейку не только имя картинки, но и полный путь(включая путь к папке и расширение картинки), то надо вместо строки:
oObj.TopLeftCell.Value = sName
записать такую:
oObj.TopLeftCell.Value = sImagesPath & sName & «.jpg»
Сохранить картинки с листа с именами картинок из ячеек
Пожалуй, самый популярный код. Он сохраняет картинки из активного листа с именами, взятыми из ячеек, в которых эти картинки расположены. При этом можно указать, чтобы имена брались из той же строки, но другого столбца:
Sub Save_Object_As_Picture_NamesFromCells() Dim li As Long, oObj As Shape, wsSh As Worksheet, wsTmpSh As Worksheet Dim sImagesPath As String, sName As String Dim lNamesCol As Long, s As String s = InputBox("Укажите номер столбца с именами для картинок" & vbNewLine & _ "(0 - столбец в котором сама картинка)", "www.excel-vba.ru", "") If StrPtr(s) = 0 Then Exit Sub lNamesCol = Val(s) sImagesPath = ActiveWorkbook.Path & "images" '" If Dir(sImagesPath, 16) = "" Then MkDir sImagesPath End If ' On Error Resume Next Application.ScreenUpdating = False Application.DisplayAlerts = False Set wsSh = ActiveSheet Set wsTmpSh = ActiveWorkbook.Sheets.Add For Each oObj In wsSh.Shapes If oObj.Type = 13 Then oObj.Copy If lNamesCol = 0 Then sName = oObj.TopLeftCell.Value Else sName = wsSh.Cells(oObj.TopLeftCell.Row, lNamesCol).Value End If 'если в ячейке были символы, запрещенные 'для использования в качестве имен для файлов - удаляем sName = CheckName(sName) 'если sName в результате пусто - даем имя unnamed_ с порядковым номером If sName = "" Then li = li + 1 sName = "unnamed_" & li End If With wsTmpSh.ChartObjects.Add(0, 0, oObj.Width, oObj.Height).Chart .ChartArea.Border.LineStyle = 0 .Parent.Select .Paste .Export Filename:=sImagesPath & sName & ".jpg", FilterName:="JPG" .Parent.Delete End With End If Next oObj Set oObj = Nothing: Set wsSh = Nothing wsTmpSh.Delete Application.DisplayAlerts = True Application.ScreenUpdating = True MsgBox "Объекты сохранены в папке: " & sImagesPath, vbInformation, "www.excel-vba.ru" End Sub '--------------------------------------------------------------------------------------- ' Procedure : CheckName ' Purpose : Функция проверки правильности имени '--------------------------------------------------------------------------------------- Function CheckName(sName As String) Dim objRegExp As Object Dim s As String Set objRegExp = CreateObject("VBScript.RegExp") objRegExp.Global = True: objRegExp.IgnoreCase = True objRegExp.Pattern = "[:,\,/,?,*,<,>,',|,""""]" s = objRegExp.Replace(sName, "") CheckName = s End Function
Укажите номер столбца с именами для картинок — указывается порядковый номер столбца на листе, из которого брать имя для сохраняемой картинки. Например, сами картинки в столбце H, а имена для них записаны в столбце B. Надо указать 2. Тогда для картинки в ячейке H3 будет использовано имя, записанное в ячейке В3. Расширение для картинки указывать не надо(например — image1, image2, image_product_sell1 и т.п.).
Если номер не указывать или указать 0 — то имя для картинок будет взято из тех ячеек, в которых находятся эти картинки.
Так же проверяется корректность значений в ячейках, т.к. они могут содержать символы, недопустимые в именах файлов(слеши и пр.). В этом случаи эти символы будут удалены. И если после удаления этих символов значение будет пустым — имена картинкам будут даваться с префиксом «unnamed_» и порядковым номером таких картинок.
Скачать пример
Tips_Macro_Save_Object_As_Picture.xls (76,0 KiB, 15 154 скачиваний)
Также см.:
Сохранить диаграммы в графический файл
Сохранение выделенного диапазона в графический файл
Как скопировать картинку из примечания?
Статья помогла? Поделись ссылкой с друзьями!
Видеоуроки
Поиск по меткам
Access
apple watch
Multex
Power Query и Power BI
VBA управление кодами
Бесплатные надстройки
Дата и время
Записки
ИП
Надстройки
Печать
Политика Конфиденциальности
Почта
Программы
Работа с приложениями
Разработка приложений
Росстат
Тренинги и вебинары
Финансовые
Форматирование
Функции Excel
акции MulTEx
ссылки
статистика
-
#2
try this,
set range and path as needed.
Code:
Option Explicit
Private Sub SaveRngAsJPG(Rng As Range, FileName As String)
Dim Cht As Chart, bScreen As Boolean, Shp As Shape
bScreen = Application.ScreenUpdating
Application.ScreenUpdating = False
Set Cht = Workbooks.Add(xlChart).Charts(1)
Cht.ChartArea.Clear
Rng.CopyPicture xlScreen, xlPicture
Cht.Paste
With Cht.Shapes(1)
.Left = 0
.Top = 0
.Width = Cht.ChartArea.Width
.Height = Cht.ChartArea.Height
End With
Cht.Export FileName, "JPEG", False
Cht.Parent.Close False
Application.ScreenUpdating = bScreen
End Sub
Sub TestIt2()
Dim Rng As Range, Fn As String
Set Rng = Range("A1:H21")
Fn = "C:resultsMyFile.jpg"
SaveRngAsJPG Rng, Fn
End Sub
hth,
Ross
-
#3
I don’t know if the issue is specific to my install of 64-bit Excel 2016/Office365, but rpaulson’s code gave me consistent errors at With Cht.Shapes(1). The remedies were two-fold: adding a DoEvents statement above Cht.Paste, and commenting out the part turning off screen updating.
I also had issues with the image being truncated. The remedies were to preserve the aspect ratio, set the image width or height (but not both), set the image control to align the image at top left, and set the image control to zoom.
The code below shows how I adjusted rpaulson’s code to work on my computer, with examples of displaying a range, picture on a worksheet, and chart on a worksheet in the userform imagecontrol. There is an annoying bit of screen flashing when the code runs, but it doesn’t give me a runtime error.
Code:
Sub LoadPictureToImageControl(flPathName As String, ImageControl As Control)
ImageControl.Picture = LoadPicture(flPathName)
End Sub
Sub SaveRangeAsJPG(Rng As Range, FileName As String)
Dim cht As Chart
Dim bScreen As Boolean
bScreen = Application.ScreenUpdating
'If bScreen Then Application.ScreenUpdating = False 'Runtime error on With cht.Shapes(1) when this statement not commented out
Rng.CopyPicture xlScreen, xlPicture
Set cht = Workbooks.Add(xlChart).Charts(1)
cht.ChartArea.Clear
DoEvents
cht.Paste
With cht.Shapes(1)
.LockAspectRatio = msoTrue
.Width = cht.ChartArea.Width
.Left = 0
.Top = 0
End With
cht.Export FileName, "JPEG", False
cht.Parent.Close False
If bScreen Then Application.ScreenUpdating = True
End Sub
Sub SaveShapeAsJPG(Shp As Shape, FileName As String)
Dim cht As Chart
Dim bScreen As Boolean
bScreen = Application.ScreenUpdating
'If bScreen Then Application.ScreenUpdating = False 'Runtime error on With cht.Shapes(1) when this statement not commented out
Shp.CopyPicture xlScreen, xlPicture
Set cht = Workbooks.Add(xlChart).Charts(1)
cht.ChartArea.Clear
DoEvents
cht.Paste
With cht.Shapes(1)
.Left = 0
.Top = 0
.Width = cht.ChartArea.Width
End With
cht.Export FileName, "JPEG", False
cht.Parent.Close False
If bScreen Then Application.ScreenUpdating = True
End Sub
Private Sub ExportImages()
Dim Rng As Range
Dim cht As Chart
Dim Fn As String
Dim shp1 As Shape, shp2 As Shape
Set shp1 = ActiveSheet.Shapes("Apple")
Set shp2 = ActiveSheet.Shapes("Coffee")
Set Rng = ActiveSheet.Range("N1:P3")
Set cht = ActiveSheet.ChartObjects(1).Chart
Fn = ThisWorkbook.Path & Application.PathSeparator
SaveRangeAsJPG Rng, Fn & "MyRange.jpg"
SaveShapeAsJPG shp1, Fn & "Apple.jpg"
SaveShapeAsJPG shp2, Fn & "Coffee.jpg"
cht.Export Fn & "FoodChart.jpg"
End Sub
Here is the code I used for my test UserForm:
Code:
Private Sub ToggleButton1_Click()
Dim ImageName As String, flPathName As String
Image1.PictureAlignment = fmPictureAlignmentTopLeft
Image1.PictureSizeMode = fmPictureSizeModeZoom
ImageName = InputBox("What image do you want to display?")
LoadPictureToImageControl ThisWorkbook.Path & Application.PathSeparator & ImageName, Image1
End Sub
Last edited: Jul 25, 2019