i have a working code from a previeous thread in here, but i would like to see if there are any possibillities to change/ rework the code so when i copy the sheet from the main workbook to new sheet that the images thats in the sheet will be small images that stay in the sheet. Today i need either to have the images in a folder or access to internet "if using url" to see the images. I would like to be able to see the images if i change pc or are offline etc.
The old thread is her : Rename or add macro to module in a copied sheet from main workbook with vba
Here is the code i use for copying the sheet:
Dim sh As Shape, wbNew As Workbook, ws As Worksheet
ThisWorkbook.Sheets("Import").Copy
Set wbNew = ActiveWorkbook
Set ws = wbNew.Sheets("Import")
For Each sh In ws.Shapes
'relink only if has action set
If Len(sh.OnAction) > 0 Then
sh.OnAction = ws.CodeName & ".Zoom_Click"
End If
Next sh
Adding some more info here:
This code below are the one i use to import the pictures and i guess this is the reason the images are not showing when i use the workbook og t.eg another pc without internet. From what i understand the images here are imported as shapes/objects and its linked to the image files instead of actually have the image within the woorkbook, am i correct here?
This is from the main Workbook where i use the coda above to copy from.
Private Sub CommandButton2_Click()
Dim theShape As shape
Dim xRg As Range
Dim xCol As Long
On Error Resume Next
Application.ScreenUpdating = False
Set rng = Worksheets("Import").Range("A4:B1000")
For Each cell In rng
Filename = cell
If InStr(UCase(Filename), "JPG") > 0 Then
Worksheets("Import").Pictures.Insert(Filename).Select
Set theShape = Selection.ShapeRange.Item(1)
LinkToFile = msoFalse
SaveWithDocument = msoTrue
If theShape Is Nothing Then GoTo isnill
xCol = cell.Column
Set xRg = Cells(cell.Row, xCol)
With theShape
.LockAspectRatio = msoFalse
.ScaleHeight 0.13, msoFalse
.ScaleWidth 0.13, msoFalse
.Top = xRg.Top + (xRg.Height - .Height) / 2
.Left = xRg.Left + (xRg.Width - .Width) / 2
End With
isnill:
Set theShape = Nothing
Range("e1").Select
End If
Next
Application.ScreenUpdating = True
Debug.Print "Done " & Now
End Sub
Hi there I have the code below which calls "Delete_Image_Click" and deletes the shape in a specified cell range and then inserts a new image from a selected filepath into the same cell range.
I need to then delete images in other ranges (on the same worksheet and other worksheets) and then add the same image into the other cell ranges on the same worksheet and then go into another named worksheet and insert the same image into two more ranges.
Could anyone help me with how I go about this?
Sub RectangleRoundedCorners6_Click()
Call Delete_Image_Click
Dim sPicture As String, pic As Picture
sPicture = Application.GetOpenFilename _
("Pictures (*.gif; *.jpg; *.bmp; *.tif; *.png), *.gif;*.png; *.jpg; *.bmp; *.tif", _
, "Select Picture to Import")
If sPicture = "False" Then Exit Sub
Set pic = ActiveSheet.Pictures.Insert(sPicture)
With pic
.ShapeRange.LockAspectRatio = msoTrue
.Height = Range("Q36:W41").Height
.Top = Range("Q36:W41").Top
.Left = Range("Q36:W41").Left
.Placement = xlMoveAndSize
End With
Set pic = Nothing
End Sub
Sub Delete_Image_Click()
Dim xPicRg As Range
Dim xPic As Picture
Dim xRg As Range
Application.ScreenUpdating = False
Set xRg = Range("Q36:W41")
For Each xPic In ActiveSheet.Pictures
Set xPicRg = Range(xPic.TopLeftCell.Address & ":" & xPic.BottomRightCell.Address)
If Not Intersect(xRg, xPicRg) Is Nothing Then xPic.Delete
Next
Application.ScreenUpdating = True
End Sub
Option Explicit
Dim rng As Range
Dim cell As Range
Dim Filename As String
Sub URLPictureInsert()
Dim theShape As Shape
Dim xRg As Range
Dim xCol As Long
On Error Resume Next
Application.ScreenUpdating = False
' Set to the range of cells you want to change to pictures
Set rng = ActiveSheet.Range("D2:D3")
For Each cell In rng
Filename = cell
' Use Shapes instead so that we can force it to save with the document
Set theShape = ActiveSheet.Shapes.AddPicture( _
Filename:=Filename, linktofile:=msoFalse, _
savewithdocument:=msoCTrue, _
Left:=cell.Left, Top:=cell.Top, Width:=60, Height:=60)
If theShape Is Nothing Then GoTo isnill
With theShape
.LockAspectRatio = msoTrue
' Shape position and sizes stuck to cell shape
.Top = cell.Top + 1
.Left = cell.Left + 1
.Height = cell.Height - 2
.Width = cell.Width - 2
' Move with the cell (and size, though that is likely buggy)
.Placement = xlMoveAndSize
End With
' Get rid of the
cell.ClearContents
isnill:
Set theShape = Nothing
Range("D2").Select
Next
Application.ScreenUpdating = True
Debug.Print "Done " & Now
End Sub
Mostly, the stated code can help me to transfer the urls to images. But some urls won't work.
such as this link:
https://www.revolvecn888.com/images/p4/n/d/AGOL-WJ95_V1.jpg
it can not be transfered to images.
I am extracting a excel table as png file the extraction is ok, but the extracted file is too zoomed out and when i zoom in it is all blurr, i am going to attach the image in a mail so the data should be clear visible,Any idea where to change the code ,changed the width and height below to almost 50 no change
With ChTemp.Parent
.Width = PicTemp.Width + 8
.Height = PicTemp.Height + 8
Here is the code
Sub check(filename As String, picturename As String)
Dim myWb As Workbook
Dim ws As Worksheet
Dim i, j As Long, LastRow As Integer
'Dim filename As String, picturename As String
Set myWb = Workbooks.Open(filename:=filename)
Worksheets("Sheet1").Activate
Dim FName As String
FName = picturename
Dim pic_rng As Range
Dim ShTemp As Worksheet
Dim ChTemp As Chart
Dim PicTemp As Picture
Application.ScreenUpdating = False
Set pic_rng = ActiveSheet.Range("A2:N42")
Set ShTemp = Worksheets.Add
Charts.Add
ActiveChart.Location Where:=xlLocationAsObject, Name:=ShTemp.Name
Set ChTemp = ActiveChart
pic_rng.CopyPicture Appearance:=xlScreen, Format:=xlPicture
ChTemp.Paste
Set PicTemp = Selection
With ChTemp.Parent
.Width = PicTemp.Width + 8
.Height = PicTemp.Height + 8
End With
ChTemp.Export filename:=picturename, FilterName:="jpg"
'UserForm1.Image1.Picture = LoadPicture(FName)
Kill FName
Application.DisplayAlerts = False
ShTemp.Delete
myWb.Close False
End Sub
The selection in your case is the Chart itself, and nothing will be increase n its dimensions. And the code must paste the picture in the increased chart... Otherwise, any increase does not help.
Try the next way, please:
'what you have in your code...
'.....
pic_rng.CopyPicture Appearance:=xlScreen, Format:=xlPicture
With ChTemp.Parent
.Width = rng.Width + 10
.Height = rng.Height + 10
End With
ChTemp.Paste
ChTemp.Export filename:=picturename, FilterName:="jpg"
'your code...
'...
This code exports the Range as .jpg to a location that is attached to an email with another module running this.
Sub Export_Dashboard_To_PC()
Dim fileSaveName As Variant, pic As Variant
Application.ScreenUpdating = False
Application.DisplayAlerts = False
FName = ThisWorkbook.Path & "\Dashboard.jpg"
With ThisWorkbook.Sheets("Dashboard")
Sheets("Dashboard").Range(Sheets("BP").Range("AE4")).CopyPicture Appearance:=xlScreen, Format:=xlPicture
Set sht = Sheets.Add
sht.Shapes.AddChart
sht.Shapes.Item(1).Select
Set objChart = ActiveChart
With objChart
.ChartArea.Height = Sheets("Dashboard").Range(Sheets("BP").Range("AE4")).Height
.ChartArea.Width = Sheets("Dashboard").Range(Sheets("BP").Range("AE4")).Width
.ChartArea.Fill.Visible = msoFalse
.ChartArea.Border.LineStyle = xlLineStyleNone
.Paste
.Export Filename:=FName, FilterName:="jpg"
End With
sht.Delete
End With
ActiveSheet.Cells(1, 1).Select
Sheets("BP").Activate
Application.ScreenUpdating = True
Application.DisplayAlerts = True
End Sub
It all happens in one and sometimes the code exports the image as a blank and attach it as a blank on the email and sends it. I can see the problem is at the export because when I go to the location of the export and open the .jpg, it shows a blank.
I have stepped through it many times, every time it works.
DoEvents gives me the same results.
I have this kind of routine in my commercial Excel add-in, and I've had to overengineer the stuffing out of it. So I started with your code, cleaned it up a bit (it wouldn't compile with Option Explicit set), and inserted some lines to (a) try to make it work, and (b) figure out where it got hung up. Part of what I did was build the copy/paste into a loop, to get more feedback faster.
Sub Export_Dashboard_To_PC()
' turn these off for testing
'Application.ScreenUpdating = False
'Application.DisplayAlerts = False
Dim RangeToCopy As Range
' fully qualify the ranges
Set RangeToCopy = ThisWorkbook.Worksheets("Dashboard"). _
Range(ThisWorkbook.Worksheets("BP").Range("AE4").Text)
Dim wks As Worksheet
Set wks = ThisWorkbook.Worksheets.Add
'DoEvents ' sometimes needed after Worksheets.Add but apparently not this time
Dim ImgNumber As Long
For ImgNumber = 1 To 20
Dim FName As String
FName = ThisWorkbook.Path & "\Dashboard" & ImgNumber & ".png"
' PNG much better image format than JPG for worksheet images (crisper, half the size)
Dim cht As Chart
Set cht = wks.Shapes.AddChart(, wks.Columns(ImgNumber).Left, wks.Rows(ImgNumber).Top).Chart
' inserted .left and .top so I could see individual charts
'DoEvents ' sometimes needed after Shapes.AddChart but apparently not here
With cht
With .ChartArea
.Height = RangeToCopy.Height
.Width = RangeToCopy.Width
.Fill.Visible = msoFalse
.Border.LineStyle = xlLineStyleNone
End With
DoEvents ' inserted because sometimes Range.CopyPicture throws an error
RangeToCopy.CopyPicture Appearance:=xlScreen, Format:=xlBitmap
' copy as bitmap here, more reliable, rather than convert to bitmap during export
Dim iLoop As Long, MaxLoop As Long
MaxLoop = 10
For iLoop = 1 To MaxLoop
DoEvents ' inserted b/c sometimes clipboard is slow to contain copied object
.Paste
If .Shapes.Count > 0 Then
' yay, image pasted into chart
Debug.Print iLoop
Exit For
End If
If iLoop >= MaxLoop Then
' boo, never succeeded
MsgBox "Export Picture Failed", vbCritical
GoTo ExitSub
End If
Next
'DoEvents
.Export Filename:=FName, FilterName:="png"
'DoEvents
'.Parent.Delete ' don't delete, examine after run
End With
Next
ExitSub:
'wks.Delete ' don't delete, examine after run
ActiveSheet.Cells(1, 1).Select
ThisWorkbook.Worksheets("BP").Activate
Application.ScreenUpdating = True
Application.DisplayAlerts = True
End Sub
So what I learned was where I needed to put the DoEvents, and where the big bottleneck occurs. The big bottleneck is getting the range copied into the clipboard. VBA starts the copy, and sometimes the copy takes longer than VBA takes to get to the paste, and VBA isn't patient enough to wait. DoEvents is supposed to make VBA wait, but it doesn't always work that way. If the clipboard is still empty (doesn't yet contain a copy of the range), then nothing is pasted, and the exported chart is blank.
So I put another loop after the copy, and did the paste inside the loop. After the paste, if the chart contained an object, then the paste must have worked, so I proceeded to the export.
Usually (in 14 of 20 big loops) the paste resulted in a shape being added to the chart in the first small loop, but in 2/20, it took as many as 6 or 7 small loops.
So for the final code, this is what I came up with. I had to insert
Application.ScreenUpdating True
before the copy, otherwise the copied range was always blank (a blank shape was pasted into the chart.
Sub Export_Dashboard_To_PC()
Application.ScreenUpdating = False
Application.DisplayAlerts = False
Dim RangeToCopy As Range
' fully qualify the ranges
Set RangeToCopy = ThisWorkbook.Worksheets("Dashboard"). _
Range(ThisWorkbook.Worksheets("BP").Range("AE4").Text)
Dim wks As Worksheet
Set wks = ThisWorkbook.Worksheets.Add
Dim FName As String
FName = ThisWorkbook.Path & "\Dashboard_" & Format(Now, "hhmmss") & ".png"
' PNG much better image format than JPG for worksheet images (crisper, half the size)
Dim cht As Chart
Set cht = wks.Shapes.AddChart.Chart
With cht
With .Parent
.Height = RangeToCopy.Height
.Width = RangeToCopy.Width
End With
With .ChartArea
.Fill.Visible = msoFalse
.Border.LineStyle = xlLineStyleNone
End With
ThisWorkbook.Worksheets("Dashboard").Activate
Application.ScreenUpdating = True ' otherwise copied region blank
DoEvents ' inserted because sometimes Range.CopyPicture throws an error
RangeToCopy.CopyPicture Appearance:=xlScreen, Format:=xlBitmap
Application.ScreenUpdating = False
Dim iLoop As Long, MaxLoop As Long
MaxLoop = 10
For iLoop = 1 To MaxLoop
DoEvents ' inserted b/c sometimes clipboard is slow to contain copied object
.Paste
If .Shapes.Count > 0 Then
' yay, image pasted into chart
Exit For
End If
If iLoop >= MaxLoop Then
' never succeeded
MsgBox "Export Picture Failed", vbCritical
GoTo ExitSub
End If
Next
.Export Filename:=FName, FilterName:="png"
End With
ExitSub:
wks.Delete
ActiveSheet.Cells(1, 1).Select
ThisWorkbook.Worksheets("BP").Activate
Application.ScreenUpdating = True
Application.DisplayAlerts = True
End Sub
Follow Up
In my production code (which I checked after posting this), I don't ever set
Application.ScreenUpdating = False
I also don't insert a new sheet, instead I put my temporary chart on the active sheet, which contains the range I'm exporting.
And my internal loop is
With .chart
Do Until .Pictures.Count = 1
DoEvents
.Paste
Loop
.Export sExportName
End With
Same thing, except it assumes it will never never get into an infinite loop.
I experienced a similar problem when using VBA to paste an image into a chart object and export it as a jpg file. I noticed there were no issues when I slowly stepped through the code line by line. Additionally, there were no issues when I added a comment box after pasting the image but before exporting as a jpg, forcing the code to pause. This led me to believe the problem was with Excel not having sufficient time to complete the paste procedure before exporting the image file.
I solved the issue by adding a 3-second loop between pasting and exporting. I also turned on Screen Updating.
Dim time1, time2
time1 = Now
time2 = Now + TimeValue("0:00:03")
Do Until time1 >= time2
DoEvents
time1 = Now()
Loop