2017-02-06 48 views
8

Mam aktualnie ustawioną funkcję, która zmieni wszystkie wartości wybranej tabeli przestawnej na średnią.Ustawienie wartości .Function za pomocą VBA

Działa dobrze, a ja złożyłem formularz, który przekazuje wartość, która również działa dobrze.

To, co chciałbym teraz zrobić, to sprawić, żeby zdecydował, do kogo obrócić wartości.

Jednak nadal otrzymuję błąd Type-Mismatch. Dzieje się tak, ponieważ jest on odczytywany jako ciąg znaków. Jak mogę to zmienić?

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

Próbowałem coś takiego w przeszłości i skończyło budowę tabelę z wartości wyliczenia ustawić typ obliczenia (naciśnij F2 i szukać 'XlConsolidationFunction') – R3uK

+0

[Utwórz dwie kolumny w polu listy, ustaw tekst i kolumny wartości] (http://stackoverflow.com/a/11062291/11683), dodaj oba podpisy (np. '" Suma "') i wartość (np. 'XlSum') dla każdej pozycji, użyj' Wartość' wybranego elementu w 'CommandButton1_Click'. – GSerg

Odpowiedz

3

oczywiście nazwę zmiennej w czasie kompilacji, takich jak xlAverage, niekoniecznie jest zgłaszane do czasu wykonywania, gdzie jest po prostu stałą całkowitą. Po kompilacji nazwy stałych zniknęły.

Istnieje wiele sposoby obejścia tego, ale mogą one przejść od skomplikowanej wykorzystania bibliotek typów które ponadto nie są dostępne na wszystkich platformach, na stosunkowo proste rozwiązanie proponuję poniżej, który korzysta ze słownika, aby śledzić odwzorowania między nazwami stałych i ich wartościami.

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 

Nawiasem mówiąc, w tej metodzie nie są zobowiązani do mapy takie same nazwy jak zmienne. Jesteś wolna mapę wszelkie nazwy, które chcesz wyświetlić w polu listy; tj. "Mimimum", "Standard Deviation", etc..

p.s.

Należy pamiętać, że miałeś jakieś literówki w nazwach:

CountNumbers ->CountNums

StdDev ->StDev

StdDevp ->StDevP

0

Twoja próba nie działa, ponieważ musisz przekazać stałe wartości, a nie ciągi. xlSum, na przykład, to -4157. Można się zorientować, co każdy z nich jest w następujący sposób:

debug.print clng(xlSum) 

ten powinien pracować dla Ciebie:

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 
+0

Jeśli jest to przydatne, wyliczenie można również uzyskać w przeglądarce obiektów VBE, wyszukując tekst dosłowny. –

0

Mogłabyś utwórz funkcję zwracającą wartość nazw, takich jak:

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 

Przypisanie zmiana:

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