[RESUELTO] Llamar función COUNTIF en CALC desde VBA

Desarrollo de Macros y programación en UNO, usar las API, llamar programas externos...
Responder
cespyag
Mensajes: 5
Registrado: Mié May 27, 2015 6:18 pm

[RESUELTO] Llamar función COUNTIF en CALC desde VBA

Mensaje por cespyag »

Hola a todos, he estado remirando por todas partes y no encuentro una solución a lo siguiente:
Estoy generando un listado en CALC, para su distribución, de un recordset de MS Access. Una vez enviado a Calc quisiera que a través de instrucciones en VBA me filtrara la lista quedando en la misma únicamente los 10 valores máximos de cada categoría para lo cual uso la función COUNTIF puesto que la lista ya está ordenada, pero no consigo que me funcione correctamente. Os lo explico mejor con el código a ver si alguien me puede ayudar.Saludos

Código: Seleccionar todo

      ' escribo los datos de un recordset en la hoja, columna B "categoria" columna C "cantidad"
       
      ' ordeno los datos en la hoja de mayor a menor por columa B y C
      
      ' hasta ahora todo perfecto
 
      ' Ahora con este loop lo que intento es seleccionar los 10 registros C superiores 
      
      ' de cada categoria  en B
 
' Creo el servicio

Set oFA = CreateObject("com.sun.star.ServiceManager")
Set oFuncAcc = oFA.createInstance("com.sun.star.sheet.FunctionAccess")

 lngFila = 2
 StartContentType = 2
 Set cCelda = oSheet.GetCellRangeByName("A1")

' recorro la lista hasta que encuentra un campo vacio (final de la lista)
  
  Do While StartContentType <> 0

' por cada fila compruebo que no este vacia y capto el dato

  Set oFilS = oSheet.GetCellRangeByName("B" & lngFila & "")
  StartContentType = oFilS.getType()
  sCelda = oFilS.GetString()

'Ahora viene el fallo no consigo que funcione la llamada a la función me da
' error argException en com.sun.lang ?

  'x = oFuncAcc.callFunction("COUNTIF", Array("B2:B" & lngFila & "", """ & sCelda & """))
  'x = oFuncAcc.callFunction("COUNTIF", Array(oFilS, sCelda))

