|
Responder
|
Página 12> |
| Autor | |
xavi
Ver perfil usuario
Enviar mensaje privado
Ver los mensajes del usuario
Visite la página de los usuarios
Añadir a la lista de amigos
Administrador
Terrassa-BCN Unido: 10/Mayo/2005 Localización: Catalunya |||| Estado: Sin conexión Puntos: 14926 |
Tema: Localizar Excel y leer datosEnviado: 19/Septiembre/2019 a las 17:20 |
|
Buenas tardes, Miro de poneros en situación. Desde una aplicación Access debe poder localizarse 2 ficheros Excel que, teóricamente, están abiertos en la misma máquina. Si no estuvieran abiertos ya mandaríamos el correspondiente mensaje de error. Una vez si si están abiertos, necesito recuperar el valor de una serie de celdas (las tengo mapeadas). Hàndicap: el nombre del fichero podría no ser siempre igual. Sería parecido pero con posibilidad de pequeños cambios. Más que nada que el propietario del fichero "versiona" en el nombre del fichero (lo que no critico ya que yo también lo he hecho) He encontrado algunos códigos para localizar el handle de la primera ventana que contenga un determinado texto:
Con eso puedo encontrar el handle de la ventana que busco. ¿Y después que? Si algo no se entiende no dudéis en preguntar. Gracias de antemano
|
|
![]() |
|
Erick Gamer
Asiduo
Unido: 08/Mayo/2016 Localización: Mexico Estado: Sin conexión Puntos: 387 |
Enviado: 19/Septiembre/2019 a las 19:03 |
|
Pues hice algo parecido en .NET con una aplicación externa JAVA.
Busco la ventana del JAVA y la activo, una vez activa y como no tengo el nombre de los controles del JAVA uso las coordenadas de ellos para mandar parametros y pulsaciones de teclas (SendKeys) uso TAB para cambiar entre pantalla de mi Aplicación a JAVA. A lo que voy es si ya encontro la ventana de Excel entonces activarla y luego extraer la informacion que necesita, enviando parametros o SendKeys. Para vba encontre esto realmente no se si te sirva de algo, espero y si Xavi. Erick Gamer
|
|
|
Aprendiz de todos, maestro de nadie.
|
|
![]() |
|
pitxiku
Colaborador
Unido: 27/Septiembre/2017 Localización: En mi casa Estado: Sin conexión Puntos: 1536 |
Enviado: 19/Septiembre/2019 a las 19:22 |
|
Otra posibilidad es usar GetObject para instanciar la aplicación Excel que este abierta. Y a partir de ahí, trabajas igual que con una instancia abierta con CreateObject:
- https://docs.microsoft.com/es-es/office/vba/language/reference/user-interface-help/getobject-function |
|
![]() |
|
guarracuco
Moderador
Unido: 24/Abril/2004 Localización: EEUU Estado: Sin conexión Puntos: 3239 |
Enviado: 19/Septiembre/2019 a las 19:38 |
|
Y si tienes código en esos archivos que exporten la información a un archivo txt?
|
|
![]() |
|
happy
Ver perfil usuario
Enviar mensaje privado
Ver los mensajes del usuario
Visite la página de los usuarios
Añadir a la lista de amigos
Moderador
Unido: 29/Enero/2005 Localización: España Estado: Sin conexión Puntos: 3200 |
Enviado: 19/Septiembre/2019 a las 23:26 |
|
Hola Xavi, ahora no estoy seguro de si la opción que te comenta pitxiku del GetObject te podría servir. Creo que necesitarías saber la ruta absoluta del libro excel para poder referenciarlo (si no recuerdo mal ...) y creo que con las rutinas para encontrar el handle no lo consigues, ni lo podrás conseguir.
Pero he encontrado un código por ahí que creo que te podría servir. Ponlo en un módulo estandar:
Para utilizar esta función deberás llamarla de la siguiente manera (tomando la variable Hwnd que ponías en el código que exponías antes): If GetXLapp(uHandle.Hwnd, xlApp) = True Then ' si llegamos aquí es que xlApp contiene un objeto ' Excel.Application del Excel que te interesa End If Espero que te sirva (Edito para poner algunos comentarios que expliquen qué hace ese código)
Editado por happy - 20/Septiembre/2019 a las 00:05 |
|
|
Saludos,
Juan M. Afan de Ribera |
|
![]() |
|
prga
Moderador
Unido: 16/Noviembre/2004 Localización: España Estado: Sin conexión Puntos: 3535 |
Enviado: 20/Septiembre/2019 a las 00:15 |
|
Hola.
Sí he entendido bien, con este código, aparentemente más sencillo, se puede "llegar" a los excel abiertos: Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As Long) As Long Public Sub Detectaexcel() Dim hWnd As Long Dim miexcel As Excel.Application Dim milibro As Excel.Workbook hWnd = FindWindow("XLMAIN", 0) If hWnd = 0 Then ' 0 quiere decir que Excel no se está ejecutando . MsgBox ("NO ESTÁ EXCEL ABIERTO") Exit Sub Else Set miexcel = GetObject(, "excel.application") For Each milibro In miexcel.Workbooks MsgBox (milibro.FullName) Next 'miexcel.Quit Set miexcel = Nothing End If End Sub Espero que ayude a resolver la duda. Un saludo a todos
|
|
![]() |
|
happy
Ver perfil usuario
Enviar mensaje privado
Ver los mensajes del usuario
Visite la página de los usuarios
Añadir a la lista de amigos
Moderador
Unido: 29/Enero/2005 Localización: España Estado: Sin conexión Puntos: 3200 |
Enviado: 20/Septiembre/2019 a las 09:43 |
|
Hola,
no se si esto pasa en todas las versiones diferentes de Excel o no, pero al menos con la versión 2013, que es la que tengo yo instalada, puedes tener más de una instancia de Excel abierta. Es decir, el código que ha expuesto prga es válido, pero sólo referenciará la primera instancia de Excel que tenga el sistema en ese momento y por tanto sólo accederá a los workbooks abiertos que cuelguen de esa instancia. Por ejemplo, y ya digo, al menos con esta versión 2013 que tengo yo, si voy al explorador de archivos y abro un libro excel, y después otro y después otro, esos 3 libros excel colgarán de la misma instancia de la aplicación. En ese caso el código con GetObject funcionará bien. Pero si al mismo tiempo abro simplemente el programa excel y desde ahí abro otro libro, se creará una segunda instancia de la aplicación. En ese momento, el GetObject ya no servirá, porque cuando lo ejecute volverá a localizar la primera instancia que haya abierto. No tengo manera, que yo sepa, de decirle que abra la segunda instancia de Excel, que es a lo mejor, la que contiene el excel que me interesa manipular. Ahí ya necesitaría indicarle en el primer parámetro la ruta absoluta del excel al que quiero acceder. ![]() |
|
|
Saludos,
Juan M. Afan de Ribera |
|
![]() |
|
Mihura
Ver perfil usuario
Enviar mensaje privado
Ver los mensajes del usuario
Visite la página de los usuarios
Añadir a la lista de amigos
Administrador
Unido: 06/Mayo/2005 Localización: En la dehesa Estado: Sin conexión Puntos: 14428 |
Enviado: 20/Septiembre/2019 a las 10:05 |
|
Desde la ignorancia de un novillo que está aprendiendo ....
![]() ¿ No hay alguna manera de recorrer todos los programas que están abiertos en windows e ir analizando uno por uno su nombre / tipo / .. ? me suena haberlo visto por algún sitio. Yo uso 2010 y también puedes tener distintas instancias de Excel, es más yo los abro así porque me es más cómodo. |
|
![]() |
|
pitxiku
Colaborador
Unido: 27/Septiembre/2017 Localización: En mi casa Estado: Sin conexión Puntos: 1536 |
Enviado: 20/Septiembre/2019 a las 11:06 |
|
Puedes usar EnumWindows para recuperar los hWnd de las ventanas abiertas, y a partir de ahí comprobar cuál es de Excel:
- https://renenyffenegger.ch/notes/development/languages/VBA/Win-API/examples/EnumWindows (Creo que en AllApi había otro ejemplo, pero ya no está online )En el ejemplo usan 2 apis para sacar el título de la ventana y su clase. Lo que no sé es si con eso se puede tomar la instancia de Excel y comprobar qué documentos tiene cargados. Editado por pitxiku - 20/Septiembre/2019 a las 11:06 |
|
![]() |
|
happy
Ver perfil usuario
Enviar mensaje privado
Ver los mensajes del usuario
Visite la página de los usuarios
Añadir a la lista de amigos
Moderador
Unido: 29/Enero/2005 Localización: España Estado: Sin conexión Puntos: 3200 |
Enviado: 20/Septiembre/2019 a las 11:32 |
|
En realidad lo que conseguirá Xavi con EnumWindows es lo mismo que obtiene con el código que expone en su primer mensaje, sólo que con un bucle y utilizando GetWindow (a lo mejor EnumWindows es una encapsulación de ese otro método en bucle o algo similar).
El problema que tiene Xavi es, una vez localizado el handle de la ventana Excel que contiene el libro de trabajo que le interesa (del cual comenta que puede incluso variar el nombre), cómo obtener una instancia del objeto COM o de automatización para esa instancia de Excel y así poder manejar con automatización el workbook, los worksheets que contenga, celdas, rangos, etc. El código que he expuesto obtiene el objeto COM de la instancia Excel indicada utilizando únicamente el handle (identificador de ventana) de la ventana principal (XLMAIN) de esa instancia Excel. Muchas de estas cosas las han resuelto con la plataforma .NET en donde, por lo que he visto, en vez de utilizar directamente APIs de Windows, han encapsulado estos métodos o pequeños procesos (igual al que estamos tratando aquí) en clases y objetos, de modo que el programador no tenga que lidiar con todos estos problemas. Que yo sepa, la mayoría de estas funciones típicas del API de Windows están escritas en C de los primeros tiempos. PUede que algunas las hayan actualizado un poco para adecuarlas, primero a 32 y luego a 64 bits, pero básicamente hacen lo mismo y tienen las mismas dificultades para el programador de VB (me refiero sobre todo al paso de argumentos a esas funciones y a los tipos de variables a utilizar para ello, así como - importante! - la manera de pasar ByVal o ByRef esas variables o valores a las funciones del API)
![]() Editado por happy - 20/Septiembre/2019 a las 11:34 |
|
|
Saludos,
Juan M. Afan de Ribera |
|
![]() |
|
xavi
Ver perfil usuario
Enviar mensaje privado
Ver los mensajes del usuario
Visite la página de los usuarios
Añadir a la lista de amigos
Administrador
Terrassa-BCN Unido: 10/Mayo/2005 Localización: Catalunya |||| Estado: Sin conexión Puntos: 14926 |
Enviado: 20/Septiembre/2019 a las 14:14 |
|
Buenas. Por alusiones, jejejeje
El primer código de pitxiku con el nombre completo (ahí el "problema") funciona OK. Probaré el codigo de Happy a ver si me permite acotar más. De todas formas también le puedo decir al cliente (el que ya sabeis...) que, o me pone la ruta completa y el mismo nombre siempre o el sistema no funciona. Bastaría con evaluar el WindowCaption de mi primer código para ver que coincida con el esperado. Os mantengo informados. Muchas gracias a todos por las aportaciones |
|
![]() |
|
pitxiku
Colaborador
Unido: 27/Septiembre/2017 Localización: En mi casa Estado: Sin conexión Puntos: 1536 |
Enviado: 20/Septiembre/2019 a las 16:55 |
|
Por partes:
- Mihura preguntó por un código para recorrer las ventanas, por eso hablé del EnumWindows. Otra cosa es que para este caso no sirva de mucho. - Con el código de prga se obtiene la instancia de Excel abierta. Una vez tenemos la instancia, podemos recorrer los libros abiertos y comprobar si algo (nombre de hoja, de libro, valor en una celda,... ) coincide con un estándar dado por el cliente para que sea ese el libro a tratar. - Lo que no consigo es abrir 2 instancias de Excel. Me explico: abro una con una hoja en blanco, abro un libro directamente, vuelvo a abrir otro Excel desde el menú con otra hoja en blanco ... Y lo que ocurre es que la primera instancia de Excel, pillada con el GetObject, incrementa el número de libros abiertos en su colección WorkBooks. |
|
![]() |
|
Emilio
Ver perfil usuario
Enviar mensaje privado
Ver los mensajes del usuario
Visite la página de los usuarios
Añadir a la lista de amigos
Administrador
Santander Unido: 08/Agosto/2004 Localización: España Estado: Sin conexión Puntos: 18836 |
Enviado: 20/Septiembre/2019 a las 17:22 |
|
Buenas, Pitxiku, para abrir dos instancias de Excel has de abrir Excel desde "su icono" en W10 puedes pulsar con el botón derecho del ratón sobre el botón de la instancia abierta y seleccionar Microsoft Excel. Si abres un libro Excel directamente siempre (que la haya) se abrirá en la instancia abierta.
|
|
![]() |
|
Mihura
Ver perfil usuario
Enviar mensaje privado
Ver los mensajes del usuario
Visite la página de los usuarios
Añadir a la lista de amigos
Administrador
Unido: 06/Mayo/2005 Localización: En la dehesa Estado: Sin conexión Puntos: 14428 |
Enviado: 20/Septiembre/2019 a las 17:39 |
![]() |
|
prga
Moderador
Unido: 16/Noviembre/2004 Localización: España Estado: Sin conexión Puntos: 3535 |
Enviado: 20/Septiembre/2019 a las 18:52 |
|
A partir de no se que versión de oficce, sólo se pueden abrir 2 o más instancias de excel o word por código (createobject). Utilizando directamente el excel, al menos yo, no he podido conseguir dos instancias diferentes del excel 2019, incluso si se abre con shell o followhyperlink. Eso sí, se crean 2 ventanas diferentes, pero una sola instancia
|
|
![]() |
|
Responder
|
Página 12> |
|
Tweet
|
| Ir al foro | Permisos de foro ![]() Usted No puede publicar nuevos temas en este foro Usted No puede responder a temas en este foro Usted No puede borrar sus mensajes en este foro Usted No puede editar sus mensajes en este foro Usted No puede crear encuestas en este foro Usted No puede votar en encuestas en este foro |