【问题标题】:Excel VBA Run-time error '13': Type mismatch, when passing a Variant Array to Application.Index methodExcel VBA 运行时错误“13”:类型不匹配,将变体数组传递给 Application.Index 方法时
【发布时间】:2018-04-19 12:47:34
【问题描述】:

我正在运行代码来创建每日报告,首先我使用单元格和偏移量来比较日期,但这很慢,现在我正在使用数组来改进代码,但我遇到了问题在尝试使用某些应用程序功能时,首先我尝试了 VLookup,我得到的只是运行时错误“13”:类型不匹配。现在我正在使用 Match 和 Index 方法,我得到了同样的错误,我似乎找不到我的错误是什么。

我正在传递一个变体数组,我是这样得到的:

Public wsrgcmes As Variant
Public wshtte As Variant

With Sheets("Resumen general de casos")
    wsrgcmes = .Range(.Cells(1, 2), .Cells(lRow, lCol)).Value
End With

当我尝试执行 Application.Index 方法时,错误就来了。

Sub gen_informe()    
     temp = Application.Index(wsrgcmes, 0, 1)        
End Sub

我在调试窗口中只运行了这一行Application.Index(wsrgcmes, 0, 1),我得到了同样的错误。变体数组 wsrgcmes 包含一个带有数字和字符串值的表。任何我无法得到的帮助,我很感激。谢谢!

wbrgc 的值:

【问题讨论】:

  • 这个数组是在哪里声明的?如果您不指定数据类型或结构,那么 Excel 将不得不“猜测”。
  • 放入wsrgcmes数组的结构。
  • 在 wsrgcmes 上添加监视以确保正确填充数组 wsrgcmes。还要检查 lRow 和 lCol 的值。
  • wsrgcmes 是公共数组吗?
  • 它是基于 1 的数组,因为您是从范围构建的。我的直接猜测是使用temp = Application.Index(wsrgcmes, 1, 1) 进行测试。

标签: arrays vba excel type-mismatch


【解决方案1】:

当您将某个范围的值设为Variant 时,它始终是一个基于 1 的二维数组:

因此行索引0 超出了数组范围,Application.Index 在这种情况下会引发类型不匹配错误。

Public Sub TestMe()        
    Dim a As Variant
    a = Range("A1:D5").Value2
    Debug.Print Application.Index(a, 1, 2)    
End Sub

来自@Mathieu Guindon 的评论:

Application 在 COM 术语中是一个可扩展的接口 - 它在运行时使用 WorksheetFunction 成员进行扩展,因此 Application.Index 确实有效,即使它是后期绑定的成员调用(无智能感知)。它的行为与其早期绑定的等效项略有不同,因为它不会在给定错误结果的情况下引发运行时错误,而是返回错误结果(例如#VALUE!)。

两种语法都完全有效,并且每种都需要不同的错误处理机制(早期绑定:On Error...,后期绑定:IfError(...))

【讨论】:

  • 感谢您的回答。如前所述,我尝试了Debug.Print Application.Index(wsrgcmes, 1, 1),但我不断收到相同的不匹配错误。是否有另一种解决方法,找不到我做错了什么。
  • @SebasXHP - 在您的 VBEdtior 中选择单词wsrgcmes,按Shift+F9 并将您在问题上看到的屏幕截图。
  • 这是我得到的,没有价值。而且我知道有数据,因为我将它用于另外三个循环,并从中获得了我想要的信息。我只是对 VLookup 和索引有问题。 imgur.com/a/Hx1EIiH
  • @SebasXHP - 按“Agregar”然后按小号+,如果你看到的话。
  • 现在如果你执行Application.Index(wsrgcmes,14630,1) 你会得到一个错误?
【解决方案2】:

Application.Index 对列数和行数有限制。如果超过此值,您将遇到类型不匹配错误。所以这可能是问题所在。

有关解决此问题的方法,请参阅以下内容:

how-do-i-slice-an-array-in-excel-vba

我不确定当前的限制是多少。它超过 65,536 行或 65,536 列。链接中的解决方案本质上是使用数组来切片而不是 Application.Index。

如果您适当注意@Vityata 的回答和索引,您可能可以确定您陷入类型不匹配的临界点。在某些情况下,您还可以通过分块处理列/行以保持在阈值以下来解决此问题。我在这里举了一个分块工作的例子来解决这个问题:Slice array to use index on larger than 65000。

您可以完全避免 Index 并使用 TimWilliams 辅助函数。

使用 @TimWilliams 辅助函数,您将拥有

Sub test 'your other sub

temp = GetColumn(wsrgcmes,1)

End Sub


Function GetColumn(arr, colNumber)
    Dim arrRet, i As Long
    ReDim arrRet(1 To UBound(arr, 1), 1 To 1)
    For i = 1 To UBound(arr, 1)
        arrRet(i, 1) = arr(i, colNumber)
    Next i
    GetColumn = arrRet
End Function

【讨论】:

  • 嘿!我尝试了您建议的功能,它确实有效。它做了我想要它做的事情。非常感谢你。也许问得太多了,但你知道是否有办法做到这一点但更快?现在完成需要很长时间,我知道有很多迭代要完成,但如果我能让它更快地工作,那就太好了。非常感谢。
  • 我希望这不会太像重定向,但他们在审查代码方面很棒,代码优化是他们的包。确实需要完整地查看代码,才能开始了解除了关闭屏幕更新、计算模式等常见问题之外,还可以在哪里进行优化。
  • 我不认为这些问题是由 INDEX 的限制引起的。根据我的回答,INDEX 将处理超过 1048576 行,但仅限于 65536 列。我相信,最初的问题(即打印到即时窗口时出错)完全取决于 OP 试图打印一个数组。
  • @jeffreyweir 很高兴收到您的来信。好像我跳了枪。很高兴知道。这些限制在哪里列出,因为我永远记不住它们?在 MSDN 上?我会看看你的答案,因为这对我来说是很好的学习。之前的评论已删除。
  • @QHarr 我没有在 MSDN 上查看...我只是编写了一些代码并在它抛出错误时进行了检查:-)
