excel的vba

目标:通过vba来实现将excel当中的表的一行数据插入到一个word模板当中,例如将word当中的A1替换为excel当中A1单元格当中的数据。

而且其中的变量可以直接在宏组件上面调节

1、开启宏

一般宏是默认禁止的,因为很容易通过宏来实现渗透,这里打开宏。

image-20260204141318226

image-20260204141254160

word版本宏代码

Sub Final_Batch_Full_List_Confirm()
' --- 1. 变量声明段 ---
Dim wdApp As Object, wdDoc As Object, wdRng As Object
Dim wsSettings As Worksheet, wsData As Worksheet
Dim templatePath As String, saveRule As String, dataSheetName As String
Dim startID As Long, endID As Long, currentID As Long, r As Long, c As Long
Dim lastCol As Long, colLetter As String, count As Integer: count = 0
Dim folderPath As String, dynamicFileName As String, fileExt As String
Dim allFilesList As String ' 用于存储弹窗显示的完整文件清单

' --- 2. 参数读取段 ---
Set wsSettings = ActiveSheet ' 设定当前点击按钮的表为控制表
templatePath = Trim(wsSettings.Range("B2").Value)
dataSheetName = Trim(wsSettings.Range("B3").Value)
startID = wsSettings.Range("B4").Value
endID = wsSettings.Range("B5").Value
saveRule = Trim(wsSettings.Range("B6").Value)

' --- 3. 环境检查段 ---
On Error Resume Next
Set wsData = ThisWorkbook.Sheets(dataSheetName) ' 尝试锁定数据表
If Err.Number <> 0 Then
MsgBox "错误:找不到名为 '" & dataSheetName & "' 的工作表,请检查B3单元格!", vbCritical
Exit Sub
End If
On Error GoTo 0

