El valor no puede ser nulo. Nombre del parámetro: objectType

El error en cuestión me salía en el diseñador de Visual Basic Express 2010 de forma insistente. Una molestia a la hora de trabajar con el diseñador, más que nada, porque luego la aplicación funcionaba sin problemas. Ayer me dediqué a buscarle solución, tirando de Google.

El problema, apuntaban en varios sitios, se daba en formularios o controles de usuario heredados y estaba causado al gestionar eventos de objetos de alguna de las clases padre con la cláusula Handles en la clase hija. Tras investigar con calma mi usercontrol, encontré que el causante del desaguisado era, efectivamente, una cláusula handles que apuntaba a un evento de un BindingSource del abuelo del usercontrol. Quité el Handles y lo sustituí por un AddHandler en el constructor y todo funciona con suavidad.

Cualquiercosa x 1 = Cualquiercosa

Necesitamos un campo que siempre valga uno.

—¿Uno? ¿Por qué?

—Porque cualquier cosa multiplicada por uno es cualquier cosa. Y necesitamos pedir cualquiercosa al usuario y la única forma es ligarlo a un campo de una tabla. Con un campo que siempre valga uno podemos meterlo en un select que nos devuelva cualquiercosa * campo_que_vale_1 y meterlo en la variable con la que necesitamos trabajar.

Momento de silencio pensativo. Los engranajes mentales zumban.

—OITM. Uno de los Salesfactor. Por defecto, valen uno y sólo usamos el primero de ellos.

Viernes, 13 horas. Avanzando en una consulta puñetera en SAP B1.

MKV con subtítulos en TDT Easy Home HD10

El otro día me compré un TDT que reproducía matroskas, de la marca BestBuy. En fin, el caso es que monté el cacharro en casa, le puse un matroska (Macross Frontier, BluRay Rip 720p, versión de Nanikano, la comenté en su día) y se veía, sí, pero no los subtítulos. Mala cosa. Temiendo que el cacharro no entendiera más allá de los SRT, probé con una versión guiri de la 2ª temporada de Shana, que tengo por ahí para traducir y, efectivamente, me mostraba los subtítulos en SRT. Pero resulta que los MKV de Shana tienen dos pistas de subtítulos, SRT y SSA y reproducía ambas. Perplejo me hallaba.

Revisé otros MKV y nada, no conseguía reproducir nada. Incluso probé a extraer los subtítulos, grabarlos como SRT y ponerlos en el pendrive, pero tampoco. Así que pensé que igual con Shana funcionaba no por los formatos, sino por tener dos cadenas de subtítulos. Hice una prueba rápida: extraje los subtítulos de un episodio, los grabé como SRT y los volví a meter en el MKV. ¡Bingo! Toca jugar un poco con el botón de Subtitle del mando hasta que se da por aludido el muy hijo de su madre, pero funciona.

Me gustaría hacer un tutorial en condiciones, con capturas y tal, del proceso, por si a alguien le pasa algo similar, pero con el poco tiempo de que dispongo es imposible, así que es esta entrada en modo telegráfico o nada.

Necesitamos el MKVtoolnix tanto para sacar los subtítulos como para añadírselo de nuevo. Para sacarlos usaremos el MKVExtractGUI2, que descargaremos aparte. Para meterlos, el mmg.exe que ya viene de serie. Usaremos, si queremos, el Subtitle Workshop si queremos guardar los subtítulos en otro formato.

1) Extraer

Lo primero es instalar el MKVtoolnix. Luego, copiaremos los archivos que vienen en el zip del MKVExtractGUI2 en la carpeta del primero (lo de siempre, archivos de programa tal y tal). Ejecutamos el MKVExtractGUI2 y nos saldrá una ventana muy simple: pinchamos en el botón de Input y le indicamos el archivo que vamos a abrir. En la caja Tracks nos aparecerá el contenido del matroska. Seleccionamos los subtítulos y pulsamos en el botón Extract. Los subtítulos se habrán guardado en la carpeta indicada en Output.

2) Guardar como…

Si queremos guardar los subtítulos con otro formato, usaremos el Subtitle Workshop. Sin complicaciones: Archivo, Cargar subtítulo y Archivo, Guardar como. Lo complicado, para mí, acostumbrado a ver sólo las extensiones de los subtítulos, fue acertar con el formato. SRT es SubRip.

Un problema que podemos tener en Subtitle Workshop es la aparición de símbolos extraños en lugar de signos de puntuación, vocales con tildes y cosas así. Para evitarlo es tan simple como abrir primero el archivo de subtítulos con el venerable Bloc de Notas, Guardar como y en Codificación elegir ANSI.

