• Privacywetgeving
    Het is bij Helpmij.nl niet toegestaan om persoonsgegevens in een voorbeeld te plaatsen. Alle voorbeelden die persoonsgegevens bevatten zullen zonder opgaaf van reden verwijderd worden. In de vraag zal specifiek vermeld moeten worden dat het om fictieve namen gaat.

VBA schermfoto, afbeeldingen kopieren naar bureaublad

Status
Niet open voor verdere reacties.

nasdreas

Gebruiker
Lid geworden
19 mei 2016
Berichten
21
Beste forumleden,

Ik heb inmiddels een code gevonden waarmee een schermkopie gemaakt kan worden. De kopie wordt opgeslagen als een afbeelding in een nieuw werkboek. Dit is al een grote stap in de juiste richting. Ik vraag me af of het ook mogelijk is dat de afbeelding opgeslagen wordt (als jpg o.i.d.) op het bureaublad ipv een nieuw werkboek?
In ieder geval al bedankt voor het meedenken. Als het niet mogelijk is hoor ik het ook graag! :thumb:

Code:
Option Explicit

'#######################################################################################
'Module code for capturing a screen image (Print Screen) and pasting to a new workbook
'Created on November 14th, 2009, compiled by Zack Barresse
'Compiled utilizing the following resources:
'   http://www.ac6la.com/makegif.html
'   http://www.andreavb.com/tip090001.html
'#######################################################################################

Private Const CCHDEVICENAME = 32
Private Const CCHFORMNAME = 32
Private Const SRCCOPY = &HCC0020 ' (DWORD) destination = source

Private Type DEVMODE
    dmDeviceName As String * CCHDEVICENAME
    dmSpecVersion As Integer
    dmDriverVersion As Integer
    dmSize As Integer
    dmDriverExtra As Integer
    dmFields As Long
    dmOrientation As Integer
    dmPaperSize As Integer
    dmPaperLength As Integer
    dmPaperWidth As Integer
    dmScale As Integer
    dmCopies As Integer
    dmDefaultSource As Integer
    dmPrintQuality As Integer
    dmColor As Integer
    dmDuplex As Integer
    dmYResolution As Integer
    dmTTOption As Integer
    dmCollate As Integer
    dmFormName As String * CCHFORMNAME
    dmUnusedPadding As Integer
    dmBitsPerPel As Long
    dmPelsWidth As Long
    dmPelsHeight As Long
    dmDisplayFlags As Long
    dmDisplayFrequency As Long
End Type

'API
Declare Function ReleaseDC Lib "user32.dll" (ByVal hWnd As Long, ByVal hdc As Long) As Long
Declare Function OpenClipboard Lib "user32.dll" (ByVal hWnd As Long) As Long
Declare Function EmptyClipboard Lib "user32.dll" () As Long
Declare Function SetClipboardData Lib "user32.dll" (ByVal wFormat As Long, ByVal hMem As Long) As Long
Declare Function CloseClipboard Lib "user32.dll" () As Long
Declare Function SelectObject Lib "gdi32.dll" (ByVal hdc As Long, ByVal hObject As Long) As Long
Declare Function DeleteDC Lib "gdi32.dll" (ByVal hdc As Long) As Long
Declare Function BitBlt Lib "gdi32.dll" (ByVal hDestDC As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal dwRop As Long) As Long
Declare Function CreateDC Lib "gdi32.dll" Alias "CreateDCA" (ByVal lpDriverName As String, ByVal lpDeviceName As String, ByVal lpOutput As String, lpInitData As DEVMODE) As Long
Declare Function CreateCompatibleBitmap Lib "gdi32.dll" (ByVal hdc As Long, ByVal nWidth As Long, ByVal nHeight As Long) As Long
Declare Function CreateCompatibleDC Lib "gdi32.dll" (ByVal hdc As Long) As Long

Declare Function CountClipboardFormats Lib "user32" () As Long
Declare Function IsClipboardFormatAvailable Lib "user32" (ByVal wFormat As Long) As Long
Declare Function CreateIC Lib "GDI32" Alias "CreateICA" _
                          (ByVal lpDriverName As String, ByVal lpDeviceName As String, _
                           ByVal lpOutput As String, lpInitData As Long) As Long
Declare Function GetDeviceCaps Lib "GDI32" (ByVal hdc As Long, ByVal nIndex As Long) As Long
Declare Function EnumClipboardFormats Lib "user32" (ByVal wFormat As Long) As Long

Sub GetPrintScreen()
'##### SET SCREEN CAPTURE SIZES HERE
    Call CaptureScreen(0, 0, 800, 600)
End Sub

