类型不匹配错误:不明白为什么

时间:2017-07-27 17:28:03

标签: excel vba excel-vba runtime-error

我正在尝试将一个值添加到另一个值,但它总是在我的代码中的某处停止并抛出:

  

错误类型13:不匹配错误

即使删除代码的一部分,也会出现另一个错误并出现相同的错误。例如:

当这个:

ThisWorkbook.Worksheets(2).Cells(i, 9) = ThisWorkbook.Worksheets(2).Cells(i, 9) + Sheets(j).Cells(i, 42)

出现了第一个错误,我想通过删除它来解决它,并且会出现同样的错误:

ThisWorkbook.Worksheets(2).Cells(i, 6) = ThisWorkbook.Worksheets(2).Cells(i, 6) + Sheets(j).Cells(i, 41)

整个代码:

Do While (j < (ThisWorkbook.Worksheets(2).Cells(1, 9)) + 3)


For i = 7 To 65

'Megaform

ThisWorkbook.Worksheets(2).Cells(i, 6) = ThisWorkbook.Worksheets(2).Cells(i, 6) + Sheets(j).Cells(i, 41)
ThisWorkbook.Worksheets(2).Cells(i, 7) = ThisWorkbook.Worksheets(2).Cells(i, 7) + Sheets(j).Cells(i, 44)
ThisWorkbook.Worksheets(2).Cells(i, 8) = ThisWorkbook.Worksheets(2).Cells(i, 8) + Sheets(j).Cells(i, 47)
ThisWorkbook.Worksheets(2).Cells(i, 9) = ThisWorkbook.Worksheets(2).Cells(i, 9) + Sheets(j).Cells(i, 42)
ThisWorkbook.Worksheets(2).Cells(i, 10) = ThisWorkbook.Worksheets(2).Cells(i, 10) + Sheets(j).Cells(i, 45)
ThisWorkbook.Worksheets(2).Cells(i, 11) = ThisWorkbook.Worksheets(2).Cells(i, 11) + Sheets(j).Cells(i, 48)

Next i

2 个答案:

答案 0 :(得分:3)

正如您对OP的评论中所提到的,您在尝试添加的单元格中有文字或错误。您可能将一个数字存储为文本,以便当您在单元格中看到它时看起来像一样,但Excel(&amp; VBA)会将其视为文本。如果是这样,每个单元格引用周围的CInt(ThisWorkbook...)将转换它。但它不会为您将Some text#ERROR转换为整数。您可能希望围绕每一行创建一些验证代码,如下所示:

Sub temp()
  Const NAN   As String = "Non-number in source data"

  With ThisWorkbook.Worksheets(2)
    Dim J     As Long
    Do While (J < (.Cells(1, 9)) + 3)
      Dim OtherWorksheet As Worksheet
      Set OtherWorksheet = ThisWorkbook.Worksheets(J)

      Dim i   As Long
      For i = 7 To 65
        'Megaform
        If IsNumeric(.Cells(i, 6)) And IsNumeric(Sheets(J).Cells(i, 41)) Then
          .Cells(i, 6) = .Cells(i, 6) + Sheets(J).Cells(i, 41)
        Else
          .Cells(i, 6) = NAN
        End If
        If IsNumeric(.Cells(i, 7)) And IsNumeric(OtherWorksheet.Cells(i, 44)) Then
          .Cells(i, 7) = .Cells(i, 7) + OtherWorksheet.Cells(i, 44)
        Else
          .Cells(i, 7) = NAN
        End If

        'etc...

      Next
      'I hope there's some incrementer for J down here!!
    Loop
  End With

End Sub

关于代码的几点说明:

  • 我将NAN声明为当输入数据无效时要插入的常量字符串
  • 我添加了With块,所以我没有必要输入ThisWorkbook.Worksheets(2)几十次
    • 这意味着以.开头的每个范围引用都会返回到此处以获取完整参考
  • 危险#1 FIRST Sheets(3)语句中的非限定If引用是指当前活动工作簿。您的'Megaform评论让我相信这可能是一个漫长的过程。这可能会导致您的用户单击另一个工作簿。如果发生这种情况,Sheets()现在指的是他刚刚选择的工作簿,而不是您正在使用的工作簿。
    • 我在 SECOND If语句中解决了这个问题,我在OtherWorksheet开始后ThisWorkbookDo While设置为工作表#J }循环。 ThisWorkbook 始终是指运行代码的工作簿,因此即使用户在您上面切换书籍,您仍然可以回到原来的位置。然后,第二个If语句使用完全限定的OtherWorksheet.表示法,以确保它从正确的工作表中读取。
  • 危险#2 Sheets()集合包括工作簿中的所有工作表类型。这包括Chart张。 Chart张不会按照您预期的方式工作,因此,如果有人碰巧在您的工作簿中插入了图表工作表,那么当{时,您的代码会爆炸(运行时错误) {1}}指向它。通过使用J集合,您可以避免这个潜在问题。
  • 我在代码中添加了一些适当的缩进,因为这样可以通过快速扫描更容易识别代码结构。我使用Rubberduck * 为我做这件事。它还具有代码检查功能,可以为您的代码提供其他改进的许多建议。
  • 您不会显示Worksheets()的声明或任何初始化或增量声明,所以我希望那些存在。这可能会使一个更简单的循环使用
    J我倾向于在终点可定义时更喜欢For J = StartValue to .Cells(1,9) + 3循环,但是没有要求这样做。
  • 我没有在所有添加声明周围写For保护。我认为这是一个很好的例子,你可以复制/粘贴其余部分。

