¿Errores internos en Dataports? Pues vayamos a ciegas!

Últimamente parece que me caen expedientes X a diario. Hoy he descubierto que es posible hacer el dataport más tonto del mundo para exportar el contenido de una tabla y (sí) puedes morir en el intento:

El tema es que he creado un dataport con un dataitem de una tabla no demasiado grande (sin demasiados campos ni demasiados registros). En la pantalla de dataport fields he añadido todos los campos de la tabla. Ejecuto la exportación de los datos y me encuentro con esto:

La longitud del origen excede del tamaño del búfer de destino. Error raro y ceño fruncido. Lo había visto otras veces al trabajar con XML cuando todavía no existían los XMLPorts, pero nunca en un dataport. Lo primero que he pensado es que quizás había información en algún campo que interfería de alguna forma extraña con el dataport. Así que he quitado todos los campos de la sección dataport fields y he vuelto a ejecutar. El resultado: El mismo! 🙁

Como me estaba empezando a impacientar, he cambiado la tabla y la he cambiado por un entero. Internamente recorría los registros guardando los campos en las variables. A partir de ahí ningún problema. He conseguido exportar los datos sin problemas sin saber cual era el origen del problema.

Al crear otro dataport para importar estos datos en otra base de datos he vuelto a intentar utilizar la tabla destino asignando los campos en la sección dataport fields. Mi gran sorpresa ha sido ver una especie de error de sobrepasamiento que decía que no podía insertar la cadena en un text de 80. Lo más asombroso de todo es que en esta tabla no existe ningún campo de esa longitud y en el dataport tampoco existe ningúna variable. ¿De que se estaba quejando NAV?

La solución: He desactivado la propiedad ShowStatus y todo ha ido como la seda. ¿Que significa esto? Pues significa que en la ventana de proceso hay una barra de proceso que se basa en las líneas que tiene el fichero y luego tiene un campo de nombre registro que muestra los valores que conforman la clave. Es una pena que los boys de NAV no hayan tenido en cuenta que los valores que componen una clave pueden ocupar concatenados más de 80 caracteres!

Así que ya sabéis, si vais a hacer dataports que ataquen a tablas con muchos campos en la clave, desactivad ShowStatus o id tirando el peine a la basura.

Registrar asientos contables y tener el control

En alguna ocasión, es probable que hayamos tenido que programar un proceso que registre movimientos contables a medida que crea los registros en la línea de diario general. Si intentamos ver cómo lo hace NAV dentro de sus procesos estándar, vemos que existen 3 codeunits que intervienen en el registro de las líneas que hay un diario general (tabla 81):

  • Codeunit 11 – Gen. Jnl.-Check Line: Se utiliza para comprobar si la línea del diario es correcta.
  • Codeunit 12 – Gen. Jnl.-Post Line: Se utiliza para registrar una sola línea del diario.
  • Codeunit 13 – Gen. Jnl.-Post Batch: Se utiliza para registrar una sección entera del diario.

La madre del cordero está en la codeunit 12. Esta codeunit es llamada por la codeunit 13 cada vez que hay que registrar una línea y, a su vez utiliza la codeunit 11 para validar que la línea es correcta. Entonces ¿por que no usar siempre la codeunit 13? Sencillo, si utilizamos la codeunit 12 seremos nosotros los que decidiremos cuando guardamos los datos. La codeunit 13 tiene varios COMMIT, pero la codeunit 12 no tiene ninguno y la codeunit 11 tampoco.

Esto significa que yo puedo ir creando líneas en el diario general y mandarlas a registrar sin más. Al no utilizar la función COMMIT, el control de la función CONSISTENT no se ejecuta y puedo tener asientos “temporalmente” descuadrados. Yo, como programador, puedo decidir cuando empieza y cuando acaba el asiento contable y el único problema que puedo tener es que no haya controlado los registros lo suficiente y al acabar el proceso o al pasar por encima de un COMMIT reciba mensaje de CONSISTENT.

Es probable que algunos nunca se hayan encontrado con un error de CONSISTENT. Quizás los que vivimos el cambio de moneda allá por el 2000 no acordamos de alguno que nos diera dolores de cabeza. Si no estoy equivocado, sólo se utiliza en un par de puntos en todo NAV.

Asignación de credenciales para acceder a servicios web

Hace un par de semanas tuve un pequeño problema cuando intentaba acceder a un servicio web publicado en NAV. Disponía de mis desarrollos en asp.net en una máquina virtual con un dominio distinto al servidor donde se encontraba NAV. Por lo tanto, tenía que indicarle de alguna manera el usuario, password y dominio que tenía que utilizar la aplicación web para conectarse. En varios sitios encontré que había que utilizar la siguiente linea de código antes de hacer la llamada a la función del servicio web:

someService.Credentials = new NetworkCredential(“user”, “password”, “domain”);

Hay que recalcar que el último parámetro es optativo pues no es necesario indicarlo cuando el servidor se ubique en el mismo dominio. En mi caso, por encontrarme en un dominio distinto, lo indiqué.

Bien, la aplicación web se conectaba sin problemas y llegados a ese punto me olvidé del tema de las credenciales. Cuando la aplicación web estaba terminada, la publiqué en el servidor definitivo que sí que se encontraba en el mismo dominio y mi sorpresa fue ver que no había forma humana de que funcionara. Constantemente obtenía un error 401 – No autorizado.

La solución: la verdad es que hice bastantes pruebas pero creo que lo hizo que funcionara fue quitarle el parámetro del dominio a la función que otorga las credenciales. A mi entender, no tiene mucho sentido que un método de autenticación falle cuando se le proporciona mas información de la que necesita. En todo caso debería ignoraría pero nunca dar error (y menos si es tan poco descriptivo).