ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 效率神器,一键搞定繁琐工作
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
让更多数据处理,一键完成 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
楼主: 过客fppt

[求助] 如何用VBA将Word文档中的域代码公式复制为图片,求大家指点

[复制链接]

TA的精华主题

TA的得分主题

发表于 2023-8-28 00:14 | 显示全部楼层
本帖最后由 batmanbbs 于 2023-8-28 09:02 编辑
过客fppt 发表于 2023-8-25 06:54
超过的话,选中区域会自动分行,生成图片也是两行的了

方法不错,重要的是兼容WORD和WPS,缺点是好像对表格和Omath公式支持的不好

TA的精华主题

TA的得分主题

 楼主| 发表于 2023-8-28 09:31 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
loquat 发表于 2023-8-27 21:38
直接cropRight好像上下也需要处理。

谢谢 loquat 老师,原来还可以这样获取宽度

TA的精华主题

TA的得分主题

发表于 2023-8-28 12:47 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
我的代码,如果选中区域换行了,就会有问题,仅适用单行的选中区域。

TA的精华主题

TA的得分主题

发表于 2023-8-28 15:57 来自手机 | 显示全部楼层
你们怎么修图片上下的多余空白的?

TA的精华主题

TA的得分主题

发表于 2023-8-28 17:11 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
loquat 发表于 2023-8-27 21:38
直接cropRight好像上下也需要处理。

老师,目前针对转图片(包括选区、EQ域代码、OMth公式、表格),经过个人测试,除了表格之外,都不需要对转换后的图片进行上下裁剪,只需将段落中的文本对齐方式设置为居中即可。
image.png
设置后的效果

image.png

TA的精华主题

TA的得分主题

 楼主| 发表于 2023-8-29 17:23 | 显示全部楼层
弄了那么多代码,但是批量上传到系统中之后,发现公司的系统实在是太垃圾了,好绝望!

WPS中转化为图片后非常正常:
1693298488255.jpg
题目批量上传到系统中之后,在系统中的效果:
1693298511633.jpg 1693298538721.jpg
手动一道道题复制到系统中才能达到理想的效果:

1693300878852.jpg

TA的精华主题

TA的得分主题

发表于 2023-8-30 20:37 | 显示全部楼层
可试试如下代码,是用GetPoint方法获得区域位置参数并借用网上截屏代码编写,只作简单测试,效率不高。Win11系统运行时库文件出错
  1.     Private Declare PtrSafe Sub keybd_event Lib "user32" (ByVal bVk As Byte, ByVal bScan As Byte, _
  2.         ByVal dwFlags As Long, ByVal dwExtraInfo As Long)
  3.     Enum JpMode
  4.           theScreen = 0 '全屏截图
  5.           theForm = 1 '当前焦点窗口截图
  6.     End Enum
  7.     Private Declare PtrSafe Function GetClipboardData Lib "user32" (ByVal wFormat As Long) As Long
  8.     Private Declare PtrSafe Function CloseClipboard Lib "user32" () As Long
  9.     Private Declare PtrSafe Function OpenClipboard Lib "user32" (ByVal hwnd As Long) As Long
  10.     Private Declare PtrSafe Function OleCreatePictureIndirect Lib "olepro32.dll" (PicDesc As PicBmp, _
  11.         RefIID As Guid, ByVal fPictureOwnsHandle As Long, IPic As IPicture) As Long
  12.     Private Const CF_BITMAP = 2
  13.     Private Type PicBmp
  14.         Size As Long
  15.         Type As Long
  16.         hBmp As Long
  17.         hPal As Long
  18.         Reserved As Long
  19.     End Type
  20.     Private Type Guid
  21.         Data1 As Long
  22.         Data2 As Integer
  23.         Data3 As Integer
  24.         Data4(0 To 7) As Byte
  25.     End Type
  26.    
  27.     Function ApiGetClipBmp() As IPicture
  28.         On Error Resume Next
  29.         Dim Pic As PicBmp, IID_IDispatch As Guid
  30.         OpenClipboard 0
  31.         With IID_IDispatch
  32.             .Data1 = &H20400
  33.             .Data4(0) = &HC0
  34.             .Data4(7) = &H46
  35.         End With
  36.         With Pic
  37.             .Size = Len(Pic)
  38.             .Type = 1
  39.             .hBmp = GetClipboardData(CF_BITMAP)
  40.         End With
  41.         OleCreatePictureIndirect Pic, IID_IDispatch, 1, ApiGetClipBmp
  42.         CloseClipboard
  43.     End Function
  44.    
  45.     Function KeyJp(Optional ByVal TheMode As JpMode = theScreen) As IPictureDisp
  46.        '版权所有,请保留作者信息.QQ:1085992075 '原声明
  47.           Call keybd_event(vbKeySnapshot, TheMode, 0, 0) '
  48.           DoEvents
  49.     End Function

  50. Function RangeToPic(rngTarget As Range) As Variant
  51.     Dim i%, l&, t&, w&, h&, isWps As Boolean
  52.     If InStr(LCase(Application.Path), "wps") > 0 Then isWps = True
  53.     'rngTarget.Select
  54.     With ActiveDocument
  55.         .ActiveWindow.View.Zoom = 100
  56.         .ActiveWindow.GetPoint l, t, w, h, Selection.Range
  57.         Selection.Collapse wdCollapseEnd
  58.         Call KeyJp(theScreen)
  59.         Call ApiGetClipBmp
  60.         rngTarget.Select
  61.         Selection.PasteSpecial DataType:=wdPasteBitmap
  62.         If isWps Then Selection.MoveStart 1, -1 Else Selection.MoveEnd 1, 1
  63.         With Selection.InlineShapes(1)
  64.             .LockAspectRatio = msoFalse
  65.             .ScaleWidth = 100
  66.             .ScaleHeight = 100
  67.             .PictureFormat.CropLeft = PixelsToPoints(l)
  68.             .PictureFormat.CropTop = PixelsToPoints(t)
  69.             .PictureFormat.CropRight = .Width - PixelsToPoints(w)
  70.             .PictureFormat.CropBottom = .Height - PixelsToPoints(h)
  71.             .Range.ParagraphFormat.BaseLineAlignment = wdBaselineAlignCenter
  72.             .Select
  73.         End With
  74.         SendKeys "{ENTER}"
  75.         Application.CommandBars.Item("Picture").Controls.Item(10).Execute '压缩图片
  76.     End With
  77. End Function

  78. Sub FieldFormulaToPic()
  79.     '将域公式内容转换为图片,仅页内矩形区域;测试环境:win10 x64, WPS 11.1
  80.     Dim aField As Field
  81.     For Each aField In ActiveDocument.Fields
  82.         If aField.Type = wdFieldFormula Then
  83.             aField.Select
  84.             Call RangeToPic(Selection.Range)
  85.         End If
  86.     Next
  87. End Sub