Public Sub ScreenToGIF_NewWorkbook()
    Dim wbDest As Workbook, wsDest As Worksheet
    Dim FromType As String, PicHigh As Single
    Dim PicWide As Single, PicWideInch As Single
    Dim PicHighInch As Single, DPI As Long
    Dim PixelsWide As Integer, PixelsHigh As Integer

    Call TOGGLEEVENTS(False)
    Call GetPrintScreen
    
    If CountClipboardFormats = 0 Then
        MsgBox "Clipboard is currently empty.", vbExclamation, "Nothing to Paste"
        GoTo EndOfSub
    End If

    'Determine the format of the current clipboard contents.  There may be multiple
    'formats available but the Paste methods below will always (?) give priority
    'to enhanced metafile (picture) if available so look for that first.
    If IsClipboardFormatAvailable(14) <> 0 Then
        FromType = "pic"
    ElseIf IsClipboardFormatAvailable(2) <> 0 Then
        FromType = "bmp"
    Else
        MsgBox "Clipboard does not contain a picture or bitmap to paste.", _
               vbExclamation, "No Picture"
        Exit Sub
    End If

    Application.StatusBar = "Pasting from clipboard ..."

    Set wbDest = Workbooks.Add(xlWBATWorksheet)
    Set wsDest = wbDest.Sheets(1)
    wbDest.Activate
    wsDest.Activate
    wsDest.Range("B3").Activate

    'Paste a picture/bitmap from the clipboard (if possible) and select it.
    'The clipboard may contain both text and picture/bitmap format items.  If so,
    'using just ActiveSheet.Paste will paste the text.  Using Pictures.Paste will
    'paste a picture if a picture/bitmap format is available, and the Typename
    'will return "Picture" (or perhaps "OLEObject").  If *only* text is available,
    'Pictures.Paste will create a new TextBox (not a picture) on the sheet and
    'the Typename will return "TextBox".  (This condition now checked above.)
    On Error Resume Next  'just in case
    wsDest.Pictures.Paste.Select
    On Error GoTo 0

    'If the pasted item is an "OLEObject" then must convert to a bitmap
    'to get the correct size, including the added border and matting.
    'Do this via a CopyPicture-Bitmap and then a second Pictures.Paste.
    If TypeName(Selection) = "OLEObject" Then
        With Selection
            .CopyPicture Appearance:=xlScreen, Format:=xlBitmap
            .Delete
            ActiveSheet.Pictures.Paste.Select
            'Modify the FromType (used below in the suggested file name)
            'to signal that the original clipboard image is not being used.
            FromType = "ole object"
        End With
    End If

    'Make sure that what was pasted and selected is as expected.
    'Note this is the Excel TypeName, not the clipboard format.
    If TypeName(Selection) = "Picture" Then
        With Selection
                PicWide = .Width
                PicHigh = .Height
                .Delete
        End With
    Else
        'Can get to here if a chart is selected and "Copy"ed instead of "Copy Picture"ed.
        'Otherwise, ???.
        If TypeName(Selection) = "ChartObject" Then
            MsgBox "Use Shift > Edit > Copy Picture on charts, not just Copy.", _
                   vbExclamation, "Got a Chart Copy, not a Chart Picture"
        Else
            MsgBox "Excel pasted a '" & TypeName(Selection) & "' instead of a Picture.", _
                   vbExclamation, "Not a Picture"
        End If
        'Clean up and quit.
        ActiveWorkbook.Close SaveChanges:=False
        GoTo EndOfSub
    End If

    'Add an empty embedded chart, sized as above, and activate it.
    'Positioned at cell B3 just for convenient debugging and final viewing.
    'Tip from Jon Peltier:  Just add the embedded chart directly, don't use the
    'macro recorder method of adding a new separate chart sheet and then relocating
    'the chart back to a worksheet.
    With Sheets(1)
        .ChartObjects.Add(.Range("B3").Left, .Range("B3").Top, PicWide, PicHigh).Activate
    End With

    'Paste the [resized] bitmap into the ChartArea, which creates ActiveChart.Shapes(1).
    On Error Resume Next
    ActiveChart.Pictures.Paste.Select
    On Error GoTo 0
    If TypeName(Selection) = "Picture" Then
        With ActiveChart
            'Adjust the position of the pasted picture, aka ActiveChart.Shapes(1).
            'Adjustment is slightly greater than the .ChartArea.Left/Top offset, why ???
            ''''         .Shapes(1).IncrementLeft -1
            ''''         .Shapes(1).IncrementTop -4
            'Remove chart border.  This must be done *after* all positioning and sizing.
            '         .ChartArea.Border.LineStyle = 0
        End With

        'Show pixel size info above the picture-in-chart-soon-to-be-GIF/JPEG/PNG.
        PicWideInch = PicWide / 72    'points to inches ("logical", not necessarily physical)
        PicHighInch = PicHigh / 72
        DPI = PixelsPerInch()         'typically 96 or 120 dpi for displays
        PixelsWide = PicWideInch * DPI
        PixelsHigh = PicHighInch * DPI
    Else
        'Something other than a Picture was pasted into the chart.
        'This is very unlikely.
        MsgBox "Clipboard corrupted, possibly by another task."
    End If
    
