vtools exportar Excel rejilla en separador

Hola:

Cuando utilizar vTools para exportar a Excel la rejilla por defecto selecciona la rejilla de la pestaña.
Qué habría que cambiar dentro del .js para que capturara la rejilla que hay en el separador que está dentro del formulario actual para que genere con los datos de la rejilla del separador.

Saludos.

Ricardo Patón

@rpaton

Desde las rejillas situadas dentro de un formulario que pertenecen a un separador de formularios también se puede usar vTools, lo que ocurre es que el formulario principal debe estar en modo TAB y no en modo diálogo. Compruébalo asignando el menú de contexto LST_TOO@vTools_app como menú de contexto de la rejilla que tienes en el subformulario y disparando el formulario principal en modo TAB.

Desconozco si se puede cambiar el comportamiento del fichero .JS que pretendes modificar.

Hola:

 Gracias Antonio por la aclaración.

 Voy a mirar a ver si encuentro alguna forma de exportar desde rejillas dentro de un separador.

 Saludos.

 Ricardo Patón

Hola Ricardo.

Antonio te ha dicho que Sí que funciona el exportador Excel de vTools para Rejillas dentro de Separadores. La única condición es que el formulario principal se muestre en modo Vista.

Para formularios modales o en modo Diálogo no nos sirve. Tendríamos que adaptar la línea “var rejilla = getActiveListControl();” del script export_rejilla_excel.js.

Habría que ejecutar desde un Manejador del subformulario la siguiente línea:
var rejilla = theRoot.dataView().mainForm().dataViewActive()

Si tengo un rato lo miro.

Saludos
Paco Satué

Hola Paco:

Gracias por contestar.

He probado a cambiarlo donde dices y no lo genera.
Tampoco genera en la rejilla principal al hacer el cambio dando un mensaje de error indicando que ‘theRoot.dataView()’ [null] is not an object.

Si encuentras alguna forma te lo agradecería ya que para editar los registros de una rejilla presento un formulario a pantalla completa. No dejo opción de varias pestañas para no confundir mucho a los usuarios que les gusta centrarse en una sola pantalla para meter los datos.

Saludos.

Ricardo Patón

Vaya tela, no me había dado cuenta de que no funciona ni los exportar ni el fitrar ni nada en modo dialogo y lo acabo de implementar en toda la aplicación.

¿Alguien lo ha solucionado?, porque si no va en modal me toca quitar vTools y agregar manejadores en TODAS las rejillas para estas cosas.

Hola info.

Dejamos claro que tal como está escrito vTools solo sirve para Rejillas en Ventanas Modo Vista o no modales.
Si queremos generalizar el uso de la Exportación Excel a cualquier Rejilla no tenemos más remedio que ejecutar la Exportación desde un Manejador de evento de la propia Rejilla.

Tendrás que adaptar todas las Rejillas de tu Solución de la siguiente forma:

  • Copia el Script export_rejilla_excel.js a un proyecto de tu solucion y lo llamas por ejemplo export_rejilla_modal_excel.js.
    Copiando el Script a tu solución no tendrás problemas cuando Velneo liber una nueva versión de vTools.
  • Cambia la línea 14 que pone “var rejilla = getActiveListControl();” por las siguientes líneas:

