Búsqueda eficiente en Control "matrix"

Búsqueda eficiente en Control

Entre mis pruebas usando el SDK de SAP Business One, he estado intentando averiguar la forma más eficiente para buscar y seleccionar dentro de un control “matrix” (cargado usando dbdatasources) una fila que cumple un criterio específico.

La idea era replicar el formulario de Listas de precios del estándar añadiendo dos columnas para vincular a los artículos, además de los precios, dos descuentos que se usarán a nivel de línea en los documentos.

Es decir, tenemos una matriz con información de precios de artículos (replicando el formulario del estándar para las listas de precios), tenemos un edittext para hacer búsquedas en la matriz (al igual que el estándar), introducimos un código de artículo en el edittext y pulsamos en un botón de buscar para realizar una búsqueda del código de artículo en la matriz de forma eficiente.

En mi caso estaba tratando con cerca de 2400 registros que se cargan velozmente usando el método del control Matrix: ”loadfromdatasource”. A continuación expongo mis experiencias:

  • El óptimo sería usar el dbdatasource de la columna por la que queremos buscar para hacer un query(conditions) con el valor que tenemos y seleccionar en la matriz la fila que se corresponde con el valor seleccionado en el dbdatasource. Pude comprobar que el query(conditions) tarda un tiempo despreciable para encontrar cuál es la línea del dbdatasource adecuada.

    El problema es que una vez encontrada la línea del dbdatasource que se está buscando no hay forma de saber con qué línea del control Matrix se corresponde. Por lo tanto, para poder saber la línea de la matrix que debía marcar, me dispuse a cargar en el dbdatasource la información de índice de cada fila. Esto lo hice de dos maneras:
    • Con un datatable de los de ado .net: Tardaba 44 segundos en cargar el formulario después de haber ejecutado el loadfromdatasource.

    • Usar arraylist cargado en el momento del form también retrasa la carga demasiado (en comparación con loadfromdatasource):

 

Código usado:

Form f = kernel.cargarForm("XML\\ITOP_PRECIOS.xml", "ITOP_PRECIOS" + FormUID);
   inicializarFormItopDtos(f, lista);
   DateTime antes = DateTime.Now;
   ArrayList listaAux = new ArrayList();
   for (int i = 0; i < f.DataSources.DBDataSources.Item("ITM1").Size; i++) {
      listaAux.Add(i);
   }
   TimeSpan tarda = DateTime.Now - antes;
   kernel.Application.MessageBox("Tarda: " + tarda.TotalSeconds.ToString(), 0, "", "", "");

Resultado carga form rellenando arraylist:

Rellenando un userdatasoure y usando mtx.addRow() en lugar de loadfromdatasource: Tardaba 74 segundos en cargar el formulario.

  • Después de los resultados anteriores (Carga de formulario demasiado lenta) me planteé desechar la búsqueda con Query(conditions), por lo que llegué a estas dos alternativas:
    • Búsqueda por ui api en la matrix…. Opción demasiado lenta.
    • Búsqueda en los datasources: Lo mejor que he encontrado. Haciendo una búsqueda secuencial en la columna que corresponda del dabdatasource adecuado se obtienen unos resultados muy buenos con los 2400 registros:

      • Último registro (empieza por f)
      • Registro no existente
      • Registro intermedio.

El código usado es el siguiente:

private void seleccionarFila(Matrix mtx, DBDataSource dbds, string columna, string codigoABuscar, string celdaFocoDestino) {
   int i = 0;
   DateTime antes = DateTime.Now;
   while ((i < dbds.Size) && (!dbds.GetValue(columna, i).Trim().StartsWith(codigoABuscar)))
   i++;
   if (i < dbds.Size) {
      mtx.SelectRow(i + 1, true, false);
      mtx.Columns.Item(celdaFocoDestino).Cells.Item(i + 1).Click(BoCellClickType.ct_Regular, 0);
   }
   else
   kernel.Application.MessageBox("Código: " + codigoABuscar + " no encontrado", 1, "", "", "");
   TimeSpan tarda = DateTime.Now - antes;
   kernel.Application.MessageBox("Tarda: " + tarda.TotalSeconds.ToString(), 0, "", "", "");
}

 

Sobre el Autor

Miguel Fernandez Cejas

Miguel Fernandez Cejas

Director General. 

Socio fundador de Itop, empresa de implantación de soluciones tecnológicas, factoría de software y formación online. Ingeniero Informático con cursos de postgrado en áreas tan diversas como la inteligencia artificial, la gestión de empresas o la calidad. Más de 25 años de experiencia en el mundo de las Tecnologías de la Información trabajando para distintas empresas nacionales e internacionales.

Su pasión por la tecnología unida a su variada experiencia, le impulsa a desarrollar distintos proyectos empresariales donde aplica las nuevas tecnologías al turismo, la sociología, el marketing o la formación.

Actualmente trabaja en temas relacionados con aplicaciones de gestión, Business Intelligence, Big Data, Mobile/Apps e Internet de las Cosas

  • Esta dirección de correo electrónico está siendo protegida contra los robots de spam. Necesita tener JavaScript habilitado para poder verlo.

Deja un comentario

Estás comentando como invitado.

¡Suscríbete a nuestra newsletter!