使用VBA将值设置为.Function

时间:2017-02-06 14:16:33

标签: excel vba excel-vba pivot-table

我目前有一个功能集,可以将所选数据透视表的所有值更改为平均值。

它工作正常,我已经组装了一个表单,该表单传递的值也可以正常工作。

此时我想做的是让它决定将值转换为什么。

然而,我不断收到Type-Mismatch错误。这是因为它被读作字符串。我怎么能调整这个呢?

Private Sub CommandButton1_Click()
  MsgBox xl & ListBox1.Value
  Dim ptf As Excel.PivotField
  With Selection.PivotTable
    .ManualUpdate = True
    For Each ptf In .DataFields
      With ptf
        .Function = "xl" & ListBox1.Value 'xlAverage works here
        .NumberFormat = "#,##0"
      End With
    Next ptf
    .ManualUpdate = False
  End With
End Sub

Private Sub ListBox1_Click()
End Sub

Private Sub UserForm_Click()
End Sub        

Private Sub UserForm_Initialize() 'Set Values Upon Opening       
  With ListBox1
    .AddItem "Sum"
    .AddItem "Count"
    .AddItem "Average"
    .AddItem "Max"
    .AddItem "Min"
    .AddItem "Product"
    .AddItem "CountNumbers"
    .AddItem "StdDev"
    .AddItem "StdDevp"
    .AddItem "Var"
    .AddItem "Varp"
  End With
End Sub

3 个答案:

答案 0 :(得分:3)

当然,编译时变量的名称(例如xlAverage)不一定会报告给运行时,它只是一个整数常量。编译后,常量名称消失了。

许多方法可以解决这个问题,但是它们可能会从复杂的类型库开始使用,而这些库并不是在所有平台上都可用,而是相对简单的解决方案我建议如下,它使用字典来跟踪常量名称及其值之间的映射。

Private Sub CommandButton1_Click()
    ' ...
    ptf.Function = GetEnumConsolidationFunction.item(ListBox1.Value)
    ' ...
End Sub

Private Sub UserForm_Initialize()
    Dim dict As Object, s
    Set dict = GetEnumConsolidationFunction
    For Each s In dict.Keys
        ListBox1.AddItem s
    Next
End Sub

' Our key function, fills a dictionary first time it is used
Function GetEnumConsolidationFunction() As Object
    Static dict As Object '<-- static because we want to fill it only once
    If dict Is Nothing Then
        Set dict = CreateObject("Scripting.Dictionary")
        With dict
            .Add "Sum", XlConsolidationFunction.xlSum
            .Add "Count", XlConsolidationFunction.xlCount
            .Add "Average", XlConsolidationFunction.xlAverage
            .Add "Max", XlConsolidationFunction.xlMax
            .Add "Min", XlConsolidationFunction.xlMin
            .Add "Product", XlConsolidationFunction.xlProduct
            .Add "CountNums", XlConsolidationFunction.xlCountNums
            .Add "StDev", XlConsolidationFunction.xlStDev
            .Add "StDevp", XlConsolidationFunction.xlStDevP
            .Add "Var", XlConsolidationFunction.xlVar
            .Add "Varp", XlConsolidationFunction.xlVarP
        End With
    End If
    Set GetEnumConsolidationFunction = dict
End Function

顺便说一句,在这种方法中,您没有义务映射与变量相同的名称。您可以自由映射要在列表框中显示的任何名称;即"Mimimum", "Standard Deviation", etc..

<强> P.S。

请注意,您的名字中有一些拼写错误:

CountNumbers - &gt; CountNums

StdDev - &gt; StDev

StdDevp - &gt; StDevP

答案 1 :(得分:0)

您的尝试不起作用,因为您需要传递常量值,而不是字符串。例如,xlSum是-4157。你可以弄清楚每个是什么:

debug.print clng(xlSum)

这应该适合你:

Private Sub CommandButton1_Click()
'Define Constants
Const C_SUM As Long = -4157
Const C_COUNT As Long = -4112
Const C_AVERAGE As Long = -4106
Dim ptf As Excel.PivotField

  With Selection.PivotTable
    .ManualUpdate = True
    For Each ptf In .DataFields
      With ptf
        Select Case ListBox1.Value
            Case "Sum"
                .Function = C_SUM
            Case "Count"
                .Function = C_COUNT
            Case "Average"
                .Function = C_AVERAGE
        End Select
        .NumberFormat = "#,##0"
      End With
    Next ptf
    .ManualUpdate = False
  End With

End Sub

答案 2 :(得分:0)

您可以创建函数来返回名称的值,例如:

Private Function GetFunctionValue(ByVal FunctionName As String) As Long
    Dim value As Long

    Select Case FunctionName
    Case "Sum"
        value = xlSum
    Case "Count"
        value = xlCount
    Case "Average"
        value = xlAverage
    Case "Max"
        value = xlMax
    Case "Min"
        value = xlMin
    Case "Product"
        value = xlProduct
    Case "CountNums"
        value = xlCountNums
    Case "StDev"
        value = xlStDev
    Case "StDevp"
        value = xlStDevP
    Case "Var"
        value = xlVar
    Case "Varp"
        value = xlVarP
    End Select

    GetFunctionValue = value
End Function

更改分配:

  With ptf
    .Function = GetFunctionValue(ListBox1.Value)
    .NumberFormat = "#,##0"
  End With