3) Meter de nuevo

Con el mmg.exe (Mkvmerge GUI). En Archivos de entrada pinchamos en Añadir y elegimos los archivos con los que vamos a trabajar, el MKV y el de subtítulos. Por lo general, él solo ofrece añadir automáticamente el subtítulo. Indicamos el nombre del archivo de salida, pinchamos en Iniciar multiplexado y esperamos a que termine.

Con la última versión del programa puede haber problemas al reproducir el MKV resultante en reproductores de salón, como el TDT de marras para el que lié todo esto. La solución consiste en, antes de iniciar el multiplexado, seleccionar tanto el vídeo como el audio del archivo (en la sección de Pistas, capítulos y etiquetas), pinchar en la pestaña Opciones adicionales y, en Compresión, seleccionar explícitamente Ninguna, o bien ir a Archivo, Opciones, pestaña mmg y marcar o desmarcar (según funcione) «Deshabilitar eliminador de la compresión del encabezado para audio y vídeo predeterminadamente» (en inglés es bastante más corto).

Es un jaleo, pero realmente no lleva más de dos minutos por episodio. Es una pesadez, pero por lo menos puedo disfrutar de mis capítulos en la tele, mientras monto el sobremesa de nuevo.

En las garras del mal: Windows Phone

Estos días pasados me he hecho, by my beautiful face™, con un móvil nuevo con Windows Phone 7. Hace un tiempo comenté que pensaba hacerme de uno, pero que su falta de sincronización directa me hizo descartarlo. Con el tiempo, este descarte quedaba aún más obligado al no poder ver en directo un cacharro con el nuevo sistema de los de Redmond: está muy maltratado por las operadoras y las tiendas de telefonía. Supongo que cuando lleguen los modelos de Nokia lo veremos más, que los hierros finlandeses gozan de gran predicamento por estos lares.

Tengo móvil nuevo, decía. Un poco triste el sacarlo de la caja: el anterior que tuve, un Touch del mismo fabricante, venía en una caja negra de cartón duro y cierre magnético que aún conservo, con protector de pantalla, manual tocho, una buena funda y puntero de reserva. El nuevo, más grande y más caro, viene constreñido en una caja barata, con guía rápida y poco más. Tristes nuevos tiempos.

El cacharro es un señor cacharro, aunque no le pueda colgar la llave del Lancelot que llevo en el Touch. Mueve con soltura lo que le han metido, el nuevo invento de Spectra para dominar los móviles, después de que la malvada cool Apple cambiara las reglas hace ya su buen tiempo con el ay!fon. El mal aprende del mal y nos hace firmar un pacto con la manzana (iba a decir con el diablo, pero aquél se conformaba con el alma) limitando muy mucho lo que podemos meter en el sistema y cómo. En la semana que llevo con el cacharro ya hay algunas cosas que echo de menos del viejo, venerable y obsoleto Windows Mobile/CE.

Pero los sistemas como Mobile o el mismísimo Symbian se han quedado viejos. Ahora que vivimos (o vamos camino de vivir) en la nube (siempre que no nos preguntemos dónde están nuestros datos, no sea que nos dé un soponcio) y consumimos servicios en la nube y, en general, es moda no tener los pies en el suelo, estos viejos sistemas que nos daban el control sobre lo que sucedía en nuestro móvil se extinguen, apartados a puntapiés de la carrera evolutiva. Pasamos a darle el control de nuestro móvil a la operadora si nos daba un buen cacharro y un servicio medio decente. El siguiente paso ¿lógico? era dar el control total al fabricante. Así, leo en multitud de sitios que a Windows Phone le hace falta una buena tienda de aplicaciones, no el poder instalar esas aplicaciones sin tener que pasar por la dichosa tienda, y cosas así. Horror de los horrores. ¿Adónde hemos llegado?

En fin, podía hacer oídos sordos a los cantos de sirena de los tres diablos (el cool, el malomalo y el buenobueno) y seguir con mi viejo cacharro (SCUMMVM al poder), o pasarme a un Symbian. Pero el problema es que, aunque fui fuerte y resisit la tentación cool y la buenrollista, he terminado probando la opción maligna der tó. Y resulta que la maldita es buena de narices. Y las preocupaciones y quejas que tenía de antes (no sincroniza con Outlook, no deja instalar aplicaciones si no es a través de su tienda de aplicaciones, ¿qué pasa con mis datos?…) han pasado a un discreto segundo plano.

