You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 03:24:21