Oh, cielos

Acabo de instalar en el curro la versión de prueba de VS2012. He conseguido convencerles de que VB Express no da más de sí y necesito algo más «tocho» (es totalmente cierto) y la duda está entre VS2010 y la nueva versión que sale estos días. La primera intención sería tirar por VS2012 si no da problemas con la conversión y compilación de las aplicaciones que estoy desarrollando. Desde VB2005 he ido cambiando de versión tan pronto me era posible. Pero esta vez…

En Visual Studio 2010 teníamos un esquema de colores que delimitaba muy bien las áreas de trabajo y la ventana o pestaña activa. Los iconos eran fácilmente reconocibles por su color antes incluso que por su forma (por ejemplo, amarillo para datos o carpetas… cosas así).

En VS2012, no. Toda el área de trabajo es gris sucio o gris oscuro. Todos los iconos son en blanco y negro, con pequeñas (pequeñísimas) notas de color plano. Si no fuera por esas notas de color disperso y la nitidez del texto y grises, me parecería estar frente al viejo Mac de mi tío, allá cuando mi padre y yo tirábamos de MS-DOS 4.01 y lo de la Multimedia sonaba a cosa futurista.

Menos mal que el código mantiene sus colores. Imagino que eso ha sido una exigencia de los desarrolladores frente al bello monocromo minimalista que proponían los diseñadores. Un poco en plan «si trabajamos con VB4 y 5, a esto sobrevivimos».

No entiendo ni entenderé ese minimalismo conceptual que nos ha caído encima con Windows 8 (y que sufrí en tiempos con Gnome, antes de huir corriendo a KDE). El sufrir con un entorno espartano y retro, como si fuera pecado que nuestras máquinas puedan mostrar millones de colores, texturas, bordes redondeados, sombras…

Visualmente, VS2012 es una rendición a los diseñadores. Sin la ayuda de contrastes, de iconos identificables y agrupables de un vistazo es cansado para la vista y para el cerebro trabajar con él.

Compañías telefónicas

—Oiga, me mudo y quiero cambiar la línea a mi nuevo domicilio.

—Sin problema. Son tropecientos leuros.

—Disculpe, pero eso es lo que pagué por el alta. No quiero un alta nueva, sólo un cambio de domicilio.

—Da igual, son tropecientos leuros. Lo pone en el contrato: si no sabe bailar la jota aragonesa a la pata coja y haciendo el pino, son tropecientos leuros.

—Perdone, pero en mi contrato no pone nada de eso.

—Es que se aplica a los contratos yuxtapuestos.

—Pero es que el mío es pluscuamperfecto.

—Da igual, son tropocientos leuros.

—Quiero poner una reclamación.

—Da igual, son tropecientos leuros.

—Váyase a paseo y dé de baja la línea, que me voy a la competencia.

—Pero, hombre. No sea así, con lo bien que lo tratamos. Mire, le diré lo que vamos a hacer: le haremos el cambio de domicilio gratis, sin cobrarle nada. Para que vea que le apreciamos.

Alucinado estoy

Me encuentro con que hay un error en el encabezado de ciertos mensajes de correo enviados automáticamente por el gestor de incidencias (SOS). Debía poner «SOSNext: aviso de cierre de la acción de mejora nº tal», pero llega cortado en la «ó» de acción, que es sustituida por un carácter raro. Lo curioso es que el resto de correos con la palabra «acción» en el título llegan sin problemas.

Lo más curioso es que la contrapartida al cierre llega sin problemas: «SOSNext: aviso de reapertura de la acción de mejora nº tal». Curioso, ¿por qué?, diréis. Bueno, pues por el código que genera el título del mensaje es similar en ambos casos:

Titulo = «SOSNext: Aviso de cierre de la « & Singular & » nº « & Id

Y

Titulo = «SOSNext: Aviso de reapertura de la « & Singular & » nº « & Id

¿Cuál es la diferencia?

La longitud de la cadena. No sé el porqué, pero el problema está en los seis caracteres que ocupa «cierre». Cambiando la longitud de la palabra o, como he hecho, añadiendo un espacio más antes de «cierre», problema solucionado.

Aunque la cara de pasmo tardará más en quitárseme.

Si no es por las buenas…

