Excel多表合并:重复公司行匹配任务及VBA错误13求助
解决方案:公司记录重复匹配任务
首先说下你遇到的**错误13(类型不匹配)**的原因:你的代码里直接用CInt转换O列的值,但如果O列单元格是空值、文本内容或者小数,CInt就会报错。比如单元格是空白、写了“三次”或者是2.5,都会触发类型不匹配。下面给你两种可行的方案,优先Excel公式,再给你修正后的VBA代码。
一、Excel公式方案(适合Excel 365/2021及以上版本)
这种方法不用写代码,直接用公式就能生成目标数据:
步骤1:展开公司记录
假设你的Blad1中,公司数据从第2行开始(第1行是表头),A列是公司名、B列地址、C列城市,O列是需要重复的次数。
在Blad3的A1单元格输入以下公式,按回车后会自动展开所有公司记录(按O列次数重复):
=TOROW(TEXTSPLIT(TEXTJOIN("|",TRUE,REPT(Blad1!A2:A6000&"|",Blad1!O2:O6000)),"|",,TRUE),,TRUE)
注:如果你的数据没有表头,直接把
A2:A6000和O2:O6000改成A1:A6000和O1:O6000。
同理,在Blad3的B1和C1分别输入对应地址、城市的公式,只需要把公式里的Blad1!A2:A6000换成Blad1!B2:B6000和Blad1!C2:C6000即可。
步骤2:匹配任务记录
假设Blad2的任务数据从第1行(表头)开始,A列任务名、B列说明、C列时长。在Blad3的D1(任务名)输入以下公式,会循环取用Blad2的任务数据:
=INDEX(Blad2!$A:$A,MOD(ROW()-1,COUNTA(Blad2!$A:$A))+1)
同样,把公式里的$A:$A换成$B:$B和$C:$C,就能在E、F列得到任务说明和时长。
二、修正后的VBA方案
如果你的Excel版本不支持365的新函数,或者需要批量处理更复杂的逻辑,可以用这个修正后的VBA代码,解决了类型不匹配的问题,还自动匹配任务:
Sub DuplicateRowsWithTasks() '定义工作表对象 Dim wsSource As Worksheet, wsTasks As Worksheet, wsOutput As Worksheet Set wsSource = ThisWorkbook.Worksheets("Blad1") Set wsTasks = ThisWorkbook.Worksheets("Blad2") Set wsOutput = ThisWorkbook.Worksheets("Blad3") '获取数据最后一行(动态适配,不用硬编码行数) Dim lastSourceRow As Long, lastTaskRow As Long lastSourceRow = wsSource.Cells(wsSource.Rows.Count, "A").End(xlUp).Row lastTaskRow = wsTasks.Cells(wsTasks.Rows.Count, "A").End(xlUp).Row Dim taskCount As Long: taskCount = lastTaskRow '任务总数 Dim currentSourceRow As Long, currentOutputRow As Long currentOutputRow = 1 '输出表起始行(如果有表头,后续会调整) '清空输出表旧数据 wsOutput.Cells.Clear '复制表头(如果你的表有表头的话,没有就删掉这段) wsSource.Range("A1:C1").Copy wsOutput.Range("A1:C1") wsTasks.Range("A1:C1").Copy wsOutput.Range("D1:F1") currentOutputRow = 2 '有表头的话,从第2行开始写入数据 Dim timesToDuplicate As Variant Dim i As Long, taskIndex As Long: taskIndex = 1 '任务起始索引 For currentSourceRow = 2 To lastSourceRow '从第2行开始读取公司数据(有表头的情况) timesToDuplicate = wsSource.Range("O" & currentSourceRow).Value2 '处理非数字/无效值的情况,默认设为1,也可以改成直接跳过该行 If Not IsNumeric(timesToDuplicate) Then timesToDuplicate = 1 End If '用CLng代替CInt,支持更大的整数(CInt最大只能到32767) timesToDuplicate = CLng(timesToDuplicate) '如果重复次数小于1,直接跳过该行 If timesToDuplicate < 1 Then GoTo NextSourceRow '循环复制公司记录,并匹配任务 For i = 1 To timesToDuplicate '复制公司信息到输出表 wsOutput.Range("A" & currentOutputRow).Value = wsSource.Range("A" & currentSourceRow).Value wsOutput.Range("B" & currentOutputRow).Value = wsSource.Range("B" & currentSourceRow).Value wsOutput.Range("C" & currentOutputRow).Value = wsSource.Range("C" & currentSourceRow).Value '复制任务信息,循环取用任务表的数据 wsOutput.Range("D" & currentOutputRow).Value = wsTasks.Range("A" & taskIndex).Value wsOutput.Range("E" & currentOutputRow).Value = wsTasks.Range("B" & taskIndex).Value wsOutput.Range("F" & currentOutputRow).Value = wsTasks.Range("C" & taskIndex).Value '更新任务索引,用完所有任务后重新从第一条开始 taskIndex = taskIndex + 1 If taskIndex > lastTaskRow Then taskIndex = 1 currentOutputRow = currentOutputRow + 1 Next i NextSourceRow: Next currentSourceRow MsgBox "数据生成完成!", vbInformation End Sub
代码修正点说明:
- 解决类型不匹配:先用
IsNumeric判断O列的值是否为数字,再用CLng转换(支持更大的整数范围) - 动态适配数据行数:自动获取公司表和任务表的最后一行,不用硬编码行数
- 自动循环匹配任务:任务用完后自动从第一条开始循环,确保每条公司重复行都有对应任务
- 处理无效数据:如果O列的值无效(非数字、小于1),默认设为1次或者跳过该行
内容的提问来源于stack exchange,提问作者Ekfa
相关产品推荐
相关产品推荐

