AOB
Well-known Member
- Joined
- Dec 15, 2010
- Messages
- 667
- Office Version
- 365
- 2016
- 2013
- Platform
- Windows
I have a function that is designed to accept a range as an argument and export that range as a PNG file to a given location (second argument)
It seems to be a bit temperamental; after much tweaking, I discovered that I had to temporarily switch ScreenUpdating on in order for it to work, and then switch it back off again. But even then, it still seemed to sporadically fail, in that the PNG generated would just be a blank / empty image rather than, effectively, a screenshot of the range provided. The failures seem to correlate with whether or not the Windows session is locked or not. The workbook runs on a schedule, hidden, throughout the day; if I am at my workstation working while it is running, the PNG generates as expected, if I lock the workstation, the PNG is empty. I can't confirm this is definitely related, it's just an anecdotal observation.
What's really weird (to me, anyway), is that when the function "fails" like this, the ErrorHandler block is invoked (suggesting an error or exception has been thrown) - but the log records no error number, description or source? Which is really puzzling me because, how could the ErrorHandler block be invoked, if there's no error?
Here is the function :
(FYI - before anybody asks - objFSO, strNetworkPath and blnWriteToLog are all declared at module level - none of these are causing issues...)
Here is the log when the PNG output is blank :
Odd, no?
It seems to be a bit temperamental; after much tweaking, I discovered that I had to temporarily switch ScreenUpdating on in order for it to work, and then switch it back off again. But even then, it still seemed to sporadically fail, in that the PNG generated would just be a blank / empty image rather than, effectively, a screenshot of the range provided. The failures seem to correlate with whether or not the Windows session is locked or not. The workbook runs on a schedule, hidden, throughout the day; if I am at my workstation working while it is running, the PNG generates as expected, if I lock the workstation, the PNG is empty. I can't confirm this is definitely related, it's just an anecdotal observation.
What's really weird (to me, anyway), is that when the function "fails" like this, the ErrorHandler block is invoked (suggesting an error or exception has been thrown) - but the log records no error number, description or source? Which is really puzzling me because, how could the ErrorHandler block be invoked, if there's no error?
Here is the function :
VBA Code:
Private Function PublishRangeAsPNG(rng As Range, strPNGOutputFilename As String) As Boolean
On Error GoTo ErrorHandler
' Declarations
Dim sht As Worksheet
Dim shtStaging As Worksheet
Dim chtStaging As ChartObject
Dim strTempLocalFilename As String
Dim strNetworkFilename As String
Dim lngFileSize As Long
Dim result As Boolean
' Status bar update and log entry
Application.StatusBar = "Publishing : " & strPNGOutputFilename
If blnWriteToLog Then Call WriteToLog("Publishing : " & strPNGOutputFilename)
' Initialise the File System Object
If objFSO Is Nothing Then Set objFSO = CreateObject("Scripting.FileSystemObject")
' Create a temporary worksheet for staging the chart object, from which the PNG will be exported
With ThisWorkbook
For Each sht In .Sheets
If sht.Name = "Staging" Then
sht.Delete
Exit For
End If
Next sht
Set shtStaging = .Sheets.Add
shtStaging.Name = "Staging"
End With
' Define paths for output files (local temporary and network share)
strTempLocalFilename = ThisWorkbook.Path & "\" & strPNGOutputFilename & ".png"
strNetworkFilename = strNetworkPath & "\" & strPNGOutputFilename & ".png"
' Temporarily re-establish screen updating
Application.ScreenUpdating = True
' Create an empty, transparent, borderless chart object the same height and width as the target range
Set chtStaging = shtStaging.ChartObjects.Add(0, 0, rng.Width, rng.Height)
With chtStaging
.ShapeRange.Fill.Visible = 0 ' msoFalse
.ShapeRange.Line.Visible = 0 ' msoFalse
End With
' Copy the target range as a picture to the chart object, export to the local temporary file and then delete it again
rng.CopyPicture xlScreen, xlBitmap
With chtStaging
.Activate
.Chart.Paste
.Chart.Export Filename:=strTempLocalFilename, FilterName:="PNG"
.Delete
End With
' Copy the local output to the network share
With objFSO
' Sporadically, this export fails resulting in an "empty" PNG file with no error thrown for some reason
' Check that the output file contains an image before replacing the existing PNG file on the network share
' Should be of the order of 100-120KB - empty image should be ~1KB - use 10KB as a threshold for success
lngFileSize = FileLen(strTempLocalFilename)
If lngFileSize > 10000 Then
If blnWriteToLog Then Call WriteToLog("PNG generated successfully (" & Format(lngFileSize, "#,##0") & " bytes)")
' Copy the local temporary file to the network share and flag the function successful
.CopyFile strTempLocalFilename, strNetworkFilename, True
result = True
Else
If blnWriteToLog Then Call WriteToLog("PNG generated was an empty file (" & Format(lngFileSize, "#,##0") & " bytes)")
' Do not copy the local temporary file to the network share and flag the function as unsuccessful
result = False
End If
' Delete the local temporary file
If .FileExists(strTempLocalFilename) Then .DeleteFile (strTempLocalFilename)
End With
Exit_PublishRangeAsPNG:
On Error Resume Next
PublishRangeAsPNG = result
Set objFSO = Nothing
Set chtStaging = Nothing
shtStaging.Delete
Set shtStaging = Nothing
Application.ScreenUpdating = False
Exit Function
ErrorHandler:
result = False
If blnWriteToLog Then
Call WriteToLog("Error in [PublishRangeAsPNG] function")
Call WriteToLog("Error #" & Err.Number)
Call WriteToLog("Description : " & Err.Description)
Call WriteToLog("Source: " & Err.Source)
Err.Clear
Call CommitLog
End If
Resume Exit_PublishRangeAsPNG
End Function
(FYI - before anybody asks - objFSO, strNetworkPath and blnWriteToLog are all declared at module level - none of these are causing issues...)
Here is the log when the PNG output is blank :
19 Aug 2022 19:08:12 | Publishing : MyPNGOutput
19 Aug 2022 19:08:14 | Error in [PublishRangeAsPNG] function
19 Aug 2022 19:08:14 | Error #0
19 Aug 2022 19:08:14 | Description :
19 Aug 2022 19:08:14 | Source:
Odd, no?