设为首页收藏本站Access中国

Office中国论坛/Access中国论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

返回列表 发新帖
查看: 6198|回复: 3
打印 上一主题 下一主题

[API] 【源码】VBA(Access或Excel)如何将剪切板的图片数据保存为BMP或JPG文件

[复制链接]

点击这里给我发消息

跳转到指定楼层
1#
发表于 2015-4-17 23:39:43 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
在帮林岚做一个将Excel的任意单元格的内容复制转为图片,然后将图片再另存为BMP或JPG
开始是使用excel自带的方法,先复制单元格内容,然后按住shift 点击编辑 菜单,有一个 复制为图片 的菜单项。这样图片就转到剪切板了
再对剪切板进行编程
后来发现还有有点麻烦。
就改成直接做成一个通用函数,可对任何指定的区域操作,将指定的区域内容直接转换保存为指定的文件

一、调用方法非常的简单,方法如下:  (www.Office-cn.net)
      
       SaveRangePic Sheet1.Range("E10:F11"), "C:\tmtony.bmp"

二、值得注意的几点
1.要定义好相应的API。可放在模块或本窗体中
2.如果你的Access同时引用了word和excel,因为word 和excel都有range对象,所以要显示将函数的range改为excel.range ,否则调用将失败
    或将excel的引用放在前面也可以

三、详细的API定义及通用函数的完整源码及注释
  1. Private Declare Function OpenClipboard Lib "user32" (ByVal hwnd As Long) As Long

  2. Private Declare Function GetClipboardData Lib "user32" (ByVal wFormat As Integer) As Long

  3. Private Declare Function CloseClipboard Lib "user32" () As Long

  4. Private Declare Function OleCreatePictureIndirect Lib "olepro32.dll" _
  5. (PicDesc As uPicDesc, RefIID As GUID, ByVal fPictureOwnsHandle As Long, _
  6. IPic As IPicture) As Long

  7. '\\ 定义一个 UDT 来保存IPicture OLE接口的 GUID
  8. Private Type GUID
  9. Data1 As Long
  10. Data2 As Integer
  11. Data3 As Integer
  12. Data4(0 To 7) As Byte
  13. End Type

  14. '\\ 定义一个 UDT保存 bitmap信息
  15. Private Type uPicDesc
  16. Size As Long
  17. Type As Long
  18. hPic As Long
  19. hPal As Long
  20. End Type

  21. Private Const CF_BITMAP = 2
  22. Private Const PICTYPE_BITMAP = 1

  23. 'Office中国通用函数 可将任意Excel区域 内容复制并另存为图片
  24. Private Sub SaveRangePic(SourceRange As Range, FilePathName As String)


  25. Dim IID_IDispatch As GUID
  26. Dim uPicinfo As uPicDesc
  27. Dim IPic As IPicture
  28. Dim hPtr As Long

  29. '\\ 复制Range到剪切板 ClipBoard  www.office-cn.net
  30. SourceRange.CopyPicture Appearance:=xlScreen, Format:=xlBitmap
  31. OpenClipboard 0
  32. hPtr = GetClipboardData(CF_BITMAP)
  33. CloseClipboard

  34. '\\ 为picture图片创建一个 GUID 接口
  35. With IID_IDispatch
  36. .Data1 = &H7BF80980
  37. .Data2 = &HBF32
  38. .Data3 = &H101A
  39. .Data4(0) = &H8B
  40. .Data4(1) = &HBB
  41. .Data4(2) = &H0
  42. .Data4(3) = &HAA
  43. .Data4(4) = &H0
  44. .Data4(5) = &H30
  45. .Data4(6) = &HC
  46. .Data4(7) = &HAB
  47. End With

  48. '\\用相关数据填充 uPicInfo
  49. With uPicinfo
  50. .Size = Len(uPicinfo) '结构体长度
  51. .Type = PICTYPE_BITMAP '图片类型
  52. .hPic = hPtr '图片句柄
  53. .hPal = 0 '\\ palette句柄 (如果 是 bitmap).
  54. End With

  55. '\\创建Range对应的 Picture对象
  56. OleCreatePictureIndirect uPicinfo, IID_IDispatch, True, IPic

  57. '\\另存 Picture 对象到文件
  58. stdole.SavePicture IPic, FilePathName

  59. End Sub
复制代码


四、以前网站和论坛与剪切板相关的贴子和链接(几乎涉及到剪切板的大部分操作的源码)

1.用代码插入图片到OLE对象的2种方法
   http://www.access-cn.com/info/info3396.html
2.Access从剪切版里复制和粘贴数据
   http://www.access-cn.com/info/info2045.html
3.最全的有关剪切板(ClipBoard)的各种操作和相关源代码集锦   
    http://www.office-cn.net/thread-119761-1-1.html
4.VBA保存剪贴板为Bmp(加PrtScrn截屏)
    http://www.access-cn.com/info/info3461.html
