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:
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 :-\
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
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:
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!¡.
Hola, para saber si un array esta inicializado hay varias formas, te dejo algunas, probalas si te sirven:
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...
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...
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.
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:
If Not Es_Array(Imagenes) Then
Estado_1.Caption = "No se han localizado imagenes"
Exit Function
End If
Strings.bas:
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.
(http://i.elhacker.net/i?i=4TevuDC-BgEzxS8-hghrq2Vo)
Probaré la otra opción con copymemory
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:
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:
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
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 (http://vbnet.mvps.org/index.html?code/helpers/getarraydims.htm)
saludos.
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
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.