I have used some code that will allow a user to store a picture in the comments of a cell using:
Application.ActiveCell.AddComment.Shape.Fill.UserPicture (fName)
I now want to write something that iterates through the comments of a worksheet and exports all the pictures used above into separate picture files. I am not sure how to reach the right object to do this.
Thanks
Martin
I cobbled some code together from a few sources. How does this work?
Sub extractCommentImage()
'Borrowed from: https://excelribbon.tips.net/T011165_Moving_Comment_Background_Pictures_to_Cells.html
Dim cmt As Comment
Dim cel As Range
Dim bvisible As Boolean
For Each cmt In ActiveSheet.Comments
With cmt
bvisible = .Visible
.Visible = True
Set cel = .Parent.Offset(0, 1)
.Shape.CopyPicture appearance:=xlScreen, Format:=xlPicture
cel.PasteSpecial
selection.ShapeRange.LockAspectRatio = msoFalse
.Visible = bvisible
.Shape.Fill.OneColorGradient msoGradientFromCenter, 1, 1
End With 'cmt
Next cmt
ExportMyPicture
End Sub
And the "Export" sub:
Sub ExportMyPicture()
'borrowed from: https://stackoverflow.com/questions/18232987/export-pictures-from-excel-file-into-jpg-using-vba
Dim MyChart As String, MyPicture As String, pic As Object
Dim PicWidth As Long, PicHeight As Long, num As Long
Dim shtName as String
num = 1
Application.ScreenUpdating = False
shtName = ActiveSheet.Name
For Each pic In ActiveSheet.Pictures
MyPicture = pic.Name
With pic
PicHeight = .ShapeRange.Height
PicWidth = .ShapeRange.Width
End With
Charts.Add
ActiveChart.Location Where:=xlLocationAsObject, Name:=shtName
selection.Border.LineStyle = 0
MyChart = Split(ActiveChart.Name, " ")(1) & " 1"
With ActiveSheet
With .Shapes(MyChart)
.Width = PicWidth
.Height = PicHeight
End With
.Shapes(MyPicture).Copy
With ActiveChart
.ChartArea.Select
.Paste
End With
.ChartObjects(1).Chart.Export Filename:="C:\Users\[CHANGE THIS]\Desktop\MyPic " & num & ".jpg", FilterName:="jpg"
num = num + 1
.Shapes(MyChart).Cut
End With
Next pic
Application.ScreenUpdating = True
Exit Sub
End Sub
Related
I'm trying to insert pictures into Excel files from entering the serial number in a cell.
I get a syntax error where it is trying to insert the pictures. Specifically where it says .Shapes.AddPicture.
Sub picture_insert()
Dim picBild As Picture
Dim blnAvailable As Boolean
Dim link As String
Dim Pattern As String
Dim Serial As String
Dim t As String
Dim P1 As String
Dim P2 As String
link = "\\chimera\home\hillerbr\My Documents\Index project\"
Pattern = Range("A14")
Serial = Range("B14")
t = ".jpg"
P1 = Range("C14")
P2 = Range("D14")
With Worksheets("Data Breakdown")
For Each picBild In .Pictures
If picBild.Name = "280.1" Then
'The picture already exists
blnVorhanden = True
Exit For
End If
Next picBild
'only execute if picture does not yet exist
If blnVorhanden = False Then
With .Shapes.AddPicture Filename := link & Pattern & Serial & P1 & t
.Name = Range("C14")
.ShapeRange.LockAspectRatio = msoFalse
.Width = 450
.Height = 500
.Left = Worksheets("Data Breakdown").Range("A10").Left
.Top = Worksheets("Data Breakdown").Range("G20").Top
End With
With .Shapes.AddPicture Filename := link & Pattern & Serial & P1 & t
.Name = Range("D14")
.ShapeRange.LockAspectRatio = msoFalse
.Width = 450
.Height = 500
.Left = Worksheets("Data Breakdown").Range("E10").Left
.Top = Worksheets("Data Breakdown").Range("G20").Top
End With
End If
End With
End Sub
Sub Image_Remove()
Dim picBild As Picture
With Worksheets("Data Breakdown")
For Each picBild In .Pictures
If picBild.Name = Range("C14") Then
picBild.Delete
Exit For
End If
Next picBild
For Each picBild In .Pictures
If picBild.Name = Range("D14") Then
picBild.Delete
Exit For
End If
Next picBild
End With
End Sub
Providing your variables point to a valid image I found the below code works.
Sub Test()
Dim sht As Worksheet
Set sht = Worksheets("Data Breakdown")
With sht
With .Shapes.AddPicture(Filename:=link & Pattern & Serial & P1 & t, _
LinkToFile:=True, SaveWithDocument:=True, _
Left:=.Range("A10").Left, Top:=.Range("G20").Top, Width:=450, Height:=500)
.Name = "ABC"
.LockAspectRatio = True
End With
End With
End Sub
The Help page for AddPicture says there's 7 required parameters.
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...
'...
I need this macro to generate 2 (or more) data columns from 2 (or more) cell references. Currently it only does one data series from one cell reference. The script generates a table and updates the table with a new data entry on each second, then updates a chart using the table data. The cell value is changing in real-time.
This should be a simple fix but I can't figure out the code. I'm out of my league. Any help would be awesome. Maybe somebody can refactor this or at least give me some hints as to what I should do.
Option Explicit
'Update the values between the quotes here:
Private Const sChartWSName = "Chart"
Private Const sSourceWSName = "Tickers"
Private Const sTableName = "tblValues"
Public RunTime As Double
Private Sub Chart_Setup()
'Create the structure needed to preserve and chart data
Dim wsChart As Worksheet
Dim lstObject As ListObject
Dim cht As Chart
Dim shp As Button
'Create sheet if necessary
Set wsChart = Worksheets.Add
wsChart.name = sChartWSName
'Set up listobject to hold data
With wsChart
.Range("A1").value = "Time"
.Range("B1").value = "Value"
Set lstObject = .ListObjects.Add( _
SourceType:=xlSrcRange, _
Source:=.Range("A1:B1"), _
xllistobjecthasheaders:=xlYes)
lstObject.name = sTableName
.Range("A2").NumberFormat = "h:mm:ss"
.columns("A:A").ColumnWidth = 25
.Select
End With
'Create the chart
With ActiveSheet
.Shapes.AddChart.Select
Set cht = ActiveChart
With cht
.ChartType = xlLine
.SetSourceData Source:=Range(sTableName)
.PlotBy = xlColumns
.Legend.Delete
.Axes(xlCategory).CategoryType = xlCategoryScale
With .SeriesCollection(1).Format.Line
.Visible = msoTrue
.Weight = 1.25
End With
End With
End With
'Add buttons to start/stop the routine
Set shp = ActiveSheet.Buttons.Add(242.25, 0, 83.75, 33.75)
With shp
.OnAction = "Chart_Initialize"
.Characters.Text = "Restart Plotting"
End With
Set shp = ActiveSheet.Buttons.Add(326.25, 0, 83.75, 33.75)
With shp
.OnAction = "Chart_Stop"
.Characters.Text = "Stop Plotting"
End With
End Sub
Public Sub Chart_Initialize()
'Initialize the routine
Dim wsTarget As Worksheet
Dim lstObject As ListObject
'Make sure worksheet exists
On Error Resume Next
Set wsTarget = Worksheets(sChartWSName)
If Err.Number <> 0 Then
Call Chart_Setup
Set wsTarget = Worksheets(sChartWSName)
End If
On Error GoTo 0
'Check if chart data exists
With Worksheets(sChartWSName)
Set lstObject = .ListObjects(sTableName)
If lstObject.ListRows.Count > 0 Then
Select Case MsgBox("You already have data. Do you want to clear it and start fresh?", vbYesNoCancel, "Clear out old data?")
Case Is = vbYes
'User wants to clear the data
lstObject.DataBodyRange.Delete
Case Is = vbCancel
'User cancelled so exit routine
Exit Sub
Case Is = vbNo
'User just wants to append to existing table
End Select
End If
'Begin appending
Call Chart_AppendData
End With
End Sub
Private Sub Chart_AppendData()
'Append data to the chart table
Dim lstObject As ListObject
Dim lRow As Long
With Worksheets(sChartWSName)
Set lstObject = .ListObjects(sTableName)
If lstObject.ListRows.Count = 0 Then
lRow = .Range("A1").End(xlDown).row
End If
If lRow = 0 Then
lRow = .Range("A" & .rows.Count).End(xlUp).offset(1, 0).row
End If
.Range("A" & lRow).value = CDate(Now)
.Range("B" & lRow).value = Worksheets(sSourceWSName).Range("M4").value
End With
RunTime = Now + TimeValue("00:00:01")
Application.OnTime RunTime, "Chart_AppendData"
End Sub
Public Sub Chart_Stop()
'Stop capturing data
On Error Resume Next
Application.OnTime EarliestTime:=RunTime, Procedure:="Chart_AppendData", Schedule:=False
End Sub
This is the snippet from "ThisWorkbook"
Private Sub Workbook_BeforeClose(Cancel As Boolean)
'Stop workbook refreshing
Call Chart_Stop
End Sub
I hope this helps.
Option Explicit
'Update the values between the quotes here:
Private Const sChartWSName = "Chart"
Private Const sSourceWSName = "Tickers"
Private Const sTableName = "tblValues"
Public RunTime As Double
Private Sub Chart_Setup()
'Create the structure needed to preserve and chart data
Dim wsChart As Worksheet
Dim lstObject As ListObject
Dim cht As Chart
Dim shp As Button
'Create sheet if necessary
Set wsChart = Worksheets.Add
wsChart.Name = sChartWSName
'Set up listobject to hold data
With wsChart
.Range("A1").Value = "Time"
.Range("B1").Value = "Value1"
'**** I added C! and changed "Value" to "Value1" and "Value2"
.Range("C1").Value = "Value2"
'**** I increased the range of the chart below to C1
Set lstObject = .ListObjects.Add( _
SourceType:=xlSrcRange, _
Source:=.Range("A1:C1"), _
xllistobjecthasheaders:=xlYes)
lstObject.Name = sTableName
.Range("A2").NumberFormat = "h:mm:ss"
.Columns("A:A").ColumnWidth = 25
.Select
End With
'Create the chart
With ActiveSheet
.Shapes.AddChart.Select
Set cht = ActiveChart
With cht
.ChartType = xlLine
.SetSourceData Source:=Range(sTableName)
.PlotBy = xlColumns
.Legend.Delete
.Axes(xlCategory).CategoryType = xlCategoryScale
With .SeriesCollection(1).Format.Line
.Visible = msoTrue
.Weight = 1.25
End With
End With
End With
'Add buttons to start/stop the routine
Set shp = ActiveSheet.Buttons.Add(242.25, 0, 83.75, 33.75)
With shp
.OnAction = "Chart_Initialize"
.Characters.Text = "Restart Plotting"
End With
Set shp = ActiveSheet.Buttons.Add(326.25, 0, 83.75, 33.75)
With shp
.OnAction = "Chart_Stop"
.Characters.Text = "Stop Plotting"
End With
End Sub
Public Sub Chart_Initialize()
'Initialize the routine
Dim wsTarget As Worksheet
Dim lstObject As ListObject
'Make sure worksheet exists
On Error Resume Next
Set wsTarget = Worksheets(sChartWSName)
If Err.Number <> 0 Then
Call Chart_Setup
Set wsTarget = Worksheets(sChartWSName)
End If
On Error GoTo 0
'Check if chart data exists
With Worksheets(sChartWSName)
Set lstObject = .ListObjects(sTableName)
If lstObject.ListRows.Count > 0 Then
Select Case MsgBox("You already have data. Do you want to clear it and start fresh?", vbYesNoCancel, "Clear out old data?")
Case Is = vbYes
'User wants to clear the data
lstObject.DataBodyRange.Delete
Case Is = vbCancel
'User cancelled so exit routine
Exit Sub
Case Is = vbNo
'User just wants to append to existing table
End Select
End If
'Begin appending
Call Chart_AppendData
End With
End Sub
Public Sub Chart_AppendData()
'Append data to the chart table
Dim lstObject As ListObject
Dim lRow As Long
With Worksheets(sChartWSName)
Set lstObject = .ListObjects(sTableName)
If lstObject.ListRows.Count = 0 Then
lRow = .Range("A1").End(xlDown).Row
End If
If lRow = 0 Then
lRow = .Range("A" & .Rows.Count).End(xlUp).Offset(1, 0).Row
End If
.Range("A" & lRow).Value = CDate(Now)
.Range("B" & lRow).Value = 4
.Range("C" & lRow).Value = 5
'******I used the two line above to test results, uncomment the line below and feel free to change M5 to any other renge location workd best for you
' .Range("B" & lRow).Value = Worksheets(sSourceWSName).Range("M4").Value
' .Range("C" & lRow).Value = Worksheets(sSourceWSName).Range("M5").Value
End With
RunTime = Now + TimeValue("00:00:01")
Application.OnTime RunTime, "Chart_AppendData"
End Sub
Public Sub Chart_Stop()
'Stop capturing data
On Error Resume Next
Application.OnTime EarliestTime:=RunTime, Procedure:="Chart_AppendData", Schedule:=False
End Sub
Hi I want to change the file format of the comment shape picture (Fill) and as well as to a standard height and width. Tried the following code but it is keep on throwing Application defined error "Run time error 1004". Please guide me to correct this one.
Sub ReduceImageSize()
Dim cmt As Comment
Dim MyChart As Chart
Dim MyPicture As String
Dim pic As Object
Dim PicWidth As Long
Dim PicHeight As Long
Dim num As Long
num = 1
Application.ScreenUpdating = False
For Each cmt In ActiveSheet.Comments
With cmt
.Visible = True
.Shape.CopyPicture Appearance:=xlScreen, Format:=xlPicture
.Visible = False
PicHeight = .Shape.Height
PicWidth = .Shape.Width
Set MyChart = Charts.Add(0, 0, 100, 100).Chart
With MyChart.Parent
.Width = PicWidth
.Height = PicHeight
.ChartArea.Select
.Paste
.ChartObjects(1).Chart.Export Filename:="C:\Temp\MyPic " & num & ".jpg", FilterName:="jpg"
End With
.Shape.Fill.UserPicture PictureFile:="C:\Temp\MyPic " & num - 1 & ".jpg"
num = num + 1
ActiveChart.Delete
End With
Next
Application.ScreenUpdating = True
End Sub
Try changing Format:=xlPicture to Format:=xlBitmap because jpg is a bitmap type image. See the following from MS. https://msdn.microsoft.com/en-us/library/office/ff837557.aspx
And also https://msdn.microsoft.com/en-us/library/office/ff195475.aspx
Found the solution:
Option Explicit
Sub ReduceImageSize()
Dim cmt As Comment
Dim MyChart As ChartObject
Dim MyPicture As String
Dim pic As Object
Dim PicWidth As Long
Dim PicHeight As Long
Dim num As Long
Dim Mysheet As Worksheet
num = 1
Application.ScreenUpdating = False
For Each Mysheet In ThisWorkbook.Worksheets
For Each cmt In ActiveSheet.Comments
With cmt
.Visible = True
.Shape.CopyPicture Appearance:=xlScreen, Format:=xlBitmap
.Visible = False
PicHeight = .Shape.Height
PicWidth = .Shape.Width
Set MyChart = ActiveSheet.ChartObjects.Add(0, 0, 100, 100)
With MyChart
.Activate
.Width = PicWidth
.Height = PicHeight
.Chart.Paste
'.ChartArea.Select
'.Paste
.Chart.Export Filename:="C:\Temp\MyPic " & num & ".jpg", FilterName:="jpg"
End With
.Shape.Fill.UserPicture PictureFile:="C:\Temp\MyPic " & num & ".jpg"
num = num + 1
MyChart.Delete
End With
Next
Application.ScreenUpdating = True
Next
End Sub
I would like to make this code save the image name from a value in a cell. For example if "cat" was in the cell Y36 I would like it to be called cat.jpg.
The code below works when I don't have & FileNumber & in it or FileNumber = Range("Y36").
Sub ExportCellsAsPicture()
FileNumber = Range("Y36")
Const FName As String = "HD:Users:User:Desktop:" & FileNumber & ".jpg"
Dim pic_rng As Range
Dim ShTemp As Worksheet
Dim ChTemp As Chart
Dim PicTemp As Picture
Application.ScreenUpdating = False
Set pic_rng = Worksheets("QR Code").Range("Y50:AS70") 'Set your range here
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 + 10
.Height = PicTemp.Height + 10
End With
ChTemp.Export Filename:="HD:Users:User:Desktop:" & FileNumber & ".jpg", FilterName:="jpg"
Application.DisplayAlerts = False
ShTemp.Delete
Application.DisplayAlerts = True
Application.ScreenUpdating = True
End Sub
UPDATE: WORKING CODE
Sub whatsup()
Dim pic_rng As Range
Dim ShTemp As Worksheet
Dim ChTemp As Chart
Dim PicTemp As Picture
Dim fileCon As String
fileCon = "JK"
Application.ScreenUpdating = False
Set pic_rng = Worksheets("QR Code").Range("Y50:AS70") 'Set your range here
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
'Here I want the .jpg to be called test_yyyy_mm_dd.jpg
ChTemp.Export Filename:="HD:Users:User1:Desktop:" & fileCon & ".jpg"
Application.DisplayAlerts = False
ShTemp.Delete
Application.DisplayAlerts = True
Application.ScreenUpdating = True
End Sub
Change the Const to a variable. By Definition, a Const(ant) can't change, but you are using it like a variable. Change it to these two lines:
Dim FName As String
FName = "HD:Users:User:Desktop:" & FileNumber & ".jpg"
You should also declare FileNumber before you set it.
Dim FileNumber As Long 'if this is a number. If not, string
FileNumber = Range("Y36")
And finally, it is always good to make everything Explicit and compile to be sure at least your syntax is correct. This will help reduce many simple but easy to miss errors. Place this at the very top of your module:
Option Explicit
Then compile and correct any syntax errors before debugging.
To debug, set a breakpoint on your first executable line (not a Dim statement) and step through line by line checking to see if it is working as you expect.