5.VBA保存剪贴板为JPG(加PrtScrn截屏)
   http://www.access-cn.com/info/info3460.html

五、网上搜索的相关资料(放在这里做个备忘,以免忘记),同时稍做了一下分类与整理,也给有同样问题的网友一个参考,希望对你们有用

1.将Excel整个截屏并另存为BMP文件 (测试是成功的)
  1. Private Declare Sub keybd_event Lib "user32" (ByVal bVk As Byte, ByVal bScan As Byte, ByVal dwFlags As Long, ByVal dwExtraInfo As Long)
  2. Enum JpMode
  3.       theScreen = 0 '全屏截图
  4.       theForm = 1 '当前焦点窗口截图
  5. End Enum


  6. Private Declare Function GetClipboardData Lib "user32" (ByVal wFormat As Long) As Long
  7. Private Declare Function CloseClipboard Lib "user32" () As Long
  8. Private Declare Function OpenClipboard Lib "user32" (ByVal hwnd As Long) As Long
  9. Private Declare Function OleCreatePictureIndirect Lib "olepro32.dll" (PicDesc As PicBmp, RefIID As Guid, ByVal fPictureOwnsHandle As Long, IPic As IPicture) As Long
  10. Private Const CF_BITMAP = 2
  11. Private Type PicBmp
  12.     Size As Long
  13.     Type As Long
  14.     hBmp As Long
  15.     hPal As Long
  16.     Reserved As Long
  17. End Type

  18. Private Type Guid
  19.     Data1 As Long
  20.     Data2 As Integer
  21.     Data3 As Integer
  22.     Data4(0 To 7) As Byte
  23. End Type
  24. Function ApiGetClipBmp() As IPicture
  25. On Error Resume Next
  26.     Dim Pic As PicBmp, IID_IDispatch As Guid
  27.     OpenClipboard 0 'OpenClipboard
  28.     With IID_IDispatch
  29.         .Data1 = &H20400
  30.         .Data4(0) = &HC0
  31.         .Data4(7) = &H46
  32.     End With

  33.     With Pic
  34.         .Size = Len(Pic)
  35.         .Type = 1
  36.         .hBmp = GetClipboardData(CF_BITMAP)
  37.     End With
  38.    
  39.     OleCreatePictureIndirect Pic, IID_IDispatch, 1, ApiGetClipBmp
  40.     'stdole.SavePicture ApiGetClipBmp, "c:\clipboard.bmp"
  41.     CloseClipboard
  42. End Function
  43. Function KeyJp(Optional ByVal TheMode As JpMode = theScreen) As IPictureDisp
  44.    '版权所有,请保留作者信息.QQ:1085992075   '如需商业用途请联系作者
  45.       Call keybd_event(vbKeySnapshot, TheMode, 0, 0) '
  46.       DoEvents
  47.       'Set KeyJp = Clipboard.GetData
  48. End Function
  49. '┗〓〓〓〓〓〓〓〓〓  KeyJp,end  〓〓〓〓〓〓〓〓〓┛
  50. Sub dd()
  51.   KeyJp (theScreen)
  52.   SavePicture ApiGetClipBmp, "c:\2.bmp"
  53. End Sub
复制代码



