Programación General > Visual Basic para principiantes
Err "ActiveX no crea objeto" y "No tipo definido x usuario"
DeathWatch:
Que onda, como estan :)
Yo aca con una de muchas consultas (y participaciones desde luego) aqui en el foro :P
Miren, tengo creado un Exe ActiveX, llamado XEjecutor.
Tengo otro Exe normal que hace uso del ActiveX, pero estoy teniendo una serie de problemas:
Dentro de este exe normal, si escribo:
--- Código: Visual Basic ---Dim Ejec_1 As Object Set Ejec_1 = CreateObject("C:Documents and SettingsDeathWatchMis documentosXEjecutor.exe") me arroja Error '429' en tiempo de ejecucion :
El componente ActiveX no puede crear el objeto.
Pero igual si en lugar de XEjecutor.exe le cambio el nombre a lasdjflk.exe, me da el mismo error, asi que creo que no esta haciendo referencia al archivo.
Por otro lado si escribo:
--- Código: Visual Basic ---Sub Main()' Aqui, se supone que registro el Exe ActiveX, y aparentemente si lo hace, supongo yo...Shell ("C:Documents and SettingsDeathWatchMis documentosXEjecutor.exe /RegServer")' Aqui llamo al Sub PruebaPruebaEnd Sub Sub Prueba()' Aqui instancio al proyecto XProyEjec, a la clase XClsEjec, que se encuentran dentro del ActiveX XEjecutorDim Ejec_1 As New XProyEjec.XClsEjecSet Ejec_1 = New XProyEjec.XClsEjec ' Llamo a un procedimiento llamado Proceso, dentro del ActiveXEjec_1.Proceso 1 ' y despejo el objeto.Set Ejec_1 = Nothing End Sub Obtengo Error de compilacion:
No se ha definido el tipo definido por el usuario.
Donde esta mi falla? :blink: :brickwall:
Les comento que la idea NO es entrar en VB, a Proyecto - Referencias, porque este exe normal y el exe activex, siempre se van a ejecutar en una maquina diferente.
Ojala puedan ayudarme
Gracias de antemano :good:
Un saludo
Nebire:
Aunque has dato algunos detalles, no son todos los necesarios para entender tu problema.
Por ejemplo, el objeto que tratas de cargar, está compilado o lo usas en el proyecto de prueba todavía en diseño ?.
Puedes exponer una imagen del cuadro de propiedades del exe activeX (de la clase)?
Hay más objetos o sólo una clase... ?
Has registrado la librería ?.
Suponiendo que por ahí no te hayas encontrado problemas, pués, pasemos a lo siguiente....
Te pongo un pequeño ejemplo que te servirá de guía, luego que lo verifiques por tí mismo, introduce las equivalencias a tu proyecto...
1 Crea un nuevo proyecto de tipo EXE ACTIVEX...
2 Dale un nombre al proyecto, por ejemplo : ExeActiveX y un nombre a la clase, por ejmplo: EXejemplo
3 Asegúrate que la clase tiene la propiedad instancing establecida a 5 (multiuse)
4 Escribe este código para clase (copia y pega)
--- Código: Visual Basic --- Private Sub Class_Initialize() MsgBox "hola"End Sub Public Sub Saludar(ByVal cadena As String) MsgBox cadenaEnd Sub 5 En proyecto propiedades del proyecto modelo de subprocesos -> activa la casilla que que mejor te convenga, para el ejemplo nos vale bien ''conjunto de: 1 subprocesos'' (puedes aumentar la cifra si lo requiere tu aplicación, pero en esta de ejemplo con 1 nos vale)
6 Ahora compila el proyecto y cuando termine, ciérralo. Ahora abrimos nuevamente el entorno de vb6 para crear una aplicaciónde tipo exe estándar...
7 en el mismo código de carga del formulario (puesto que es un simple ejemplo vale, si lo prefieres ponlo para un botón), pega este código:
--- Código: Visual Basic --- Private Sub Form_Load()' Dim Ejec_1 As ExeActiveX.EXejemplo ' sólo si se añade una referencia Dim Ejec_1 As Object 'ExeActiveX.EXejemplo 'Set Ejec_1 = New ExeActiveX.EXejemplo ' sólo si se añade una referencia al proyecto. Set Ejec_1 = CreateObject("ExeActiveX2.EXejemplo") Set Ejec_1 = GetObject("", "ExeActiveX2.EXejemplo") Ejec_1.Saludar ("funciona correctamente")End Sub Debería funcionarte sin problemas... cuando creas la instancia se crea la clase, por lo qwue se invoca el método initialize del activex y se ejecutará el código que pusimos, nos responderá 'Hola'
Cuando se ejecute el método Saludar, tomará la cadena que le hemos pasado y deberá mostrarnos el mensaje pertienente...
Fíjate que podemos usar tanto GetObject como CreateObject... (cada una utiliza sus propios parámetros)
fíjate que no señalo ninguna ruta... ¿ por qué ? te preguntaras... porque cuando he compilado el proyecto automáticamente se ha registrado la librería. Por tanto lo que tienes que hacer es registrar adecuadamente la librería.
DeathWatch:
Amigo(a), mil mil gracias. No sabes cuanto te lo agradezco!!! :D :D :good: :beer:
Te juro que lo siguiente que te escribo no es para hacerte la “barba”, como decimos aquí en Mexico. Con tus ejemplos he entendido mejor esto de las clases, y la clave para que se solucionara mi problema, fue el ultimo comentario que hiciste:
--- Citar ---fíjate que no señalo ninguna ruta... ¿ por qué ? te preguntaras... porque cuando he compilado el proyecto automáticamente se ha registrado la librería.
--- Fin de la cita ---
Y la solucion fue:
--- Código: Visual Basic ---Dim Ejec_1 As ObjectSet Ejec_1 = CreateObject("XProyEjec.XClsEjec")Ejec_1.Ejecutor 1Set Ejec_1 = Nothing
O sea, usando tu ejemplo, yo lo que estaba haciendo era:
Set Ejec_1 = CreateObject("C:Documents and SettingsDeathWatchMis documentos ExeActiveX.exe")
en lugar de escribir:
Set Ejec_1 = CreateObject("ExeActiveX2.EXejemplo")
siendo que ya la habia registrado en:
Shell ("C:Documents and SettingsDeathWatchMis documentosExeActiveX.exe /RegServer")
Mira, te escribo todo el rollo que estaba haciendo, hasta que me trabé…
Buscando un tipo multi-threading en VB, me encontre con la siguiente pagina:
todoexpertos.com/categorias/tecnologia-e-internet/programacion/visual-basic/respuestas/168589/se-pueden-ejecutar-consultas-en-paralelo
donde se explica como realizar varias consultas al mismo tiempo.
Ese ejemplo me sirvio para darme una idea de cómo ejecutar varias aplicaciones al mismo.
Entonces realice lo siguiente:
1.- Abri un Proycto Exe ActiveX, con nombre XProyEjec.
En donde mencionas lo de “En proyecto propiedades del proyecto modelo de subprocesos -> activa la casilla que que mejor te convenga”, marco la casilla Subprocesos por objeto.
2.- Cree una clase llamada XClsEjec, con el siguiente codigo:
--- Código: Visual Basic ---Public Sub Ejecutor(ValNum As Integer)Dim frmEjec As XProyEjec.XFrmEjecSet frmEjec = New XProyEjec.XFrmEjec Load frmEjec frmEjec.MultiProcs ValNum Set frmEjec = Nothing End Sub
3.- Luego agregue un nuevo proyecto Exe Standard, y genero un formulario, el cual tiene el siguiente codigo:
--- Código: Visual Basic ---Private VN As Integer Public Sub MultiProcs(ValN As Integer)VN = ValNEnd Sub
4.- Y al form, le agregue un Timer, con el siguiente codigo:
--- Código: Visual Basic ---Private Sub Timer1_Timer()MsgBox VN Unload MeEnd Sub
5.- Y genero el archivo XEjecutor.exe
6.- Luego, abro un proyecto Exe Standard independiente. Quito el formulario y agrego un modulo, con el siguiente codigo:
--- Código: Visual Basic ---Sub Main()Shell ("C:Documents and SettingsKyllMis documentosActiveXThreadsXEjecutor.exe /RegServer") PruebaEnd Sub
Y un sub donde tenia el problema.
Aun cuando habia registrado el ActiveX, si escribía
--- Código: Visual Basic ---Sub Prueba()Dim Ejec_1 As New XProyEjec.XClsEjecDim Ejec_2 As New XProyEjec.XClsEjec Set Ejec_1 = New XProyEjec.XClsEjecSet Ejec_2 = New XProyEjec.XClsEjec Ejec_1.Ejecutor 1Ejec_2.Ejecutor 2 Set Ejec_1 = NothingSet Ejec_2 = Nothing End Sub
Recibia Error de compilacion: No se ha definido el tipo definido por el usuario.
Y lo sigo recibiendo. Supongo que si no se hace referencia entrando a Proyecto – Referencias, y agregando el ActiveX, no se puede hacer referencia de la manera que expuse anteriormente.
Y si probaba con:
--- Código: Visual Basic ---Sub Prueba()Dim Ejec_1 As ObjectDim Ejec_2 As Object Set Ejec_1 = CreateObject("C:Documents and SettingsDeathWatchMis documentosXEjecutor.exe")Set Ejec_2 = CreateObject("C:Documents and SettingsDeathWatchMis documentosXEjecutor.exe") Ejec_1.Ejecutor 1Ejec_2.Ejecutor 2 Set Ejec_1 = NothingSet Ejec_2 = Nothing End Sub
pues recibia el mensaje Error '429' en tiempo de ejecucion : El componente ActiveX no puede crear el objeto.
Asi que como bien dijiste, la solucion fue cambiar el Set para que quedara:
Set Ejec_1 = CreateObject("XProyEjec.XClsEjec")
Ese era todo el rollo.
Si no deje algo en claro, comentamelo, para tratar de exponerlo un poco mejor.
Pues nuevamente, te agradezco mucho tu tiempo y tu ayuda. :beer: :good: :good:
Un saludo :hola:
Nebire:
--- Cita de: "DeathWatch" ---]Recibia Error de compilacion: No se ha definido el tipo definido por el usuario.
Y lo sigo recibiendo. Supongo que si no se hace referencia entrando a Proyecto – Referencias, y agregando el ActiveX, no se puede hacer referencia de la manera que expuse anteriormente.
--- Fin de la cita ---
Exactamente. Si no hay una referencia añadida no se puede usar NEW, porque no consta en la tabla (ROT) dicho objeto. Precisamente para eso sirven las referencias, para localizarlo en la tabla, por eso usar referencias es más rápido... Cuando se usa NEW, por debajo le está diciendo que debe buscarlo en la ROT y crear una instancia desde allí. Usando CreateObject le está diciendo que busque en el registro. y GetObject le está diciendo que si ya hay una instancia cargada con createobject, la obtenga de ahí (ahorra tiempo en verificaciones) y si no que la localice en el registro...
--- Cita de: "DeathWatch" ---Si no deje algo en claro, comentamelo, para tratar de exponerlo un poco mejor.
Pues nuevamente, te agradezco mucho tu tiempo y tu ayuda. :beer: :good: :good:
--- Fin de la cita ---
:rolleyes: Eres tú quien pregunta y tienes dudas... yo lo tengo muy claro.
Tienes un pequeño error de concepto, que trataré de corregir..
Cuando usas la función CreateObject, la dirección que admite en todo caso se utiliza para el 2ª parámetro no para el 1º, además ahí la ruta se refiere a una ruta del servidor... de red donde se desea crear el objeto.
Luego, si por ejemplo tu aplicación opera con un tipo de archivo cuya extensión fuera pongamos ".banco" , podrías utilizar la función getobject para crear el objeto cargando ya el archivo indicado...
--- Código: Visual Basic ---dim miObjeto as objectSet miObjeto= GetObject("C:archivo.banco", "MiproyectoActivexexe.Suclase") Y por tanto como podrás ver, nada tiene que ver esta ruta con la ruta donde se localiza el exe activeX
DeathWatch:
Hola de nuevo, ya ando por aqui otra vez :P
Nada mas para comentar y consultar algunas cosas:
En
--- Citar ---Nebire escribio:
Eres tú quien pregunta y tienes dudas... yo lo tengo muy claro.
--- Fin de la cita ---
:huh:
Yo se que tu lo tienes claro, puesto que me explicaste y me ayudaste a resolver mi problema.
Me referia a si no habia enredado mucho comentando lo que estaba haciendo, de forma que solo yo me estuviera entendiendo, y si habia explicado esta vez la raiz del problema que tenia.
Pero bueno, es igual ^_^ , nada mas lo comenté, porque desde luego no me referia a que no supieras lo que me estabas explicando, o que no entendieras lo que estaba yo haciendo, sino que si lo que habia escrito, era entendible... :P
Cambiando de tema...
Creo que si tengo un error de concepto :P
Que bueno que me lo dices.
Y creo que ese error lo tenemos muchos, por lo que he visto en muchos foros :o
Ya estuve echandole un ojo a ROT y a GetObject.
A ver si entendi bien lo que me comentabas... pongo un ejemplo
Hice un VBScript con el codigo:
dim fso, carp
--- Código: Visual Basic ---set fso=GetObject("", "Scripting.FileSystemObject")set carp=fso.GetFolder("C:Documents and SettingsDeathWatchMis documentosScripts")x=carp.Namemsgbox xset fso=Nothingset carp=Nothing
Me mostró el nombre de la carpeta.
Esto es porque en ROT ya existe la clase Scripting.FileSystemObject? Es a lo que te referías?
En mi ejemplo, al registrar el Exe ActiveX con /RegServer, debo usar GetObject en lugar de CreateObject?
Si no lo registro, usando Set Ejec_1 = GetObject("C:Documents and SettingsDeathWatchMis documentosXEjecutor.exe", "XProyEjec.XClsEjec"), funcionaría? (Esto lo voy a probar personalmente, pero si no funciona, si me pudieras comentar la razon, porfas)
Una ultima pregunta :P
Usando el ejemplo que puse, si en lugar de un Exe ActiveX fuera un Dll ActiveX, tal cual con los objetos form y timer y demas, he indicando en las propiedades del proyecto, Subprocesos independientes, si escribo
Set Ejec_1 = GetObject("C:Documents and SettingsDeathWatchMis documentosXEjecutor.dll", "XProyEjec.XClsEjec")
podria funcionar? respetando el multi-threading?
Realmente aunque el programa final se va a ejecutar en un equipo diferente, el programa principal y el ActiveX, ya sea Exe o Dll, van a estar siempre en una usb, en la misma ruta. Por eso lo pregunto.
(Por cierto, es para facilitar un proceso en el trabajo... no es una herramienta de hacking, ni nada por el estilo :P )
Te agradezco nuevamente tu tiempo y tus comentarios.
Me han servido de mucho
Buen fin de semana :good:
Navegación
[#] Página Siguiente
Ir a la versión completa