复制代码

评分

2

查看全部评分

TA的精华主题

TA的得分主题

发表于 2023-8-30 23:11 | 显示全部楼层
sylun 发表于 2023-8-30 20:37
可试试如下代码,是用GetPoint方法获得区域位置参数并借用网上截屏代码编写,只作简单测试,效率不高。Win1 ...

老师,通过这段代码又学习到不少新知识,谢谢!

经测试采用结合GETPOINT和截图两种方式处理转图的效果并不太理想:

(1)像素转磅本身就受很多因素影响,虽然解决了WORD界面的缩放问题(其实就位图来说,我觉得更好的办法不是恢复到100%后截图,而是放大后截图再缩小,这样图片效果更好一些),但是仍受屏幕PPI等因素影响(在本本上的情况尤为突出)。

(2)窗口本身也受很多因素影响,比如有其他的置顶窗口(例如:我会使用QUICKER的悬浮按钮)会遮挡屏幕和窗口,这时截图的内容可能就不是真正需要的内容。

(3)代码中有两处使用了快捷键,一个是全屏截图,一个是确认压缩图片。全屏截图的快捷键有可能会被其他软件占用失效(虽然这个概率比较小);压缩图片会弹出窗口WORD压缩图片的确认窗口(有二次确认窗口),影响了代码的运行,另外该功能使用WORD本身的控件,有可能面临WORD和WPS不兼容的问题。

(4)由于采用的截屏方式,必须移动到对应的域代码,让其显示在屏幕上,才能截屏。这导致无法禁止屏幕刷新,大大地降低了运行效率。

(5)剪切图片需要一个过程,每做一次剪切(上下左右一共是4次)都会影响到段落排版,在没有禁止屏幕刷新的情况,极有可能影响截图内容的准确性。(可能还需要一个延时来处理才行)

PS:代码中有两处是不是有点问题:
(1)识别WORD/WPS后,选择插入转换的嵌入式图片,是不是WORD和WPS不同的选择方式写反了?
(2)发送回车键是不是应该在调用压缩图片对话窗口之后?

TA的精华主题

TA的得分主题

 楼主| 发表于 2023-8-31 10:31 | 显示全部楼层
sylun 发表于 2023-8-30 20:37
可试试如下代码,是用GetPoint方法获得区域位置参数并借用网上截屏代码编写,只作简单测试,效率不高。Win1 ...

非常感谢 sylun 老师的帮助,以前我们一直用手动截图一个个公式进行的,但是因为打印出来质量不好,后来要求输入转化为Word自带公式;昨天我也找了公司系统的开发人员,他们今天回复:经过技术评估,后端暂时做不了优化,这个问题以前就存在的,技术之前测试过其他方案都没有办法解决。
总体来说,就是公司的系统太垃圾了,唉

TA的精华主题

TA的得分主题

发表于 2023-8-31 18:20 | 显示全部楼层
本帖最后由 zhanglei1371 于 2023-8-31 19:11 编辑
过客fppt 发表于 2023-8-31 10:31
非常感谢 sylun 老师的帮助,以前我们一直用手动截图一个个公式进行的,但是因为打印出来质量不好,后来 ...

test.rar (109.46 KB, 下载次数: 43)
这个应该没问题吧
3.gif
还没做好...

评分

1

查看全部评分

您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2024-11-21 16:39 , Processed in 0.043136 second(s), 10 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

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