EndOfSub:
    Call TOGGLEEVENTS(True)
End Sub

Public Sub TOGGLEEVENTS(blnState As Boolean)
'Originally written by Zack Barresse
    With Application
        .DisplayAlerts = blnState
        .EnableEvents = blnState
        .ScreenUpdating = blnState
        If blnState Then .CutCopyMode = False
        If blnState Then .StatusBar = False
    End With
End Sub

Public Function PixelsPerInch() As Long
   'Get the screen resolution in pixels per inch.
   'Under Excel 2000 and above could use Application.DefaultWebOptions.PixelsPerInch.
   Dim hdc As Long
   hdc = CreateIC("DISPLAY", vbNullString, vbNullString, 0)
   PixelsPerInch = GetDeviceCaps(hdc, 88)  'LOGPIXELSX = 88 = Logical pixels/inch in X
   DeleteDC (hdc)
End Function

'Screen Capture Procedure, coordinates are expressed in pixels
Public Sub CaptureScreen(Left As Long, Top As Long, Width As Long, Height As Long)
    Dim srcDC As Long, trgDC As Long, BMPHandle As Long, dm As DEVMODE
    srcDC = CreateDC("DISPLAY", "", "", dm)
    trgDC = CreateCompatibleDC(srcDC)
    BMPHandle = CreateCompatibleBitmap(srcDC, Width, Height)
    SelectObject trgDC, BMPHandle
    BitBlt trgDC, 0, 0, Width, Height, srcDC, Left, Top, SRCCOPY
    OpenClipboard 0&
    EmptyClipboard
    SetClipboardData 2, BMPHandle
    CloseClipboard
    DeleteDC trgDC
    ReleaseDC BMPHandle, srcDC
End Sub
[ATTACH]274831.vB[/ATTACH]
 

Bijlagen

Eigenlijk kan ik mijn verzoek eenvoudiger verwoorden: heeft er iemand een code om een bepaald bereik op te slaan als een JPG afbeelding. Dus door op een knop te drukken popt het 'opslaan als' venster open. Wellicht kan de naam van bestand dat opgeslagen wordt al ingevuld worden met de waarde die aangegeven staan in cel a1 (naam) en a2 ( datum).
 
Ik ben nu nog verder:

Code:
Sub ExportImage()


Dim sFilePath As String
Dim sView As String

'Huidige view
sView = ActiveWindow.View

'normale pagina view geen "Page X" overlays
ActiveWindow.View = xlNormalView

'Screenupdate uitzetten
Application.ScreenUpdating = False

Set Sheet = ActiveSheet

'Hier wordt het bestand naar toe gekopieerd
sFilePath = CreateObject("WScript.Shell").specialfolders("Desktop") & "\" & "Premieberekening" & " " & Range("C2").Value & " " & Range("C5").Value & ".png"

'Als print preview, maar vaste range aangegeven. Deze dient gewijzigd te worden in geval van uitbreidingen e.d.
zoom_coef = 100 / Sheet.Parent.Windows(1).Zoom
Set area = Sheet.Range("B1:L58")
area.CopyPicture xlPrinter
Set chartobj = Sheet.ChartObjects.Add(0, 0, area.Width * zoom_coef, area.Height * zoom_coef)
chartobj.Chart.Paste
chartobj.Chart.Export sFilePath, "png"
chartobj.Delete

'Terug naar normale view
ActiveWindow.View = sView

'Screen update aan
Application.ScreenUpdating = True

'Uitleg
MsgBox ("Export voltooid. Het bestand is terug te vinden in:" & Chr(10) & Chr(10) & sFilePath)

End Sub

De code werkt. Er is 1 probleem. Als het blad beveiligd is, werkt die niet. Dat komt door deze regel: Set chartobj = Sheet.ChartObjects.Add(0, 0, area.Width * zoom_coef, area.Height * zoom_coef)

Waarschijnlijk wordt die geblokkeerd doordat het beveiligd is. Enige methoden om dit te omzeilen?
 
Misschien is het handig om er even een voorbeeldbestand bij te doen. Om het ww te omzeilen kan je zoiets gebruiken.