【解决方案3】:

当您向 INDEX 函数提供 0 时,您是在告诉它“我想要整行或整列”。

如果您将Application.Index(wsrgcmes, 0, 1) 分配给一个变体,它可以正常工作...您有一个包含数组的变体。

如果您尝试将Application.Index(wsrgcmes, 0, 1) 打印到即时窗口,则会收到错误消息,因为您正在尝试打印数组。您需要将其包装在 JOIN 函数中。

我不知道您为什么在 Application.Index(wsrgcmes, 14630, 1) 上收到错误消息,但我的猜测是,在您执行此操作时,wsrgcmes 没有被填充或者不是那个维度。我需要查看错误发生时您正在使用的代码的确切部分的屏幕截图以及 Watch Window 中数组的屏幕截图。

我不认为您的问题是由 INDEX 的限制引起的,因为您离它们还很远。

以下代码显示了从 VBA 调用时 INDEX 的限制:

 Sub IndexLimitations()

Dim v       As Variant
Dim i       As Long
Dim j       As Long
Dim k       As Long
Dim vArray  As Variant
Dim vItem   As Variant

vArray = Array(65536, 65537, 1048576, 1048577)

For Each vItem In vArray
    i = vItem
    ReDim v(1 To i, 1 To 2)
    For j = 1 To i
        For k = 1 To 2
            v(j, k) = j * k
        Next k
    Next j
    Debug.Print "Rows dimension test: " & i
    Debug.Print Application.Index(v, i, 1)
    Debug.Print ""

    ReDim v(1 To 2, 1 To i)
    For j = 1 To i
        For k = 1 To 2
            v(k, j) = j * k
        Next k
    Next j

    Debug.Print "Columns dimension test: " & i
    Debug.Print Application.Index(v, 1, i)
    Debug.Print ""

Next vItem

End Sub

这是它返回的内容:

Rows dimension test: 65536
 65536 

Columns dimension test: 65536
 65536 

Rows dimension test: 65537
 65537 

Columns dimension test: 65537
Error 2023

Rows dimension test: 1048576
 1048576 

Columns dimension test: 1048576
Error 2023

Rows dimension test: 1048577
 1048577 

Columns dimension test: 1048577
Error 2023

这里的学习是,如果使用 INDEX 函数返回一列,则限制为 65536 列,但似乎不受网格中行数的限制。我怀疑这与我在 http://dailydoseofexcel.com/archives/2013/10/23/dictionaries-can-be-rude/ 中提到的 TRANSPOSE 错误有关

【讨论】:

  • 嘿!谢谢你的帮助。所以我还没有使用 Index 方法的限制。 wsrgcmes 也是从一开始就被填充的,因为首先我运行一个 sub 来加载数组,然后我运行 sub 来创建报告。这是您要求的屏幕截图,如果您需要任何其他信息,我会提供。非常感谢你。 imgur.com/a/fhNAyCh
  • 好的。那么你能给我们显示 wsrgcmes 声明的位置吗?例如“DIM wsrgcmes as...”。只是为了确认一下,如果在突出显示时按 F8,您会在该行上遇到什么错误?
  • 它是在开头声明的,在子 Public wsrgcmes As Variant 之外,当我运行该行时,没有显示错误。信息正在加载到该 Variant Array 中,因为我已经将这些信息用于其他事情,但是当我使用 Index 函数时,问题就出现了。
  • 确认一下,它在该特定行抛出错误? IE。如果您在该屏幕截图中所处的阶段按 F8,会出现错误吗?
  • 不,它只是将我发送到子目录的开头。这真的很奇怪。我将尝试删除出现错误的行之前的代码行,看看是否运行没有问题。
【解决方案4】:

我也有这个问题,见here。 我认为application.Index不能应用于包含不同类型变量的数组。 我有一个 100 X 2 数组,第一列包含双精度类型,第二列包含字符串。 即使我选择了相同类型的内容(仅从第 1 列或第 2 列),我也无法使用 application.Index 将数组中的内容粘贴到 Excel 工作表中。 然后我用数字双精度值替换了字符串类型值,这一次application.Index 工作正常。 但是,我们仍然不知道application.Index 是否仅适用于数字类型。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多