|
41
|
Programación / Programación Visual Basic / vb6 es tonto
|
en: 2 Octubre 2011, 01:08 am
|
Hola chicos, bueno a raíz de una discusión con la profesora de programación he investigado sobre los Ifs de vb6... En esta situación: If A = True Or B = False Then
Lo lógico sería que al leer A=True no comprobara Lo siguiente puesto que la condición se cumpliría de todas formas. Pero no, vb te comprueba TODO el If pase lo que pase en todos los casos. Aquí un código que lo demuestra: Option Explicit Private Function OrTest(ByVal bReturn As Boolean) As Boolean '// Imprimo un texto para saber que he pasado por la función. Debug.Print Time$, "Función con el argumento " & bReturn & " llamada." OrTest = bReturn End Function Private Sub Form_Load() '// Aquí lo logico sería comprobar las dos ya que '// si la primera no es true, lo puede ser la segunda. If OrTest(False) Or OrTest(False) Then '// Nothing End If Debug.Print String$(75, "=") '// Lo lógico sería que se saltase la segunda función puesto '// que la primera es true, pero no, nuestro querido vb '// comprueba igual... If OrTest(True) Or OrTest(False) Then '// Nothing End If End Sub
Retorno: 00:27:48 Función con el argumento Falso llamada. 00:27:48 Función con el argumento Falso llamada. =========================================================================== 00:27:48 Función con el argumento Verdadero llamada. 00:27:48 Función con el argumento Falso llamada.
Sé que alguno dirá: ¿y a mí qué más me da si el resultado es el mismo?Bueno, pues imagina que tienes un If tal que así: If Calculo(1) Or Calculo(2) Or Calculo(3) Or Calculo(4) Or Calculo(5) Then '... End If
La función Calculo() es un algoritmo complejo y tarda 1 segundo de media. Si fuera otro lenguaje de programación si Calculo(1) es true se saltaría los demás, pero nuestro querido vb6 llamará a todas las demás funciones perdiendo tiempo innecesariamente... Pasando de 1 seg a 5 en este caso. La alternativa que propongo en estos casos es (no son agradables a la vista, aviso ) : Sustituir esto: If A(324) = 45 Or B(12) = 2 Or B(4563) = 56 Then Call DoIt End If
Por esto: If A(324) = 45 Then Call DoIt ElseIf B(12)=2 Then Call DoIt ElseIf B(4563) = 56 Then Call DoIt End If
Esto: If A(324) = 45 And B(12) = 2 And B(4563) = 56 Then '... End If
Por esto: If A(324) = 45 Then If B(12) = 2 Then If B(4563) = 56 Then '... End If End If End If
Con esto no quiero decir que lo hagáis así de normal, sólo cuando necesitemos velocidad. Hice estas pruebas a ver si algún lenguaje más era tonto, pero por ahora sólo es vb6. Si alguien sabe de otro hacedmelo saber, me interesa mucho. Dedico este articulo a Karcrack, BlackZero, TheSwash y raul338 por orientarme y ayudarme con los test. VB.NET tiene una expresion para evitar esto: Short-Circuiting Logical Operations http://msdn.microsoft.com/en-us/library/wz3k228a.aspx Más info: http://en.wikipedia.org/wiki/Short-circuit_evaluation Espero que al menos a alguien le sirva todo esto. DoEvents!
|
|
|
42
|
Programación / Programación Visual Basic / [RETO] Palabras pronunciables
|
en: 29 Septiembre 2011, 11:01 am
|
Bueno, pues la idea es generar una funcion donde ingresemos la longitud de la cadena y te generara una palabra pronunciable. Por supuesto deben estar contemplados las combinaciones entre dos consonantes. Ejemplos falsos: asdoijs ouughjt esrah wilsohc Ejemplos verdaderos: hola chema llama nikos clueim tefral Sin límite de entrega, todo vale... DoEvents!
|
|
|
43
|
Programación / Programación Visual Basic / Verificar celdas...
|
en: 23 Septiembre 2011, 18:58 pm
|
Hola buenas, pido vuestra ayuda: Hay un juego del estilo al biotronic, y al igual que el bioSolver necesito hacer una plantilla que descifre los cuadros que hay debajo. Para ello pensé hacer 4 GetPixel() por cada celda, si esos cuatro puntos son de un color similar, podré deducir el color de la celda. El problema es que hay figuras diferentes que no sé como validar: Este: O podría confundir estos dos: ¿Alguna idea? ¿Alguna forma mejor de hacerlo? Tened en cuenta que debe ser algo rápido, se debe actualizar cada 500ms o así... Igual con el CheatEngine se podría hacer algo, pero a todo el mundo que pregunto me llama loco. Gracias. DoEvents!
|
|
|
44
|
Programación / Programación Visual Basic / [RETO] Sudoku
|
en: 21 Septiembre 2011, 20:50 pm
|
Un reto dificilillo... Function SolveSudoku_raul338(s() As Byte) As Byte() Se introduce una matriz bidimensional de 9x9. Los huecos serán "0" Info http://es.wikipedia.org/wiki/Sudoku Vale todo, el más rápido gana. DoEvents!
|
|
|
46
|
Media / Diseño Gráfico / Efecto "comic" en fotos
|
en: 7 Agosto 2011, 02:37 am
|
Hola chicos, vengo con una duda muy concreta. ¿Cómo podría conseguir el efecto que tienen las fotos de esta web? ¿Se podría hacer con el GIMP también? Muchas gracias
|
|
|
47
|
Foros Generales / Foro Libre / Se acerca... ya está ahí...
|
en: 30 Mayo 2011, 18:11 pm
|
... la P.A.U. ( Prueba de Acceso Universitaria) o Selectividad o como la queráis llamar. Quedan sólo dos días, abro este post para saber si alguien más se va a examinar en España y cómo lleva la materia. DoEvents!
|
|
|
48
|
Programación / Programación Visual Basic / [SRC] LoadRndNumericArray
|
en: 27 Mayo 2011, 20:14 pm
|
Bueno, cómo ahora está de moda los numeros aleatorios encontré un hueco entre mis estudios y hice esto. Soporta divrersos tipos de arrays...( Long, Byte, Integer...). Uso la funcion de BlackZer0x : http://goo.gl/RG4BxTuve que cambiar un par de cosas nada más para adaptarlo. Función: Option Explicit '====================================================================== ' º Function : LoadRndNumericArray ' º Author : Psyke1 ' º Country : Spain ' º Mail : vbpsyke1@mixmail.com ' º Date : 27/05/2011 ' º Twitter : http://twitter.com/#!/PsYkE1 ' º Dedicated : BlackZer0x ' º Requirements : http://goo.gl/vgbtQ || http://goo.gl/BAPXx ' º Recommended Websites : ' http://foro.h-sec.org ' http://www.frogcheat.com.ar ' http://InfrAngeluX.Sytes.Net '====================================================================== Private Declare Sub RtlMoveMemory Lib "kernel32.dll" (ByVal Destination&, ByVal Source&, ByVal Length&) Public Static Function LoadRndNumericArray(lngMin&, lngMax&, varOutPutArr, Optional varExceptionArr) As Boolean Dim lngTotal&, lngFinalArr&(), lngRndIndex&, Q&, C& If IsArray(varOutPutArr) Then If lngMin < lngMax Then lngTotal = lngMax - lngMin C = 0 If Not IsMissing(varExceptionArr) And IsArray(varExceptionArr) Then Start_QuickSort varExceptionArr '// With little mod. lngTotal = lngTotal - (UBound(varExceptionArr) - LBound(varExceptionArr) + 1) ReDim lngFinalArr&(0 To lngTotal) '// Fix repetitions and numbers out of range. For Q = lngMin To lngMax If IsInArray(varExceptionArr, Q, , , , True) = -1 Then lngFinalArr(C) = Q C = C + 1 End If Next Q Else ReDim lngFinalArr&(0 To lngTotal) For Q = lngMin To lngMax lngFinalArr(C) = Q C = C + 1 Next Q End If ReDim varOutPutArr(0 To lngTotal) Randomize Timer For Q = 0 To lngTotal lngRndIndex = Rnd * lngTotal varOutPutArr(Q) = lngFinalArr(lngRndIndex) RtlMoveMemory VarPtr(lngFinalArr(lngRndIndex)), VarPtr(lngFinalArr(lngRndIndex + 1)), (lngTotal - lngRndIndex) * &H4 lngTotal = lngTotal - 1 Next Q LoadRndNumericArray = True End If End If End Function
Ejemplo: Option Explicit Private Declare Sub RtlMoveMemory Lib "kernel32.dll" (ByVal Destination&, ByVal Source&, ByVal Length&) Enum EnuListOrder AcendetOrder = 0 DecendentOrder = 1 End Enum Public Static Function LoadRndNumericArray(lngMin&, lngMax&, varOutPutArr, Optional varExceptionArr) As Boolean Dim lngTotal&, lngFinalArr&(), lngRndIndex&, Q&, C& If IsArray(varOutPutArr) Then If lngMin < lngMax Then lngTotal = lngMax - lngMin C = 0 If Not IsMissing(varExceptionArr) And IsArray(varExceptionArr) Then Start_QuickSort varExceptionArr lngTotal = lngTotal - (UBound(varExceptionArr) - LBound(varExceptionArr) + 1) ReDim lngFinalArr&(0 To lngTotal) '// Fix repetitions and numbers out of range. For Q = lngMin To lngMax If IsInArray(varExceptionArr, Q, , , , True) = -1 Then lngFinalArr(C) = Q C = C + 1 End If Next Q Else ReDim lngFinalArr&(0 To lngTotal) For Q = lngMin To lngMax lngFinalArr(C) = Q C = C + 1 Next Q End If ReDim varOutPutArr(0 To lngTotal) Randomize Timer For Q = 0 To lngTotal lngRndIndex = Rnd * lngTotal varOutPutArr(Q) = lngFinalArr(lngRndIndex) RtlMoveMemory VarPtr(lngFinalArr(lngRndIndex)), VarPtr(lngFinalArr(lngRndIndex + 1)), (lngTotal - lngRndIndex) * &H4 lngTotal = lngTotal - 1 Next Q LoadRndNumericArray = True End If End If End Function ' ///////////////////////////////////////////////////////////// ' // Autor Algoritmo: C.A.R. Hoare en 1960 // ' // Autor: BlackZeroX ( Ortega Avila Miguel Angel ) // ' // // ' // Web: http://InfrAngeluX.Sytes.Net/ // ' // // ' // |-> Pueden Distribuir Este Codigo siempre y cuando // ' // no se eliminen los creditos originales de este codigo // ' // No importando que sea modificado/editado o engrandesido // ' // o achicado, si es en base a este codigo // ' ///////////////////////////////////////////////////////////// Private Sub AuxOrden(ByRef mArray, i As Long, j As Long, il As Long, jl As Long) Dim C As String Dim c2 As Long C = mArray(j) mArray(j) = mArray(i) mArray(i) = C c2 = il il = -jl jl = -c2 End Sub Private Sub PreSort(ByRef mArray, lb As Long, ub As Long, k As Long, Optional Order As EnuListOrder = DecendentOrder) Dim i As Long Dim j As Long Dim il As Long Dim jl As Long il = 0: jl = -1 i = lb: j = ub While i < j If Order = DecendentOrder Then If IsNumeric(mArray(i)) And IsNumeric(mArray(j)) Then If Val(mArray(i)) > Val(mArray(j)) Then Call AuxOrden(mArray(), i, j, il, jl) End If Else If mArray(i) > mArray(j) Then Call AuxOrden(mArray(), i, j, il, jl) End If End If Else If IsNumeric(mArray(i)) And IsNumeric(mArray(j)) Then If Val(mArray(i)) < Val(mArray(j)) Then Call AuxOrden(mArray(), i, j, il, jl) End If Else If mArray(i) < mArray(j) Then Call AuxOrden(mArray(), i, j, il, jl) End If End If End If i = i + il j = j + jl Wend k = i End Sub Private Sub QSort(ByRef mArray, lb As Long, ub As Long, _ Optional Order As EnuListOrder = DecendentOrder) Dim k As Long If lb < ub Then PreSort mArray, lb, ub, k, Order Call QSort(mArray, lb, k - 1, Order) Call QSort(mArray, k + 1, ub, Order) End If End Sub Public Sub Start_QuickSort(ByRef mArray, Optional Order As EnuListOrder = DecendentOrder) QSort mArray, LBound(mArray), UBound(mArray), Order End Sub '// by Psyke1 Public Static Function IsInArray&(varArr, _ varValue, _ Optional lngStart&, _ Optional lngEnd&, _ Optional bolFindFirst As Boolean, _ Optional bolIsSorted As Boolean) Dim lngLB&, lngUB&, Q&, C& If (IsArray(varArr) = True) And (IsArray(varValue) = False) Then lngLB = LBound(varArr) lngUB = UBound(varArr) If Not IsMissing(lngStart) Then If (lngStart > lngLB) And (lngStart < lngUB) Then lngLB = lngStart End If If Not IsMissing(lngEnd) Then If (lngEnd > lngLB) And (lngEnd < lngUB) Then lngUB = lngEnd End If If bolIsSorted Then If varArr(lngLB) = varValue Then IsInArray = lngLB Exit Function ElseIf varArr(lngUB) = varValue Then If bolFindFirst Then Do While (varArr(lngUB) = varArr(lngUB - 1)) And (Q > lngLB) lngUB = lngUB - 1 Loop End If IsInArray = lngUB Exit Function End If If lngUB - lngLB < 2 Then GoTo NotFound If (varArr(lngLB) > varValue) Or (varArr(lngUB) < varValue) Then GoTo NotFound C = 0 Do Q = (lngUB + lngLB) \ 2 If C = Q Then GoTo NotFound If varArr(Q) > varValue Then lngUB = Q ElseIf varArr(Q) < varValue Then lngLB = Q C = lngLB Else If bolFindFirst Then Do While (varArr(Q) = varArr(Q - 1)) And (Q > lngLB) Q = Q - 1 Loop End If IsInArray = Q Exit Function End If Loop Else For Q = lngLB To lngUB If varArr(Q) = varValue Then IsInArray = Q Exit Function End If Next Q GoTo NotFound End If End If Exit Function NotFound: IsInArray = -1 End Function Private Sub Form_Load() Dim varItem, lngOut&(), intEx%(0 To 3) intEx(0) = -2 intEx(1) = 1 intEx(2) = 5 intEx(3) = 8 Debug.Print String$(40, "="), Time$ If LoadRndNumericArray(-5, 10, lngOut, intEx) Then For Each varItem In lngOut Debug.Print varItem Next varItem End If End Sub
Resultado: ======================================== 20:10:55 4 -4 7 3 9 -1 -5 0 10 2 6 -3 Voy a seguir estudiando para la selectividad... Bye DoEvents!
|
|
|
49
|
Programación / Programación Visual Basic / [Src] IsInArray
|
en: 9 Mayo 2011, 14:24 pm
|
Bueno, aquí os dejo esta sencilla función. Su finalidad es devolver el Index de un Item que se encuentre en un array (acepta todo tipo de Arrays : String, Double, Long...), con la opción de devolver el primero que se encuentre en el array y con los parámetros lngStart y lngEnd podemos establecer límites en nuestra búsqueda. Para ordenarlo aconsejo usar esta maravillosa función que hizo mi amigo BlackZer0x : http://goo.gl/RG4BxOption Explicit '====================================================================== ' º Function : IsInArray ' º Author : Psyke1 ' º Country : Spain ' º Mail : vbpsyke1@mixmail.com ' º Date : 09/05/2011 ' º Twitter : http://twitter.com/#!/PsYkE1 ' º Dedicated : BlackZer0x ' º Reference : http://goo.gl/RDQhK ' º Recommended Websites : ' http://foro.h-sec.org ' http://www.frogcheat.com.ar ' http://InfrAngeluX.Sytes.Net '====================================================================== Public Static Function IsInArray&(varArr, _ varValue, _ Optional lngStart&, _ Optional lngEnd&, _ Optional bolFindFirst As Boolean, _ Optional bolIsSorted As Boolean) Dim lngLB&, lngUB&, Q&, C& If (IsArray(varArr) = True) And (IsArray(varValue) = False) Then lngLB = LBound(varArr) lngUB = UBound(varArr) If Not IsMissing(lngStart) Then If (lngStart > lngLB) And (lngStart < lngUB) Then lngLB = lngStart End If If Not IsMissing(lngEnd) Then If (lngEnd > lngLB) And (lngEnd < lngUB) Then lngUB = lngEnd End If If bolIsSorted Then If varArr(lngLB) = varValue Then IsInArray = lngLB Exit Function ElseIf varArr(lngUB) = varValue Then If bolFindFirst Then Do While (varArr(lngUB) = varArr(lngUB - 1)) And (Q > lngLB) lngUB = lngUB - 1 Loop End If IsInArray = lngUB Exit Function End If If lngUB - lngLB < 2 Then GoTo NotFound If (varArr(lngLB) > varValue) Or (varArr(lngUB) < varValue) Then GoTo NotFound C = 0 Do Q = (lngUB + lngLB) \ 2 If C = Q Then GoTo NotFound If varArr(Q) > varValue Then lngUB = Q ElseIf varArr(Q) < varValue Then lngLB = Q C = lngLB Else If bolFindFirst Then Do While (varArr(Q) = varArr(Q - 1)) And (Q > lngLB) Q = Q - 1 Loop End If IsInArray = Q Exit Function End If Loop Else For Q = lngLB To lngUB If varArr(Q) = varValue Then IsInArray = Q Exit Function End If Next Q GoTo NotFound End If End If Exit Function NotFound: IsInArray = -1 End Function
Un ejemplo: Option Explicit Private Const strLine$ = "------------------------------" Private Sub Form_Load() Dim L&(60), S(), Q& For Q = 0 To 60 L(Q) = Q * 2 Next Q Debug.Print strLine$, Time$, strLine$ Debug.Print IsInArray(L, 15) '---> -1 Debug.Print IsInArray(L, 40) '---> 20 Debug.Print IsInArray(L, 85) '---> -1 Debug.Print IsInArray(L, 100) '---> 50 S = Array("abba", "acero", "karcrack", "sereno", "silencio", "tonto", "tonto", "tonto", "tonto", "zalme") Debug.Print strLine$ Debug.Print IsInArray(S, "zalme") '---> 9 Debug.Print IsInArray(S, "zalme", , 4) '---> -1 Debug.Print IsInArray(S, "mesa") '---> -1 Debug.Print IsInArray(S, "besos") '---> -1 Debug.Print IsInArray(S, "karcrack") '---> 2 Debug.Print IsInArray(S, "karcrack", 3) '---> -1 Debug.Print IsInArray(S, "tonto") '---> 6 Debug.Print IsInArray(S, "tonto", , , True) '---> 5 End Sub
Retorna: ------------------------------ 18:59:54 ------------------------------ -1 20 -1 50 ------------------------------ 9 -1 -1 -1 2 -1 6 5
Si necesitamos especial velocidad y lo queremos para un tipo de variable en concreto, sólo hay que modificar un par de cosas. Aquí un ejemplo para buscar en un array Long, comparado con el código de BlackZer0x ( http://goo.gl/RDQhK ) : Option Explicit '// Compilado sin la comprobación de límites en los arrays xP
Private Sub Form_Load() Dim L&(6000), Q&, t As New CTiming, y& If App.LogMode = 0 Then End For Q = 0 To 6000 L(Q) = Q * 2 Next Q Me.AutoRedraw = True t.Reset For Q = 1 To 1000 IsInArray L, 15 IsInArray L, 40 IsInArray L, 2001 IsInArray L, 5020 IsInArray L, 12000 Next Q Me.Print "IsInArray", , t.sElapsed t.Reset For Q = 1 To 1000 ExitsInArrayNR 15, L, y ExitsInArrayNR 40, L, y ExitsInArrayNR 2001, L, y ExitsInArrayNR 5020, L, y ExitsInArrayNR 12000, L, y Next Q Me.Print "ExitsInArrayNR", t.sElapsed End Sub
'// by Psyke1 Public Static Function IsInArray&(lngArr&(), lngValue&, Optional lngStart&, Optional lngEnd&, Optional bolFindFirst As Boolean) Dim lngLB&, lngUB&, lngItem&, Q&, C& lngLB = LBound(lngArr) lngUB = UBound(lngArr) If Not IsMissing(lngStart) Then If (lngStart > lngLB) And (lngStart < lngUB) Then lngLB = lngStart End If If Not IsMissing(lngEnd) Then If (lngEnd > lngLB) And (lngEnd < lngUB) Then lngUB = lngEnd End If If lngArr(lngLB) = lngValue Then IsInArray = lngLB Exit Function ElseIf lngArr(lngUB) = lngValue Then If bolFindFirst Then Do While (lngArr(lngUB) = lngArr(lngUB - 1)) And (Q > lngLB) lngUB = lngUB - 1 Loop End If IsInArray = lngUB Exit Function End If If lngUB - lngLB < 2 Then GoTo NotFound If (lngArr(lngLB) > lngValue) Or (lngArr(lngUB) < lngValue) Then GoTo NotFound C = 0 Do Q = (lngUB + lngLB) \ 2 If C = Q Then GoTo NotFound
If lngArr(Q) > lngValue Then lngUB = Q ElseIf lngArr(Q) < lngValue Then lngLB = Q C = lngLB Else If bolFindFirst Then Do While (lngArr(Q) = lngArr(Q - 1)) And (Q > lngLB) Q = Q - 1 Loop End If IsInArray = Q Exit Function End If Loop Exit Function
NotFound: IsInArray = -1 End Function
'// by BlackZer0x Public Function ExitsInArrayNR(ByRef vValue As Long, ByRef vBuff() As Long, ByRef p As Long) As Boolean Dim lng_lb As Long Dim lng_Ub As Long lng_lb = LBound(vBuff&()) lng_Ub = UBound(vBuff&()) If Not vBuff&(lng_Ub) > vBuff&(lng_lb) Then Dim t As Long t = lng_Ub lng_Ub = lng_lb lng_lb = t End If Do Until ExitsInArrayNR Select Case vValue Case vBuff&(lng_lb&) p& = lng_lb& ExitsInArrayNR = True Case vBuff&(lng_Ub&) p& = lng_Ub& ExitsInArrayNR = True Case Else p = (lng_lb& + lng_Ub&) / 2 If p <> lng_lb& And p& <> lng_Ub& Then If vBuff&(p&) < vValue& Then lng_lb = p ElseIf vBuff&(p&) > vValue& Then lng_Ub = p ElseIf vBuff&(p&) = vValue& Then ExitsInArrayNR = True End If Else Exit Do End If End Select Loop End Function Resultado: DoEvents!
|
|
|
50
|
Programación / Programación General / Duda simple expresiones regulares
|
en: 7 Mayo 2011, 17:02 pm
|
Hola buenas, vengo aquí con un problemilla muy sencillo que tengo con RegExp. Necesito validar nombres de usuario que sólo pueden contener : números, letras y "_" ; tener un mínimo de un carácter y un máximo de 15. Para ello, pensé esto: El problema es que si tengo esto: La validación me da positiva, pues, encuentra caracteres alfanuméricos... Sólo quiero que me admita ( \w y " _") nada más. ¿Me echáis una mano? Gracias DoEvents!
|
|
|
|
|
|
|