El infierno de los códigos de barras

Con motivo del día de Satán, también conocido como nuestro arranque con SAP B1, hemos tenido un fin de semana horroroso de preparativos que se alargó un día más de lo previsto, como colofón a una semana horrorosa y preludio a otra igual de terrible. Una de las cosas que más guerra nos ha dado la impresión de etiquetas de códigos de barra que antes las hacíamos con un programa y ahora teníamos pensado emplear informes de Crystal Reports. No había manera de conseguir imprimir un EAN14 válido. El problema añadido es que en Internet no encontrábamos mucha ayuda.

Al final, la solución vino de un foro del venerable Visual FoxPro, solución que resumo aquí como aviso para navegantes:

El EAN/DUN14 es un churro de números. Información sobre cómo componer un número válido es fácil de encontrar: que debe tener un número par de cifras, cómo se calcula el dígito de control, la norma para su composición… Pero averiguar cómo imprimir eso en un código de barras es harina de otro costal.

Para el código de barras se usa una codificación Interleaved 2 of 5, que representa dos números como un grupo de cinco líneas y espacios. Aquí viene nuestro problema, porque con una fuente de texto sola no hacemos nada: cada carácter de nuestro código de barras se corresponde con dos números de nuestro DUN14. O sea, nuestro código de barras tendrá la mitad de caracteres que nuestro DUN14. Esto nos obliga a usar un algoritmo que nos convierta nuestro chorro de números en esa cadena. Esta cadena, con un tipo de letra Interleaved 2 of 5, será nuestro código de barras.

Y aquí es donde se nos presenta el problema, porque el algoritmo depende de la fuente empleada (o al revés, vamos). De nada nos vale una fuente I2o5 si no tenemos el algoritmo. ¿Por qué? Porque los casos que he visto funcionan del siguiente modo:

Vamos recorriendo nuestro DUN14, cogiendo cada par de números. Al número que representan (por ejemplo, 58) se le suma un valor dado (digamos 52). Se obtiene el carácter correspondiente a ese código numérico (110) y ése, en nuestra fuente I2o5, se corresponderá con las cinco barras-espacios que necesitamos. Como se ve, si nuestra fuente no es la correspondiente a nuestro algoritmo, el carácter representado no tiene por qué coincidir (y no lo hará) con el buscado.

Al final, debemos tener una cadena de caracteres formada por un carácter de apertura, la cadena tratada y un carácter de fin, que nuestro lector será capaz de entender.

En el artículo que menciono antes encontramos código para generar una representación de nuestro DUN14 para una fuente I2o5 y, además, nos da la fuente. El código, pese a los nombres de las variables, es muy simple: la mayor parte de la función se dedica en calcular el dígito de control y en asegurarse que la longitud sea correcta. Si ya tenemos nuestro código válido, todo se reduce a lo siguiente:

1) Tomamos cada par de números de nuestro código (para 14 cifras tendremos, pues, 7 pares).

2) Si el número de dos cifras que componen es menor de 50, le sumamos 48. Si es mayor, 142.

3) Sacamos el carácter correspondiente a ese código.

4) Formamos una nueva cadena de caracteres con los que hemos obtenido, en orden.

5) Como cabecera le añadimos el carácter 40 y como cierre, el 41 (los paréntesis)

6) Aplicamos la fuente I2o5 que acompaña al ejemplo y listo.

La primera aplicación de esto la hice a mano, en Excel, para un código dado y la alegría de ver cómo el lector entendía el puñetero código después de tan horroroso y desesperante fin de semana es difícil de explicar.

Restaurar Menú Inicio Todos los programas en Windows 7

Si a raíz de una infección vírica se han borrado los accesos directos de Menú Inicio\Todos los programas en Windows 7/Vista y/o los iconos de acceso directo del escritorio de todos los usuarios (antiguo All Users, ahora Public), probar lo siguiente:

1) Que la carpeta AppData\Local\Temp\smtmp\1\ dentro de la cuenta de nuestro usuario (C:\Users\Usuario\AppData\Local\Temp\smtmp\1\) existe y tiene todas las carpetas y accesos directos del Todos los programas

2) Que la carpeta AppData\Local\Temp\smtmp\4\ dentro de la cuenta de nuestro usuario (C:\Users\<Usuario>\AppData\Local\Temp\smtmp\4\) existe y tiene los elementos del escritorio público.

