miércoles, 24 de septiembre de 2014

Convertir fichero KML a PLT y GPX II

https://drive.google.com/file/d/0B0wjloS-L7fxbzBnQ2RMZlcxNUU
Hasta el momento, lo que he logrado ver, es que las coordenadas en un fichero kml  son una serie de ternas de números (-6.0906000,43.0571700,1200) separadas por un espacio. Cada terna está formada por la longitud (-6.0906000), la latitud (43.0571700) y la altitud, separadas por comas, en una única línea. El principal problema a la hora de convertir esas coordenadas es que cada coordenada no está en una línea distinta, todas ellas están en la misma línea. Aunque oziexplorer permite abrir el fichero KML y salvarlo como PLT o como GPX, yo no conozco ninguna aplicación que trasforme el camino seguido a wpt o a ruta.
 He preparado tres métodos para introducir esos saltos de línea y un libro excel que convierte el formato kml a los formatos que utilizan Oziexplorer y Garmin (GPX).

  • Actualmente sigo utilizando windows XP y office 2003. Puede que con otra configuración los siguientes pasos funcionen de manera diferente, o no funciones.
  • Aunque hay varios editores de texto que pueden valernos, yo utilizo el que todos los usuarios de windows tenemos, el Bloc de notas (notepad). 
  • Utilizo excel, pero puede ser muy interesante tener instalado open office o libre office.
  • Abrimos con el bloc de notas el fichero kml. Buscamos, estan al final, la línea con las coordenadas. Nos quedamos solo con las coordenadas. Salvamos como texto.
  • Abrimos un libro excel en blanco, escribimos, en cualquier celda =caracter(10). Nos sale un carácter inidentificable.
  • En el bloc de notas de las coordenadas elegimos Edición->Reemplazar. Buscamos los espacios en blanco, un golpe al espaciador. En reemplazar ponemos el carácter 10, para ello vamos a la celda en donde hemos escrito =caracter(10), copiamos y situados en Reemplazar pegamos ese valor con ctrl+V. Si además de el carácter 10 aparecen unas comillas, las eliminamos. Reemplazamos todo.
  • Guardamos como TXT. 
  • Abrimos ese fichero con excel, bien desde el propio excel, bien mediante el botón derecho del ratón con "Abrir con" y seleccionando excel.

Segundo método: 

  • Nos quedamos solo con las coordenadas.
  • Reemplazamos los espacios por "<br>".
  • Salvamos como HTM.
  • Damos un doble click sobre el fichero. Se abre con el explorador.
  • Copiamos del explorador a excel.
Tercer método:

  • Consiste en crear una tabla HTM.
  • Nos quedamos solo con las coordenadas.
  • Trasformamos esa línea en una tabla HTM. Pra ello:
  • Reemplazamos los espacios en blanco por </tr><tr><td>
  • Antes de las coordenadas escribimos <table><tr><td>
  • Después de las coordenadas escribimos </table>
  • Guardamos como HTM
  • Abrimos ese fichero con excel, bien desde el propio excel, bien mediante el botón derecho del ratón con "Abrir con" y seleccionando excel.
  • Las coordenadas ocupan una sola columna. Para pasarlas a varias columnas utilizo, seleccionando toda la columna, Datos->Texto en Columnas. Indicamos que la coma funciona como separador y que todos los campos son campos de texto. Procedemos.
  • Los distintos formatos, tanto el de Oziexplorer como el de Garmin, son sencillos, no necesitan grandes explicaciones. Concatenando textos llegamos a ellos (columnas de la E a la H de la hoja Kml-Plt1)
  • En este caso utilizo tres variables con nombre, Comillas = Caracter(34), NL (nueva línea) =Caracter(10) y PaM, factor conversión, de metros a pies, 3,3333333
  • de Kml a PLT (Ozi): =$C2&","&$B2&",0,"&ENTERO($D2*PaM)
  • De Kml a Wpt (Ozi): =$F2&",P"&$F2&","&$C2&","&$B2&",,"&$D2&",,,,,,,"&",P"&$F2&",,,,"&ENTERO($D2*PaM)
  • De Kml a ruta GPX: ="<rtept lat="&Comillas&$C2&Comillas&" lon="&Comillas&$B2&Comillas&">"&NL&"<ele>"&$D2&"</ele>"&NL&" <sym>Waypoint</sym>"&NL&"</rtept>"
  • De Kml a wpt GPX: ="<wpt lat="&Comillas&$C2&Comillas&" lon="&Comillas&$B2&Comillas&">"&NL&"<ele>"&$D2&"</ele>"&NL&" <sym>Waypoint</sym>"&NL&"</wpt>"
  • Arrastramos y completamos todas las coordenadas.
  • Ponemos, tanto en Oziexplorer como en MapSource, el datum a WGS84.
  • Creamos y salvamos, en Oziexplorer, un fichero plt (track) y un fichero wpt.
  • Creamos y salvamos un fichero con un par de puntos para los wpt y un fichero con una ruta con esos dos puntos en MapSource. Salvamos como GPX.
  • Editamos, se puede utilizar cualquier editor de textos, el fichero plt. Borramos los puntos del camino (son muy fáciles de identificar, están al final). Copiamos los puntos creados en el fichero excel, columna E (sin la cabecera, a partir de E2). Los pegamos en el fichero PLT y salvamos. Comprobamos, con ozi, que funcionan.
  • Editamos, se puede utilizar cualquier editor de textos, el fichero wpt. Borramos los puntos (son muy fáciles de identificar, están al final). Copiamos los puntos creados en el fichero excel, columna G (sin la cabecera, a partir de G2). Los pegamos en el fichero wpt y salvamos. Comprobamos, con ozi, que funcionan.
  • Por lo que yo he visto oziexplorer es muy flexible con los errores pero MapSource es todo lo contrario, es muy poco flexible, rechaza el mas mínimo error. Hay que tener mucho cuidado al editar un fichero GPX.
  • En los ficheros GPX eliminamos los wpt y los puntos de la ruta y los sustituimos por las valores calculados en la columna H para la ruta y la columna I para los wpt.
  • Los wpt están al principio, no están incluidos entre etiquetas y con los datos que les pasamos basta. <wpt lat="42.9791983" lon="-6.1071474"><ele>1200</ele><sym>Waypoint</sym></wpt>
  • Las rutas están incluidas entre las etiquetas <rte> y </rte>, sustituimos los puntos por los creados, columna H (sin la cabecera, nos daría un error) <rtept lat="42.9791983" lon="-6.1071474"><ele>1200</ele><sym>Waypoint</sym></rtept>