* Rubberduck是一个开源项目(可在GitHub上获得),努力将VBE带入21世纪。我的参与是一个满意的用户和半专业的抱怨测试员。

解决If错误:

您需要注意的是,在子弹点中我确实指出,我在原始代码中没有看到任何设置为Subscript out of range的内容。如果没有任何内容,则会从J开始,该0超出WorkSheet集合的范围(它基于1)。我还提出了一个建议,以确保那里有一些东西可以增加它。

我的假设是Thisworkbook.Worksheets(2).Cells(1,9)包含您要处理的工作表的数字(由于某种原因减去3)。现在听起来好像你正在尝试使用它来跟踪WorkSheetsWorkBook的数量,这是不必要的并且充满错误。

如果您正在尝试处理所有 WorkSheets中的WorkBookWorksheets(2)除外,这是数据最终的位置,我推测),替换:

Dim J as Long
Do While (J < (.Cells(1, 9)) + 3)
  Dim OtherWorksheet As Worksheet
  Set OtherWorksheet = ThisWorkbook.Worksheets(J)
  .
  .
  .
Loop

使用此代码:

Dim CurrentSheet as WorkSheet
For Each CurrentSheet in ThisWorkbook
  If CurrentSheet.Name <> ThisWorkbook.Worksheets(2).Name Then
    .
    'the existing code here.
    'NOTE: references to OtherWorksheet need to be changed to CurrentSheet
    '      Or, change "CurrentSheet" to "OtherWorksheet" in three places here, whichever is easier
    .
Next

这将处理WorkSheetsWorkBook的所有WorkSheet(2),跳过按名称标识的If。如果您还需要跳过其他工作表,可以将它们添加到And语句中间,.Name = "Fred" And .Name = "Barney"介于Private Sub Worksheet_SelectionChange(ByVal Target As Range) Dim str As Variant Dim strarr() As String Dim j As Long If Not Intersect(Target, Range("C:C")) Is Nothing Then Range("B:B").Interior.Pattern = xlNone If Target <> "" Then strarr = Split(Target, ",") For Each str In strarr j = 0 On Error Resume Next j = Application.WorksheetFunction.Match(CLng(Application.Trim(str)), Range("A:A"), 0) On Error GoTo 0 If j <> 0 Then Cells(j, 2).Interior.Color = 65535 End If Next str End If End If End Sub 之间(例如var div = ''; add.onclick = function() { var div = document.createElement('div'); div.className = "alert"; div.id = "vv"; div.innerHTML = "<div id='complex-div'><strong>Yes!</strong></div>"; new_b.appendChild(div); }; 不要处理)

答案 1 :(得分:0)

我不确定这实际上是否属实,但仍然分享我的假设。我相信当你运行这个宏时,另一个工作簿是开放的。当您在不参考任何工作簿的情况下在代码中引用Sheets()时,Excel会从已激活的图书中选取工作表。如果第二本书处于活动状态,这可能不是您想要的。

要解决此问题,您需要明确提及要用作源的工作簿。我修改了你的代码来执行此操作:

Dim SourceSheet As Worksheet
Dim DestinationSheet As Worksheet

Set DestinationSheet = ThisWorkbook.Worksheets(2)

j = 1

Do While (j < (ThisWorkbook.Worksheets(2).Cells(1, 9)) + 3)

    Set SourceSheet = ThisWorkbook.Worksheets(j)

    For i = 7 To 65

        DestinationSheet.Cells(i, 6) = DestinationSheet.Cells(i, 6) + SourceSheet.Cells(i, 41)
        DestinationSheet.Cells(i, 7) = DestinationSheet.Cells(i, 7) + SourceSheet.Cells(i, 44)
        DestinationSheet.Cells(i, 8) = DestinationSheet.Cells(i, 8) + SourceSheet.Cells(i, 47)
        DestinationSheet.Cells(i, 9) = DestinationSheet.Cells(i, 9) + SourceSheet.Cells(i, 42)
        DestinationSheet.Cells(i, 10) = DestinationSheet.Cells(i, 10) + SourceSheet.Cells(i, 45)
        DestinationSheet.Cells(i, 11) = DestinationSheet.Cells(i, 11) + SourceSheet.Cells(i, 48)

    Next i

    j = j + 1

Loop