Using Excel VBA macro to capture + save screenshot of specific area in one file

I am trying to create a macro that uses an ActiveX control button (click) to take a screenshot of my desktop screen and save it in the same excel sheet as the button. How do I take an 800x600 screenshot (not a full desktop) and then paste it on the left side of the same sheet as the button? I've tried these numerous ways including sendkeys (the simplest one).

I saved the capture process in a module:

Sub PasteScreenShot()
Application.SendKeys "({1068})"
ActiveSheet.Paste
End Sub

      

And then call sub in your ActiveX button code. The grabber works, but I can't find a way to manipulate its capturing the area or its inserted position on the sheet.

I am trying to automate with buttons, not with a shutdown tool.

+3


source to share


2 answers


Without use SendKeys

Option Explicit

Private Declare Sub keybd_event Lib "user32" (ByVal bVk As Byte, ByVal _
  bScan As Byte, ByVal dwFlags As Long, ByVal dwExtraInfo As Long)

Private Const VK_SNAPSHOT = &H2C

Sub PrintScreen()
    keybd_event VK_SNAPSHOT, 1, 0, 0
    ActiveSheet.Paste
End Sub

      

However, using this approach, if you are using multiple monitors, it will only capture the active monitor, so extra effort needs to be made if you need to capture another monitor (maybe this can be done with API calls, but I don't know got this far).

Note. The operator AppActivate

can be used to activate another (non-Excel) application, and if you do, the function keybd_event

will only capture that application, for example:

AppActivate "Windows Command Processor" 'Modify as needed
keybd_event VK_SNAPSHOT, 1, 0, 0
ActiveSheet.Paste

      

Usage SendKeys

, problem solved:

While it SendKeys

is notorious, if you need to use this method due to the limitations of the API method described above, you may have some problems. As we noticed, the call ActiveSheet.Paste

did not actually insert the print screen, but rather pasted what was previously in the clipboard queue, in the sense that you had to click a button to invoke the macro twice before it actually inserted the screenshot.

I tried several different things to no avail, but didn't notice the obvious: while debugging, if I put a breakpoint on ActiveSheet.Paste

, I no longer see the problem described above!

enter image description here

This tells me that it SendKeys

is not processing fast enough to put the data on the clipboard before executing the next line of code, there are two possible solutions to solve this problem.

  • You can try Application.Wait

    . This method seems to work when I test it, but I would warn you that it is also unreliable.
  • The best option would be DoEvents

    because it is clearly designed to work with things like this:


DoEvents transfers control to the operating system. Control returns after the operating system has finished processing events in its queue and all keys in the SendKeys queue have been sent.

This works for me whether I run the macro manually from the IDE, from the Macros ribbon, or using Click

the event procedure button :

Option Explicit
Sub CopyScreen()

Application.SendKeys "({1068})", True
DoEvents
ActiveSheet.Paste

Dim shp As Shape
With ActiveSheet
    Set shp = .Shapes(.Shapes.Count)
End With

End Sub

      

How to install, resize and crop an image:

Regardless of which method you use, once the image has been inserted with ActiveSheet.Paste

, it will be a shape that you can manipulate with.

To resize: when you have a form descriptor, just assign properties to it Height

and Width

as needed:

Dim shp As Shape
With ActiveSheet
    Set shp = .Shapes(.Shapes.Count)
End With
shp.Height = 600
shp.Width = 800

      

To post this: use the form TopLeftCell

property
.

To cut it: use shp.PictureFormat.Crop

(and / or CropLeft

, CropTop

, CropBottom

, CropRight

, if you need to fine-tune what part of the screenshot is needed, for example, it puts a screenshot in the screenshot at 800x600.:

Dim h As Single, w As Single
h = -(600 - shp.Height)
w = -(800 - shp.Width)

shp.LockAspectRatio = False
shp.PictureFormat.CropRight = w
shp.PictureFormat.CropBottom = h

      

+6


source


Sub SavePicToFile(namefile)
 Selection.CopyPicture xlScreen, xlBitmap
 Application.DisplayAlerts = False
 Set tmp = Charts.Add
 On Error Resume Next
 With tmp
    .SeriesCollection(1).Delete
    .Width = Selection.Width
    .Height = Selection.Height
    .Paste
    .Export filename:=namefile, Filtername:="jpeg"
    .Delete
 End With
End Sub
foto = Application.ActiveWorkbook.Path & "\Foto" & ".jpeg"
ActiveWorkbook.Sheets(1).Range("A1:Z30").Select
SavePicToFile (foto)

      



-1


source







All Articles