' 解析保存规则中的文件夹路径 (获取最后一个反斜杠之前的内容)
If InStrRev(saveRule, "\") > 0 Then
folderPath = Left(saveRule, InStrRev(saveRule, "\"))
fileExt = ".docx"
Else
MsgBox "错误:B6保存路径缺少文件夹位置!", vbCritical: Exit Sub
End If

' --- 4. 启动 Word 引擎 ---
Set wdApp = CreateObject("Word.Application") ' 后期绑定,无需手动引用库
wdApp.Visible = False ' 后台运行,提高速度
' 获取数据表最后一列的范围
lastCol = wsData.Cells(1, wsData.Columns.count).End(xlToLeft).Column

' --- 5. 核心处理循环 ---
For currentID = startID To endID
r = currentID + 1 ' 关键逻辑:ID 1 对应数据表的第 2 行

' 仅处理 B 列不为空的行,防止空跑
If wsData.Cells(r, 2).Text <> "" Then
Set wdDoc = wdApp.Documents.Open(templatePath, ReadOnly:=True) ' 以只读方式打开模板

' A. 遍历列进行替换
For c = 2 To lastCol
colLetter = Split(wsData.Cells(1, c).Address, "$")(1) ' 获取列字母 (B, C, D...)
Dim placeholder As String, content As String
placeholder = "$" & colLetter & "2" ' 生成占位符,如 $B2
content = wsData.Cells(r, c).Text ' 获取当前行单元格内容

Set wdRng = wdDoc.content
With wdRng.Find
.ClearFormatting
.Text = placeholder
Do While .Execute
' B. 图片识别逻辑:如果内容是有效的本地图片路径
If (InStr(content, ":\") > 0 Or InStr(content, "/") > 0) And _
(Right(LCase(content), 4) = ".jpg" Or Right(LCase(content), 4) = ".png" Or Right(LCase(content), 5) = ".jpeg") And _
Dir(content) <> "" Then

wdRng.Text = "" ' 删掉占位符文字
Dim shp As Object
Set shp = wdDoc.InlineShapes.AddPicture(fileName:=content, LinkToFile:=False, SaveWithDocument:=True, Range:=wdRng)
shp.LockAspectRatio = True ' 锁定纵横比
shp.Width = 350 ' 设置宽度为 350 磅 (约 12.3 厘米)
Else
' C. 文本替换逻辑
wdRng.Text = content
End If
wdRng.Collapse 0 ' 继续向下查找,防止同一占位符多次出现只替换一个
Loop
End With
Next c

' --- 6. 动态文件名解析段 ---
' 提取 B6 中 \ 之后的文件名模板
dynamicFileName = Mid(saveRule, InStrRev(saveRule, "\") + 1)
' 去掉后缀名干扰
If InStr(dynamicFileName, ".") > 0 Then dynamicFileName = Left(dynamicFileName, InStrRev(dynamicFileName, ".") - 1)

' 将文件名模板中的 $B2 等替换为实际内容
For c = 1 To lastCol
Dim tempColLetter As String
tempColLetter = Split(wsData.Cells(1, c).Address, "$")(1)
Dim filePlaceholder As String
filePlaceholder = "$" & tempColLetter & "2"
If InStr(dynamicFileName, filePlaceholder) > 0 Then
dynamicFileName = Replace(dynamicFileName, filePlaceholder, wsData.Cells(r, c).Text)
End If
Next c

' --- 7. 保存与归档 ---
count = count + 1
Dim finalName As String: finalName = dynamicFileName & fileExt
wdDoc.SaveAs2 folderPath & finalName
wdDoc.Close False ' 关闭 Word 文档,不保存模板更改

' 累加文件名清单用于最后的报告
allFilesList = allFilesList & count & ". " & finalName & vbCrLf
End If
Next currentID

' --- 8. 释放资源与反馈 ---
wdApp.Quit
Set wdApp = Nothing

' 弹出最终生成的清单报告
MsgBox "处理成功!" & vbCrLf & _
"共生成文件:" & count & " 个" & vbCrLf & _
"------------------------" & vbCrLf & _
allFilesList, vbInformation, "生成报告"
End Sub

Word 插件版:批量文档生成工具使用说明

  1. 核心功能概述

本工具通过 Excel 控制台,读取指定的 Word 模板,并根据数据源表中的内容进行批量替换。

  • 文本替换:自动将模板中的 $B2$C2 等占位符替换为对应列的文字。
  • 图片插入:若单元格内容为本地图片路径,自动将其插入并调整至高清尺寸(350 磅)。
  • 动态命名:支持根据 Excel 单元格内容(如姓名、日期)动态生成 Word 文件名。

  1. 控制台配置指南 (单元格 B2-B6)
单元格 项目名称 填写示例 说明
B2 模板路径 C:\模板\设备报告.docx 必须是完整的磁盘路径,包含扩展名。
B3 数据来源 Sheet1 存放数据的工作表名称。
B4 起始 ID 1 对应数据表中的 ID。代码会处理第 ID + 1 行。
B5 结束 ID 5 批量处理的终止 ID。
B6 保存路径 D:\结果\$B2_$C2.docx $B2 等占位符会被替换为该行对应列的内容。

配置 B6 单元格的不同方式及结果:

B6 填写格式 (示例) 生成的文件名效果 适用场景
D:\报告\$B2.docx 塔吊A.docx 简单命名,以主键为准
D:\报告\$B2-检查记录.docx 塔吊A-检查记录.docx 固定后缀,易于分类
D:\报告\$D2_$B2_$C2.docx 2024-05-01_塔吊A_张三.docx 多信息组合,避免重名

excel版本宏代码

Sub Final_Excel_Only_Bulletproof_Version()
Dim wbTemplate As Workbook, wsSettings As Worksheet, wsData As Worksheet, wsTemp As Worksheet
Dim templatePath As String, saveRule As String, dataSheetName As String
Dim startID As Long, endID As Long, currentID As Long, r As Long, c As Long
Dim lastCol As Long, colLetter As String, count As Integer: count = 0
Dim folderPath As String, dynamicFileName As String, fileExt As String
Dim allFilesList As String, cell As Range

' --- 1. 参数安全读取 (修复 13 错误) ---
On Error Resume Next
Set wsSettings = ActiveSheet
templatePath = Trim(wsSettings.Range("B2").Value)
dataSheetName = Trim(wsSettings.Range("B3").Value)
' 使用 Val 将单元格内容强制转为数字,彻底解决“类型不匹配”错误
startID = Val(wsSettings.Range("B4").Value)
endID = Val(wsSettings.Range("B5").Value)
saveRule = Trim(wsSettings.Range("B6").Value)

Set wsData = ThisWorkbook.Sheets(dataSheetName)
If Err.Number <> 0 Then
MsgBox "错误:找不到名为 '" & dataSheetName & "' 的工作表,请检查 B3 单元格。", vbCritical
Exit Sub
End If
On Error GoTo 0

' 路径合规性处理
If InStrRev(saveRule, "\") > 0 Then
folderPath = Left(saveRule, InStrRev(saveRule, "\"))
If Right(folderPath, 1) <> "\" Then folderPath = folderPath & "\"
fileExt = ".xlsx"
Else
MsgBox "错误:B6 保存路径必须包含文件夹路径。", vbCritical: Exit Sub
End If

' 性能优化:关闭刷新
Application.ScreenUpdating = False
Application.DisplayAlerts = False
Application.Calculation = xlCalculationManual

' --- 2. 批量处理循环 ---
For currentID = startID To endID
r = currentID + 1 ' 关键:ID 1 对应数据源第 2 行

' 检查该行是否存在数据
If wsData.Cells(r, 1).Text <> "" Or wsData.Cells(r, 2).Text <> "" Then
' 打开模板 (解决 424 错误:显式初始化模板对象)
Set wbTemplate = Workbooks.Open(templatePath, ReadOnly:=True, UpdateLinks:=False)
Set wsTemp = wbTemplate.Sheets(1)

' 获取数据源最后一列
lastCol = wsData.Cells(1, wsData.Columns.count).End(xlToLeft).Column

' --- 核心改进:全表扫描替换 (避开 FindNext 1004 错误) ---
' 我们直接遍历模板中有内容的区域,逐个匹配占位符
For Each cell In wsTemp.UsedRange
If InStr(cell.Text, "$") > 0 Then ' 只检查包含 $ 的单元格
For c = 2 To lastCol
colLetter = Split(wsData.Cells(1, c).Address, "$")(1)
Dim placeholder As String, content As String
placeholder = "$" & colLetter & "2"
content = wsData.Cells(r, c).Text

' 如果匹配到占位符
If cell.Text = placeholder Then
' 判断是否为图片路径
If (InStr(content, ":\") > 0 Or InStr(content, "/") > 0) And _
(InStr(LCase(content), ".jpg") > 0 Or InStr(LCase(content), ".png") > 0) And _
Dir(content) <> "" Then

cell.Value = "" ' 清空占位符文字
Dim pic As Object
Set pic = wsTemp.Pictures.Insert(content)
With pic
.ShapeRange.LockAspectRatio = msoTrue
.Top = cell.Top + 1
.Left = cell.Left + 1
' 图片高度适配当前单元格高度
.Height = IIf(cell.Height > 5, cell.Height - 2, 50)
End With
Else
' 普通文字填充
cell.Value = content
End If
End If
Next c
End If
Next cell

' --- 3. 解析动态文件名 ---
dynamicFileName = Mid(saveRule, InStrRev(saveRule, "\") + 1)
If InStr(dynamicFileName, ".") > 0 Then dynamicFileName = Left(dynamicFileName, InStrRev(dynamicFileName, ".") - 1)

For c = 1 To lastCol
Dim tCol As String: tCol = Split(wsData.Cells(1, c).Address, "$")(1)
dynamicFileName = Replace(dynamicFileName, "$" & tCol & "2", wsData.Cells(r, c).Text)
Next c

' --- 4. 安全保存与关闭 ---
count = count + 1
wbTemplate.SaveAs Filename:=folderPath & dynamicFileName & fileExt
wbTemplate.Close SaveChanges:=False
Set wbTemplate = Nothing ' 显式销毁对象,彻底杜绝 424 错误再次发生

allFilesList = allFilesList & count & ". " & dynamicFileName & fileExt & vbCrLf
End If
Next currentID

' --- 5. 恢复环境并反馈 ---
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
Application.DisplayAlerts = True

MsgBox "处理成功!" & vbCrLf & _
"共生成 Excel 文件:" & count & " 个" & vbCrLf & _
"------------------------" & vbCrLf & _
allFilesList, vbInformation, "生成报告"
End Sub