Conversión de De PLT a GPX
Conversión de GPX a PLT
http://ellibrosobreexcelquenoescribirenunca.blogspot.com.es/2011/11/de-gpx-plt.html
http://ellibrosobreexcelquenoescribirenunca.blogspot.com.es/2011/11/de-gpx-plt-ii.html
http://ellibrosobreexcelquenoescribirenunca.blogspot.com.es/2011/11/de-gpx-plt-iii.html











      viernes, 5 de septiembre de 2014

      Cálculo del area de un polígono irregular

      Libro Excel

      Este libro excel, hay que descargarlo, permite calcular el área de un polígono irregular mediante el método de dividirlo en triángulos. El área de cada triángulo la calculo utilizando el teorema del coseno para calcular la altura del triángulo. De momento no presenta la gráfica del polígono, solo calcula el área.

      • Calculo el ángulo, en radianes con :=(ACOS((A3*A3+B3*B3-C3*C3)/(2*A3*B3)))
      • La altura se calcula con =A3*SENO(D3).
      • El área resultante de cada triángulo es =($H3*$B3)/2



      ¿Como utilizar el libro?


      • Dibujamos a mano alzada la parcela, mas o menos con la forma real de la parcela. 
      • Sobre el plano dividimos en triángulos.
      • Si es preciso colocamos en el terreno señales desde  donde y hasta donde medir.
      • Después de esta división en triángulos se mide, sobre el terreno, los tres lados de cada triángulo. 
      • Esos valores los llevamos a la hoja excel, solo hay una en el libro, columnas D1,L y D2. Automáticamente sale el área del triangulo en la columna I. 
      • Se necesita una fila por triangulo. 
      • Si fuese necesario habría que repetir o arrastrar la fila 3 hasta completar o igualar el número de  filas con el número de triángulos.
      • La suma de áreas está en I1. Suma desde I3 a I22. Como es lógico se debe adaptar a cada necesidad.

      lunes, 1 de septiembre de 2014

      Área de un cuadrado irregular


      Libro excel
      El otro día nos surgió la necesidad de conocer el área de una parcela, una antigua era de un pueblo castellano. En una de las entradas anteriores de este blog explico como se puede medir una superficie situando dos focos y midiendo desde esos focos a los vértices. El método utilizado para medir la era es una versión reducida del anterior, solo hay que hacer cinco medidas, pero solo vale para cuadriláteros cuyas diagonales sean interiores (mas o menos con la forma del cuadrilátero inferior). Para cuadriláteros con diagonales externas el método vale pero el área de los dos triángulos formados se resta en vez de sumarse. Es como en mi entrada anterior dedicada a este tema es un método gráfico reconvertido a excel. Desde los extremos de la diagonal trazamos con un compás  las circunferencias de radio L2 y L3. La intersección de las circunferencias nos da el vértice superior. Si repetimos la operación para L1 y L4 obtenemos el vértice inferior.
       La diagonal está en este caso es el eje X, según el dibujo.
       Con un dibujo similar a este, dibujado a mano alzada, medimos, y anotamos los valores medidos, los cuatro lados y la diagonal. Llevamos los valores medidos a la hoja "Area". 
      Con esta posición se ve claramente que el cuadrilátero se puede dividir en dos triángulos de los que conocemos, o para ser exactos, podemos conocer todos los parámetros que nos dan su área. El área del triangulo superior es D*H1/2. El área del triangulo inferior es D*H2/2 (valor absoluto de H2, sin signo).El área del cuadrilátero es la suma del área de los dos triángulos, D*(H1+H2)/2. La cuestión ahora es cuanto valen, o como calculamos, H1 y H2. 

      Los valores H1 y H2 se pueden calcular aplicando el teorema del coseno o, como en este caso, utilizando la formula de la circunferencias con radio l2 y l3 (o l4 y l1). 
      • X^2+Y^2=L_2^2 =>Y^2=L_2^2-X^2
      • (X-D)^2+Y^2=L_3^2 =>Y^2=L_3^2-(X-D)^2
      • Como las Y son iguales: L_2^2-X^2=L_3^2-(X-D)^2
      • Despejando X_1=(D^2+L_2^2-L_3^2)/(2*D)
      • De manera similar: X_2=(D^2+L_1^2-L_4^2)/(2*D)
      • Llevando X_1 a la fórmula inicial calculamos Y, que es igual a H_1. Por tanto H_1=RAIZ((L_2^2-X_1^2))
      • De manera similar, H_2=-RAIZ(L_1^2-x_2^2), incluyendo el signo.
      Todo esto es, desde el punto de vista de las matemáticas,  o relativamente sencillo o relativamente complejo, según la soltura matemática de cada cual, pero hacerlo "a mano" siempre es un poco lioso, lo ideal es utilizar una hoja de cálculo, en este caso Excel.

      • Además de calcular las dimensiones, el área, de la parcela, roto y traslado la gráfica con el fin de que cada cual la pueda ver desde el punto de vista que prefiera.
      • La rotación consiste en dejar uno de los lados sobre el eje X.
      • Una vez conocidas las coordenadas de los vértices calcular el ángulo que forma un lado con el eje x es tan sencillo como dividir el incremento de y por el incremento de x entre los vértices de un lado. Esto nos da la tangente y con ATAN calculamos el ángulo en radianes (=ATAN(($F3-$F2)/($D3-$D2))
      • El nuevo valor de x, conocido el giro, es =D2*COS(Alfa)+F2*SENO(Alfa)
      • El de y es : =F2*COS(Alfa)-D2*SENO(Alfa)
      • Donde Alfa es el ángulo seleccionado por el desplegable.
      • Por último calculo los cuatro ángulos formados por los cuatro lados. Para el cálculo de los ángulos utilizo el teorema del coseno.




      Utilizo los siguientes variables y rangos con nombre:

      Alfa=Era!$G$8
      Alfas=Era!$G$2:$G$6
      Ang=Aux!$B$1:$B$5
      D=Era!$B$1
      Eje=Era!$G$7
      H_1=RAIZ((L_2^2-X_1^2))
      H_2=-RAIZ(L_1^2-x_2^2)
      L_1=Era!$B$2
      L_2=Era!$B$3
      L_3=Era!$B$4
      L_4=Era!$B$5
      MaxX=MAX(Era!$D$2:$D$6)
      MaxY=MAX(Era!$F$2:$F$6)
      X_1=(D^2+L_2^2-L_3^2)/(2*D)
      X_2=(D^2+L_1^2-L_4^2)/(2*D)


      El libro excel no está protegido ni explicado, si alguien quiere utilizarlo solamente, los datos, diagonal y lados , se escriben en la hoja "Area"  y directamente presenta el  resultado en esa misma hoja. La forma, aproximada, de la parcela está en el gráfico Plano(2). Esta hoja presenta un desplegable que permite seleccionar el eje que va sobre el eje x.



      martes, 8 de julio de 2014

      Controlar calefacción vía internet con Excel y RealTerm



      ¿Que hace un hombre de mi edad encendiendo y apagando lucecitas? No lo he hecho como me gustaría, lo haré, pero de momento consigo encender y apagar un led a distancia, vía internet.
      Utilizo RealTerm, estaba en otro tema cuando me encontré con RealTerm, Excel y Arduino. No buscaba controlar un apagado -encendido desde la red, estaba intentado hacer una gráfica en excel  con los datos leídos y pasados por Arduino.

      • En una entrada de mi blog dedicado a Excel pongo la lista de comandos a ejecutar, enmarcados por unas palabras clave, que me permite identificar claramente el área de comandos. Tan fácil como limitar este area con "Inicio lista de comandos" y "Fin lista de comandos"
      • Con el vbasic de Excel leo periodicamente esa entrada en mi blog.
      • RealTerm es un terminal serie que permite comunicar el ordenador con Arduino, es equivalente al monitor de Arduino.
      • Para comunicar Excel y Arduino hay que insertar un objeto en la programación VBasic que nos permita esa comunicación. RealTerm tiene en internet un ejemplo incompleto de como se inserta el objeto RealTerm. Dándole vueltas y echando un poco de imaginación terminé encontrado algunas sentencias, que no encontré en internet, que me permitieron automatizar esa comunicación.
      • En Arduino preparé un pequeño programa que lee la entrada serie y que, entre otras cosas, al reconocer el comando de encendido, enciende, y al reconocer el comando de apagado, apaga.
      • Resumiendo hay tres niveles de programación, VBasic propiamente dicho, inserción de RealTerm y lo que queramos que haga el microcontrlador.


      Inserción de RealTerm:

      Sub AbreRealterm()
      Dim Puerto, Baudios, Captura, Titulo, FicCap, FicEnvio
        Set RT = CreateObject("Realterm.RealtermIntf")

       With Sheets("Aux")
        Puerto = .Range("b3").Value
        Baudios = .Range("c3").Value
        Captura = .Range("d3").Value
        FicCap = .Range("e3").Value
        FicEnvio = .Range("f3").Value
      Titulo = .Range("g3").Value
        End With
        
        
        With RT
       ' .displayas = 1
        .HalfDuplex = True
        .Caption = Titulo ' "Realterm Controlado desde Excel"

        .port = Puerto
        .baud = Baudios
        .capture = Captura 'True
        .portopen = True
       ' .capture = False
        
      '.sendfile = "c:\temp\Envios.txt" ' False
      .capturefile = FicCap '"c:\temp\Captura.txt"

        
      '  .SelectTabSheet ("I2C")
        End With


        

      End Sub



      Sub RealtermVisible()
      Sheets("Inicio").Select
      ActiveSheet.Shapes("Button 7").Select
      If RT.Visible Then
          Selection.Characters.Text = "Ver Realterm"
          RT.Visible = False
          Else
            Selection.Characters.Text = "No Ver Realterm"
          RT.Visible = True
          End If
          ActiveSheet.Range("a1").Select
      End Sub


      Sub ActualizaTerminal()
      With RT
       ' .HalfDuplex = True
        '.Caption = "Realterm Controlado desde Excel"
        '.portopen = True
        '.port = 14
        '.baud = 9600
        '.capture = "file = c:\temp\xxxx.txt"
       ' .sendfile = "c:\temp\xxxx.txt" ' False
       ' .capturefile = "c:\temp\xxxx.txt"
       ' .ansi = True
       ' .SelectTabSheet ("I2C")
        
        .capture = False
       ' .capture = True
       .sendfile = "c:\temp\Envios.txt" ' False
       .capturefile = "c:\temp\Captura.txt"
       .terminal.Clear
      '.capturestart = 0
      '.alfduplex = True
        
        End With

      End Sub


      viernes, 13 de junio de 2014

      Valor que se ve y valor real en Excel

      Estaba esta mañana trasteando con Arduino en algo relativo a fechas cuando me acorde de un pequeño problema que tuvo una compañera, hace años, al contar duraciones. No le cuadraba, no contaba bien, una de las duraciones que debía estar incluida en un determinado apartado, no lo estaba. Profundizando vimos que lo que pasaba era que aunque en la celda aparecía un valor, el valor real era unas millonésimas menor. Por tanto no debía estar incluido en ese apartado. No recuerdo los valores, lógico, pero para reproducir el incidente:
      • En A1 pongo =30/(24*60)-0,00000000001.
      • En B1 pongo =A1, pero doy formato de hora, HH:MM. Da 00:30
      • En C1 pongo =MINUTO(A1). Da 30.
      • En D1 pongo =A1*24*60. Con formato número, sin decimales o con pocos decimales. Aparece 30. Todo indica que es un valor igual a 30.
      • En E1 pongo =D1=30. Da falso. Da que D1 no es igual a 30.
      • Modifico el formato de D1. Aumento el número de decimales hasta el máximo numero de decimales o hasta que se note la variación. Aparece 29,9999999856, que efectivamente no es 30.

      martes, 13 de mayo de 2014

      Reloj digital. Formato condicional.







      No hay reloj analógico sin reloj digital. Esta es una frase rotunda, en absoluto  cierta, pero ya que hice un reloj analógico puedo hacer uno digital. Incluyo el mismo código VBasic que utilice en el reloj analógico pero solamente para refrescar el dato.
      Esta vez el reloj se basa en la posibilidad de cambiar el formato de una celda en función del valor que contenga o de el valor que tome una determinada función. En una entrada anterior, Formato condicional, Emulación de un display, ya traté este tema. Este reloj digital no supone una gran diferencia con respecto a esa entrada, es una utilización práctica de la emulación del display. En vez de uno, seis.
      Modificando el ancho y el alto de filas y columnas emulo o doy forma a 6 displays. Cada segmento, en este caso los display tienen 13 en vez de los 7 que tiene el display de la entrada anterior. Como decía, cada segmento, "luce" o "no luce" en función del número a representar. Los números a representar son:
      • H0. Parte izquierda de la hora. Para obtener la hora utilizo, dentro de una variable con nombre (HH), la función Hora(ahora()).  
      • H_1. Parte derecha de la hora.
      • M0. Parte izquierda de los minutos. Para obtener los minutos utilizo, dentro de una variable con nombre (MM), la función MINUTO(AHORA())   
      • M_1. Parte derecha de los minutos.
      • S0. Parte izquierda de los segundos. Para obtener los segundos utilizo, dentro de una variable con nombre (MM), la función SEGUNDO(AHORA())    
      • S_1. Parte derecha de los segundos.
      • La separación de los dígitos derecho derecho e izquierdo la hago con Izquierdo  Entero(HH/10),Entero(MM/10),Entero(SS/10) y Derecho HH-Entero(HH/10), MM-Entero(MM/10), SS-Entero(SS/10)
      • Estos cálculos los realizo directamente en las variables con nombre. La hoja, por tanto, no contiene nada, está vacía. La información, la hora, la presento cambiando el formato, mediante el formato condicional, de las celdas.
      • Como esta entrada está pensada para trabajar con formatos condicionales el número de segmentos es un poco indiferente, con representar razonablemente todos los números vale. La resolución de cada display depende de lo que deseemos o consideremos que es nuestro objetivo. Cuantos mas puntos mas resolución, mejor representación pero mucho mas trabajo.
      •  Si aumentamos el número de puntos aumentamos el número de funciones que los controlan.
      • Cada punto tiene su propia función.
      • Dibujamos (incluso a mano alzada), los n segmentos.
      • Número a número "dibujamos", realzando, los segmentos que hacen que se vea cada número.
      • En principio la función obtenida, o al menos la mas sencilla de sacar, es del tipo O. Se puede leer "este segmento se enciende cuando H0 vale 0 o cuando vale 2 o cuando vale 6 ..."  (=O(M0=0;M0=2;M0=6;M0=8))
      • Algunas de las funciones obtenidas  se pueden simplificar mediante la función Y, (=Y(H0<>5;H0<>6)), que se puede leer "este segmento se enciende cuando H0 es distinto de 5 y H0 es distinto de 6". Esta función da los mismos resultados que O(H0=0;H0=1;H0=2;H0=3;H0=4;H0=7;H0=8;H0=9;)

      jueves, 10 de abril de 2014

      Reloj Analógico. Gráfica XY dinámica.






      Funciones utilizadas:
      Ahora()
      Residuo()
      Pi()
      Entero()
      Seno()
      Cos()
      Radianes()


      Variables y rangos con nombre:

      Fech
      Horas
      Minutos
      RadHora
      RadMin
      RHora
      RMin
      RReloj
      Segundos
      SegX
      SegY
      XHora
      XSeg:RMin*(SENO(RadMin*Segundos))
      XSeg2:
      RMin*(SENO(RadMin*ENTERO((RESIDUO(AHORA();1)*24*60)*60)))
      YHoras:RHora*(COS(RadHora*Horas))
      YSeg: RMin*(COS(RadMin*Segundos))

      El objeto de este ejercicio es representar un reloj analógico mediante un gráfico xy de excel. Aunque incorporo algo de  programación, el cálculo de los valores de la gráfica lo hago mediante fórmulas excel. Podría hacerlo por programa, pero no es el objeto del ejercicio.

      • La gráfica emula el aspecto de un reloj clásico.
      • Una corona circular dividida en 60 partes, para 60 minutos. 
      • Otra, situada sobre la anterior, dividida en 12 partes, para las 12 horas.
      • Una manecilla de horas. Esta manecilla se debe mueve de manera continua, sin saltos.
      • La hora podría calcularla mediante la función =HORA(A1) pero esto haría que la manecilla se moviese a saltos de una hora, la función hora solo cambia de valor cada hora. Para evitar ese salto calculo la parte no entera de la fecha (vease sistema de fechas en excel)  y la multiplico por 24.  horas = RESIDUO(AHORA();1)*24 y Fech=RESIDUO(AHORA();1)
      • Un minutero. Esta manecilla se debe mover de manera continua, sin saltos.
      • Los minutos podría calcularlos mediante la función =MINUTO(A1) pero esto haría que la manecilla se moviese a saltos. Para evitar ese salto, calculo la parte no entera de la  hora (vease punto anterior)  y la multiplico por 60. minutos=RESIDUO(Fech*24;1)*60.
      • Un segundero. Esta manecilla se mueve de segundo en segundo. ENTERO(RESIDUO(Fech*24*60;1)*60) . Aquí si podría haber utilizado la función SEGUNDO()
      • Los puntos de corona que representa los  minutos las calculo en las columnas M y N de la hoja AUX. Sesenta y un puntos  aunque el último coincide con el primero con el fin de cerrar el circulo (360º/60 = 6º por punto). Cada punto esta calculado en función del radio de la corona y del seno y coseno del ángulo. 60 separaciones dan un efecto circular, no es un circulo pero lo parece.
      • Los puntos de corona que representa las horas las calculo en las columnas I y J de la hoja AUX. Trece puntos calculados en función del radio y del seno y coseno del ángulo . En este caso las 12 separaciones no son suficientes para parecer un círculo, por lo que, manualmente, al preparar la gráfica, elimino los segmentos que unen los puntos entre si.
      • Las tres manecillas tienen un punto común, el centro del reloj, el 0,0.
      • Los puntos para la hora los calculo a partir de un radio mediante el seno y coseno del  ángulo resultante de multiplicar la hora (función Hora()) por 30º (columnas AB), pero convertidos a radianes, que es como se calculan los valores trigonométricos en excel. A su vez hago el cálculo de los valores XY en una variable con nombre, en vez de en una celda. Minutos y segundos utilizan un ángulo de 6º (columnas CD y EF)
      • La actualización de la hora representada en el gráfico se puede hacer mediante la tecla F9. Funciona pero queda poco bonito, poco útil. Incorporo el mínimo código vbasic que permite actualizar, cada segundo, el reloj.

      Código utilizado para actualizar el reloj:

      El procedimiento Auto_Open se ejecuta al abrir el libro, es el primer procedimiento que se ejecuta. En este caso se limita a seleccionar la hoja RELOJ y a lanzar el procedimiento "RECALCULA"
      Public Proc
      Sub Auto_open()
      Sheets("Reloj").Select
       Proc = "Recalcula"
      Recalcula
      End Sub




      El procedimiento Recalcula recalcula el valor de las fórmulas y prepara la siguiente su siguiente ejecución. Es decir se llama si mismo, pero un segundo después, mediante  el evento, del objeto application, OnTime. La instrucción .OnTime Now() + 0.0000115741 * 1, Proc  se puede leer "Cuando sea la hora actual mas un segundo (0.0000115741 es 1/(24*60*60)) ejecuta el procedimiento Proc. Actualizar un libro excel cada cierto tiempo es así de sencillo.


      Sub Recalcula()
      'Dim Proc


        With Application
        .ScreenUpdating = False
         Calculate
         .ScreenUpdating = True
      .OnTime Now() + 0.0000115741 * 1, Proc 
        End With
        

      End Sub








      miércoles, 26 de febrero de 2014

      Desafío del profesor Letona del 26/02/2014

      Libro EXCEL



      El profesor Letona, para los que no lo sepan, es un tipo que habla de matemáticas en el programa de RNE de las tardes. Normalmente habla los viernes por la tarde y a mi me suele pillar conduciendo. No se porque esta semana ha hablado el Martes, y me ha pillado en casa. La prueba, o al menos lo que yo he entendido es que se debe encontrar el máximo resto que se puede dar al dividir un número de dos cifras entre la suma de esas cifras. Hecho con Excel, sin mas. De momento no se si voy a pensarlo mas. Si me decido ( y lo encuentro) ya subiré los resultados.

      Funciones utilizadas:
      • Derecha(). Separo el número de la derecha.
      • Izquierda(). Separo el número de la izquierda.
      • Revisando, me acabo de dar cuenta de que tengo un error en las cabeceras Izquierda y Derecha, estan cambiadas de posición.
      • Operación suma. Los sumo (I+D).
      • Residuo(). Calculo el resto de dividir el número por i+d.
      • Max(). Encuentro el máximo de los restos.
      • Coincidir(). Encuentro la línea en la que está ese máximo.
      • Indice(). Presento el valor encontrado.
      • Esta vez no utilizo ni rangos ni variables con nombre.



      sábado, 25 de enero de 2014

      Forma y tamaño de un área. Encimera de mi cocina.









      Tengo que cambiar la encimera de cocina, he retirado un mueble y eso me obliga a cambiar la encimera. Para medir la parte de la cocina que ocupa la encimera utilizo un método gráfico reconvertido a excel . 

      El método gráfico consiste en:
      • Hay que dibujar un plano a mano alzada de la zona a medir. 
      • Sobre el lugar, en mi caso sobre la encimera actual, situamos o marcamos dos focos (F1,F2) o puntos desde los que se va a medir las distancias a los vértices, procurando que desde cada foco se vean los vertices. Si no se viesen, habría que situar otros focos secundarios, lo que complica el dibujo. Mides la distancia entre focos y las anotas en el plano. 
      • Mides la distancia entre cada vértice y los dos focos (las anotas).
      • Para dibujar el plano gráficamente primero dibujas a escala los focos y con un compás, también a escala, con radio igual a la distancia entre F1 y el punto trazas un arco y entre F2 y el punto trazas otro arco. La intersección de los arcos supone que sitúas sobre el plano, ya a escala,  el punto o vértice.
      • Vamos a dibujar el plano convirtiendo este método gráfico a un gráfico xy de excel.
      • Si dibujas los dos focos , el punto, y los unes, veras que forman un triangulo. De ese triangulo conoces los tres lados.



      • Para pasar a coordenadas cartesianas utilizamos, en un primer paso, la línea que une ambos focos como eje  X y F1 como cero del eje X.
      • En el libro excel situamos la distancia entre focos en la hoja Puntos!$A$2. Este celda, a su vez, la utilizo para dar valor a la variable DF.
      • Aplicando el teorema del coseno, según la imagen, calculamos el coseno del ángulo (en el libro excel hoja puntos rango E2:E10). A partir del coseno calculamos el ángulo y, conocido el ángulo, calculamos el seno (rango F2:10). 
      • Conocidos seno, coseno y distancia (D) entre F1 y el punto, x=D*cos, y=D*sen (Puntos!I2I10 y Puntos!J2J10).  El ángulo se calcula a partir del coseno. En realidad ese cálculo da dos resultados (+ -) lo que si afecta al valor de Y. Por eso introduzco, a mano, un factor (1 o -1) para el signo de Y, uno si el valor de Y está por encima del eje X y menos uno si está por debajo.
      • Puede suceder que haya  una esquina a la que no se  llegue, o no te apetezca mover el microondas (en mi caso). Si podemos suponer que las paredes son lineales se puede calcular la intersección de dos líneas (puntos realzados en el libro excel, rango K6:N6 ).
      • Una vez calculados los distintos X,Y se pasan un gráfico de excel XY. Modificas el gráfico para que X e Y tengan la misma escala y la retícula tenga el mismo tamaño por unidad para el eje X y para el eje Y.
      • Esta primera gráfica nos coloca en una posición poco útil el plano, por eso es conveniente tener la posibilidad de disponer de un cambio de ejes.  En este caso lo he preparado para que cada cambio de eje ponga uno de los lados  paralelo al eje X.
      • Cada lado forma un ángulo con respecto al eje definido por los dos focos. Como tengo al menos dos puntos por pared (línea) calculo ese ángulo encontrando primero la pendiente de la línea, (y2-y1)/(x2-x1), (hoja puntos, rango K3:K9) para después hcer una rotación de ejes utilizando ese ángulo.
      • Paso estos valores a las variables Eje1,Eje2,Eje3 y Eje4. En la siguiente versión el cálculo se puede efectuar directamente al dar valor a la variable, en vez de Eje2=Puntos!K6, Eje2=(Puntos!J6-Puntos!J5)/(Puntos!I6-Puntos!I5).
      • Ordeno un poco el tema de los ejes el la hoja Ejes. Paso los valores de las pendientes al rango A3:A6, calculo seno y coseno correspondientes en B2:B6. 
      • Ejes!F3 es la celda vinculada al desplegable de selección de eje. El valor del seno y del coseno seleccionado los sitúo en Ejes!G3 y en Ejes!F3, mediante la función =ÍNDICE($D$2:$D$6;$F$3). Esta operación se podría hacer asignando estos valores directamente a una variable.
      • Además de rotar, desplazo los ejes para que no haya valores, ni de X ni de Y por debajo de 0. Para ello calculo los valores mínimos de X y de Y (función MIN()). Esta operación de puede hacer directamente sobre una variable. 
      • Los valores rotados y desplazados, rango CambioEjes!G2:H10 ,los llevo a otra gráfica XY con un desplegable que me permite seleccionar la posición en la que quiero ver el plano.

      Hay que medir con mucha exactitud, una diferencia de medio centímetro, en estas dimensiones, produce un gran error. Si mides bien el resultado es bastante exacto.

      miércoles, 23 de octubre de 2013

      Entrada analógica microprocesador.Cálculo de una botonera.

      Ahora me dedico al cacharreo con el microprocesador Arduino Uno. Este microprocesador dispone de varias entradas o salidas digitales y de varias entradas analógicas. Las entradas analógicas hacen la conversión de un valor de tensión analógico (de 0 a 5V) a un valor digital comprendido entre 0 y 1023. Una botonera son varios botones, normalmente mas de uno, que según se pulse uno u otro botón la acción a realizar es distinta. 

      Este diseño de botonera ocupa una sola entrada analógica del microprocesador Arduino UNO. Consta de N resistencias en serie y de N-1 pulsadores de los que cierran el circuito al pulsarlos. Mientras no se pulse el botón el circuito permanece abierto.




      • Uno de los terminales de los pulsadores va a la línea de tensión positiva y el otro terminal se situa entre dos resistencias.
      • Los pulsadores cortocircuitan todas las resistencias situadas entre sus  contactos, según el gráfico. El primer interruptor cortocircuita todas las resistencias situadas por encima de R0, el segundo todas las situadas por encima de R1, el tercero todas las situadas por encima de R2, etc...
      • La  entrada analógica va conectada al punto de unión de R0 y R1, salida de la botonera. 
      • Al pulsar cada uno de los botones varía el nivel de tensión de salida. El cálculo de los valores de R para obtener un valor deseado es sencillo, pero un poco pesado. Por eso he preparado un libro excel que realiza estos cálculos.
      •  Parto del supuesto que  dos botónes consecutivos presentan un salto de tensión equivalente (1023/Num. Int.).
      •  Una vez calculados los valores teóricos de las resistencias busca los valores comerciales mas próximos.
      •  Una vez conocidos los valores comerciales de las resistencias calcula los valores que leerá la entrada analógica del microcontrolador.
      •  El libro excel está preparado para calcular botoneras de hasta 20 botones.


      • En  la columna B de la hoja "Botonera" calculo el valor digital que debe tomar la salida.
      • No voy a explicar como se despeja una ecuación con una incógnita. En la columna C de la hoja "Botonera" calculo un factor X por el que hay que multiplicar R0 para obtener las distintas Rn.
      •  Con esto encuentro los valores teóricos exactos que satisfacen las necesidades de la botonera.
      • Los valores teóricos obtenidos normalmente no coinciden con los valores comerciales de las resistencias. Para encontrar los valores comerciales mas próximos a los teóricos utilizo =COINCIDIR($E2;Resistencias;1). Esta formula devuelve la línea en la que está el último valor menor o igual al buscado.
      • Con los valores comerciales encontrados repito los cálculos para saber el valor digital correspondiente.
      • Repito los cálculos con los valores comerciales inmediatamente superiores a los teóricos.
      • Hay que repetir los cálculos n veces, una para cada resistencia, este es un trabajo típico de hoja de cálculo.




      viernes, 15 de marzo de 2013

      Números primos y conjetura de Goldbach.




      Pequeña y poco útil herramienta, ¿ alguien se ha encontrado en el  mundo real con la necesidad de saber si un número es primo o no?  ,para saber si un número es primo o no y para saber cuales son los dos números primos que sumados dan un número par determinado.
      Funciones utilizadas:
      1. Coincidir()
      2. Indice()
      3. Si()
      4. Entero
      Rangos o variables con nombre:
      1. CGB=ConjeturaGoldbach!$B$1
      2. Num=Primo!$B$1
      3. Primos=NPrimos!$A:$A
      4. RaizNum=ENTERO(RAIZ(Primo!$B$1))
      5. RanSum=INDIRECTO("$g$3:$g" & Primo!$D$1+1)
      6. UCoin=Primo!$D$1

      ¿ Como podemos calcular si un número es primo o no? En principio un número primo es aquel que solo es divisible por uno o por si mismo. Si un número no es primo tiene al menos dos divisores, uno con un valor inferior a su raíz cuadrada  y el otro con un valor superior a esa raíz, salvo en el caso de que su raíz cuadrada sea un valor entero, en el solo podemos asegurar un divisor. Además al menos uno de los divisores es un número primo. Por tanto, para calcular si un número es primo, o no, se puede dividir por todos y cada uno de los números comprendidos entre el entero de su raíz cuadrada y dos. Si una de esas divisiones nos da entero, en número no es primo y si en ninguna de ellas nos da entero el número es primo. Este es el camino largo, para acortar el proceso basta con dividir por los números primos que hay entre su raíz cuadrada y dos. Es mas complejo pero permite, dadas las limitaciones del Excel, aumentar el máximo numero a comprobar. En la hoja de cálculo utilizo este segundo método. Los 65536 primeros números primos los encuentro mediante programación, con la siguiente subrutina:

      Sub NumPrimos()
      Dim N, I, X As Double, Es
      N = 2
      I = 1
      Sheets(1).UsedRange.Clear

      While N < 65536

      I = I + 2
      X = Int(Sqr(I))
      Es = True
      For j = X To 2 Step -1
      If I / j = Int(I / j) Then
      Es = False
      Exit For
      End If
      Next
      If Es Then
      N = N + 1
      Sheets(1).Range("a" & N).Value = I
      End If

      Wend

      End Sub

      La hoja NPrimos contiene los 65536 primeros números primos, en la hoja "Primo" hago encuentro si un numero es primo o no. En la hoja "ConjeturaGoldbach" encuentro al menos una pareja de números primos que sumados dan un determinado número par.  El mecanismo de funcionamiento exige, en ambas hojas, activar el filtro después de escribir el número, eligiendo 1 en el desplegable de valores de la columna G en Primo y de la columna I en la conjetura.

      Números primos. Hoja "PRIMO":

      1. El numero a procesar se escribe en B1 (variable con nombre Num)
      2. Incluyo en la columna C, a partir de la línea 3, los números enteros del 0 al  655333.
      3. En D1, mediante la fórmula =COINCIDIR(RaizNum;Primos;1) (ver rangos y variables con nombre) , localizo el mayor número primo que es menor o igual al entero  de la raíz cuadrada del número.
      4. En la columna E divido el número Num por los números primos menores al primero encontrado. Para ello utilizo la función  =Num/INDICE(Primos;UCoin-$C3). Esta función produce un error cuando UCoin-$C3 es menor que uno.
      5. En la columna G, mediante la función condicional =SI(ENTERO($E3)=E3;1;0) indico que si el resultado de la división del apartado anterior es entero de un uno y si no un cero.
      6. Sumo la columna G en la variable con nombre RanSum ,=INDIRECTO("$g$3:$g" & Primo!$D$1+1). Si un número no es primo tiene varios divisores primos, hasta llegar a uno, y si lo es solo tiene uno, el uno. En ambos casos hay que sumar hasta la línea del uno, pero no incluirla. Esto significa que si el último primos menor o igual a la raíz está en la línea N hay que sumar N-1 terminos. Como empezamos el la línea tres, corregimos la fórmula hasta D1+1. No es necesario gestionar los errores dado que solo utilizamos el rango en el que no se ha producido ninguno.
      7. En H, mediante la función condicional =SI(SUMA(RanSum)=0;"Es primo";"No es primo") presento el resultado del proceso. 
      8. Lamentablemente el filtro no se actualiza automáticamente, hay que activarlo cada vez, seleccionando uno en G.

      Hoja ConjeturaGoldbach:

      1. El número par a comprobar se sitúa en B1. 
      2. Cálculo la mitad de ese número en d1.
      3. Encuentro el mayor número primo que es menor o igual a la mitad del número procesado.
      4. El algoritmo consiste en restar cada número primo inferior a igual a la mitad del número procesado, restarlo del número para después encontrar, media la función COINCIDIR, el último primo menor que el resultado de la resta. Si este segundo número primo encontrado sumado al primero suman igual que el número procesado la conjetura se cumple. En la columna I, mediante el condicional SI se prepara, mediante 0 o 1 la selección del par de primos que hacen que la conjetura se cumpla.
      5. Lamentablemente el filtro no se actualiza automáticamente, hay que activarlo cada vez, seleccionando uno en I.









      jueves, 7 de marzo de 2013

      Conversión de ficheros formato Kml a formato PLT


      Y a formato GPX. Un fichero KML es uno de los tipos de fichero que utiliza  Google Hearth para representar una ruta. Es un fichero de texto leíble con cualquier editor de textos.
      Una ruta en formato KML esta formada por una serie de comandos XML. Cada comando está dedicado a un tema, cabecera, nombre, el color, etc... Aquí solo nos interesan las coordenadas, que son una única línea en la que están todos los puntos de una ruta separados por un espacio. Cada punto, a su vez, está formado por un valor X para la longitud, un valor Y para la latitud y un valor Z para la altura, separados por comas X,Y,Z 
      Esta estructura de datos nos crea un problema a la hora de trabajar con ellos en Excel, los datos no vienen en columnas, vienen en una sola línea, lo que junto a que una hoja excel tiene 256 columnas como máximo y a que el número de caracteres en una celda también es limitado nos impide trabajar, al menos, con rutas de mas de 256 puntos.
      Cuando empecé este trabajo no tuve en cuenta estas limitaciones, me limité a abrir el fichero KML con excel y a procesar la línea con los puntos de la ruta. En esta primera forma de trabajar , durante el primer paso, necesitaba una columna por punto. Esta la limitación de 256 columnas me impedía trabajar rutas de mas 256 puntos. Posteriormente pensé ¿Como convierto esa línea de n puntos en una columna con n líneas de un punto? Se puede hacer y de hecho es relativamente sencillo. Como he dicho estos ficheros son editables con cualquier editor de textos, en mi caso utilicé el bloc de notas. 
      • Hacemos una copia del fichero KML, pongamos pru.kml, y la abrimos con el bloc de notas.
      • Eliminamos todas las líneas de comandos y nos quedamos solo con la enorme línea con los puntos de la ruta.
      • Delante de esa línea insertamos <table><tr><td>
      • Como en este caso el separador de los puntos de la ruta es un espacio sustituimos ese espacio por <tr><td>. Accedemos a la utilidad de reemplazar, escribimos un espacio en la casilla "buscar" y <tr><td> en la casilla "reemplazar por". Pulsamos reemplazar todo.
      • Añadimos después de la línea con los puntos </table>
      • Guardamos el fichero con "Guardar Como" cambiando la extensión del fichero a HTM. Pongamos pru.htm
      • Con el botón derecho del ratón (botón secundario) abrimos este fichero htm con excel. Por lo menos en mi PC funciona, ya tenemos la línea convertida en columna.
      • Copiamos la columna, con pegado especial-> Valores, a un libro nuevo.
      • En este punto hay que separar los distintos X,Y,Z de cada punto. Con Datos->texto en columnas los vamos a separar.
      • Seleccionamos la columna completa. Datos->Texto en columna, delimitados. En este caso el separador en una coma.
      • A la hora de convertir un punto de formato no vamos a tocar ni el valor X ni el Y. El valor Z lo tenemos que convertir a pies, por lo que tiene que ser numérico.
      • En el paso 3 de la conversión seleccionaríamos los dos primeros campos (X e Y) como texto y par el tercero, la altura, lo dejamos como "General" y con la opción avanzadas indicamos que el separador decimal es un punto y el separador de miles es una coma. Indicamos la celda de destino y finalizamos.
      • Para pasar la altura de metros a pies divido la altura en metros por 0,3 y ya de paso redondeo el resultado. Utilizo  la función =REDONDEAR(C1/0,3;0) 
      • El resto es concatenar los distintos valores XYZ para que tengan la estructura de los distintos formatos OZIEXPLORER o GPX.
      • Añadimos los valores en los ficheros de texto que tengamos preparados con cabeceras y colas, y ya podemos funcionar.
      Conversión de De PLT a GPX
      Conversión de GPX a PLT
      http://ellibrosobreexcelquenoescribirenunca.blogspot.com.es/2011/11/de-gpx-plt.html
      http://ellibrosobreexcelquenoescribirenunca.blogspot.com.es/2011/11/de-gpx-plt-ii.html
      http://ellibrosobreexcelquenoescribirenunca.blogspot.com.es/2011/11/de-gpx-plt-iii.html




      martes, 19 de febrero de 2013

      Separar nombres y apellidos II

      Antes de nada voy a explicar como se maneja esta herramienta. Este libro tiene dos hojas, una de ellas (hoja "Nombres") contiene los nombres  mas habituales, sin acento y otra con la relación de nombres completos a separar (hoja "Personal"). Su uso es tan fácil como:

      • Habilitar macros.
      • Eliminar las líneas usadas anteriormente en la hoja Personal. Eliminarlas, no borrarlas.
      • Copiar en la columna D de la hoja personal la lista de los nombres completos.
      • Si fuese necesario hay que eliminar los dobles espacios.
      • Realizar el proceso automático.
      • Realizar el proceso manual.
      • La búsqueda de nombres se basa en la lista de nombres. Si Se  añaden nuevos nombres a la lista de la hoja Nombres esta búsqueda mejora. No es necesario ni ordenarla ni que solo aparezca solo una vez cada nombre, se pueden repetir. Los nombres se deben añadir sin acento. 

      He logrado encontrar un algoritmo que me permite separar nombre y apellidos de manera automática. No todos, calculo que quizás no encuentre bien menos 10% de los nombres, o no los encuentra o los encuentra mal, pero encuentra mas del 90%.
      Los apellidos simples los encuentra todos si el nombre no es compuesto y casi todos si el nombre es compuesto.
      Los apellidos compuestos, algunos de ellos para saber como van hay que hablar con el sujeto en cuestión, creo que tiene un acierto mayor al 80%. El resto hay que resolverlos a mano.
      Mi algoritmo está pensado para nombres compuestos de hasta cuatro palabras, dos nombres y dos partículas, del tipo "María de las Mercedes". Este algoritmo no contempla un nombre compuesto de mas de dos nombres. De los apellidos compuestos solo estudio dos  palabras, para saber si son partículas. 
      Recordemos que en la composición de nombres y apellidos, en algunas de sus opciones, no se dan certezas, se dan casos mas probables.

      Para nombres:
      • He recopilado los 380 nombres mas comunes en España. En este caso necesito saber si una palabra esta incluida en la relación de nombres.
      • Cuento el número de palabras del texto con el nombre y apellidos. Para que uno de esos textos tenga un nombre compuesto o un apellido compuesto debe tener mas de tres palabras. 
      • Si tiene tres palabras, la primera es el nombre, la segunda es el primer apellido y la tercera es el segundo apellido. Las separaciones las indican el primer y segundo espacio del texto.
      • Si tiene cuatro puede tener un nombre compuesto de dos palabras (José María), la primera y la segunda palabra. Hay que comprobar si esa segunda palabra está en la relación de nombres. Si lo esta la separación entre el nombre, en este caso compuesto, es el segundo espacio, si no es el primero.
      • Si tiene cinco puede tener un nombre compuesto de tres  palabras, dos nombres y una partícula (María del Carmen). Si la segunda palabra es nombre se aplica el anterior punto. Si no es nombre lo supongo partícula y compruebo que la tercera palabra sea nombre. Debería comprobar que la segunda palabra fuese una partícula pero, con estos niveles de error, da un poco lo mismo. Además el algoritmo está pensado para funciones Excel no para programación, lo que multiplicaría por mil las funciones anidadas. Si la tercera palabra es nombre la separación es el tercer espacio. Si no, el primero.
      • Si tiene séis puede tener un nombre compuesto de cuatro  palabras, dos nombres y dos partícula (María de las Mercedes). Si la segunda palabra es nombre se aplica lo dicho en puntos anteriores. Si no es nombre lo supongo partícula y compruebo que la tercera palabra sea nombre, como en el anterior punto. Si la cuarta palabra es nombre  la separación es el cuarto espacio. Si no, el primero.

      Resumiendo: 

      • Si el texto tiene  cuatro o mas palabras (>=4) y la segunda palabra es nombre la separación la da el segundo espacio.
      • Si el texto tiene  cinco o mas palabras (>=5) y la segunda palabra es una partícula y la tercera es nombre la separación la da el tercer espacio.
      • Si el texto tiene  seis o mas  palabras (>=6) y la segunda palabra es una partícula y la tercera es nombre la separación la da el cuarto espacio espacio.
      • En todos los demás casos la separación la da el primer espacio.


      El formulón que resuelve este algoritmo es:

      =SI(P1<=3;1;SI(Y(NO(ESNOD(COINCIDIR(J1;Nom;0)));P1>=4);2;SI(Y(NO(ESNOD(COINCIDIR(K1;Nom;0)));P1>=5);3;SI(Y(NO(ESNOD(COINCIDIR(L1;Nom;0)));P1>=6);4;1))))

      En Donde:

      •  P1 (columna P) es el número de palabras del texto original.
      • J1 (columna J) es la segunda palabra, K1 la tercera y L1 la cuarta.
      • El rango con nombre Nom es =Nombres!$A:$A
      • Durante la fase de desarrollo separé las palabras del texto mediante la opción "Texto en Columnas". El número de palabras la calculé con =SI(L1="";3;SI(M1="";4;SI(N1="";5;SI(O1="";6;7))))
      Podía haber separado mediante una fórmula similar los apellidos, pero dado que es realmente farragoso y que además es un trabajo dedicado a mi esposa, ella lo va a utilizar, decidí pasarme a la programación.

      Para apellidos estudio las tres palabras siguientes al nombre o nombre compuesto encontrado. Los casos encontrados y su respuesta mas probable son:

      • Si primera de estas palabras es partícula y la segunda no (Del Corral) la separación se produce dos espacios después del nombre.
      • Si esas dos palabras son partículas (De la Parra) la separación es tres espacios después del nombre.
      • Si después del nombre hay cuatro o mas palabras y ninguna de las tres primeras es una partícula la separación se produce dos espacios después del nombre.
      • Si después del nombre hay cuatro o mas palabras y la primera no es partícula, la segunda si y la tercera no la separación se produce tres espacios después del nombre.
      • En todos los demás casos la separación se produce un espacio después del nombre.
      Las partículas que considero son: "de" , "del" , "la" , "los" , "las", "a", "as", "o", "os", "y", "i", "do" , "dos", "van", "den", "san" 







      viernes, 8 de febrero de 2013

      Como crear nuestras propias funciones en Excel.

      En alguno de los ejemplos anteriores he expuesto algunas funciones anidadas realmente complejas. Si nos encontramos con un caso de estos, funciones complejas, situaciones difíciles de calcular con las funciones propias de Excel, podemos crear con VBasic nuestras propias funciones.
      En programación una función es una subrutina que devuelve un valor. En VBasic estas subrutinas se utilizan:

      • Function NombreFunción(Parametro1,parametro2,....)
      • operaciones necesarias para obtener el resultado
      • NombreFunción=resultado
      • end function
      Para utilizar estas funciones hacemos como con las funciones propias de Excel, nos situamos en lacelda correspondiente y escribimos =NombreFunción(Param1;Param2;....)

      Como ejemplo:

      Function XCart(Dist, Rumbo)

      XCart = Dist * Sin(3.14159265358979 * Rumbo / 180)

      End Function

      Esta función pasa los grados sexagesimales del parámetro Rumbo a radianes y calcula la el valor de la proyección del parámetro Dist en función del seno del rumbo.

      Para utilizarla dentro de una hoja de cálculo, situándonos en la celda correspondiente:
      =xcart(F3;I3)

      jueves, 7 de febrero de 2013

      Subrutina o Subprograma.


      • En computación, una subrutina o subprograma (también llamada procedimiento, función o rutina), como idea general, se presenta como un subalgoritmo que forma parte del algoritmo principal, el cual permite resolver una tarea específica. Algunos lenguajes de programación, como Visual Basic .NET o Fortran, utilizan el nombre función para referirse a subrutinas que devuelven un valor.
      • Se le llama subrutina a un segmento de codigo separado del bloque principal y que puede ser invocado en cualquier momento desde este o desde otra subrutina.
      • Las subrutinas permiten realizar separadamente del programa principal determinadas tareas repetitivas. Normalmente para utilizarlas es necesario pasarles unas variables de trabajo (parametros).
      • Las subrutinas facilitan la estructuración del programa. Cuando el programa principal llama a una subrutina para que ésta se ejecute, la subrutina procesa su programa hasta el final. El sistema retorna luego el control al segmento del programa principal desde donde se llamó a la subrutina.
      • Las subrutinas sirven para estructurar o dividir el programa en bloques más pequeños y, por tanto, más fáciles de gestionar. Los bloques más pequeños facilitan la comprobación y la eliminación de errores tanto en las subrutinas como en el programa entero.
      • Básicamente una Subrutina es un segmento de código que se escribe sólo una vez pero puede invocarse o ejecutarse muchas veces. Existen dos tipos: Procedimientos y Funciones.
      • Procedimientos: Son un tipo de subrutina que ejecuta un conjunto de acciones sin devolver valor alguno como resultado de dichas operaciones. 
      •  Funciones: A diferencia de los procedimientos, las funciones después de ejecutar un conjunto de acciones devuelven sólo un valor del tipo usado en la declaración de ésta.




      lunes, 4 de febrero de 2013

      Comprobar la existencia de una hoja.

      Al trabajar con VBasic muchas veces necesitamos utilizar una hoja, que puede que no exista, que hay que añadir, o puede que ya exista, con lo que no hay que crearla. Una manera de gestionar este tipo de asuntos es gestionar los errores que puedan producirse. La gestión de errores al  intentar utilizar una hoja, si no existe, nos da un error (<>0) y si existe nos da una ausencia de error (0), lo que de una manera simple nos permite saber si una hoja existe o no. Conocido el error o la ausencia de este procedemos a crear la hoja, si fuera necesario.
      En VBasic hay una primera función para controlar los errores, la función Err. Esta función devuelve un valor numérico. Si no se produce un error devuelve cero y dependiendo del error, un número distinto de cero. Por otra parte los errores en tiempo de ejecución detienen el proceso. Para evitar que el proceso se detenga al aparecer un error utilizamos la instrucción On Error Resume Next. Debemos recoger el error inmediatamente después de producirse, en la siguiente instrucción, E = Err. Al terminar la gestión del error debemos activar de nuevo la detención de la ejecución al producirse un error, mediante On Error Goto 0.
      En esta rutina además de comprobar la existencia de la hoja, en caso de que no exista, la crea.


      Sub Comprueba(Hoja)

      On Error Resume Next

      Set h = Sheets(Hoja)

      E = Err

      On Error GoTo 0

      If E <> 0 Then

      Sheets.Add.Name = Hoja 

      End If

      End Sub 
      Preparamos la gestión.


      Provocamos el error.

      Guardamos el error en una
       variable.
      Reactivamos la detención.

      Si el error es distinto de

      cero.
      Añadimos una hoja.