2.这个程序说起来也不复杂,涉及到两类API函数,一类是剪贴板函数,用于读取剪贴板中的位图句柄,另外一类是GDI+函数,用于位图到jpg文件的转换,具体代码如下:
  1. Option Explicit
  2. Private Declare Function OpenClipboard Lib "user32" (ByVal hwnd As Long) As Long
  3. Private Declare Function CloseClipboard Lib "user32" () As Long
  4. Private Declare Function GetClipboardData Lib "user32" (ByVal wFormat As Long) As Long
  5. Private Const CF_BITMAP = 2

  6. Private Type GUID
  7. Data1 As Long
  8. Data2 As Integer
  9. Data3 As Integer
  10. Data4(0 To 7) As Byte
  11. End Type

  12. Private Type GdiplusStartupInput
  13. GdiplusVersion As Long
  14. DebugEventCallback As Long
  15. SuppressBackgroundThread As Long
  16. SuppressExternalCodecs As Long
  17. End Type

  18. Private Type EncoderParameter
  19. GUID As GUID
  20. NumberOfValues As Long
  21. type As Long
  22. Value As Long
  23. End Type

  24. Private Type EncoderParameters
  25. Count As Long
  26. Parameter As EncoderParameter
  27. End Type

  28. Private Declare Function GdiplusStartup Lib "GDIPlus" (token As Long, inputbuf As GdiplusStartupInput, ByVal outputbuf As Long) As Long
  29. Private Declare Function GdiplusShutdown Lib "GDIPlus" (ByVal token As Long) As Long
  30. Private Declare Function GdipDisposeImage Lib "GDIPlus" (ByVal Image As Long) As Long
  31. Private Declare Function GdipSaveImageToFile Lib "GDIPlus" (ByVal Image As Long, ByVal filename As Long, clsidEncoder As GUID, encoderParams As Any) As Long
  32. Private Declare Function CLSIDFromString Lib "ole32" (ByVal str As Long, id As GUID) As Long
  33. Private Declare Function GdipCreateBitmapFromHBITMAP Lib "GDIPlus" (ByVal hbm As Long, ByVal hPal As Long, BITMAP As Long) As Long

  34. Sub test()
  35.     Select Case CliptoJPG("c:\test.jpg")
  36.         Case 0:
  37.             MsgBox "剪贴板图片已保存"
  38.         Case 1:
  39.             MsgBox "剪贴板图片保存失败"
  40.         Case 2:
  41.             MsgBox "剪贴板中无图片"
  42.         Case 3:
  43.             MsgBox "剪贴板无法打开,可能被其他程序所占用"
  44.     End Select
  45. End Sub


  46. Private Function CliptoJPG(ByVal destfilename As String, Optional ByVal quality As Byte = 80) As Integer
  47. '*****该函数用于取出剪贴板中图片转换为jpg文件另存到指定路径****
  48. '参数说明:
  49. '     destfilename:要保存的jpg文件的完整路径,必要参数;
  50. '     quality: jpg文件的质量,0-100之间的数值,数值越大,图片质量越高
  51. '返回值:
  52. '     0-保存成功;1-保存失败;2-剪贴板中无位图数据;3-无法打开剪贴板

  53.     Dim tSI As GdiplusStartupInput
  54.     Dim lRes As Long
  55.     Dim lGDIP As Long
  56.     Dim lBitmap As Long
  57.     Dim hBmp As Long
  58.    
  59.     '尝试打开剪贴板
  60.     If OpenClipboard(0) Then
  61.         '尝试取出剪贴板中位图的句柄
  62.         hBmp = GetClipboardData(CF_BITMAP)
  63.         '如果hBmp为0,说明剪贴板中没有存放图片
  64.         If hBmp = 0 Then
  65.             CliptoJPG = 2
  66.             CloseClipboard
  67.             Exit Function
  68.         End If
  69.         CloseClipboard
  70.     Else   '如果openclipboard返回0(False),说明剪贴板被其他程序所占用
  71.         CliptoJPG = 3
  72.         Exit Function
  73.     End If
  74.    
  75.     '初始化 GDI+
  76.     tSI.GdiplusVersion = 1
  77.     lRes = GdiplusStartup(lGDIP, tSI, 0)
  78.      
  79.     If lRes = 0 Then
  80.         '从句柄创建 GDI+ 图像
  81.         lRes = GdipCreateBitmapFromHBITMAP(hBmp, 0, lBitmap)
  82.          
  83.         If lRes = 0 Then
  84.             Dim tJpgEncoder As GUID
  85.             Dim tParams As EncoderParameters
  86.             
  87.             '初始化解码器的GUID标识
  88.             CLSIDFromString StrPtr("{557CF401-1A04-11D3-9A73-0000F81EF32E}"), tJpgEncoder
  89.             
  90.             '设置解码器参数
  91.             tParams.Count = 1
  92.             With tParams.Parameter ' Quality
  93.                 '得到Quality参数的GUID标识
  94.                 CLSIDFromString StrPtr("{1D5BE4B5-FA4A-452D-9CDD-5DB35105E7EB}"), .GUID
  95.                 .NumberOfValues = 1
  96.                 .type = 4
  97.                 .Value = VarPtr(quality)
  98.             End With
  99.             
  100.             '保存图像
  101.             lRes = GdipSaveImageToFile(lBitmap, StrPtr(destfilename), tJpgEncoder, tParams)
  102.             If lRes = 0 Then
  103.                 CliptoJPG = 0  '转换成功
  104.             Else
  105.                 CliptoJPG = 1  '转换失败
  106.             End If
  107.             
  108.             '销毁GDI+图像
  109.             GdipDisposeImage lBitmap
  110.         End If
  111.          
  112.         '销毁 GDI+
  113.         GdiplusShutdown lGDIP
  114.     End If
  115. End Function
复制代码











分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏2 分享分享 分享淘帖 订阅订阅

点击这里给我发消息

2#
发表于 2015-4-17 23:51:46 | 只看该作者
好资料!
回复

使用道具 举报

3#
发表于 2015-7-6 00:24:48 | 只看该作者
这么麻烦的。

打开的记录集某个字段怎样取剪贴板的值?

比如rst("地址")=后面怎么写?
4#
发表于 2016-7-10 00:30:50 | 只看该作者
好好好呵呵呵呵呵
您需要登录后才可以回帖 登录 | 注册

本版积分规则

QQ|站长邮箱|小黑屋|手机版|Office中国/Access中国 ( 粤ICP备10043721号-1 )  

GMT+8, 2024-5-5 18:00 , Processed in 0.085501 second(s), 27 queries .

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表