jueves, 15 de septiembre de 2011

3 de 3 y con 3 diferentes

A pesar de la frustracion de no haber podido estar en el #GX21 ayer fue un dia interesante a nivel de logros personales. 3 de 3 y con 3 versiones distintas. A la mañana con la version 8, a la tarde con la version 9  y esta noche/madrugada con a Ev1.

El primer logro fue mas bien un tema de encontrar el problema. Un reporte que antes funcionaba bien y "de repente" dejo de funcionar. Detectamos algunos problemas con los parametros, los corregimos y nada... seguia igual de pesado y sin terminar. Entonces con la ayuda del jdbc.log y mucha paciencia (se trataba de un proceso con muchos registros, mas de seis mil) pudimos ubicar unos 16 registros que presentaban anomalias en la confirmación de un atributo codigo que inducia a un bucle infinito. Corregidos los datos, se soluciono el problema. Edgar 1 - Problemas 0.

El segundo desafio se presento a la tarde en otro cliente. Con la 9. En un webpanel (heredado) en el que se actualizaban direcciones de clientes mediante BC, habia que implementar una alerta del tipo "Esta Ud. seguro de modificar los datos?" al momento de hacer clic en el botón correspondiente. Hasta ahi no habia problemas ya que con el metodo .jsevent(...) se logra eso. Lo que realmente fue un desafio es hacer que el mensaje incluya cuales direcciones habian cambiado (habia tipos de direcciones en el form: Particular, Laboral y Alternativa). La solucion vino por el lado de javascript:
  1. Cree un textblock con formato html al final del webform
  2. Le asocie un codigo html que incluia el script que realizaba la validacion sobre tres variables recibidas (una para cada tipo de direccion) y retornaba un string con la lista de direcciones que habian cambiado.
  3. En el jsevent del boton "Enter" puse algo asi como button1.jsevent(("onclick","confirm(validardirecciones("+&Dirpart.InternalName+".value, "+&Dirlab.InternalName+".value, "+&Diralt.InernalName+".value)"). Es interesante mencionar el uso de la propiedad InernalName en este caso.
Con estos cambios conseguimos hacer que el usuario reciba lo que estaba pidiendo. Edgar 2 - Problemas 0.

El ultimo problema se me planteo en casa con el trabajo de mi esposa. Genexus Ev1 - K2B Tools Patterns.

Dadas dos transacciones "Expedientes" y "Movimientos de Expedientes"  se planteó la necesidad de que los filtros del wwexpedientes incluyan atributos de movimientos. Es decir que se pueda filtrar por ej. por la fecha del movimiento y ver solo los expedientes que se movieron en una fecha dada. Esto se solucionaria incluyendo el atributo fecha de movimiento en la lista de atributos del nodo WorkWith Expedientes, pero si un expediente tuvo mas de un movimiento en el mismo dia, saldria repetido y eso no era lo que se esperaba. Luego de buscar muchas alternativas (es una lastima que en las grillas no se pueda incluir la clausula distinct o que se pueda hacer uso del operador in dataselector) se me ocurrio hacer una prueba: Incluir un for each el evento load de la grilla (algo que muy acertadamente nos disponibiliza el k2b tools pattern). Con esto se fuerza el corte de control y se eliminan los registros duplicados. Edgar 3 - Problemas 0.

3 de 3 y con 3 diferentes.

lunes, 29 de noviembre de 2010

BC y nulos

Como parte de un trabajo de migracion de datos a partir de una planilla excel en la que podrian no venir todos los datos de la manera esperada, me propuse realizar la importacion  de las filas via BC.

Para ello todos los atributos de la transaccion afectada (menos la PK) fueron seteadas con nullable = yes.

Luego en el proceso una vez obtenido el emparejamiento de los atributos y las columnas del tipo Att = col, almacenados en un SDT para el proposito, realice la importacion con los siguientes pasos:

  1. &Xml = &Transaction1.toXml() // &xml (longvarchar) y &Transaction1 (BC)
  2. Por cada atributo que exista en el par Atributo, Columna
    • &Buscar = '<'+&Atributo+'/>' // buscamos el atributo vacio (los numericos tienen otro tratamiento)
    • &Reemplazar = '<'+&Atributo+'>'+&Dato+'</'+&Atributo+'>'
    • &Xml = &Xml.Replace(&Buscar,&Reemplazar)
  3. &Transaction1.FromXml(&Xml)
  4. &Transaction1.Save()
  5. Commit
Ahora bien, el problema se daba con las claves extranjeras que no estaban referenciadas, provocaba violacion de la integridad referencial.

A pesar de haber modificado las propiedades Empty As Null en la transaccion para cada atributo, me seguia rebotando.

Finalmente encontre una documentacion que hablaba que esa propiedad no funcionaba para BC por lo que habria que poner una regla del tipo ClaveExt.SetNull() if ClaveExt.isEmpty(); en la transaccion referenciada por el BC.

Con eso solucionamos el problema y pudimos migrar los datos correctamente (los que pudimos, el resto quedo en null).

En otra entrada voy a dar mas detalles de la solucion completa y presentar el asistente que creamos para la migracion que bien puede ser objeto de  un pattern que proximamente estaremos encarando.

viernes, 12 de noviembre de 2010

Un bug viejo, descubierto recien ahora

Hace poco me encontre con un problema dificil de explicar al cliente. Una Kb que habia desarrollado desde cero en la version 9.0 hace casi dos años luego paso a la version X y ultimamente en la Ev1, demoraba mucho mas de lo aceptable en cada especificacion y generacion.

Si bien los objetos en los que demoraba tampoco eran comunes, unas transacciones con muchas subordinaciones (en algunos casos hasta 19, y hasta 3 niveles) y muchas formulas (varios sum verticales sobre las subordinadas y varias horizontales sobre estas sum). Algunas de estas transacciones llevaban mas de 20 minutos solo de especificacion. En toda la KB habia mas de 20 de estas transacciones (10 con interface y 10 BC), lo que nos llevaba mas de 9 horas para un build all o un build normal ya que siempre que se tocaba alguna de estas transacciones las especificaba todas.

Despues de muchas dudas y bajo mucha presion decidi comentar el problema en el foro de Artech y confieso sin muchas esperanzas de que alguien aporte algo.

Mi sopresa fue que la misma gente de Artech se intereso en el problema y siguiendo por fuera del foro acompañaron la solucion (que vino por corregir el especificador y facilitarnos un build que arreglaba el problema).

Ahora me arrepiento de no haber informado antes del problema.