Dynamic pictures with UserForms - operation too slow sometimes

gravanoc

Active Member
Joined
Oct 20, 2015
Messages
351
Office Version
  1. 365
Platform
  1. Windows
  2. Mobile
I've got a userform that is populated with some checkboxes and image controls displaying a section of a worksheet. It is successful probably about 85% of the time. The other times it just doesn't export the picture to the folder properly, and when it populates it looks blank or like an empty chart (since a chart is used in the process). If I run the code step by step instead of like normal it will always work, so something like the paste command is not consistently working. Here is the code involved:

VBA Code:
Sub ExportAsPicture(Optional choice As String, Optional bAddImages As Boolean, Optional y As Long)

    Dim fso As Object, aFold As Object
    Dim aFile As Object
    Dim thePic As Picture
    Dim rngView(0 To 3) As Range
    Dim MyChart As String, MyPicture As String
    Dim PicWidth As Long, PicHeight As Long
    Dim fileName As String
    Dim filePath As String
    Dim i As Long, X As Long
    
    ' choice = wksDefinitions.Range("CF20")
    filePath = Environ("UserProfile") & "\OneDrive\Pictures\Budget Tool\"

    Set fso = CreateObject("Scripting.FileSystemObject")
    On Error Resume Next
    Set aFold = fso.GetFolder(filePath)
    
    If Err.Number <> 0 Then
        Set aFold = fso.CreateFolder(filePath)
    End If
    
    On Error GoTo 0
    
    If bAddImages = False Then
        wksDefinitions.Range("BY18").Offset(0, 0).Value = ""
        wksDefinitions.Range("BY18").Offset(0, 1).Value = ""
        wksDefinitions.Range("BY18").Offset(0, 2).Value = ""
        wksDefinitions.Range("BY18").Offset(0, 3).Value = ""
        X = 3
    Else
        X = 0
    End If

    Application.ScreenUpdating = False
    wksDashboard.Activate
    For i = 0 To X
        Set rngView(i) = wksDashboard.Range("View" & i + 1)
        If InStr(1, LCase(choice), "view " & (i + y) + 1) Then
            
            DoEvents
            rngView(i).CopyPicture Appearance:=xlScreen, format:=1
            ActiveSheet.Paste
            Set thePic = Selection
            fileName = Replace(Replace(Replace(Replace(Now, ":", ""), "/", ""), " ", ""), "PM", "") & (i + y)
            
            MyPicture = Selection.Name
            With Selection
                  PicHeight = .ShapeRange.Height
                  PicWidth = .ShapeRange.Width
            End With
        
            wksDashboard.Shapes.AddChart2(201, xlColumnClustered).Select
            ActiveChart.Location Where:=xlLocationAsObject, Name:="Dashboard"
            Selection.Border.LineStyle = 0
            MyChart = Selection.Name
        
            With wksDashboard
                  With .Shapes(MyChart)
                        .Width = PicWidth
                        .Height = PicHeight
                  End With
        
                  .Shapes(MyPicture).Copy
        
                  With ActiveChart
                        .ChartArea.Select
                        .Paste
                  End With

                  .ChartObjects(1).Chart.Export fileName:=filePath & fileName & ".jpg", FilterName:="jpg"
                  .Shapes(MyChart).Delete
            End With
            thePic.Delete
            wksDefinitions.Range("Attachments").Offset(0, i).Value = "\Pictures\Budget Tool\" & fileName & ".jpg"
        End If
    Next i
    wksTracker.Activate
    Application.ScreenUpdating = True
    Exit Sub

Finish:

End Sub

This is how it should look:
1655833382740.png


This is how it looks sometimes:

1655833447826.png
 

Attachments

  • 1655824538315.png
    1655824538315.png
    103.4 KB · Views: 10

Excel Facts

How to calculate loan payments in Excel?
Use the PMT function: =PMT(5%/12,60,-25000) is for a $25,000 loan, 5% annual interest, 60 month loan.
Do you need to save the image files to disk ? Are you importing the save image files when loading the userform ? I wouldn't use the chart object Export method for this when using it repetitively inside a loop and expect it to be fast. Better not to save the image file to disk at all.

I would copy the image of the range(s) , query the clipboard for the CF_ENHMETAFILE format using GetClipboardData and then use OleCreatePictureIndirect to obtain a StdPicture object from the clipboard image pointer. Once you obtain the StdPic object, you just assign it to the Picture Property of your userform image controls... No file saving to disk will be involved at all.

This would be much quicker but you will probably need to change the overall design of your code.

Do a search for OleCreatePictureIndirect and GetClipboardData. There are many examples online and in this message board.
 
Upvote 0
Solution
Thanks! Well, I did end up just copying a range to a new workbook. I had been copying the area as picture & then doing that process. I used some static pictures instead for the controls. Thank you for your advice on this though, as I'm sure I'll need to use something similar again in the future.
 
Upvote 0

Forum statistics

Threads
1,224,815
Messages
6,181,136
Members
453,021
Latest member
Justyna P

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top