El otro día, intentando filtrar un DataView, me encontré con un problema pintoresco: quería filtrar los usuarios con determinados permisos en la aplicación, para lo cual necesitaba hacer una comparación bit a bit. Hacer esa comparación en SQL no supone problema (Permisos & PermisoPedido = PermisoPedido). En VB, tampoco (UsuarioActivo.Permisos AND PermisoPedido = PermisoPedido), pero la propiedad RowFilter del DataView es mucho más restrictiva. Usa sintaxis SQL, pero con muchas limitaciones.

En la Geekpedia encontré una solución al problema: pasar de las operaciones bit a bit y resolver el problema con operaciones decimales normales y corrientes:

(Convert((Permisos – Permisos % PermisoPedido) / PermisoPedido,’System.Int32′) % PermisoPedido = 1)

Donde PermisoPedido es el valor numérico buscado de nuestra enumeración (1, 2, 4, 8, 16…). El operador % es, en Visual Basic, el módulo (resto de la división entera).

Hola, si lo hacemos mal os las apañáis vosotros

Tengo un amigo que trabaja en un distribuidor de cierta compañía de telefonía. Oírle hablar de los programas informáticos que usan para hacer su trabajo me demuestra que no sólo es el trato al cliente lo que falla en las empresas de telefonía y que la externalización a bajo coste de los servicios incluye algunas áreas que debieran ser básicas para el funcionamiento de la empresa. La última que me ha contado va de un problema para dar de alta un servicio a un cliente. Un problema que, tras pruebas varias y la intervención del soporte técnico que, como distribuidor, tiene a su disposición, tiene todas y cada una de las papeletas de ser un bug del programa. Así que se abre una incidencia a los responsables del susodicho programa.

Que empiezan a marear la perdiz. Lo suficiente como para que la promoción caduque y se retire dicha opción del programa. Dado lo que sé del programa, me imagino una subcontrata con becarios y picacódigos con poca experiencia, mal pagados y echando horas a manta, con una motivación por los suelos y una productividad e interés por hacer bien su trabajo en consonancia (modificada a la baja por la falta de respeto que puedan recibir de sus jefes). Ante la queja del usuario y para dos días que faltan del tema, que le den a él y a su cliente. Y luego, todos, así te las apañes con tu cliente, que no es problema nuestro.

Ya la versión 2… cómo pasa el tiempo

La semana pasada cerré el diseño de la versión 2.0 (nombre clave «La Cigala») de nuestro gestor de incidencias, ahora ampliado también a gestor de proyectos. Dos meses de trabajo para una versión preliminar a la que aún tengo que echarle mucho trabajo. Pero ya casi está. Ahora tengo que preparar un par de programitas auxiliares para importar datos a cascoporro desde unos Excel que se usan ahora y a quienes mi criaturita va a jubilar.

Da gusto ver el trabajo de uno en funcionamiento y que los usuarios lo acepten y usen.

No debería haber pasado

—¡Permiso para ir a Donde-sale-el-sol y caparle, señor!

—Ya lo haré yo el lunes.

Los viernes son terroríficos. Siempre pasa algo. Que además de viernes sea el día en que sensei empieza vacaciones es tentar al diablo, así que senpai y yo estábamos con la mosca detrás de la oreja y esperando… Esperando…

A media mañana, el caos: los usuarios avisan de que no pueden entrar en SAP. Donde-sale-el-sol ha desaparecido del mapa. Y bien desaparecido: no responde ni por MPLS ni por ADSL. ¡Ni siquiera por teléfono! ¡Un meteorito ha arrasado la fábrica! ¡Nos invaden los extraterrestres!

La cara de sensei, al móvil, mientras le van dando partes, es todo un poema. Un lumbreras de mantenimiento, sin avisar, se ha puesto a hacer pruebas con las líneas eléctricas. Como resultado, ha tumbado la luz en la fábrica.

—No lo entiendo. No debería haber pasado.

Y la línea de los SAIs. Y con ella, los routers, los switches, el MPLS, la centralita… y todos y cada uno de los servidores.

—Pero si no debería haber pasado nada.

Y mientras intentábamos arrancar todo y lo chequeábamos, yo iba haciendo mentalmente la lista de cosas que necesitaba para un fin de semana de trabajo no planeado, por si las moscas. E incluía una escopeta.

