2013-01-23 8 views
6

Przyszliśmy do kilku scenariuszy, które chcielibyśmy przekazać operators jako parameter w funkcji lub metodzie. According to this post Java doesn't have that ability, hence need to create an Enum as the primary workaround.Czy istnieje sposób przekazywania operatora arytmetycznego i logicznego jako parametru metody w języku VBA?

E.g.

Function doCalcs(ByRef AND as LogicalOperator, ByRef greater ArithmeticOperator) 

Chociaż VBA ma znacznie mniejsze w porównaniu do bibliotek .NET, Java, tworząc Enum jest dobrze obsługiwane. Być może nie jestem tego świadomy, więc jeśli istnieje możliwość, że VBA ma operator types lub jakiekolwiek inne obejścia możemy przejść an operator, zastrzelmy to. (Inne niż if else/case, aby sprawdzić ciąg zawierający parametr operatora .. =)) Co Pytam: different from what's mentioned here.

  • Pytanie jest zadawane w kategoriach redukcji kodów, optymalizacji.

Np. Jeśli spojrzysz na CountIFS, ma możliwość pobrania operators. Nawet jeśli ktoś może wyjaśnić ewentualne prace back-end w tej funkcji,

  1. Jak to przekonwertować te ciągi do właściwego operator?
  2. Czy to jest struktura Enum czy coś bardziej wydajnego niż to czy mniejsze?

Odpowiedź na te pytania jest nadal akceptowalna.

+0

To naprawdę zależy od tego, co robisz z parametrem wewnątrz funkcji. Najbardziej użyteczną rzeczą, jaką mogę zrobić z operatorem koncepcyjnym przekazanym jako parametr, jest użycie go jako wywołania zwrotnego. Na przykład, być może mam funkcję 'get3op2()' która akceptuje operator binarny, taki jak '+' lub '*', i zwraca wynik użycia tego operatora na predefiniowanych operandach, takich jak '3' i' 2' . Następnie, hipotetycznie, 'get3op2 (+)' zwróci 5 (to znaczy 3 + 2), podczas gdy 'get3op2 (*)' zwróci 6 (to jest 3 * 2). Czy to właśnie próbujesz zrobić? – psmay

+0

Uwaga: struktura typu enum zawiera jedynie listę opisowych stałych nazw jako wartości dla stałych o długich typach. Jeśli chodzi o twoje pytanie, nie widzę wartości dodanej używania enum. Jeśli chodzi o pytanie, czy możliwe jest przekazanie bezpośrednio operatora: nie jest to w VBA. Jeśli chodzi o obejście problemu, tak, jest, gdzie eval byłby najlepszą opcją, o której wspomniano. W przeciwnym razie mogę nie zrozumieć prawdziwego pytania ... – Trace

+0

@Kim są dwa pytania: '1.' operatory jako parametry' 2.' mechanizm odpowiedzialny za ocenę operatora funkcji CountIFS. – bonCodigo

Odpowiedz

2

podejście wykorzystujące zajęcia:

Zdefiniuj klasę interfejsu

Op

Public Function eval(operand1, operand2) 
End Function 

Dla każdej pożądanej operatora określenie realizacji.Na przykład

OpMinus

Implements Op 

Private Function Op_eval(operand1 As Variant, operand2 As Variant) As Variant 
    Op_eval = operand1 - operand2 
End Function 

OpPlus

Implements Op 

Private Function Op_eval(operand1 As Variant, operand2 As Variant) As Variant 
    Op_eval = operand1 + operand2 
End Function 

Teraz pewnych procedur testowych w module:

Sub test() 
    Dim Minus As New OpMinus 
    Dim Plus As New OpPlus 
    Dim o, v1, v2 

    For Each o In Array(Minus, Plus) 
     For Each v1 In Array(1, 2, 3) 
      For Each v2 In Array(1, 2, 3) 
       operate o, v1, v2 
      Next 
      Debug.Print "" 
     Next 
     Debug.Print "" 
    Next 
End Sub 

Sub operate(ByVal operator As Op, operand1, operand2) 
    Debug.Print operator.eval(operand1, operand2), 
End Sub 

outpu t:

0   -1   -2    
1    0   -1    
2    1    0    

2    3    4    
3    4    5    
4    5    6    

Uwaga, możesz chcieć użyć np. Double zamiast Variant w interfejsie, jeśli wiesz o jakim typie będziesz pracować.

+0

+1 dla podejścia klasowego, nie musieli Państwo jednak usuwać wcześniejszej odpowiedzi. Dla początkowego etapu 'Podwójny' jest wystarczający, ale dzięki za podanie' Wariant'. Jeśli można wyjaśnić mechanizm zachodzący za funkcją taką jak "CountIfs", to świetnie, ponieważ zależy mi na aspekcie wydajności. Przetestuję twoje i przedstawię kolejny komentarz =) – bonCodigo

2

Brak typu LogicalOperator, typu ArithmeticOperator lub czegoś podobnego. O najbliższym możesz przyjść to użyć funkcji Eval w MS Access VBA lub (podobnej, ale innej) funkcji Evaluate w Excel VBA.

W rzeczywistości prawdopodobnie korzystałeś z funkcji Evaluate w Excelu, nawet o tym nie wiedząc. Z pomocy pliku Excel:

Note Używanie nawiasów kwadratowych (na przykład „[A1: C5]”) jest identyczny z wywołaniem metody oceniać z argumentem strun. Na przykład poniższe pary wyrażeń są równoważne.

[a1].Value = 25 
Evaluate("A1").Value = 25 
+0

+1 dla "ewaluacji" i "oceny" i objaśnień, chociaż nie do końca jestem tym, za czym jestem. – bonCodigo

2

Jak rozwiązać sprawę

1) Odnosi się Microsof Script Controler 1,0 biblioteka

Option Explicit 

Sub Base_Sub() 

Dim iNumber1  As Integer 
Dim iNumber2  As Integer 
Dim iSum   As Integer 
Dim iMultiply  As Integer 
Dim dDivision  As Double 
Dim iDifference  As Integer 
Dim lPower   As Long 

iNumber1 = 2 
iNumber2 = 6 

iSum = CalculateThis("+", iNumber1, iNumber2) 
iMultiply = CalculateThis("*", iNumber1, iNumber2) 
iDifference = CalculateThis("-", iNumber1, iNumber2) 
dDivision = CalculateThis("/", iNumber1, iNumber2) 
lPower = CalculateThis("^", iNumber1, iNumber2) 

End Sub 



Public Function CalculateThis(operator As String, iNumber1 As Integer, iNumber2 As Integer) 

Dim script As ScriptControl 

Set script = New ScriptControl 
script.Language = "VBScript" 

CalculateThis = script.Eval(iNumber1 & operator & iNumber2) 

End Function 
+0

To jest inny sposób owijania tą samą funkcją 'Eval', o której wspominają obie inne odpowiedzi. Również Excel 'Evaluate'. Byłoby jednak lepiej, gdybyśmy pokazali również "logiczną" i "relacyjną" ocenę operatorów .... – bonCodigo

Powiązane problemy