2.4 图片查找与引用
Excel 支持图文混排,在一个表中可以存放无数个图片。本节对工作表中图片的查找、引用,以及从磁盘中引用图片到工作簿、窗体等进行案例演示。在本书第8章将进行更全面的图形对象应用详解。
疑难50 如何瞬间删除当前表中所有图片
工作表中有图片、自选图形和图表、艺术字等,可以删除所有图片吗?
解决方案
遍历当前表所有图形对象,逐一判断其类型,如果是图片(即msoPicture)类型那么删除。
操作方法
步骤1 按【Alt+F11】组合键打开VBE窗口。
步骤2 选择菜单“插入”→“模块”,并输入以下代码:
Sub 删除图片() Dim sh As Shape '声明图形对象变量 For Each sh In ActiveSheet.Shapes '遍历本表所有图形对象 If sh.Type = msoPicture Then '如果是图片 sh.Delete '删除 End If Next sh End Sub
步骤3 光标置于代码中任意位置,并按【F5】键执行,活动工作表中的所有图片可以瞬间删除。
原理分析
※ DrawingObjects与Shape对象的区别 ※
所有图片、形状、图表、文本框、艺术字等都属于DrawingObjects对象和Shape对象,通过 DrawingObjects.Delete 可以一次全部删除,通过 Shapes(Item).Delete 一次可以删除一个,配合循环则可以全部删除。本例中要求只删除图片,所以必须利用图形对象的 Type 属性将图片与其他图形对象区别开再进行删除。所以要判断图形对象的类别时不能通过DrawingObjects对象删除图形,而是要通过Shapes(Item).Delete。
知识扩展
图形对象的Type属性表示对象的类型,其不同类型的表示方法如表2-4表示。
█ 表2-4 Shape对象的Type属性列表
疑难51 可以将签名图片复制到表中所有签名处吗
工作表已手动分页,每页末在“制表签名:”处都需要签名。在表中有一个签名的图片,那么所有需要签名处都可以引用这张签名的图片吗?
解决方案
选择签名图片,然后查找所有包括“制表签名:”的单元格,将图片复制到该单元格处,并调整图片大小,使其刚好容纳至单元格。
操作方法
步骤1 按【Alt+F11】组合键打开VBE窗口。
步骤2 选择菜单“插入”→“模块”,并输入以下代码:
Sub 复制签名() Dim cell As Range, FirstAdd As String, ActiveShape As String '如果选择的对象不是图片则退出,否则复制当前对象 If TypeName(Selection) <> "Picture" Then Exit Sub Else Selection.Copy ActiveShape = Selection.name '查找“制表签名:” Set cell = Cells.Find("制表签名:", lookat:=xlWhole) If Not cell Is Nothing Then '如果已找到 FirstAdd = cell.Address '记录第一个找到的单元格的地址 Do ActiveSheet.Paste '粘贴图片 With Selection '设置图片的位置,让图片比单元格稍小一点 .Top = cell.Offset(0, 1).Top + 1 .Left = cell.Offset(0, 1).Left + 1 .Width = cell.Offset(0, 1).Width - 2 .Height = cell.Offset(0, 1).Height - 2 End With Set cell = Cells.FindNext(cell) '查找下一个 Loop Until cell.Address = FirstAdd '直到找到的地址等于首个单元格地址 End If ActiveSheet.Shapes(ActiveShape).Delete '删除原有的图片 End Sub
步骤3 返回工作表界面,在表中插入一张用于签名的图片。选择该图片,选择功能区“开发工具”选项卡,单击“宏”按钮,执行过程“复制签名”,签名图片会瞬间排列在所有要签名的单元格中,而当前选择的签名图片将被删除。图2-57所示的H51单元格中的图片即为页末签名图片之一。
█ 图2-57 每页末产生签名图片
原理分析
※ 复制图形对象与复制数据的区别 ※
将图片复制到多个单元格,不能像复制数据那样找到所有单元格后再一次性粘贴,图片只能一次复制一份。将图片粘贴后,需要对其Top、Left、Width、Height四个属性进行设置,否则图片的位置会偏离目标单元格,以及大小与单元格不一致,影响美观。
知识扩展
※ Selection代表什么 ※
Selection 表示当前选择的对象,它可以是单元格对象,也可以是图形对象、图表系列对象、SmartArt对象、控件等。所以复制对象前有必要利用Typename函数判断Selection对象的类型。需要特别注意的是Typename区分大小写。
疑难52 如何像vlookup引用数据一样引用图片
工作中常用vlookup函数引用单价等数据,如果工作表中有数据和图片名称,那么图2-58所示的表格可以像公式一样根据名称引用图片吗?
解决方案
插入一个窗体,让用户设置存放图片名称的单元格,以及待引用的图片区域地址和图片在该区域中第几列等三个参数。然后根据设置添加一个包括图片引用的名称。最后将公式应用在图片的公式中,实现在图片中引用目标图片。而且图片可以随图片名称变化而变化。
█ 图2-58 待引用图片的工作表
操作方法
步骤1 按【Alt+F11】组合键打开VBE窗口。
步骤2 选择菜单“插入”→“用户窗体”,并从工具箱中将标签、文本框、命令按钮和微调按钮拖到窗体中,其中标签、文本框、命令按钮控件各三个,微调按钮控件一个,并将各自的Caption属性和位置布局按图2-59所示设置。
█ 图2-59 窗体控件布局
步骤3 双击窗体打开代码窗口,删除自动产生的代码,然后输入以下代码:
Private Sub UserForm_Activate() '窗体激活时将活动单元格地址赋予文本框 TextBox1 = ActiveCell.Address End Sub Private Sub CommandButton1_Click() '指定图片存放地址 Dim rng As Range On Error Resume Next star: Set rng = Application.InputBox("请选择单元格:", "图片查询存放地址",Active Cell.Address, , , , , 8) If Err <> 0 Then GoTo star '如果存在错误,则返回Star标签重新指定 TextBox1 = rng(1).Address '将指定的区域中左上角单元格赋予文本框 End Sub Private Sub CommandButton2_Click() '指定图片引用区域,多行多列 Dim rng As Range On Error Resume Next star: '让用户选择,默认是AB列已用区域 Set rng = Application.InputBox("请选择存放图片名称的区域:", "图片引用源 ", Intersect([a:b], Union([a1], ActiveSheet.UsedRange)).Address(0, 0), , , , , 8) If Err <> 0 Then GoTo star '如果存在错误,则返回Star标签重新指定 TextBox2 = rng.Address '将指定区域赋予文本框 End Sub Private Sub SpinButton1_Change() '修改微调按钮时执行 TextBox3 = SpinButton1.Value '文本框显示微调按钮的值 End Sub Private Sub CommandButton3_Click() '根据上面的设定数据添加名称 On Error Resume Next '防错,避免数据填写有误时无法正确执行 If Len(TextBox1) = 0 Or Len(TextBox2) = 0 Or Len(TextBox3) = 0 Then MsgBox "请填写完整!": Exit Sub If Range(TextBox2)(1) = "" Then MsgBox "请选择图片名称区域,不能空白。 ",64:Exit Sub If Me.TextBox3.Value < 0 Or Me.TextBox3.Value > Columns.Count - ActiveCell.Column Then MsgBox "图片所在列超出有效范围!": Exit Sub ActiveWorkbook.Names("照片").Delete '删除原有名称"照片",如果有的话 '添加名称,该名称根据TextBox1的值查找与它同名的图片所在单元格地址。 ActiveWorkbook.Names.Add Name:="照片", RefersTo:="=OFFSET(" & Range (TextBox2)(1).Address & ",MATCH(" & TextBox1.Text & "," & Range (TextBox2).Resize(Range(TextBox2).Rows.Count, 1).Address & ",0)-1," & Me.TextBox3.Value - 1 & ",1,)" With Range(TextBox1.Text).Validation '对TextBox1指定的单元格设置数据有效性 .Delete '删除原有设置,添加新的引用,引用区域为TextBox2代表的区域中第一列 .Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, Operator: =xlBetween, Formula1:="=" & Range(TextBox2).Resize(Range(TextBox2). Rows.Count, 1).Address .InCellDropdown = True .ShowInput = True End With Range(TextBox1.Text).Value = Range(TextBox2)(1).Value '指定默认值 Unload Me '关闭窗口 End Sub
步骤4 选择菜单“插入”→“模块”,并在模块中输入以下代码:
Sub 引用图片() UserForm1.Show 0 '显示窗体 End Sub
步骤5 返回工作表界面,选择单元格D2,选择功能区“开发工具”选项卡,单击“宏”按钮,从弹出的对话框中选择“引用图片”并执行该SUB过程。
步骤6 窗口中第一个文本框的单元格地址保持不变,第二个文本框可以手工写入单元格地址,也可以单击“浏览”按钮来选择区域,本例选择 A2:A25;在图片所在列的文本框中输入数字2。
步骤7 单击“生成查询系统”按钮,窗体会自动关闭,同时在D2单元格产生下拉列表。
█ 图2-60 设定图片引用选项
步骤8 在工作表中任意插入一张图片,并在选择图片的同时在编辑栏输入公式“=照片”,此时图片将变成D2单元格所代表的图片。如果修改D2的姓名,E2的图片相应变化,如图2-61所示。
█ 图2-61 修改图片的公式为“=照片”
原理分析
公式可以任意引用单元格的数据,却无法引用悬浮在单元格上层的图片。不过将公式定义成名称,将名称用于图片的公式引用时却可以实现。在本例中窗体的功能是设置一个引用图片区域的名称,而插入的图片则通过该名称引用对应的图片。
知识扩展
※ 对图片设置公式引用其他图片 ※
在Excel 2003中可通过控件和图片实现引用图片,而Excel 2010只能使用插入的图片引用其他图片。所幸的是对图片添加公式引用图片在Excel 2003和2010都通用,所以在实际工作中尽量使用图片来引用其他图片。
疑难53 如何通过窗体预览指定目录中的所有图片
解决方案
在窗体中添加一个复合框和图片控件,复合框的下拉列表用于显示文件夹中所有图片名称,而修改复合框的显示值时,图像控件则通过LoadPicture函数引用文件夹下同名图片。
操作方法
步骤1 按【Alt+F11】组合键打开VBE窗口,选择菜单“插入”→“用户窗体”。按【F4】键打开“属性”窗口,在属性窗口中将窗体的“Caption”修改为“图片浏览器”。
步骤2 双击窗体进入代码窗口,将自动产生的代码删除,然后输入以下代码:
Dim n As Integer, arr(), PathStr As String Private Sub UserForm_Activate() '激活窗体时执行过程 Dim str As String, fd On Error GoTo err '程序出错时则退出 Set fd = Application.FileDialog(msoFileDialogFolderPicker) With fd '显示一个选择文件夹的对话框,如果选择了文件夹则取其名称,否则退出 If .Show = -1 Then PathStr = .SelectedItems(1) Else Exit Sub End With str = Dir(PathStr & "\*.jpg") '开始查找文件,格式为所有jpg文件 While Len(str) > 0 n = n + 1 '累加变量,该变量代表文件数量 ReDim Preserve arr(1 To n) '重置数组范围 arr(n) = Split(LCase(str), ".jpg")(0) '将文件的后缀名去掉,然后导入数组中 str = Dir() '查找下一个 Wend If n > 0 Then Me.ComboBox1.List = arr: Me.ComboBox1.Text = arr(1) '将数组的值赋予复合框 err: End Sub Private Sub ComboBox1_Change() '修改复合框时执行 '如果复合框非空白,那么图像控件中调用与复合框中字符串同名的图片 If Len(ComboBox1.Text) > 0 Then Image1.Picture = LoadPicture(PathStr & IIf(Right(PathStr, 1) = "\", "", "\") & ComboBox1.Text & ".jpg") End Sub
步骤3 选择菜单“插入”→“模块”,并输入以下代码:
Sub 图片浏览() UserForm1.Show 0 End Sub
步骤4 光标置于过程“图片浏览”中任意位置,并按【F5】键执行,将打开自定义窗体“图片浏览器”,同时弹出选择文件夹的对话框。在对话框中选择存放图片的文件夹“D:\图片”,当单击“确定”按钮返回窗体界面后,复合框和图像控件都默认调用文件夹中第一张图片。如果修改复合框,图像相应变化,如图2-62所示。
█ 图2-62 图像控件中浏览图片
原理分析
窗体中的图像控件通过LoadPicture函数可以调用指定路径的图片,所以通过FileDialog对话框让用户选择路径,而Dir函数可以逐个取出所有图片文件名,那么将两者组合即可成为图片的完整路径供LoadPicture函数调用,从而显示在窗体中。
知识扩展
※ 通过LoadPicture函数加载图片 ※
LoadPicture 函数的参数必须是包括盘符的完整路径,所以对工作表中的图片是无法调用的。如果要在窗体中显示工作表中的图片,通常将图片导入到硬盘再引用到窗体中。