Aghhhh, quiero morir

En algún momento, pareció buena idea. Desdoblar incidencias para cubrir también peticiones de servicio. Se trataba sólo de añadir un campo a tres tablas y luego gestionarlo en tres formularios.

Ya, claro.

Pero había cuatro vistas de esas tablas. Y luego procedimientos almacenados sobre esas vistas y esas tablas. Que eran llamados por los tableadapters de cinco datasets tipados, que los usaban para trabajar con esas vistas y esas tablas. Una docena de tableadapters, más o menos. Muchos métodos llamados (por fortuna) desde unos pocos sitios bien controlados.

Un horror de día.

Las datarow pasan a modificadas al navegar entre registros

He tenido durante meses un problema pintoresco: en una aplicación de Windows Forms con enlace de datos (datasets tipados, BindingSource y demás) se me cambiaba el estado de las datarow a modificadas sólo con navegar entre los registros. Dado cómo se actualizaban los datos a la base de datos, resultó ser un problema menor, pero molesto. El problema parecía estar en el enlace de datos (binding) de usercontrols. En su día no encontré nada en MSDN y lo dejé para otra ocasión. Ayer, buscando otra cosa, encontré la solución al problema.

Resumiendo: si buscamos ayuda sobre cómo hacer un enlace de datos simple en nuestro control personalizado, nos dicen que usemos <BindableAttribute(True)>:

<BindableAttribute(True)>
Public Property IdAccion As Integer

Pero resulta que, con sólo eso, el BindingSource supone que siempre cambian los valores enlazados y actualiza el origen de datos. Resulta que además debemos implementar la interface INotifyPropertyChanged y notificar cuándo cambia el valor, tal que de esta forma:

<BindableAttribute(True)>
Public Property IdAccion As Integer
    Get
        Return Me._IdAccion
    End Get
    Set(value As Integer)
        If _IdAccion <> value Then
            Me._IdAccion = value
            RaiseEvent PropertyChanged(Me, _
                    New PropertyChangedEventArgs("IdAccion"))
            Me._IdAccion = value
        End If
    End Set
End Property

Sigo, eso sí, sin haberlo visto tan bien explicado en la documentación. Menos mal que existen los foros y los blogs.

Pero, ajá, no es la panacea. Ahora me encuentro con que, a veces, el valor no cambia aunque debería. Por ejemplo, al añadir un nuevo registro que tiene (o tendrá) el mismo valor de la propiedad que el anterior. Hay que revisar estos casos con cuidado para, o bien asegurarnos de que cambia el valor de la propiedad o bien provocar a mano el evento cuando lo creamos necesario. En fin, problemas del enlace a datos.

Datasets tipados, amor y odio

Llevo varios meses con un proyecto que empezó siendo algo pequeño (sustituir una aplicación Access de gestión de incidencias por un desarrollo en .NET, por temas de falta de licencias de Access para todos los usuarios) y ha ido creciendo hasta el punto que mataría por tener una semana para documentar con calma todo lo que llevo hecho. Este crecimiento, aunque lo tenía en mente (no tanto, claro) cuando diseñé la aplicación, me hace dudar de ciertas decisiones que tomé en su día, como el uso de datasets tipados.

Supongo que la idea de usar datasets tipados con VB2010 teniendo Entity Framework puede parecer rara o anacrónica, pero llevo usando datasets desde 2005 y tirar de ellos me ahorraba un tiempo de aprendizaje que no tenía. Ahora, con 17 datasets tipados (y creciendo) no sé hasta qué punto fue buena idea.

Entendámonos, me gustan porque el asistente es cómodo y puedo personalizarlos rápida y fácilmente. Se han convertido en poderosas (y pesadas, me temo) entidades que se mueven entre la aplicación tanto con los datos como con las órdenes de qué hacer con ellos.

El problema viene cuando tengo que reconfigurar alguno, porque se ha añadido algún campo a la base de datos o, como está pasando estos días, ha habido que hacer cirugía mayor y donde antes tiraban de una tabla ahora lo hacen de una vista. Esa forma de machacarse la configuración de los campos existentes, esos problemas con el AllowDBNull y con los NullValue…

A veces odio los datasets tipados.