复制图片 - Excel VBA

12

概述-

我需要将一个嵌入在一个Excel图片对象中的图像(.png格式)复制到另一个现有的图片中(覆盖其图像数据),同时保留目标形状的身份和字段(位置、可见性、大小、标题等)。这是针对简单的图片,而不是ActiveX OLEObject。


情况:

我使用的是Windows 7,Excel 2010。

我有一个包含多个图片对象的工作表。

根据用户的设置,显示的图片需要频繁更改。我已经设置了触发器等等。

有时,单个形状需要显示几个不同的图片。我想只需从“库”图片(嵌入在另一形状中,对用户隐藏)中复制图像数据到目标位置,但我可以通过简单地替换图片对象来解决这个问题。

然而,有时界面中的多个形状需要显示相同的图像,同时保留它们各自的唯一数据(名称、ID、大小、可见性、标题等)。这种“交换”技巧是禁止的-我必须为UI中每个可能需要采用该外观的实例创建五十个副本的每个“库”对象。


期望:

所以我希望能够简单地拥有那些图片的一个库副本,并能够将该图像复制到集成到UI中的图片对象中。


问题:

我找不到如何做到这一点的方法。

在VBA数据结构内部,我找不到任何对应于图片对象的“图像”部分的字段。

CopyPicture()然后 Paste() 似乎仅在将Paste() 的目标设置为地址(例如 Range("A1"))时才起作用,然后它会创建一个的图片对象。但是我不想要一个新对象,我也不想粘贴到单元格中。我想用另一个图片对象的图像数据覆盖现有图片对象的图像数据。

Duplicate()及类似例程是以上操作的变体,它们创建一个新的图片对象。我有特定的事件等与现有对象绑定,即要更改其图像数据的目标对象,因此我必须更改它的图像,而不是每次都用一些新创建的对象替换它。
LoadPicture() - 它通过硬盘而不是剪贴板(速度较慢,因此不太理想)似乎不能在形状对象上工作,只能在OLEObjects上工作。我需要将所有这些图片对象都转换为ActiveX图像吗?对于静态图片来说,这是很大的开销!并且我期望所有的磁盘读写会明显地拖慢表格。
ActiveX - 我可以将这些图片对象更改为ActiveX图像对象,然后更改'库'对象,然后使用分配(Shapes("Name").DrawingObject.Object.Picture = Shape("Library").DrawingObject.Object.Picture)。[ 这种方法类似于这里的方法 - Excel VBA:从图像控件复制图片到ActiveX对象 ] 我不确定我是否可以使其适用于我的情况。我已经设计了许多UI来利用Shape / Pictures具有而OLEObjects没有的特性和功能(例如3D格式和'填充'在图片对象上工作的特定方法),而且操作OLEObjects比操作简单图片明显慢,对于用户来说足够让人沮丧。(这是我在开发的早期阶段切换到不使用OLEObjects的主要原因之一。)
本质上,我想做的就是当右键单击图片对象时得到的“更改图片”命令的等效操作(除了从另一个图片对象或必要时从剪贴板获取图像数据,而不是从磁盘文件获取)。但是当我记录该操作的宏时,它出现为空白 - 显然,“更改图片”没有生成任何宏代码。

大量的网络搜索和文档浏览都没有找到其他的内容。


嗯....求助?


感谢迄今为止的回复:<br>* 版本/机器 - 抱歉,我应该加上。Windows,Excel 2010。<br><br>Shape.Duplicate - 不幸的是,它只是创建一个新形状,本质上是复制/粘贴的简写。 "destination"变量是一个范围:即它将新副本定向到特定单元格。 我需要覆盖现有图片中的图像数据。<br>* excel.tips:巧妙的技巧,但可悲的是这不适用于我。 我正在独立于单元格位置移动这些形状; 除了重写工作表之外,唯一的解决方案是将图像复制到现有形状对象中。 - user2157978
更新 - 我现在尝试通过创建一个包含放置在形状对象上方的ActiveX图片的组对象来解决这个问题。这样可以满足UI所需的两种行为,但代价是需要更多的VBA编码(没关系),并且Excel对象的数量增加了三倍(比其他一些替代方案要好)。但是,正如预期的那样(并且与表格早期版本发生的情况相同),拖动这个组对象(带有ActiveX图片控件)的速度比简单形状慢得多。实时更改常规图片对象的图像仍然是理想的解决方案。还有其他建议吗? - user2157978
你有考虑使用一些Windows API调用来完成这个任务吗?也许可以从BitBlt()开始。 - Ross McConeghy
你也许会发现这篇Stack Overflow帖子中的API函数很有帮助。 - Ross McConeghy
BitBlt - 感谢提供这些链接。我以前没有使用过API命令,所以我对BitBlt进行了更多的搜索和阅读。如果我理解正确,它用于从屏幕或另一个位图中捕获选择作为位图到新位图中。我可以看到这如何与OLEObject一起使用,它具有指向位图的“Picture”字段。但是,对于这样的图片,我已经可以获得该行为(请参见上面的OP关于ActiveX)。但是对于一个shape对象的图片却不行。我如何找到这样一个形状的位图地址,以便使用BitBlt从一个复制到另一个? - user2157978
显示剩余4条评论
1个回答

2

我不想说这个,但我认为你已经陷入了一个死角。Excel的对象不支持以你所描述的方式修改图片数据,这意味着你不能在表格打开时进行这些更改。即使你找到了如何对原始文件进行更改的方法,也无法满足你的用户界面要求。

你的解决方法可能是最好的(基于Excel的)答案。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接