var rejilla = null
try {
   // theSender contiene el objeto que ha generado el Evento Activar Señal
   rejilla = theSender
} catch(err) {
   alert(err);
}
if (rejilla!=null  ....
   ....

  • La Acción EXP_XLS de vTools la sustituyes por otra Acción ACC_EXP_XLS_MODAL cuyo comando es “Disparar señal”
    Esta Acción ACC_EXP_XLS_MODAL irá en el Menú contextual de las Rejillas
  • En cada Rejilla crea un Manejador de evento EXPORTAR_EXCEL_JS con la señal “Acción disparada” desde ACC_EXP_XLS_MODAL
  • El Manejador EXPORTAR_EXCEL_JS contiene únicamente la línea:

#include "<<id_proyecto.vca>>/Excel_exportar/export_rejilla_modal_excel.js"

Como ves el cambio no es para tanto.
Muchos seguro que es la primera vez que ven el objeto theSender, éste representa al objeto que ha generado el Evento del manejador, en este caso la Rejilla.

Es lo mismo que si el Manejador EXPORTAR_EXCEL_JS lo cambiamos por:


#include "<<id_proyecto.vca>>/Excel_exportar/export_rejilla_modal_excel.js"
exportarExcel(theRoot.dataView())

y en el Script export_rejilla_excel.js cambiamos la línea 14 por:


function exportarExcel(rejilla) {
   // La función recibe como parámetro el control Rejilla sobre el que operamos
   if (rejilla!=null  ....
   ....
}

Se puede concluir que si Velneo nativo fuera capaz de pasar variables tipo Objeto (controles en ejecución) entre manejadores, funciones y procesos, las posibilidades se ampliarían bastante. De momento el API está para eso.

Saludos
Paco Satué

Muchas Gracias Paco.

Estaba haciéndolo ya de la segunda forma que comentas, porque ciertamente no sabía que existía el objeto theSender.

Un manejador para cada exportación, otro para filtrar…

Me duele mucho mucho la mano de hacer Ctrl+V.

Al life is soft voy a ir con el brazo en cabestrillo.

Lo que no consigo es que la función de filtrar funcione en rejillas en formularios modales/dialogo.

El problema es que theSender dentro del formulario de filtrado apunta al propio formulario de filtrado (ya que los eventos post-init etc se disparan con señales del propio form y no de la rejilla que los invocó).

No se me ocurre cómo pasarle al formulario de filtrado el objeto rejilla que tiene que usar.

Supongo que lo mismo pasará con las funciones de combinar, rebuscar, etc…, si al maestro se le ocurre algo le invito a algo en el LIS, jejejeje.

Hola info.

La verdad es que a este paso vamos a destrozar las vTools. De todas formas son una buena fuente para aprender el API de Velneo. He adaptado la función de Filtrado de Listas que creo que es la más interesante, lo de Rebuscar y Combinar lo dejamos para otro día.

Tendrás que adaptar todas las Rejillas de tu Solución de la siguiente forma:

  • Copia el formulario FLT a tu proyecto o heredado. Lo llamamos FRM_SIS_LISTAS_FILTRAR.
    Este es el único objeto de vTools que copiamos

  • Ya dijimos que en Velneo no podemos pasar objetos entre los controles en ejecución. Pero ahora disponemos de la posibilidad de serializar una Lista de registros (Lista Virtual) y pasarla como un String. Este String contiene ademas información de la tabla a la que pertenecen los registros. Perfecto, ya podemos usar formularios sin origen con toda la libertad que da eso.

Vamos pues a destrozar el formulario de filtrado de vTools

  • Añadimos 2 Variables locales: _CLISTA_VIRTUAL y _NPOS_LISTA
   _CLISTA_VIRTUAL - Recoge la Lista Virtual
   _NPOS_LISTA - Recoge la posición del registro seleccionado en la Rejilla
  • Código de POST_INI
    Sustituímos las líneas 12 a 17 por:

///////////////// MODIFICADO - 10/03/2015 - Adaptado a Rejillas en Formularios modales
// Obtenemos el control activo que tenga una lista
// var control = getActiveListControl();
// if (control && control.objectInfo().inputType() == VObjectInfo.IOList) {
// Obtenemos la lista del control
// var lista = new VRegisterList(control.root());
// control.getList(lista);

// Recibimos una Lista Virtual codificada como un String base64 
var lista = new VRegisterList(theRoot)
var oByteArrayDestino = new VByteArray()
var oTexto = new VByteArray()
// Cargamos la Lista en Base64
oTexto.setText(theRoot.varToString("_CLISTA_VIRTUAL"))
// Obtenemos el ByteArray original de la Lista Virtual
oByteArrayDestino.fromBase64(oTexto)
// Obtenemos la Lista original de la Rejilla con tabla y todo, ¡¡ NO, no es magia !!
if (lista.loadFromData(oByteArrayDestino)) {
////////////////////////////////

  • Código de BTN_FLT
    Sustituímos las líneas 13 a 18 por:

////////////// MODIFICADO - 10/03/2015 - Adaptado a Rejillas en Formularios modales
// var control = getActiveListControl();
// var lista = new VRegisterList(control.root());
// control.getList(lista); 
// var listaDestino = new VRegisterList(control.root());
// control.getList(listaDestino);
// listaDestino.clear();
var lista = new VRegisterList(theRoot)
var listaDestino = new VRegisterList(theRoot)
var oByteArrayDestino = new VByteArray();
var oTexto = new VByteArray();
// Cargamos la Lista en Base64
oTexto.setText(theRoot.varToString("_CLISTA_VIRTUAL"))
// Obtenemos el ByteArray original de la Lista Virtual
oByteArrayDestino.fromBase64(oTexto)
lista.loadFromData(oByteArrayDestino)
// Preparamos una Lista vacía para volcar el filtrado
listaDestino.loadFromData(oByteArrayDestino)
listaDestino.clear()
//////////////////////////

Sustituímos la línea 75 por:


///////////// MODIFICADO - 10/03/2015 - Adaptado a Rejillas en Formularios modales
// registro = lista.readAt(control.currentSelect())
registro = lista.readAt(theRoot.varToInt("_NPOS_LISTA"))
//////////////////////////

Sustituímos las líneas 189 a 195 por:


///////////// MODIFICADO - 10/03/2015 - Adaptado a Rejillas en Formularios modales
// Si ha marcado usar otra vista, abrimos otra vista del mismo tipo que la lista de origen
// if (theRoot.dataView().control("CMP_ABRIR_OTRA_VISTA").checked)
// Si el resultado va en una vista nueva, utilizamos la misma lista de origen
// theMainWindow.addDataView(control.objectInfo().type(), control.objectInfo().idRef(), listaDestino)
// else
// Usamos la misma vista para la lista resultante
// control.setList(listaDestino);
// Devolvemos la Lista Virtual filtrada
var oByteArray = listaDestino.saveToData()
var oBase64 = oByteArray.toBase64()
theRoot.setVar("_CLISTA_VIRTUAL",oBase64.toLatin1String())
////////////////////////////////

  • Creamos un script JS llamado ListasFiltrar.js

var oRejilla = null
try {
	// theSender contiene el objeto que ha generado el Evento Activar Señal
	oRejilla = theSender
} catch(err) {
	alert(err)
}
if (oRejilla!=null) {
   // Pasamos la Lista al formulario de Filtrado como una Lista Virtual
   var oLista = new VRegisterList(theRoot)
   // Volcamos en oLista los registros de la Rejilla
   oRejilla.getList(oLista)
   // Convertimos la Lista Virtual a una cadena de texto codificada como Base64
   var oByteArray = oLista.saveToData()
   var oBase64 = oByteArray.toBase64()
   var cListaVirtual = oBase64.toLatin1String()
   // Instanciamos y ejecutamos el formulario de filtrado
   var oForm = new VDataViewDialog(theRoot)
   oForm.setDataView(VObjectInfo.TypeForm, "0PS__Sistema_app/FRM_SIS_LISTAS_FILTRAR")
   // Le pasamos la Lista Virtual
   oForm.setVar("_CLISTA_VIRTUAL", cListaVirtual)
   // Le pasamos el registro seleccionado en la Rejilla
   oForm.setVar("_NPOS_LISTA", oRejilla.currentSelect())
   // Mostramos el formulario
   if(oForm.exec()) {
      // Leemos el valor de la Lista Virtual modificada
      cListaVirtual = oForm.varToString("_CLISTA_VIRTUAL")
      // Cargamos la Lista en Base64
      var oByteArrayDestino = new VByteArray()
      var oTexto = new VByteArray()
      oTexto.setText(cListaVirtual)
      // Obtenemos el ByteArray original de la Lista Virtual
      oByteArrayDestino.fromBase64(oTexto)
      // Recargamos la Rejilla con los registros filtrados
      if (oLista.loadFromData(oByteArrayDestino)) {
         oRejilla.setList(oLista)
      }
   }
}

– La Acción FLT de vTools la sustituyes por otra Acción ACC_FILTRAR_MODAL cuyo comando es “Disparar señal”
Esta Acción ACC_FILTRAR_MODAL irá en el Menú contextual de las Rejillas
– En cada Rejilla crea un Manejador de evento FILTRAR_LISTA_JS con la señal “Acción disparada” desde ACC_FILTRAR_MODAL
– El Manejador FILTRAR_LISTA_JS contiene únicamente la línea:


#include "<<id_proyecto.vca>>/Listas_gestion/ListasFiltrar.js"

Y eso es todo.
Me imagino que entenderás que este código solo lo publico como un ejercicio para aprender el API de Velneo. No está probado en producción ni mucho menos depurado. Úsalo con todas las precauciones lógicas.
Lo más adecuado es rehacer esta parte de vTools desde cero.

Espero que haya buenas tapas y cerveza en el bar de la UNI

Saludos
Paco Satué

[OFF-TOPIC]
Y si se suben todo este código a un github para gestionarlo mejor. Incluso podría ser el propio Velneo quien lo haga y así la comunidad puede apotar cambios y ellos mismo sacan las versiones con los pullrequest.

Dios mío que máquina, había empezado ha hacerlo con tablas temporales destrozando también el form de filtrado, pero esta solución le da mil vueltas.

Ahora lo probaré.

Y sí, esto debería estar de base, porque que esas acciones no funcionen en modales hace que se limite mucho su uso, queda realmente mal que el user pulse filtrar o exportar sobre una rejilla y haga la operación en la rejilla de un formulario que queda por debajo…

Y como esto muchas cosas que la comunidad en general (y Paco en particular, jejejeje) podrían ayudar a mejorar.

Por fin pude implementrar el filtrado de Paco.

Como era de esperar funciona perfecto a la primera y super rápido.

El método lista.loadFromData es símplemente genial, en estos momentos, tengo scripts js que son únicos, pero he tenido que crear un proceso para cada tabla, símplemente porque necesitaba el origen de entrada del proceso.

De la forma que aquí se explica, ahora sí se pueden hacer scripts completamente genéricos que se traspasan registros entre procesos, formularios etc…, me voy a ahorrar unos cuantos cientos de procesos y un montón de cestas porque antes tenía que hacer un circo para traspasar registros.

Por ésto se necesita una buena documentación y ejemplos de calidad, esos métodos js existen desde hace 6 meses, pero yo no sabía cómo sacarle partido, porque no había donde mirar ejemplos.

Muchas gracias.