coo saber si existe una variante?

Iniciado por WHK, 10 Octubre 2009, 09:15 AM

0 Miembros y 2 Visitantes están viendo este tema.

WHK

Hola, tengo un array de datos que varía por lo tanto lo hize variante.
Mas abajo en el código hize un loop para obtener cada variante y procesar los datos pero cuando la variante está vacia marcaría error por lo tanto le puse el siguiente código para verificar si realmente hay variante o no antes de procesar:

Código (vb) [Seleccionar]
If UBound(Imagenes) = 0 Then
  Estado_1.Caption = "No se han localizado imagenes"
  Exit Function
End If


Pero resulta que UBound solo procesa variantes o arrays existentes, por eso me da error cuando esta vacio, por o tanto esa verificación no me sirve.

Como lo puedo hacer?

Y aprovechando el mismo tema... como puedo saber si un control está cargado? por ejemplo image(6).picture como index de 6 sin tener que hacer un for each en cada verificación.

Supongo que habrá alguna función o algo que verifique si alguno de esos dos casos existe, en casoc ontrario tendría que hacer una funcion con un foreach y comenzar a verificar el index contra el valor del index a comprobar  :-\

BlackZeroX

#1
No se me ocurre nada mas, pero para eso puedes llevar registros y evitar usar on error pero si no deseas eso aquí esta con on error

Código (vb) [Seleccionar]

on error goto ErrOut
If UBound(Imagenes) = 0 Then
 Estado_1.Caption = "No se han localizado imagenes"
 Exit Function
End If
Exit function' Exit sub
ErrOut:
msgbox "Error Array Nulo"
err.clear' Solo por si las moscas


y lo de objetos argados similar:

Código (vb) [Seleccionar]

Private Sub Form_Load()
   MsgBox cargado(Picture1(4))
End Sub

Public Function Cargado(Objeto As Object) As Boolean
On Error GoTo ErrOut
   If Objeto.Index >= 0 Then
       cargado = True
   End If
   Exit Function
ErrOut:
   cargado = False
End Function


Dulces Lunas!¡.
The Dark Shadow is my passion.

seba123neo

Hola, para saber si un array esta inicializado hay varias formas, te dejo algunas, probalas si te sirven:

Código (vb) [Seleccionar]
Private Sub Form_Load()
    Dim ArrayPrueba() As String
    Dim CadenaPrueba As String
   
    CadenaPrueba = "hola,como,va"
   
    If ((Not ArrayPrueba) = -1) Then
        MsgBox "No esta Inicializado"
    Else
        MsgBox "Si esta Inicializado"
    End If
   
    ArrayPrueba = Split(CadenaPrueba, ",")
   
    If ((Not ArrayPrueba) = -1) Then
        MsgBox "No esta Inicializado"
    Else
        MsgBox "Si esta Inicializado"
    End If
End Sub


otra con la api CopyMemory...

Código (vb) [Seleccionar]
Option Explicit

Private Const VT_BYREF = &H4000
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (lpDest As Any, lpSource As Any, ByVal cBytes As Long)

Private Sub Form_Load()
    Dim ArrayPrueba() As String
    Dim CadenaPrueba As String
   
    CadenaPrueba = "hola,como,va"
    MsgBox ArrayEstaDimensionado(ArrayPrueba)

    ArrayPrueba = Split(CadenaPrueba, ",")
    MsgBox ArrayEstaDimensionado(ArrayPrueba)
End Sub

Private Function ArrayEstaDimensionado(ByVal pArray As Variant) As Boolean
    Dim lp As Long, VType As Integer
    If Not IsArray(pArray) Then Exit Function
    Dim nDims As Integer
    CopyMemory ByVal VarPtr(VType), ByVal VarPtr(pArray), 2
    CopyMemory ByVal VarPtr(lp), ByVal (VarPtr(pArray) + 8), 4
    If lp = 0 Then Exit Function
    If (VType And VT_BYREF) <> 0 Then
        CopyMemory ByVal VarPtr(lp), ByVal lp, 4
    End If
    If lp = 0 Then Exit Function
    CopyMemory nDims, ByVal lp, 2
    ArrayEstaDimensionado = CBool(nDims)
End Function


y con la misma api + ArrPtr...

Código (vb) [Seleccionar]
Option Explicit

Private Declare Function ArrPtr Lib "msvbvm60" Alias "VarPtr" (arr() As Any) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (pDst As Any, pSrc As Any, ByVal ByteLen As Long)

Private Sub Form_Load()
    Dim ArrayPrueba() As String
    Dim CadenaPrueba As String
   
    CadenaPrueba = "hola,como,va"
    MsgBox ArrayEstaDimensionado(ArrayPrueba)

    ArrayPrueba = Split(CadenaPrueba, ",")
    MsgBox ArrayEstaDimensionado(ArrayPrueba)
End Sub

Private Function ArrayEstaDimensionado(pArray) As Boolean
  Dim vValorMemoria As Long
  CopyMemory vValorMemoria, ByVal VarPtr(pArray) + 8, ByVal 4
  CopyMemory vValorMemoria, ByVal vValorMemoria, ByVal 4
  ArrayEstaDimensionado = (vValorMemoria <> 0)
End Function


saludos.

