VBA IF条件仅首次循环生效且报类型不匹配错误求助
问题描述
尝试通过VBA创建折线图:匹配main工作表C3单元格的名称与vol工作表第2行的目标名称(如B2、Q2等),匹配成功则基于data工作表的数据生成折线图。当前存在两个问题:
- IF条件仅首次循环生效
- 运行时出现「Run-time error "13": Type mismatch」类型不匹配错误
附原代码:
Sub graph() Dim chrt As ChartObject Dim i As Long Dim LastRow As Long Dim LastColumn As Long 'Find the last used row LastRow = Sheets("vol").Range("B65536").End(xlUp).Row 'Find the last used column LastColumn = 500 'Looping from second row till last row which has the data For i = 2 To LastColumn If Worksheets("vol").Cells(2, i) = Worksheets("main").Cells(3, 3) Then 'Sheet main is selected bcoz charts will be inserted here Sheets("main").Select ActiveSheet.Shapes.AddChart.Select 'this adds the chart and selects it in the same statement ActiveChart.ChartType = xlLine 'now the line chart is added...setting its data source here ActiveChart.SeriesCollection.NewSeries ActiveChart.SeriesCollection(1).Name = "25%" ActiveChart.SeriesCollection(1).XValues = Worksheets("data").Range(Worksheets("data").Cells(6, i), Worksheets("data").Cells(LastRow, i)) ActiveChart.SeriesCollection(1).Values = Worksheets("data").Range(Worksheets("data").Cells(6, i + 1), Worksheets("data").Cells(LastRow, i + 1)) 'now the line chart is added...setting its data source here ActiveChart.SeriesCollection.NewSeries ActiveChart.SeriesCollection(2).Name = "50%" ActiveChart.SeriesCollection(2).XValues = Worksheets("data").Range(Worksheets("data").Cells(6, i), Worksheets("data").Cells(LastRow, i)) ActiveChart.SeriesCollection(2).Values = Worksheets("data").Range(Worksheets("data").Cells(6, i + 6), Worksheets("data").Cells(LastRow, i + 6)) 'now the line chart is added...setting its data source here ActiveChart.SeriesCollection.NewSeries ActiveChart.SeriesCollection(3).Name = "25%" ActiveChart.SeriesCollection(3).XValues = Worksheets("data").Range(Worksheets("data").Cells(6, i), Worksheets("data").Cells(LastRow, i)) ActiveChart.SeriesCollection(3).Values = Worksheets("data").Range(Worksheets("data").Cells(6, i + 11), Worksheets("data").Cells(LastRow, i + 11)) With Worksheets("main").ChartObjects(1).Chart .HasTitle = True .ChartTitle.Text = "1 month" End With End If i = i + 15 Next i End Sub
问题排查与修复
1. 类型不匹配错误根源
直接用=比较单元格值时,若单元格存在空值、数值与文本类型不匹配的情况,会触发类型不匹配错误。需先转换为统一类型再比较,或使用StrComp函数忽略类型差异。
2. 循环逻辑错误
原代码在For循环内手动执行i = i + 15,同时Next i会自动将i加1,导致实际步长为16,且容易超出列范围。应改用Step 15定义循环步长,避免手动修改循环变量。
3. 选择/激活操作的隐患
依赖Select和ActiveChart的操作不稳定,容易因工作表切换、焦点变化导致错误。应直接引用对象,避免激活操作。
4. 图表对象引用错误
原代码固定引用ChartObjects(1),多次创建图表时会始终操作第一个图表,导致后续图表无法正确设置属性。需将新建的图表对象赋值给变量,直接操作该变量。
5. 数据源行号逻辑错误
原代码从vol工作表取最后行号,但实际数据源是data工作表,需修正为从data工作表获取有效行号。
6. 硬编码列数问题
原代码固定LastColumn = 500,应动态获取vol工作表第2行的实际最后列,避免不必要的循环。
修复后的完整代码
Sub CreateLineChart() Dim chrtObj As ChartObject Dim i As Long Dim lastRowData As Long Dim lastColVol As Long Dim targetName As String Dim wsMain As Worksheet, wsVol As Worksheet, wsData As Worksheet ' 初始化工作表对象,避免重复查找 Set wsMain = ThisWorkbook.Worksheets("main") Set wsVol = ThisWorkbook.Worksheets("vol") Set wsData = ThisWorkbook.Worksheets("data") ' 获取目标名称(main工作表C3) targetName = CStr(wsMain.Cells(3, 3).Value) ' 获取data工作表的有效数据最后行(以第2列为例,可根据实际调整) lastRowData = wsData.Cells(wsData.Rows.Count, 2).End(xlUp).Row ' 获取vol工作表第2行的最后列 lastColVol = wsVol.Cells(2, wsVol.Columns.Count).End(xlToLeft).Column ' 按步长15循环列(从第2列开始) For i = 2 To lastColVol Step 15 ' 处理空值,统一转换为文本后比较 If CStr(wsVol.Cells(2, i).Value) = targetName Then ' 在main工作表新建图表对象,指定位置和大小 Set chrtObj = wsMain.ChartObjects.Add( _ Left:=100, Top:=100, Width:=600, Height:=300) With chrtObj.Chart .ChartType = xlLine .HasTitle = True .ChartTitle.Text = "1 month" ' 添加第一个系列 With .SeriesCollection.NewSeries .Name = "25%" .XValues = wsData.Range(wsData.Cells(6, i), wsData.Cells(lastRowData, i)) .Values = wsData.Range(wsData.Cells(6, i + 1), wsData.Cells(lastRowData, i + 1)) End With ' 添加第二个系列 With .SeriesCollection.NewSeries .Name = "50%" .XValues = wsData.Range(wsData.Cells(6, i), wsData.Cells(lastRowData, i)) .Values = wsData.Range(wsData.Cells(6, i + 6), wsData.Cells(lastRowData, i + 6)) End With ' 添加第三个系列(修正原代码重复命名问题) With .SeriesCollection.NewSeries .Name = "75%" .XValues = wsData.Range(wsData.Cells(6, i), wsData.Cells(lastRowData, i)) .Values = wsData.Range(wsData.Cells(6, i + 11), wsData.Cells(lastRowData, i + 11)) End With End With End If Next i End Sub
额外优化说明
- 原代码中第三个系列名称重复为
25%,已修改为75%,避免图表系列名称混淆 - 新增了图表位置和大小的定义,可根据实际需求调整
Left、Top、Width、Height参数 - 使用
ThisWorkbook确保引用当前工作簿的工作表,避免外部工作簿干扰
内容的提问来源于stack exchange,提问作者user19536738
相关产品推荐
相关产品推荐

