【问题标题】:Type Mismatch VBA when copying range data to array将范围数据复制到数组时键入不匹配 VBA
【发布时间】:2017-08-22 07:54:01
【问题描述】:

所以我正在 VBA 中开发这个模块,我可以

  1. 将数据从工作表范围复制到数组。

  2. 计算该数组中每个整数的出现次数。

我尝试将整数数组元素与整数类型进行比较,但它给出了类型不匹配错误,所以我试图找出 range.offset.value 的数据类型,但它总是给出类型不匹配。

这是我的代码。请帮忙!!!

编辑:

我尝试将所有数组转换为 Variant,但现在 If 语句给了我一个类型不匹配错误。 如果 k = first(j) 那么 total(k) = total(k) + 3

'-------------------------

Option Explicit

Sub Task1()

Dim total(32) As Integer
Dim first(32) As Integer
Dim second(32) As Integer
Dim third(32) As Integer

Dim firs As Range
Dim secon As Range
Dim thir As Range

Set firs = Range("B2:B33")
Set secon = Range("C2:C33")
Set thir = Range("D2:D33")

Dim i As Integer

'copying data from first , second and third range to specific arrays
'gives type mismatchy error here
For i = 0 To 32
   first(i) = firs.Offset(i, 0).Value
   second(i) = secon.Offset(i, 0).Value
   third(i) = thir.Offset(i, 0).Value
 Next

'initialize total array with 0
For i = 0 To 32
    total(i) = 0
Next


Call reader(total, first)


End Sub

'---------------------------------------------------

    Sub reader(total() As Integer, first() As Integer)
    Dim i, j, k As Integer

    'Checks the occurance of every array element
    For i = 0 To 32
        'gives type mismatch error here
        k = first(i)
        j = i + 1
        For j = i To 32

        If k = first(j) Then total(k) = total(k) + 3

        Next

    Next


    End Sub

【问题讨论】:

  • 我认为这将是一个变体。此外,ranges.value 作为数组存在,因此 arr=range("a1:a100").value 也会为您节省一个循环。在即时窗口中,输入? typename(first(I)) 也只有k被定义为整数,I和j不会是
  • 您的范围内是否有任何错误值?
  • 我没有任何错误值。都是整数@Rory
  • @Nathan_Sav 我尝试通过 arr=range("a1:a100").value 分配值,但它没有那样工作。
  • 如果只需要统计某个范围内整数的出现次数,为什么不直接使用COUNTIF?。您可以循环遍历您的范围并以这种方式获得结果

标签: arrays vba excel


【解决方案1】:

将单元格范围转换为一维数组可能会有所帮助

    Dim aaa As Variant

    aaa = Range("B2:B33")               ' 2D array (32x1)
    Debug.Print aaa(2, 1)

    aaa = Application.Transpose(aaa)    ' 1D array
    Debug.Print aaa(2)

    ' note: if you start with row data, then do a second transpose to get 1D array

【讨论】:

    【解决方案2】:

    该值很可能无法解析为Integer。 只需将以下内容添加到您的代码中并查看发生错误的值:

    For i = 0 To 32
            Debug.Print firs.Offset(i, 0)
            Debug.Print secon.Offset(i, 0)
            Debug.Print thir.Offset(i, 0)
            first(i) = firs.Offset(i, 0)
            second(i) = secon.Offset(i, 0)
            third(i) = thir.Offset(i, 0)
    Next
    

    可能的修复 - 只是猜测您可以在代码中的任何位置将 Integer 更改为 LongDouble。或者在收到错误后查看即时窗口中的值。

    【讨论】:

    • 我仍然遇到同样的错误。试图将所有数组更改为 Variant 类型,但在以下行中出现错误 - If k = first(j) Then total(k) = total(k) + 3
    • @PhastOfTheFuture - 您在即时窗口中看到了什么?
    • 我看到类型不匹配错误 13。与以前相同的错误。
    • @PhastOfTheFuture - 在谷歌中检查什么是即时窗口。然后看看那里。 google.com/search?q=what+is+an+immediate+window+vba
    【解决方案3】:

    一些注意事项:

    1. Excel 将所有数值处理为 Double
    2. Range.Value 始终为多个单元格返回 Variant/Variant()
    3. 不能在 VBA 中直接转换数组

    检查下面代码的注释。

    Option Explicit
    
    Sub Task1()
    
        Dim total(32) As Integer
        'Range.Value return Variant() for multiple cells. VBA doesn't cast arrays!
        Dim first, second, third
    
        Dim firs As Range
        Dim secon As Range
        Dim thir As Range
        Set firs = Range("B2:B33")
        Set secon = Range("C2:C33")
        Set thir = Range("D2:D33")
    
        'Assuming you are copying data to array for performance reasons, make just a single assignement:
        first = firs.Value
        second = secon.Value
        third = thir.Value
    
        'Variables in VBA are always initialized, so all integers already 0%
        'For i = 0 To 32
        '    total(i) = 0
        'Next
    
    
        Call reader(total, first)
    
    End Sub
    
    Sub reader(total() As Integer, first)
        'This notation from VB.Net doesn't work in VBA: i and j are Variant!
        'Dim i, j, k As Integer
    
        'Don't undersatnd your code objective, propose new counter:
        Dim v
        For Each v In first
            'Excel only handles Double
            If VarType(v) = vbDouble Then total(v) = total(v) + 1
        Next
    
    End Sub
    

    【讨论】:

      【解决方案4】:

      您的宏正在尝试将您指定的整个范围(嗯,范围偏移给定数量)放入每个操作中的数组中。由于数组不是用来保存范围的,因此您需要将它们更改为范围内每个单元格中保存的值:

      For i = 0 To 32
         first(i) = firs.Cells(i, 1).Value
         second(i) = secon.Cells(i, 1).Value
         third(i) = thir.Cells(i, 1).Value
      Next
      

      甚至更简单:

      Dim first() As Variant ' declare an unallocated array
      Arr = Range("B2:B33")' Arr is now an allocated array
      

      This page 提供了一些很好的信息,可帮助您开始在 VBA 中使用数组。

      【讨论】:

        【解决方案5】:

        首先,您的数组与您的范围大小不同 - 您的数组有 33 个元素,范围只有 32 个。其次,您试图为数组的每个元素分配多个单元格范围。你的循环应该是这样的:

        For i = 0 To 31
           first(i) = firs.Cells(i + 1, 1).Value
           second(i) = secon.Cells(i + 1, 1).Value
           third(i) = thir.Offset(i + 1, 1).Value
         Next
        

        注意使用Cells 而不是Offset。 (虽然你也可以OffsetResize

        【讨论】:

          【解决方案6】:

          当源范围正好是一个单元格时,我遇到了这个问题。我应用了 Chip Pearson 的解决方案并解决了它。

          来自查尔斯·皮尔森的优秀article on Arrays and Ranges:

          当工作表上的区域是单个单元格时,有一种特殊情况。扩展上面的代码,如果范围可能是单个单元格,您应该使用下面的代码:

          Dim Arr() As Variant
          Dim RangeName As String
          Dim R As Long
          Dim C As Long
          Dim RR As Range
          
          RangeName = "TheRange"
          Set RR = Range(RangeName)
          If RR.Cells.Count = 1 Then
              ReDim Arr(1 To 1, 1 To 1)
              Arr(1, 1) = RR.Value
          Else
              Arr = Range(RangeName)
          End If
          

          来源:www.cpearson.com/excel/ArraysAndRanges.aspx 版权所有 2018,Charles H. Pearson

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2011-10-21
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多