Hola Alex, ¿qué tal? muchas gracias por tus comentarios. Entiendo que es muy difícil entender el código y/ó pgm de otra persona, y te agradezco mucho tu ayuda, Y SOBRE TODO, TU TIEMPO.
Paso a responder tus comentarios y preguntas:
a) Cuando has hablado del error 28 y de que estás tratando de investigar en torno a este error ¿por qué es que estás investigando sobre este error? ¿porque ocasionalmente se te detiene el programa trabajando con él y te informa de este error? ¿tienes alguna evidencia que relacione este error con el problema de impresión o no hay seguridad de la relación entre ambos problemas?Respuesta: Lo del Error 28 es una hipótesis mía, de acuerdo a mi anterior experiencia. Mi pgm no se ha trancado ni informado de este error. Solamente me acordé de este error, porque hace mucho tiempo, pasé mucho trabajo con él y el CrystalReport, e investigué mucho en ese momento, y me acordaba que eran muchas las posibles causas de este error, entre ellas la sobrecarga de memoria, y pensando ahora, en la alietoriedad del problema de impresión, me planteé esto como una hipótesis mía, pero no tengo ninguna evidencia de que estén relacionados.
b) Cuando has hablado del problema con la impresión y el tamaño de fuente y el que piensas que puede estar relacionado con saturación de memoria, pila de llamadas, tamaño del módulo bas, etc. ¿tienes alguna evidencia de que puede haber alguna relación entre estas cuestiones y el problema de impresión?Respuesta: Lo mismo de la pregunta anterior: son hipótesis que me planteé de acuerdo a mi experiencia anterior, pero sin evidencias (ahora, para este problema) que lo sustente. Lo del tamaño del módulo también me lo planteé, porque hace mucho, en mis investigaciones de ese momento, recuerdo haber encontrado y leído algo al respecto, y recomendaban agregar un segundo módulo. Lamentablemente, no recuerdo dónde lo leí (foros, ayudas, etc), ni tampoco logré encontrar, ahora, nada al respecto. Capaz que lo leí en algún sitio web que ya no está más, pero estoy seguro que lo leí en algún lugar, no estoy loco, je je.
c) ¿La aplicación tiene otros problemas destacables además del problema de impresión?Respuesta: NO, mi pgm funciona bien, desde hace muchos años, en varios clientes, con uno ó varios pcs, con XP y Seven 32-64, con impresoras de diferentes marcas, y hasta la versión anterior no presentaba este problema. Una de las pruebas que hice, fue volver a usar esa versión anterior y no tuvieron el problema de impresión.
En esta nueva versión, hay un parámetro de configuración, para que cada cliente elija si quiere utilizar ó no esta nueva funcionalidad. Si elijen SI, se muestra el formulario que te envié el código. Si elijen NO, no se muestra el formulario, y el pgm guarda automatica-mente un registro por defecto, con el total de la factura, como Efectivo.
También probé configurarles como NO, y han trabajado e impreso normalmente, pero si vuelvo a configurarles como SI, vuelve el problema aleatorio de impresión.
Por todo esto es que SUPONGO QUE HAY ALGO EN ESTE FORMULARIO, que está provocando algún tipo de conflicto, ó desconfigura la impresora (en mis pruebas, no he logrado nunca, ver que la variable Tamaño haya perdido su valor), ó sobrecarga la memoria, ó capaz que es un bug de VB.
Ahora, respondiendo tus comentarios:
1) Sobre uso de variables.
Aquí veo cosas que me llaman la atención porque a priori yo no las plantearía así, no digo que estén bien o que estén mal, sino que me llaman la atención. ¿Por qué declarar todo como String pudiendo usar otro tipo de variables que son más eficientes tanto a la hora de procesarse como de consumo de memoria? Por ejemplo FPAGO_POR_DEFECTO supongo que es una forma de pago, y quizás hay 5, 10 ó 20 formas de pago. ¿Por qué usar un String cuando puedes usar un Integer que es mucho más eficiente simplemente estableciendo una equivalencia? Esto no sé qué importancia puede tener en el global del programa. Desde luego que si afecta a 20, 40 ó 50 variables no tendrá importancia pero si afecta a un gran número de variables habría que verlo.Respuesta: Esas variables son string realmente, porque no contienen un ID (por ejemplo), sino que contienen información (cadenas de texto) recopilada durante la realización de la factura y que son utilizadas para la impresión, de forma tal que, al clicar sobre el botón Imprimir, no tenga que volver a buscar esa info, sino que ya la tiene en variables de memoria, y con eso el proceso de la impresión sería más rápido. No sé si es lo ideal, pero fue la manera que lo hice.
2) Sobre control de múltiples llamadas a procedimientos que ya están en ejecución. Una fuente de problemas puede ser que si el usuario hace click en un botón, por ejemplo el botón "Imprimir", se produce el evento click sobre este botón y si el usuario ve que tarda un segundo en cargar es posible que vuelva a hacer doble click sobre el botón pensando que no responde. Esto lo que ocasiona es que se dispare de nuevo el evento y que esta llamada y los recursos que consume se acumulen en la pila del programa (lo que puede llevar a una sobrecarga). Frente a esto hay formas de controlar si se está ejecutando el código de respuesta a un evento para impedir que un nuevo click vuelva a disparar el evento ¿Tienes algún tipo de control para evitar esta situación?Respuesta: SI, eso está controlado. No le bloqueo el botón, por ejemplo, pero le muestro un mensaje pidiendo confirmación, antes de comenzar el proceso de impresión (que es bastante rápido, incluso por la red). No creo que pueda ser esto, pero podría ser, lo voy a chequear.
3) Tampoco estoy seguro de si puede estar afectando, pero una recomendación que se suele hacer es no confiar en que las variables u objetos de tipo recordset, database, workspace, etc. se destruyan automáticamente cuando se cierran ventanas o procedimientos locales. Por ejemplo con el evento unload proceder a realizar algo como llamar a una función para cerrar todo.Respuesta: Lo que uso para controlar estos temas, es salir de cada formulario usando
"Unload Me", para descargar todo lo que sea local, pero no la bd ó tablas que, eventual-mente, puedan estar en uso por otro formulario.
Además, utilizo
"DBEngine.Idle dbFreeLocks", según las recomendaciones del MSDN:
http://support.microsoft.com/kb/550617/esUtilización de dbFreeLocks en entorno multiusuario.
Según la ayuda de Visual Basic, el método Idle "suspende el procesamiento de datos, permitiendo al motor de base de datos Microsoft Jet completar las tareas que tenga pendientes, como la optimización de la memoria o los tiempos de espera de página."
Con el método Idle puede dar al motor de base de datos ocasión de realizar tareas de segundo plano que pueden no encontrarse actualizadas a causa de un procesamiento de datos intenso. Esta situación se produce a menudo en entornos multiusuario y multitarea en los que no hay suficiente tiempo de procesamiento en segundo plano
para mantener actualizados todos los registros de un conjunto de registros.
La utilización periódica del método Idle concede tiempo al motor de base de datos para liberar los bloqueos de lectura innecesarios. Si especifica la constante dbFreeLocks como argumento, el procesamiento se retrasará hasta que se hayan liberado todos los bloqueos de lectura.