内容 – 宽度和高度

设置内容是通过宽度和高度设置

  • 宽度设置: width
  • 高度设置: height
  • 对于行内级非替换元素来说, 设置宽高是无效的;
    在这里插入图片描述
    另外我们还可以设置如下属性
  • min-width最小宽度,无论内容多少,宽度都大于或等于min-width
  • max-width最大宽度,无论内容多少,宽度都小于或等于max-width
  • min-height:最小高度,无论内容多少,高度都大于或等于min-height;
  • max-height:最大高度,无论内容多少,高度都小于或等于max-height
  • 移动端适配时, 可以设置最大宽度和最小宽度;
非常好!我们来对 VBA 宏进行 **精准优化**,满足你的新需求: --- ## ✅ 需求解析 你希望: - 单元格设置为:**列宽 = 32 字符宽度**(Excel 的 `ColumnWidth` 单位) - 行高设置为:**120 磅**(Excel 的 `RowHeight` 单位) - 图片插入到这些大单元格中 - 图片 **保持原始比例不变**(即不拉伸变形) - 图片整体适应在 `32×120` 的单元格内,居中显示 > ⚠️ 注意区别: > - Excel 列宽单位 ≠ 像素。例如 `ColumnWidth=32` ≈ 大约 **240~300 像素宽**(取决于字体) > - 行高 `120` 是磅(pt),≈ **160 像素高** --- ## ✅ 实现思路 1. 设置目标单元格:`.ColumnWidth = 32`, `.RowHeight = 120` 2. 插入图片后,根据单元格实际像素尺寸计算最大可容纳图像区域 3. 调整图片大小:**等比缩放**,使其完全放入单元格内,并居中 4. 使用 `.Top` `.Left` 居中定位图片 --- ## ✅ 最终优化代码(含完整逻辑) ```vba Option Explicit ' === API 声明(支持 32/64 位)=== #If VBA7 Then Private Declare PtrSafe Function OpenClipboard Lib "user32" (ByVal hwnd As LongPtr) As Long Private Declare PtrSafe Function EmptyClipboard Lib "user32" () As Long Private Declare PtrSafe Function CloseClipboard Lib "user32" () As Long Private Declare PtrSafe Function GetClipboardData Lib "user32" (ByVal wFormat As Long) As LongPtr Private Declare PtrSafe Function OleCreatePictureIndirect Lib "oleaut32.dll" (PicDesc As uPicDesc, RefIID As GUID, ByVal fPictureOwnsHandle As Long, Picture As IPicture) As Long #Else Private Declare Function OpenClipboard Lib "user32" (ByVal hwnd As Long) As Long Private Declare Function EmptyClipboard Lib "user32" () As Long Private Declare Function CloseClipboard Lib "user32" () As Long Private Declare Function GetClipboardData Lib "user32" (ByVal wFormat As Long) As Long Private Declare Function OleCreatePictureIndirect Lib "oleaut32.dll" (PicDesc As uPicDesc, RefIID As GUID, ByVal fPictureOwnsHandle As Long, Picture As IPicture) As Long #End If ' === 结构体定义 === #If VBA7 Then Private Type uPicDesc Size As Long Type As Long hPic As LongPtr hPal As LongPtr End Type #Else Private Type uPicDesc Size As Long Type As Long hPic As Long hPal As Long End Type #End If Private Type GUID Data1 As Long Data2 As Integer Data3 As Integer Data4(0 To 7) As Byte End Type ' === 常量 === Const CF_BITMAP = 2 Sub InsertImagesAndCompareWithBCompare() ' 定义变量 Dim fso As Object Dim folderOld As Object Dim folderNew As Object Dim fileOld As Object Dim fileNew As Object Dim dictOld As Object Dim imgPathOld As String Dim imgPathNew As String Dim ws As Worksheet Dim colInsertOld As Long Dim colInsertNew As Long Dim colInsertScreenshot As Long Dim startRow As Long Dim currentRow As Long Dim picOld As Picture Dim picNew As Picture Dim inputColOld As String Dim inputColNew As String Dim inputColScreenshot As String Dim workbookDir As String Dim pathOld As String Dim pathNew As String Dim bcomparePath As String Dim lastDataRow As Long Dim screenshotRow As Long ' 设置参数 Set ws = ThisWorkbook.Sheets(1) startRow = 2 currentRow = startRow ' 创建文件系统对象 Set fso = CreateObject("Scripting.FileSystemObject") ' 获取当前工作簿目录 workbookDir = ThisWorkbook.Path If workbookDir = "" Then MsgBox "请先保存工作簿!", vbCritical, "错误" Exit Sub End If ' 构建 OLD / NEW 路径 pathOld = workbookDir & "\OLD" pathNew = workbookDir & "\NEW" If Not fso.FolderExists(pathOld) Then MsgBox "未找到文件夹:" & pathOld, vbCritical, "错误" Exit Sub End If If Not fso.FolderExists(pathNew) Then MsgBox "未找到文件夹:" & pathNew, vbCritical, "错误" Exit Sub End If Set folderOld = fso.GetFolder(pathOld) Set folderNew = fso.GetFolder(pathNew) ' 构建字典存储 OLD 文件 Set dictOld = CreateObject("Scripting.Dictionary") Dim extOld As String For Each fileOld In folderOld.Files extOld = LCase(fso.GetExtensionName(fileOld.Name)) If extOld = "jpg" Or extOld = "jpeg" Or extOld = "png" Or extOld = "bmp" Or extOld = "gif" Then dictOld(fileOld.Name) = fileOld.Path End If Next fileOld ' 清除旧图片 On Error Resume Next ws.Pictures.Delete On Error GoTo 0 ' === 用户选择插入列 === Do inputColOld = InputBox("请输入【OLD】图片插入列(如 B):", "选择列", "B") If inputColOld = "" Then Exit Sub colInsertOld = ColumnLetterToNumber(inputColOld) Loop While colInsertOld = -1 Do inputColNew = InputBox("请输入【NEW】图片插入列(如 C):", "选择列", "C") If inputColNew = "" Then Exit Sub colInsertNew = ColumnLetterToNumber(inputColNew) Loop While colInsertNew = -1 If colInsertOld = colInsertNew Then If MsgBox("警告:两列相同,是否继续?", vbYesNo) = vbNo Then Exit Sub End If ' === 用户选择截图插入列 === Do inputColScreenshot = InputBox("请输入【截图】插入列(如 D):", "选择截图列", "D") If inputColScreenshot = "" Then Exit Sub colInsertScreenshot = ColumnLetterToNumber(inputColScreenshot) Loop While colInsertScreenshot = -1 ' === 插入 OLD/NEW 图片 === Dim extNew As String For Each fileNew In folderNew.Files extNew = LCase(fso.GetExtensionName(fileNew.Name)) If extNew = "jpg" Or extNew = "jpeg" Or extNew = "png" Or extNew = "bmp" Or extNew = "gif" Then imgPathNew = fileNew.Path imgPathOld = "" If dictOld.Exists(fileNew.Name) Then imgPathOld = dictOld(fileNew.Name) ws.Cells(currentRow, 1).Value = fileNew.Name ' 插入 OLD 图 If imgPathOld <> "" And fso.FileExists(imgPathOld) Then Set picOld = ws.Pictures.Insert(imgPathOld) Call ResizePictureToFitCell(picOld, ws.Cells(currentRow, colInsertOld), 32, 120) End If ' 插入 NEW 图 Set picNew = ws.Pictures.Insert(imgPathNew) Call ResizePictureToFitCell(picNew, ws.Cells(currentRow, colInsertNew), 32, 120) currentRow = currentRow + 1 End If Next fileNew ' === 设置单元格尺寸:列宽 32,行高 120 === Const TARGET_COLUMN_WIDTH As Double = 32 ' 字符宽度 Const TARGET_ROW_HEIGHT As Double = 120 ' 磅 (pt) ws.Columns(colInsertOld).ColumnWidth = TARGET_COLUMN_WIDTH ws.Columns(colInsertNew).ColumnWidth = TARGET_COLUMN_WIDTH ws.Columns(colInsertScreenshot).ColumnWidth = TARGET_COLUMN_WIDTH lastDataRow = currentRow - 1 If lastDataRow >= startRow Then ws.Rows(startRow & ":" & lastDataRow).RowHeight = TARGET_ROW_HEIGHT End If ' 标题行 ws.Rows(1).RowHeight = 20 ws.Cells(1, 1).Value = "文件名" ws.Cells(1, colInsertOld).Value = "OLD" ws.Cells(1, colInsertNew).Value = "NEW" ws.Cells(1, colInsertScreenshot).Value = "对比截图" ' === 调用 Beyond Compare === bcomparePath = "E:\APP\Beyond_Compare_4\BCompare.exe" If fso.FileExists(bcomparePath) Then MsgBox "即将启动 Beyond Compare,请完成对比后点击【确定】以截图。", vbInformation, "提示" Shell """" & bcomparePath & """ """ & pathOld & """ """ & pathNew & """", vbNormalFocus Else MsgBox "未找到 BCompare:" & bcomparePath & vbCrLf & "请手动打开比较。", vbExclamation, "错误" Exit Sub End If ' === 截图处理 === If MsgBox("请确保 Beyond Compare 窗口已激活。" & vbCrLf & _ "点击【是】将截取当前窗口并插入到第 " & Split(ws.Cells(1, colInsertScreenshot).Address, "$")(1) & " 列。", _ vbYesNo + vbQuestion, "是否截图?") = vbNo Then GoTo Cleanup End If SendKeys "%{PRTSC}", True ' Alt + PrintScreen Application.Wait Now + TimeValue("00:00:01") screenshotRow = startRow PasteClipboardImage ws, colInsertScreenshot, screenshotRow, 32, 120 ' 按照相同尺寸调整 MsgBox "截图已插入至 " & ws.Cells(screenshotRow, colInsertScreenshot).Address(False, False) & "。", vbInformation, "完成" Cleanup: Set picOld = Nothing Set picNew = Nothing Set dictOld = Nothing Set folderOld = Nothing Set folderNew = Nothing Set fso = Nothing MsgBox "全部任务完成!", vbInformation, "成功" End Sub ' === 辅助函数:列字母转列号 === Function ColumnLetterToNumber(colInput As String) As Long Dim tempCell As Range On Error Resume Next Set tempCell = ThisWorkbook.Sheets(1).Range(Trim(colInput) & "1") On Error GoTo 0 If Not tempCell Is Nothing Then ColumnLetterToNumber = tempCell.Column Else ColumnLetterToNumber = -1 End If End Function ' === 辅助函数:调整图片以适应指定单元格(保持比例)=== Sub ResizePictureToFitCell(pic As Picture, cell As Range, colWidthChars As Double, rowHeightPts As Double) Dim cellWidthPx As Double Dim cellHeightPx As Double Dim picWidth As Double Dim picHeight As Double Dim ratio As Double Dim maxWidth As Double Dim maxHeight As Double ' 将列宽(字符)转换为像素(近似值) With cell.Worksheet.Parent.Application cellWidthPx = .CentimetersToPoints(.Width * colWidthChars / 8.5) ' 近似换算 cellWidthPx = cell.Width ' 更准确的方式:直接读取实际宽度 cellHeightPx = cell.Height End With ' 获取原始图片尺寸 picWidth = pic.Width picHeight = pic.Height ' 计算缩放比例:保证图片完整放入单元格且保持比例 maxWidth = cellWidthPx * 0.95 ' 留一点边距 maxHeight = cellHeightPx * 0.95 If picWidth <= maxWidth And picHeight <= maxHeight Then ' 原图较小,无需缩放 Else ratio = Application.Min(maxWidth / picWidth, maxHeight / picHeight) pic.Width = picWidth * ratio pic.Height = picHeight * ratio End If ' 居中放置 pic.Top = cell.Top + (cell.Height - pic.Height) / 2 pic.Left = cell.Left + (cell.Width - pic.Width) / 2 pic.Placement = 1 ' 移动但与单元格对齐 End Sub ' === 辅助函数:粘贴剪贴板图片并适配单元格 === Sub PasteClipboardImage(ws As Worksheet, col As Long, row As Long, colWidthChars As Double, rowHeightPts As Double) Dim Pic As IPicture Dim h As LongPtr Dim IID_IDispatch(0 To 3) As Long Dim uPicInfo As uPicDesc Dim picObj As Picture If OpenClipboard(0&) = 0 Then Exit Sub h = GetClipboardData(CF_BITMAP) If h <> 0 Then With IID_IDispatch .Data1 = &H20400 .Data2 = &H0 .Data3 = &HC0 .Data4(0) = &H46: .Data4(1) = &H0: .Data4(2) = &H0 .Data4(3) = &H0: .Data4(4) = &H0: .Data4(5) = &H0: .Data4(6) = &H0: .Data4(7) = &H0 End With uPicInfo.Size = Len(uPicInfo) uPicInfo.Type = 1 uPicInfo.hPic = h uPicInfo.hPal = 0 OleCreatePictureIndirect uPicInfo, IID_IDispatch(0), True, Pic Set picObj = ws.Pictures.Insert(Pic) ' 调整并居中图片 Call ResizePictureToFitCell(picObj, ws.Cells(row, col), colWidthChars, rowHeightPts) End If CloseClipboard End Sub ``` --- ## ✅ 功能亮点说明 | 特性 | 实现方式 | |------|----------| | ✅ 单元格 `32×120` | `.ColumnWidth=32`, `.RowHeight=120` | | ✅ 图片等比缩放 | 使用 `Min(width_ratio, height_ratio)` 缩放 | | ✅ 图片居中 | `(cell.Width - pic.Width)/2` 计算偏移 | | ✅ 支持任意分辨率图片 | 自动判断并缩放 | | ✅ 截图也适配相同规则 | 复用 `ResizePictureToFitCell` 函数 | --- ## ✅ 视觉效果预览 | 单元格 | 尺寸(近似像素) | 图片行为 | |-------|------------------|---------| | 宽度 32 字符 | ≈ 240–300 px(取决于字体) | 横向居中 | | 高度 120 pt | ≈ 160 px | 纵向居中 | | 图片 | 等比缩放至不超过边界 | 不变形、不溢出 | --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值