Code:
With ActiveSheet
    .Unprotect "ww"
    zoom_coef = 100 / .Parent.Windows(1).Zoom
    Set area = .Range("B1:L58")
    area.CopyPicture xlPrinter
    Set chartobj = .ChartObjects.Add(0, 0, area.Width * zoom_coef, area.Height * zoom_coef)
    chartobj.Chart.Paste
    chartobj.Chart.Export sFilePath, "png"
    chartobj.Delete
    .Protect "ww"
End With
 
Ha, VenA,

Bedankt voor die code. Die kan ik ook gebruiken inderdaad.
Ik heb even een voorbeeld bestand als bijlage nu opgenomen met alle codes erin. Hij doet nu precies wat die moet doen.
Maar, alles gaat nu automatisch. Eigenlijk wil ik toch een pop up scherm met het bekende 'opslaan als'. alleen de bestandsnaam, het bestandsformaat (JPG) en het bereik moeten al vooraf ingevuld zijn. Een groot deel van de code is al compleet.

Code:
Sub ExportImage()

Dim sFilePath As String
Dim sView As String


'Huidige view
sView = ActiveWindow.View

'normale pagina view geen "Page X" overlays
ActiveWindow.View = xlNormalView

'Screenupdate uitzetten
Application.ScreenUpdating = False

Set Sheet = ActiveSheet

'Hier wordt het bestand naar toe gekopieerd. En volgens mij moet hier het opslaan als code ook neergezet worden als het goed is? 
sFilePath = CreateObject("WScript.Shell").specialfolders("Desktop") & "\" & "Tekst" & " " & Range("C2").Value & " " & Range("C5").Value & ".png"

'Als print preview, maar vaste range aangegeven. Deze dient gewijzigd te worden in geval van uitbreidingen e.d.

With ActiveSheet
.Unprotect "ww"
zoom_coef = 100 / Sheet.Parent.Windows(1).Zoom
Set area = Sheet.Range("B1:L58")
area.CopyPicture xlPrinter
Set chartobj = Sheet.ChartObjects.Add(0, 0, area.Width * zoom_coef, area.Height * zoom_coef)
chartobj.Chart.Paste
chartobj.Chart.Export sFilePath, "png"
chartobj.Delete
.Protect "ww"
End With

'Terug naar normale view
ActiveWindow.View = sView

'Screen update aan
Application.ScreenUpdating = True

'Uitleg
MsgBox ("Export voltooid. Het bestand is terug te vinden in:" & Chr(10) & Chr(10) & sFilePath)

End Sub

Op die manier kunnen gebruikers nog zelf kiezen waar het bestand terecht moet komen op hun computer.

Bekijk bijlage Voorbeeld.xlsm
 
Laatst bewerkt:
Met een op het www gevonden udf en wat aanpassingen in de code.

UDF:
Code:
Function GetFolder(strPath As String) As String
Dim fldr As FileDialog
Dim sItem As String
Set fldr = Application.FileDialog(msoFileDialogFolderPicker)
With fldr
    .Title = "Select a Folder"
    .AllowMultiSelect = False
    .InitialFileName = strPath
    If .Show <> -1 Then GoTo NextCode
    sItem = .SelectedItems(1)
End With
NextCode:
GetFolder = sItem
Set fldr = Nothing
End Function

Code zonder mijn eerder geplaatste reactie. Was blijkbaar teveel moeite om het in het voorbeeldbestand te stoppen?
Code:
Sub ExportImage()
On Error GoTo Err

Dim sFilePath As String
Dim sView As String
Dim c00

c00 = "\" & "Tekst" & " " & Range("C2").Value & " " & Range("C5").Value & ".png"

'Huidige view
sView = ActiveWindow.View

'normale pagina view geen "Page X" overlays
ActiveWindow.View = xlNormalView

'Screenupdate uitzetten
Application.ScreenUpdating = False

Set Sheet = ActiveSheet

'Hier wordt het bestand naar toe gekopieerd
sFilePath = GetFolder(CreateObject("WScript.Shell").specialfolders("Desktop")) & c00
'Als print preview, maar vaste range aangegeven. Deze dient gewijzigd te worden in geval van uitbreidingen e.d.
zoom_coef = 100 / Sheet.Parent.Windows(1).Zoom
Set area = Sheet.Range("B1:L58")
area.CopyPicture xlPrinter
Set chartobj = Sheet.ChartObjects.Add(0, 0, area.Width * zoom_coef, area.Height * zoom_coef)
chartobj.Chart.Paste
chartobj.Chart.Export sFilePath, "png"
chartobj.Delete

'Terug naar normale view
ActiveWindow.View = sView

'Screen update aan
Application.ScreenUpdating = True

'Uitleg
MsgBox ("Export voltooid. Het bestand is terug te vinden in:" & Chr(10) & Chr(10) & sFilePath)

Err: Resume Next

End Sub
 
Status
Niet open voor verdere reacties.
Terug
Bovenaan Onderaan