2013-01-23 15 views
6

In un paio di scenari si vorrebbe passare operators come parameter in una funzione o un metodo. According to this post Java doesn't have that ability, hence need to create an Enum as the primary workaround.Esiste un modo per passare l'operatore aritmetico e logico come parametro del metodo in VBA?

E.g.

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

Anche se VBA ha librerie molto minore rispetto a .Net, Java, creando Enum è ben supportato. Forse non ne sono a conoscenza, quindi se c'è una possibilità che VBA abbia operator types o altre soluzioni alternative potremmo passare an operator, riprendere quello in. (Diverso da if else/case per controllare una stringa che contiene il parametro operatore. =)) Cosa Sto chiedendo è different from what's mentioned here.

  • La domanda viene posta in termini di riduzione dei codici, ottimizzazione.

E.g. Se si guarda CountIFS, ha la capacità di contenere operators. Anche se qualcuno può spiegare l'eventuale lavoro di back-end all'interno di questa funzione,

  1. Come convertire queste stringhe in un vero operator?
  2. È una struttura Enum o qualcosa di più efficiente o minore?

Una risposta a queste domande è ancora accettabile.

+0

Questo dipende molto da cosa si sta facendo con il parametro all'interno della funzione. La cosa più utile che posso pensare di fare con un operatore concettuale passato come parametro è usarlo come callback. Per esempio, forse ho una funzione 'get3op2()' che accetta un operatore binario, come '+' o '*', e restituisce il risultato dell'uso di quell'operatore su operandi predefiniti, come '3' e' 2' . Quindi, ipoteticamente, 'get3op2 (+)' restituirebbe 5 (cioè 3 + 2) mentre 'get3op2 (*)' restituirebbe 6 (cioè 3 * 2). E 'quello che stai cercando di fare? – psmay

+0

Nota: una struttura tipizzata enum contiene semplicemente un elenco di nomi di costanti descrittivi come valore per costanti lunghe tipizzate. Per quanto riguarda la tua domanda, non vedo davvero il valore aggiunto dell'uso di una enumerazione. Per quanto riguarda la domanda se è possibile passare direttamente un operatore: non è in VBA. Per quanto riguarda la soluzione, sì, c'è, dove eval sarebbe la migliore opzione come menzionato. Altrimenti, potrei non capire la vera domanda ... – Trace

+0

@Kim ci sono due domande: '1.' gli operatori come parametri' 2.' il meccanismo alla base della valutazione dell'operatore della funzione 'CountIFS'. – bonCodigo

risposta

2

Un approccio che utilizzano classi:

definire una classe interfaccia

Op

Public Function eval(operand1, operand2) 
End Function 

Per ciascun operatore desiderato, definire un'implementazione.Per esempio

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 

Ora, alcune routine di test in un modulo:

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    

Nota che è possibile utilizzare ad es. Double invece di Variant nell'interfaccia se sai su quale tipo sarai operativo.

+0

+1 per l'approccio di classe, non era necessario eliminare la risposta precedente. Per la fase iniziale 'Double' è sufficiente, ma grazie per aver dato' Variant'. Se si può spiegare il meccanismo che si svolge dietro una funzione come "CountIfs", è grandioso quanto mi piace l'aspetto delle prestazioni. Metterò alla prova la tua e darò un ulteriore commento =) – bonCodigo

2

Non esiste un tipo LogicalOperator, ArithmeticOperator o qualcosa di simile. Il più vicino possibile è utilizzare la funzione Eval in MS Access VBA o la (simile ma diversa) funzione Evaluate in VBA di Excel.

In effetti, probabilmente hai utilizzato la funzione Evaluate in Excel senza nemmeno accorgertene. Dal file di aiuto di Excel:

Nota Utilizzando le parentesi quadre (ad esempio, "[A1: C5]") è identico a chiamare il metodo Evaluate con un argomento stringa. Ad esempio, le seguenti coppie di espressioni sono equivalenti.

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

+1 per 'eval' e' evaluate' e spiegazioni anche se non è esattamente quello che sto cercando. – bonCodigo

2

Come faccio a risolvere il problema

1) Fare riferimento alla Microsof Script Controller 1.0 biblioteca

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

Questo è un altro modo di avvolgere la stessa funzione 'Eval' che è stata menzionata da entrambe le altre risposte. Anche il 'Valutazione 'di Excel. Tuttavia, sarebbe stato meglio se uno avesse anche mostrato la valutazione degli operatori 'logici 'e' relazionali' .... – bonCodigo

Problemi correlati