Si es así, sólo queda restaurarlos. La forma más rápida es abrir una ventana de comando con permisos de Administrador (ojo con esto) y tirar de Xcopy:

xcopy %Temp%\smtmp\1 «C:\ProgramData\Microsoft\Windows\Start Menu» /H /I /S /Y /C

xcopy %Temp%\smtmp\4 «C:\Users\Public\Desktop» /H /I /S /Y /C

El bicho en cuestión también había hecho desaparecer todo lo existente en Users. En casos como ese es importante no dejarse llevar por el pánico. Puede haberlos ocultado o convertido en archivos de sistema. El comando Attrib es de gran ayuda en estos casos. Como antes, siempre ejecutando la consola en modo administrador.

Tocamiento de narices de un TextBox

Ando estos días programando una serie de plantillas y controles personalizados. He estado preparando un TextBox personalizado con posibilidad de validación y filtrado de datos de serie o mediante validadores/filtradores a medida que implementen cierta interfaz. Hasta ahí sin problema. Como el tipo de TextBox en cuestión va a ir montado, como regla general, sobre un formulario o un control de usuario que incorporan un sistema de gestión del estado (VerDatos, Modificar, Nuevo, etc.) se me ha ocurrido que el TextBox ajuste su estado ReadOnly automáticamente. Vale, sin problema. Ha funcionado a la primera. Salvo por un pequeño detalle visual.

Al indicar ReadOnly=True el color de fondo del TextBox cambia.

Pensé en controlar el evento ReadOnlyChanged, pero no conozco el color de fondo anterior al cambio y, francamente, saberlo complicaría más las cosas (reescribir la propiedad BackColor y el método OnReadOnlyChanged). Reescribir el método OnPaint, que de todas formas ni se me pasaba por la cabeza, no serviría porque, leído aquí, el cambio de color provocado por el cambio de ReadOnly se hace «por su cuenta» (Actually, .Net TextBox is a simple wrapper of Win32 Edit control, and it passes the painting issue to the Win32 Edit control). En el mensaje en cuestión se propone sobreescribir la propiedad ReadOnly del TextBox, algo que parece sencillo, simple y razonablemente elegante.

Salvo por otro pequeño problema: ReadOnly es una palabra reservada. Todo intento de crear una propiedad que se llame ReadOnly es frustrada por el propio IDE. ¿Cómo se hace para llamar a una propiedad como una palabra reservada?

Este pequeño problema me ha llevado bastante rato solucionarlo, así que lo comparto. Es una tontería y tiene su lógica, pero me ha hecho perder un tiempo precioso.

Usar corchetes:

Public Overloads Property [ReadOnly] as Boolean

En fin, sigamos…

Pegar datos de una hoja de Excel a un DataGridView

Un intento de simplificar el uso de una aplicación por lo demás bastante simple (de cara al usuario) me ha llevado a jugar con el portapapeles para permitir que el usuario copie una serie de valores de una hoja de cálculo (Excel, para más señas) y las pegue en un DataGridView, algo que me ha costado un buen rato, no porque sea complicado, sino porque no he encontrado información al respecto por Internet (seguramente por la torpeza «buscativa» de uno).

El problema, como digo, no es complicado. Por una parte, acceder al portapapeles es muy sencillo, mediante My.Computer.Clipboard y hay varios métodos para extraer su contenido según lo que contenga. En este caso (la copia de texto) usaremos el método GetText, que nos devuelve un String. El dónde gestionar esto ya queda a gusto del consumidor pero, para mí, lo más fácil es añadir un menú contextual con el habitual atajo de teclado (Ctrl + V).

El siguiente paso es tratar ese texto. Cualquier colección de celdas de Excel es copiada al portapapeles como un conjunto de valores separados por tabulación. El otro día mostraba el uso de la clase TextFieldParser para procesar ficheros de texto que nos viene como anillo al dedo. Bueno, casi, porque al TextFieldParser no le podemos pasar un String, está pensado para procesar ficheros. Si vemos sus constructores, a uno se le pasa la ruta de un fichero, a otro un Stream, precisamente para tratar con un fichero, y a la tercera sobrecarga, un TextReader.

¿Qué es un TextReader (era la primera vez que lo veía)? Según la biblioteca de MSDN, TextReader es la clase abstracta de StreamReader (éste si lo conocía) y StringReader. Éste último tiene en su nombre la palabra mágica, String, así que merece la pena echar un ojo. Me da igual los tutoriales que nos puedan aparecer ni los mil usos que tenga StringReader. Para el caso que nos ocupa, todo se reduce a crear un StringReader a partir del texto contenido en el portapapeles:

Dim miTexto As StringReader

miTexto = New StringReader(My.Computer.Clipboard.GetText)

Y pasarle ese StringReader a un TextFieldParser, con lo que estamos casi, casi, en el mismo caso del ejemplo de TextFieldParser. Ya podemos trabajar de forma simple con el texto del portapapeles. Sólo hay que añadir los controles de errores necesarios y decidir qué vamos a hacer con cada fila válida devuelta por el TextFieldParser. Siguiendo la lógica del título de esta entrada, pasárselas al DataGridView, pero tengo que confesar que no lo hice así. La razón es muy simple: me interesaba más pasárselo directamente al origen de datos del DataGridView.

Para mi caso concreto (Origen de datos + BindingSource + DataGridView), antes de iniciar el proceso de lectura de TextFieldParser, llamé al CancelEdit del BindingSource para evitar la posibilidad de que se generase una fila en blanco o no válida (si se da el caso, se saltaría la validación de datos) y le quité también la referencia al DataSource:

Me.bsArticulos.CancelEdit()

Me.bsArticulos.DataSource = «»

Después de añadir los valores del portapapeles al origen de datos, se vuelve a enlazar el BindingSource con éste y listo. Bueno, vale, no he pegado realmente en el DataGridView. Espero que nadie se sienta estafado.

Nos vemos en el Forlon.

¿No con Outlook?

Mi viejo HTC Touch empieza a darme problemas. Le ha dado por reiniciarse en mitad de una llamada, de forma aleatoria. El problema es que, claro, al que llama se le corta la llamada igual que si se la hubiera cortado deliberadamente, pero a mí no me queda constancia de la misma. Aprovechando que estamos en Navidades y suele haber ofertas varias para estas fechas, he empezado a buscar un posible sustituto. En su día me llamó bastante la atención las noticias que salían sobre el futuro Windows Phone 7 (o Windows Mobile 7), así que mi primera opción ahora que ya ha salido ha sido buscar un terminal con este sistema operativo, encontrando uno muy majo.

El siguiente paso ha sido buscar información concreta sobre Windows Phone 7. Tras una somera búsqueda, unos comentarios preocupantes y una búsqueda más a fondo, se me ha quedado una cara de tonto que espanta. Menor, claro está, que si me hubiera dado cuenta de la tontería que han hecho en Spectra después de comprarme un terminal.

Así, sin anestesia: no hay forma humana de sincronizar contactos, tareas y calendario de Outlook con el nuevo Phone 7. No voy a preguntarme quién es el lumbreras a quien se le ha ocurrido semejante estupidez. Tengo otra pregunta más importante.

Y ahora, ¿qué? ¿Qué opciones tengo?

1) Esperar a ver si consigo hacerme con un terminal con Windows Mobile 6.5 a buen precio, algún resto de stock o similar.

2) Volver a Symbian.

3) Pasarme a Android.

4) ¿?

En todo caso, mis necesidades son simples: sincronización de contactos, tareas y calendario con Outlook. Que sirva para llamar y mandar SMS. Que tenga wi-fi. Y que me permita editar documentos de Word y Excel. Se valorará que haya una versión de SCUMMVM para él.

Me encanta mi trabajo

Hay días que me reconcilio con mi profesión. Días que me recuerdan lo estimulante que es ser administrador de sistema o comedor de marrones en general. Días que me demuestran que los ingenieros crean hermosas máquinas, pero los fp somos el lubricante que las permite funcionar. Hoy ha sido uno de esos días. Un día horroroso. Un día genial. Un día de recordar viejas entradas leídas en blogs y foros, día de darle caña al Process Explorer y rastrear lo que hace un programa al arrancar. Y a partir de ahí intentar entender qué quiso hacer el programador, pasar de ver el qué hace el programa al porqué lo hace. Y luego, los ojos lagrimeando de tanto ver líneas que indican accesos al registro y a archivos, de revisar los archivos de la aplicación y buscar dónde se guarda lo que estamos buscando, encontrar con que no hay forma de averiguarlo. No, por lo menos, con mis conocimientos.

Día perdido.

Pero el olfato está ahí. Sacando posibilidades de supuestos totalmente inconexos. Olfato, olfato, idea, prueba y… ¡bingo!

Problema resuelto.

Hay a quien le gusta los sudokus o los puzles. A mí que me den un problema interesante. Que las cabezas sesudas se preocupen de conquistar países, que yo pongo los puentes.