' de momento lo he solucionado metiendo el string de la formula directamente en una celda
' y capturando el valor si es mayor de 10 elimino la fila

  cCelda.setFormula ("=COUNTIF(B2:B" & lngFila & "; """ & sCelda & """)")
  x = cCelda.getValue()

	If x > 10 Then
	Call oSheet.removeRange(oFilS.getRangeAddress, 3)
	Else
	lngFila = lngFila + 1
	End If

Loop

  ' pero esto es extremadamente lento sirve si tienes pocos registros pero si son miles tarda minutos. 
Última edición por mauricio el Mié Jun 03, 2015 6:09 pm, editado 2 veces en total.
Razón: Marcar resuelto correctamente
OpenOffice 4.1 en Windows 7
Avatar de Usuario
mauricio
Mensajes: 6092
Registrado: Sab Nov 22, 2008 5:36 am
Ubicación: CDMX
Contactar:

Re: Llamar función COUNTIF en CALC desde VBA

Mensaje por mauricio »

Si, los Do...While son extremadamente ineficientes...
siempre será mucho más rápido hacer operaciones usando cualquier motor de base de datos... ¿no puedes recuperar los datos ya como los quieres directamente de la base de datos?

Para el error callFunction, en mi experiencia y así sin ver, generalmente el error se debe a pasar mal los argumentos que requiere la función...

Saludos
______________________________________________
"Todo cuanto no podemos dar nos posee". - André Gide
LibreOffice 6.2 | ArchLinux | Gnome3
No respondo preguntas privadas, por favor, usa el foro
Avatar de Usuario
fornelasa
Mensajes: 3268
Registrado: Jue Feb 17, 2011 8:30 pm
Ubicación: Estado de México, México.

Re: Llamar función COUNTIF en CALC desde VBA

Mensaje por fornelasa »

La pregunta nos dice: "Llamar función COUNTIF en CALC desde VBA" y luego mas abajo decimos que si funciona en esta linea:

Código: Seleccionar todo

cCelda.setFormula ("=COUNTIF(B2:B" & lngFila & "; """ & sCelda & """)")
entonces la respuesta obvia es: tema resuelto porque si "funciona" el COUNTIF en CALC desde VB

¿Que diferencia hay entre?

Código: Seleccionar todo

'x = oFuncAcc.callFunction("COUNTIF", Array("B2:B" & lngFila & "", """ & sCelda & """))
y

Código: Seleccionar todo

cCelda.setFormula ("=COUNTIF(B2:B" & lngFila & "; """ & sCelda & """)")
¿Que la primera se almacena en una variable pero no funciona y la segunda se almacena en una celda y si funciona? ..... bien, ya sea "chana" o "juana" la formula funciona, entonces cual será el problema?

Creo que el problema lo tenemos en el borrado de filas por la lentitud del codigo y no en el COUNTIF, lo anterior nos llevaría a que el titulo de la pregunta no es correcto.

Saludos, Federico
lo 6.2.0 | aoo 4.1.6 | win 7/10
¡Un aplauso para todos los que luchan por proteger y promover la Web abierta!
cespyag
Mensajes: 5
Registrado: Mié May 27, 2015 6:18 pm

Re: Llamar función COUNTIF en CALC desde VBA

Mensaje por cespyag »

Hola gracias por contestar tan rápido.
Perdón si me expresado mal, de lo que me quejo es de la lentitud del código, no de que no se pueda hacer funcionar, creía que que guardar la variable directamente en memoria era más eficiente y rápido que ir guardando el string en una celda e ir leyéndolo cada vez; Para exportarlo a MS Excel lo tengo así y va bastante más rápido y pensé que si se puede hacer de esta otra manera sería asumible la velocidad obtenida.
Si alguien no puede darme una pista con el problema con los argumentos en la instrucción tendré que ,como bien dice Mauricio ,que ponerme a modificar la SLQ de la consulta que es ya de por si muy compleja y no tenia muchas ganas de tocarla (vago que es uno) y pretendia economizar código aprovechando lo que ya tenía.
Gracias a todos

PD Si no consigo solución la pondré como resuelto porque realmente se puede hacer y para listados cortos funciona perfectamente. Saludos
OpenOffice 4.1 en Windows 7
Avatar de Usuario
fornelasa
Mensajes: 3268
Registrado: Jue Feb 17, 2011 8:30 pm
Ubicación: Estado de México, México.

Re: Llamar función COUNTIF en CALC desde VBA

Mensaje por fornelasa »

Intenta así (en caso de que fuera la hoja indice 0 ThisComponent.Sheets(0), si no cambiala por lo que usas oSheet):

Código: Seleccionar todo

Sub Mainn        
    Set oFA = CreateObject("com.sun.star.ServiceManager")
    Set oFuncAcc = oFA.createInstance("com.sun.star.sheet.FunctionAccess")
    	lngFila = 2
    	StartContentType = 2
    Set cCelda = ThisComponent.Sheets(0).GetCellRangeByName("A1")       
      Do While StartContentType <> 0   
      Set oFilS = ThisComponent.Sheets(0).GetCellRangeByName("B" & lngFila & "")
      StartContentType = oFilS.getType()
      sCelda = oFilS.GetString()    
				rango = ThisComponent.Sheets(0).GetCellRangeByName("B2:B" & lngFila)
      			x = oFuncAcc.callFunction("COUNTIF", Array(rango, sCelda)     
       If x > 10 Then
       Call  ThisComponent.Sheets(0).removeRange(oFilS.getRangeAddress, 3)
       Else
       lngFila = lngFila + 1
       End If
    Loop     
End Sub
Saludos, Federico.
lo 6.2.0 | aoo 4.1.6 | win 7/10
¡Un aplauso para todos los que luchan por proteger y promover la Web abierta!
cespyag
Mensajes: 5
Registrado: Mié May 27, 2015 6:18 pm

Re: Llamar función COUNTIF en CALC desde VBA

Mensaje por cespyag »

Ok Gracias, mañana lunes le doy una vuelta,ahora en casa no tengo el código.

Uso el oSheet porque este bucle esta dentro de otro que desde otro recordset me genera una hoja nueva por cada centro de trabajo, el índice va variando y el objeto ThisComponent, como tal, no funciona en VBA, pero lo repasaré a ver si por ahí está el fallo :super: Gracias por tu interés.

Saludos buen fin de semana
OpenOffice 4.1 en Windows 7
Avatar de Usuario
mauricio
Mensajes: 6092
Registrado: Sab Nov 22, 2008 5:36 am
Ubicación: CDMX
Contactar:

Re: Llamar función COUNTIF en CALC desde VBA

Mensaje por mauricio »

cespyag escribió:el objeto ThisComponent, como tal, no funciona en VBA
Claro, VBA no conoce a los objetos de OOBasic, pero se los puedes presentar...

Código: Seleccionar todo

Set oServiceManager = CreateObject("com.sun.star.ServiceManager")
Set oDesktop = oServiceManager.createInstance("com.sun.star.frame.Desktop")
Set oDocument = oDesktop.loadComponentFromURL("private:factory/scalc", "_blank", 0, args)
Ahora oDcument puedes usarlo como si fuera ThisComponent
______________________________________________
"Todo cuanto no podemos dar nos posee". - André Gide
LibreOffice 6.2 | ArchLinux | Gnome3
No respondo preguntas privadas, por favor, usa el foro
cespyag
Mensajes: 5
Registrado: Mié May 27, 2015 6:18 pm

Re: Llamar función COUNTIF en CALC desde VBA

Mensaje por cespyag »

Buenos dias
Si si claro así lo uso

Código: Seleccionar todo

Set oManager = CreateObject("com.sun.star.ServiceManager")
 Set oDesktop = oManager.createInstance("com.sun.star.frame.Desktop")
 sURL = "private:factory/scalc"
 Set oDoc = oDesktop.loadComponentFromURL(sURL, "_blank", 0, noArgs())
Set ThisCom = oDesktop.getCurrentComponent()
y el obj oSheet que uso en el codigo es

Código: Seleccionar todo

Set oSheet = oDoc.GetSheets().GetByIndex(oSheetEnum)
He probado lo que recomienda Federico pero no me va, no se si hay algún bug en la utilizacion del COUNTIF desde Access porque no funciona ni metiendo las variables directamente con distindos formatos

probando con otras funciones p.e "SUM" si lo pilla.

Ayer me cambiaron la máquina por un i5 y viva la diferencia ahora va bastante más rápido.
Así que si no hay nadie que se le ocurra nada más y como bien dice Federico funciona ya sea "chana" o "juana" lo daré por resuelto
OpenOffice 4.1 en Windows 7
Avatar de Usuario
mauricio
Mensajes: 6092
Registrado: Sab Nov 22, 2008 5:36 am
Ubicación: CDMX
Contactar:

Re: Llamar función COUNTIF en CALC desde VBA

Mensaje por mauricio »

No, no hay ningún bug en COUNTIF, las variables se deben de pasar con el formato correcto, con esto funcionará, si no, no funcionará...
______________________________________________
"Todo cuanto no podemos dar nos posee". - André Gide
LibreOffice 6.2 | ArchLinux | Gnome3
No respondo preguntas privadas, por favor, usa el foro
Avatar de Usuario
fornelasa
Mensajes: 3268
Registrado: Jue Feb 17, 2011 8:30 pm
Ubicación: Estado de México, México.

Re: Llamar función COUNTIF en CALC desde VBA

Mensaje por fornelasa »

Así que si no hay nadie que se le ocurra nada más y como bien dice Federico funciona ya sea "chana" o "juana" lo daré por resuelto
Me parece que si, por la maquina nueva y la macro funcionando con la segunda opción del COUNTIF entonces éste debería ser un tema resuelto.

Lo más curioso es que dices que si lo "pilla" con SUM (cosa que no creo), no al menos de manera "normal", ..... pero esa es otra historia.

Si, hay otros caminos pero no tiene caso caminarlos porque precisamente la macro funciona.

Saludos, Federico.
lo 6.2.0 | aoo 4.1.6 | win 7/10
¡Un aplauso para todos los que luchan por proteger y promover la Web abierta!
cespyag
Mensajes: 5
Registrado: Mié May 27, 2015 6:18 pm

Re:(RESUELTO) Llamar función COUNTIF en CALC desde VBA

Mensaje por cespyag »

Buenos dias
Cuando digo que lo "pilla"(perdón por la expresión si en algún sitio significa otra cosa)quiero de decir que si le paso un par de argumentos a esta función funciona perfectamente en el código

Código: Seleccionar todo

a = oFuncAcc.callFunction("SUM", Array(StartContentType, lngFila))


sin embargo si pongo la función COUNTIF directa no consigo averiguar que falla en los argumentos

Código: Seleccionar todo

a= oFuncAcc.callFunction("COUNTIF", Array("B2:B3", "HOLA"))
No obstante como ya dije doy el tema por resuelto ya que se puede hacer y funciona

Muchas gracias Federico, Mauricio por vuestro tiempo y ayuda :bravo:

PD: pero lo seguiré intentando " Caminante no hay camino se hace camino al andar" A.M.
OpenOffice 4.1 en Windows 7
Avatar de Usuario
fornelasa
Mensajes: 3268
Registrado: Jue Feb 17, 2011 8:30 pm
Ubicación: Estado de México, México.

Re: (RESUELTO)Llamar función COUNTIF en CALC desde VBA

Mensaje por fornelasa »

Si, si se puede ..... pero hasta donde yo sé, es imposible de una manera "normal" ..... ¿a que le llamo "normal"? .....
Estamos hablando de VBA y de una macro que se "corre" desde un modulo de Access, bajo éste contexto lo "normal" sería construir la formula así:

Código: Seleccionar todo

x = oFuncAcc.callFunction("COUNTIF", Array(rango, criterios)  
y lo anterior (que sería lo normal) no funciona llamando la macro desde VBA-Access ..... obvio en Cal modulo macros funciona correctamente.
Se hace camino al andar
¡perfecto! ojala despues podamos descubrir como lo pudieramos hacer normalmente ..... pero es que no se puede, no se puede ..... de "forma normal" :oops:
Saludos, Federico.
lo 6.2.0 | aoo 4.1.6 | win 7/10
¡Un aplauso para todos los que luchan por proteger y promover la Web abierta!
Responder