Using Excel VBA Macro To Capture + Save Screenshot of Specific Area In Same File

匿名 (未验证) 提交于 2019-12-03 02:52:02

问题:

I'm trying to create a macro which uses an ActiveX control button (click) to take a screenshot of my desktop screen and save it within the same excel sheet as the button. How can I create a screenshot 800x600 in size (not full desktop view) and then have it pasted into the left hand side of the same sheet as the button? I have tried this numerous ways including sendkeys (simplest).

I saved the capture process in a module:

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

And then call the sub in the ActiveX button code. The capture works but I cannot figure out a way to manipulate its area grab or its pasted location on the sheet.

I am trying to automate with buttons rather than using the snipping tool.

回答1:

Without using 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, with this approach if you are using multiple monitors, it will only capture the active monitor, so further effort needs to be made if you need to capture the other monitor (this can probably be done with API calls but I haven't gotten that far).

NB: The AppActivate statement can be used to activate another (non-Excel) application and if you do this, then the keybd_event function will only capture that application, e.g;

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

Using SendKeys, Problem Solved:

While SendKeys is notoriously flaky, if you need to use this method due to limiations of the API method described above, you might have some problems. As we both observed, the call to ActiveSheet.Paste was not actually pasting the Print Screen, but rather it was pasting whatever was previously in the Clipboard queue, to the effect that you needed to click your button to call the macro twice, before it would actually paste the screenshot.

I tried a few different things to no avail, but overlooked the obvious: While debugging, if I put a breakpoint on ActiveSheet.Paste, I was no longer seeing the problem described above!

This tells me that the SendKeys is not processed fast enough to put the data in the Clipboard before the next line of code executes, to solve that problem there are two possible solutions.

  1. You could try Application.Wait. This method seems to work when I test it, but I'd caution that it's also unreliable.
  2. A better option would be DoEvents, because it's explicitly designed to handle this sort of thing:

DoEvents passes control to the operating system. Control is returned after the operating system has finished processing the 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 from a button Click event procedure:

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 Position, Resize & Crop the Image:

Regardless of which method you use, once the picture has been pasted using ActiveSheet.Paste it will be a Shape which you can manipulate.

To Resize: once you have a handle on the shape, just assign its Height and Width properties as needed:

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

To Position It: use the shape's TopLeftCell property.

To Crop It: use the shp.PictureFormat.Crop (and/or CropLeft, CropTop, CropBottom, CropRight if you need to fine-tune what part of the screenshot is needed. For instance, this crops the pasted screenshot to 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 


回答2:

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) 


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!