2011-08-10 14 views
40
Function Foo(thiscell As Range) As Boolean 
    Foo = thiscell.hasFormula And (InStr(1, UCase(Split(thiscell.formula, Chr(40))(0)), "bar") > 0) 
End Function 

existe Esta función para probar la presencia de un cierto subcadena (bar, en este caso) antes de la (.¿El operador "Y" de VBA evalúa el segundo argumento cuando el primero es falso?

El caso tengo problemas con es cuando la célula pasado a la función está vacía , thisCell.hasFormula es falso, pero la instrucción después de y aún se está evaluando. Esto me da un subíndice de error fuera de rango en tiempo de ejecución

¿VBA en realidad continúa evaluando el segundo argumento para el Y, incluso cuando el primero fue falso?

+3

Tenga en cuenta que el operador 'Y' de VBA no cortocircuita porque es un operador * bitwise * y no * uno *. Consulte: http://stackoverflow.com/questions/8042744/excel-vba-instr-condition-doesnt-work-with-2-or-more-conditions/8047021#8047021 – jtolle

+3

@jtolle no es verdad - devolverá un booleano si sus argumentos son booleanos, entonces es compatible con la operación lógica y en modo bit. (seguro que podría argumentar que lógico es un caso especial de bit a bit utilizando enteros de 1 bit, pero el punto es que Microsoft podría haber sido soportado en cortocircuito si así lo desean) –

+0

@Hugh, interesante. Todo este tiempo he estado asumiendo que 'Y' era solo un operador bit a bit, aunque uno que simulaba operaciones lógicas porque 'True = -1' y 'False = 0'. Pero tiene razón en que 'Y' * es * un operador lógico si las dos expresiones que se le pasan son booleanas. Solo es bit a bit si uno o ambos operandos son números. Pero supongo que no puede provocar un cortocircuito porque ambas expresiones deben evaluarse de todos modos, para garantizar que uno o ambos no sean números ni booleanos. Por lo tanto, creo que "bitwiseness" todavía no provoca ningún cortocircuito aquí. – jtolle

Respuesta

51

Lo que está buscando se llama "evaluación de cortocircuito ".

VBA no lo tiene.

Puede ver un enfoque que probablemente se adapte a su situación here.

El enfoque que se eligió allí implicó sustituir un Select Case por el If. También hay un ejemplo de uso de Ifs anidado.

+65

Cuando estoy trabajando con VBA comienza a sentirse como si estuviera tratando de dibujar la Mona Lisa con crayones. – James

+1

De hecho. Lástima que no puede usar C# en su lugar :( –

10

Como DOK mentioned: No, VBA no tiene una evaluación de cortocircuito.

Es técnicamente más eficiente usar declaraciones 2 If-then en lugar de usar el operador AND, pero a menos que lo haga muchas veces, no notará los ahorros, así que vaya por lo que sea más legible. Y si quiere ser realmente técnico, VBA maneja múltiples declaraciones If-then más rápido que Select Case también.

VBA es peculiar :)

2

La respuesta es sí, VBA hace la evaluación provoque cortocircuitos.

No es solo una cuestión de estilo; hace una gran diferencia en una situación como esta:

If i <= UBound(Arr, 1) And j <= UBound(Arr, 2) And Arr(i, 1) <= UBound(Arr2, 1) Then 
    Arr2(Arr(i, 1), j) = Arr(i, j) 
End If 

... que es incorrecto. Más apropiadamente:

If i <= UBound(Arr, 1) And j <= UBound(Arr, 2) Then 
    If Arr(i, 1) <= UBound(Arr2, 1) Then 
     Arr2(Arr(i, 1), j) = Arr(i, j) 
    End If 
End If 

O si usted tiene una aversión a ifs anidados:

If i > UBound(Arr, 1) Or j > UBound(Arr, 2) Then 
    ' Do Nothing 
ElseIf Arr(i, 1) > UBound(Arr2, 1) Then 
    ' Do Nothing 
Else 
    Arr2(Arr(i, 1), j) = Arr(i, j) 
End If 
1

VBA tiene el comportamiento de uno de cortocircuitos similares. Normalmente Null se propaga a través de expresiones, ej. 3 + Null es Null, y True And Null es Null. Sin embargo :

? False And Null
False

Esto se parece a la conducta de cortocircuito - lo que está pasando? Null no se propaga cuando el otro argumento a una conjunción (And) es False o 0 - el resultado es solo False o 0.No importa si es el argumento izquierdo o derecho. Lo mismo se aplica si el otro argumento para una disyunción (Or) es True o un número entero distinto de cero (un valor de coma flotante se redondeará a un número entero usando this rule).

Por lo tanto, no se pueden evitar los efectos secundarios y los errores en los argumentos And y Or, pero la propagación Null se puede "cortocircuitar". Este comportamiento parece ser heredado de SQL.

+0

Hmm, estoy perdido, podría agregar un ejemplo de cómo funciona para una condición 'A y B' – Enissay

+0

@Enissay dos de mis ejemplos usan' Y'. ¿podría explicar mejor de qué está confundido? –

+0

Esto no tiene nada que ver con el comportamiento de cortocircuito. Las dos expresiones se evalúan, la primera devuelve 'False' y la segunda devuelve' True', no hay cortocircuito aquí. Entonces VBA realiza algún tipo de conversión extraña y devuelve de forma incoherente ya sea 'False' o' Null' – stenci

-1

Tenga en cuenta el código de máquina que debe ejecutarse. El más rápido debe ser a lo largo de las líneas de una mezcla de código como ...

si sfsf continuación Goto SkipAB

si FDF continuación Goto goneBad

si dffdefedwf continuación Goto Musthave

SkipAB: si DSDA> 4 a continuación musthave

GoneBad: función de salida

Musthave: ThisIs = true

'sólo ahorra unos momentos en que el programa tiene que correr a través de él muchos miles de veces ... por ejemplo, búsqueda de archivos una gran unidad o cuando un simple análisis de Boole se utiliza para saltarse una función de tiempo consumir como encontrar todas las hojas y los nombres en una hoja de cálculo cerrada [code]

 If Not wFF.UsingFileExtMatch Then GoTo SkipExt 
       If Not wFF.OKFileEXTMatch Then GoTo BADFile 

SkipExt: Si no wFF.UsingFileNameMatch Luego Ir SkipFileMatch Si no wFF.OKFileNameMatch Then GoTo 0 ArchivoMalosSkipFileMatch: Si no wFF.UsingDaysAgo Luego Ir SkipDaysAgo Si no wFF.OKDaysAgo Luego Ir ArchivoMalos SkipDaysAgo:

[/ code]

0

Creo que esta es la mejor práctica:

sub my conditions() 
     If Condition1=constraint1 then 
     if Condition2=constraint2 then 
      if condition3=constraint3 then 
      ... 
      .... 
     end if 
     end if 
      end if 
    else 
     end if 
      .... 
    end if 
end sub 

Por lo tanto, solo pasará por las condiciones si y solo si la condición i se cumple.

+0

Hace más de 5 años, el OP preguntaba si la palabra clave 'y' en una sentencia condicional 'cortocircuitó' si la primera condición era falsa. ¿Está respondiendo esa pregunta? ? – ppovoski

+0

@ppovoski sí realmente soy – Moreno

Cuestiones relacionadas