La característica extraordinaria de las leyes de la física es que se aplican en todos lados, sea que tú elijas o no creer en ellas. Lo bueno de las ciencias es que siempre tienen la verdad, quieras creerla o no.

Neil deGrasse Tyson

WHK

#3
Hola,
estaba haciendo este proyecto y me puse de metano usar control de errores ya que quiero que mi programa pueda estar preparado ante cualquier defecto y aprender mas, asi que no quisiera tomar por opción forzar un error para saber si el array existe o no asi que tomé la segunda opción que fue como dijo seba123neo:

form:
Código (vb) [Seleccionar]
If Not Es_Array(Imagenes) Then
 Estado_1.Caption = "No se han localizado imagenes"
 Exit Function
End If


Strings.bas:
Código (vb) [Seleccionar]
Private Declare Function ArrPtr Lib "msvbvm60" Alias "VarPtr" (arr() As Any) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (pDst As Any, pSrc As Any, ByVal ByteLen As Long)

' .........

Public Function Es_Array(Array_data) As Boolean
Dim vValorMemoria As Long
CopyMemory vValorMemoria, ByVal VarPtr(Array_data) + 8, ByVal 4
CopyMemory vValorMemoria, ByVal vValorMemoria, ByVal 4
Es_Array = (vValorMemoria <> 0)
End Function

' ..........


Cuando lo hecho a correr me funciona bién la comprobación cuando si hay valor en el array pero cuando no hay valor el IDE de visual basic se cae lanzando el drwin y cerrandome la ventana.


Probaré la otra opción con copymemory


Código (vb) [Seleccionar]
Private Sub Form_Load()
    Dim ArrayPrueba() As String
    Dim CadenaPrueba As String

    CadenaPrueba = "hola,como,va"

    If ((Not ArrayPrueba) = -1) Then
        MsgBox "No esta Inicializado"
    Else
        MsgBox "Si esta Inicializado"
    End If

    ArrayPrueba = Split(CadenaPrueba, ",")

    If ((Not ArrayPrueba) = -1) Then
        MsgBox "No esta Inicializado"
    Else
        MsgBox "Si esta Inicializado"
    End If
End Sub


Acá me dice que no coinciden los tipos pero es raro porque si le estoy enviando la variante

form:
Código (vb) [Seleccionar]

Imagenes = Obtiene_imagenes(Text1.Text)

If Not Es_Array(Imagenes) Then
  Estado_1.Caption = "No se han localizado imagenes"
  Exit Function
End If


Archivos.bas:
Código (vb) [Seleccionar]
Public Function Obtiene_archivos(Ruta_expreg As String) As String
Dim Archivo As String, temp As String
Archivo = Dir(Ruta_expreg)
While Archivo <> ""
  Archivo = Dir
  If Es_String(Archivo) Then
   Obtiene_archivos = Obtiene_archivos & Archivo & ","
  End If
Wend
End Function

Public Function Obtiene_imagenes(Ruta As String) As Variant
Dim Archivos As String, Imagenes As Variant, Cuenta As Integer, Buffer As String

' Obtiene el listado de imagenes con posibles extensiones
Archivos = _
  Obtiene_archivos(Ruta & "*.jpg") & _
  Obtiene_archivos(Ruta & "*.jpeg") & _
  Obtiene_archivos(Ruta & "*.png") & _
  Obtiene_archivos(Ruta & "*.gif")

' Separa en array
Imagenes = Split(Archivos, ",")
 
' Procesa una por una
For Cuenta = 0 To UBound(Imagenes) - 1
  ' Filtra imagenes de hasta 1.5 MB solamente
  If FileLen(Ruta & Imagenes(Cuenta)) < 1500000 Then
   Buffer = Buffer & Imagenes(Cuenta) & ","
  End If
Next Cuenta

' Retorna solamente si hay imagenes válidas
If Es_String(Buffer) Then
  Obtiene_imagenes = Split(Buffer, ",")
End If
End Function



Algo pasa que me está dando conflictos en los tipos

seba123neo

si, ese codigo esta malo, a mi me paso lo mismo una vez, proba este por lo que veo es el mejor con api's, te dice si un array ha sido inicilizado o no, y es muy corto el codigo:

CopyMemory: Determining Array Initialization State and Dimensions

saludos.
La característica extraordinaria de las leyes de la física es que se aplican en todos lados, sea que tú elijas o no creer en ellas. Lo bueno de las ciencias es que siempre tienen la verdad, quieras creerla o no.

Neil deGrasse Tyson

WHK

#5
ahora veo porque no funcionaba, tu le pasas arrays y yo variantes  :P

edito:
bueno me aburrí, traté de pasar de variantes a array como una variable temporal antes de procesar pero tenia el mismo problema si la variante estaba vacia, decia que los tipos no coincidian porque se considera la variante como un string nulo y tampoco puedo devolver arrays desde una función porque tendria que declararlo como string y hacerle redim a la función con string_r() as string y eso no se puede asi que me resigné y voy a tener que utilizar errores forzados para hacer las comprobaciones como decia blackzero.
talves por eso todo lo de windows funciona a base de errores xD

Código (vb) [Seleccionar]
Public Function Es_Array(Array_data) As Boolean
On Error GoTo Error
If UBound(Array_data) > 0 Then
 Es_Array = True
 Exit Function
End If
Error:
Es_Array = False
End Function


Gracias por el tiempo.