【问题标题】:Using variant in array causes Excel VBA type mismatch error在数组中使用变量会导致 Excel VBA 类型不匹配错误
【发布时间】:2014-03-07 06:30:25
【问题描述】:

我正在尝试根据代码设置切片器值以选择连续 13 个月的范围。如果我在代码中使用该变量,则会产生类型不匹配错误。如果我 debug.print 变量并粘贴值而不是变量,则代码可以正常工作。尝试使用变量 myStr 时是否遗漏了什么?

出错的代码:

Sub Test()
Dim wb As Workbook
Dim myStr As Variant
Dim str2 As String

Set wb = ThisWorkbook
myStr = wb.Worksheets("Filters").Range("G57").Value
str2 = wb.Worksheets("filters").Range("D32").Value

 If str2 = "All" Then
    wb.SlicerCaches("Slicer_Month1").ClearManualFilter
 Else
    wb.SlicerCaches("Slicer_Month1").VisibleSlicerItemsList = Array(myStr)
 End If

End Sub

有效的代码(代替 myStr 的值来自 ?mystr :

Sub Test()
Dim wb As Workbook
Dim myStr As Variant
Dim str2 As String

Set wb = ThisWorkbook
'myStr = wb.Worksheets("Filters").Range("G57").Value
str2 = wb.Worksheets("filters").Range("D32").Value

 If str2 = "All" Then
    wb.SlicerCaches("Slicer_Month1").ClearManualFilter
 Else
    wb.SlicerCaches("Slicer_Month1").VisibleSlicerItemsList = Array("[Date].[Month].& _
    [2014-02-01T00:00:00]", "[Date].[Month].&[2014-01-01T00:00:00]", "[Date].[Month].& _     
    [2013-12-01T00:00:00]", "[Date].[Month].&[2013-11-01T00:00:00]", "[Date].[Month].& _
    [2013-10-01T00:00:00]", "[Date].[Month].&[2013-09-01T00:00:00]", "[Date].[Month].& _
    [2013-08-01T00:00:00]", "[Date].[Month].&[2013-07-01T00:00:00]", "[Date].[Month].& _
    [2013-06-01T00:00:00]", "[Date].[Month].&[2013-05-01T00:00:00]", "[Date].[Month].& _
    [2013-04-01T00:00:00]", "[Date].[Month].&[2013-03-01T00:00:00]", "[Date].[Month].& _
    [2013-02-01T00:00:00]")
 End If

End Sub

编辑:

我的原始代码使用 Join(Transpose(Range),",") (见下文) 来创建数组,而不是在单元格 G57 中使用合并字符串。我将结果连接到 G57 中,以便在故障排除工作中基本上创建所需的字符串。

mystr = _
Join(Application.WorksheetFunction.Transpose(Worksheets("Filters").Range("G43:G55")),",")

.VisibleSlicerItemList = Array(myStr)

我无法发布屏幕截图,因为我还没有足够的分数,但单元格 G43:G55 包含设置切片器值所需的正确时间/日期戳。格式为“[日期].[月份].&[YYYY-MM-DD&"T"&HH:MM:SS]"。 G57 中的值是 G43:G55 的连接结果,用逗号分隔并包含引号。

编辑 2:

这不是一个真正的解决方案,而且完全不雅,但时间就是金钱,所以我作弊并为 13 个可能的日期值中的每一个声明变量作为临时解决方案。报告包的一部分显示基于选定月份和前 12 个月的每月值,因此至少可能值的数量是固定的。对于需要类似解决方案的其他人来说,它并不能真正解决问题——想象一下 100 多种可能的选择,畏缩!

Private Sub Worksheet_Calculate()
Dim wb As Workbook
Dim str2 As String
Dim mstr1 As Variant
Dim mstr2 As Variant
Dim mstr3 As Variant
Dim mstr4 As Variant
Dim mstr5 As Variant
Dim mstr6 As Variant
Dim mstr7 As Variant
Dim mstr8 As Variant
Dim mstr9 As Variant
Dim mstr10 As Variant
Dim mstr11 As Variant
Dim mstr12 As Variant
Dim mstr13 As Variant

'Other code runs here
  Set wb = ThisWorkbook
  mstr1 = wb.Worksheets("Filters").Range("G43").Value
  mstr2 = wb.Worksheets("Filters").Range("G44").Value
  mstr3 = wb.Worksheets("Filters").Range("G45").Value
  mstr4 = wb.Worksheets("Filters").Range("G46").Value
  mstr5 = wb.Worksheets("Filters").Range("G47").Value
  mstr6 = wb.Worksheets("Filters").Range("G48").Value
  mstr7 = wb.Worksheets("Filters").Range("G49").Value
  mstr8 = wb.Worksheets("Filters").Range("G50").Value
  mstr9 = wb.Worksheets("Filters").Range("G51").Value
  mstr10 = wb.Worksheets("Filters").Range("G52").Value
  mstr11 = wb.Worksheets("Filters").Range("G53").Value
  mstr12 = wb.Worksheets("Filters").Range("G54").Value
  mstr13 = wb.Worksheets("Filters").Range("G55").Value

  str2 = wb.Worksheets("filters").Range("D32").Value

    If str2 = "All" Then
        wb.SlicerCaches("Slicer_Month1").ClearManualFilter
    Else
        wb.SlicerCaches("Slicer_Month1").VisibleSlicerItemsList = Array(mstr1, mstr2, mstr3, mstr4, mstr5, mstr6, mstr7, mstr8, mstr9, mstr10, mstr11, mstr12, mstr13)
    End If

'More code runs here
 ErrHandler:
 RestoreXL
 Exit Sub

 End Sub

【问题讨论】:

  • 所以在 G57 中你有一个逗号分隔的引用值列表?你不能通过将它传递给Array()来创建一个数组,也许可以试试Split(myStr, ",")
  • 您有机会发布 G57 中的内容的屏幕截图吗?从您的问题中不清楚那是什么样的。
  • @Tim Williams:我能做的最好的不是截图,而是值字符串:“[Date].[Month].&[2014-02-01T00:00:00]”,“[Date] .[月].&[2014-01-01T00:00:00]"...
  • 查看我更新的答案 - 我认为如果 VisibleSlicerItemsList 所需的数组是从零开始的,那么应该这样做。
  • @TimWilliams:我非常感谢您的帮助并怀疑我们已经接近了,但是在设置 VisibleSlicerItemList = myArray 时我仍然收到 1004 错误

标签: excel vba excel-2010 pivot-table


【解决方案1】:

试试这个(基于 G43:G55 中的值)

Sub Test()
Dim wb As Workbook
Dim shtF as Worksheet
Dim myArray
Dim str2 As String

    Set wb = ThisWorkbook
    Set shtF = wb.Worksheets("Filters")

    str2 = shtF.Range("D32").Value
    myArray = Get1DArray( shtF.Range("G43:G55") )

    With wb.SlicerCaches("Slicer_Month1")
        If str2 = "All" Then
            .ClearManualFilter
        Else
            .VisibleSlicerItemsList = myArray
        End If
    End With

End Sub

'get a 1-D zero-based array of values from a single-row/column
'   range of cells
Function Get1DArray(rng As Range)
    Dim arr
    arr = Application.Transpose(rng.Value)
    If rng.Rows.Count = 1 Then arr = Application.Transpose(arr)
    'convert from 1-based to zero-based array
    Get1DArray = Split(Join(arr, vbNull), vbNull)
End Function

【讨论】:

  • 当我尝试此更改时,我收到运行时错误 1004(应用程序定义或对象定义错误)。
【解决方案2】:

编辑如下。蒂姆是对的。试试这个:

    Sub Test()
    Dim wb As Workbook
    Dim myStr As Variant
    Dim str2 As String

    Set wb = ThisWorkbook
    myStr = Split(wb.Worksheets("Filters").Range("G57").Value, ",")
    str2 = wb.Worksheets("filters").Range("D32").Value

    If str2 = "All" Then 
    wb.SlicerCaches("Slicer_Month1").ClearManualFilter
    Else
    wb.SlicerCaches("Slicer_Month1").VisibleSlicerItemsList = myStr
    End If

    End Sub

【讨论】:

  • myStr 不是数组 - 您不会通过将单个单元格分配给 Variant 变量来获得数组。
  • 好吧,蒂姆,你是对的,它是一个单元格。它似乎是一个单元格 G57 中引用值的逗号分隔列表。 1. 这样他就可以把G57中的数据解析成Range("H57.T57") 2. 然后myStr = wb.Worksheets("Filters").Range("h57.t57").Value 3. 然后wb.SlicerCaches("Slicer_Month1").VisibleSlicerItemsList = myStr
  • @Chen 嗨,只需编辑您的答案而不是评论它。 :D
【解决方案3】:

编辑1:

如果您的所有Filters 确实像 Tim 所指出的那样在 G57 中,您也可以在下面尝试 :)

Sub AnotherPossibleWay()

Dim str1 As String, str2 As String
Dim myStr As Variant
Dim wb As Workbook

Set wb = Thisworkbook

str1 = Replace(wb.Worksheets("Filters").Range("G57").Value, ",", """,""")
str1 = """" & str1 & """"
myStr = Evaluate("{" & str1 & "}")
str2 = wb.Worksheets("Filters").Range("D32").Value

If str2 = "All" Then
    wb.SlicerCaches("Slicer_Month1").ClearManualFilter
Else
    wb.SlicerCaches("Slicer_Month1").VisibleSlicerItemsList = myStr
End If

End Sub

希望这不会让您感到困惑。
最主要的是,正确地将您的Range Value 转换为Array

【讨论】:

  • @TimWilliams 明白了。编辑了我的答案。 :)
猜你喜欢
  • 1970-01-01
  • 2017-04-12
  • 1970-01-01
  • 2023-03-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-12
相关资源
最近更新 更多