Páginas

viernes, 20 de noviembre de 2015

Python: Funcion para crear un numero de identidad basado en la fecha

 
from datetime import datetime

def create_id(prefix = "test"):
    '''creates id with a prefix chosen by user'''
    thisday = datetime.now()
    return prefix+str(thisday.year)+str(thisday.month)+str(thisday.year)+ str(thisday.hour)+str(thisday.minute)+str(thisday.second)
    
if __name__ == "__main__":
    new_id = create_id("RUBEN")
    print new_id

viernes, 23 de octubre de 2015

Test sobre Valoracion Aduanera en los Estados Unidos

Para mis amigos profesionales del comercio exterior, una vez mas pónganse a prueba!

Cuales de los siguientes Incotermos son utilizados por la aduana de los Estados Unidos como base imponible para el cálculo de los impuestos a la importación?
  • FAS
  • FOB
  • CIP
  • CIF
  • CPT
  • FCA
  • CFR

jueves, 22 de octubre de 2015

VBA Excel: Como abrir, pasar y extraer datos de una pagina web usando Macros.

Hace poco mas de un año escribí un post sobre como abrir una pagina web desde excel, pero viéndolo bien, estába un poco complicado. Así que decidí hacer una nueva publicación un poco mas didáctica y fácil de reproducir por cualquiera que desee intentarlo.

Esta macro entra al sitio web de Airbnb y extrae los precios que se despliegan en la primera página de resultados. Las técnicas que se utilizan en este ejemplo pueden servir para que cada uno las aplique a algun otro tipo de investigación para su trabajo o estudio.

Comenzamos con un archivo en el cual ingreso una ciudad, fecha de check in, fecha de salida y número de huéspedes. Las celdas de fecha tienen formato de texto para que coincida con el formato que exige la página.


 Antes de escribir el código, debemos incluir las librerías que nos permiten acceder a los controles de internet que vamos a utilizar, eso lo hacemos en el editor de visual basic, en tools/references. Allí seleccionamos las opciones que vemos a continuación (Microsoft Internet Controls y Microsoft HTML Object Library):



Ahora sí comenzamos a escribir la macro:


Sub navegar()

'las declaraciones son opcionales, pero ayudan a visualizar las opciones mientras se digita
Dim ie As InternetExplorer
Dim pagina As HTMLDocument
Dim buscar As HTMLButtonElement
Dim precios As Object
Dim precio As Object

'crea el explorador de internet
Set ie = New InternetExplorer

'hacemos visible el explorador
ie.Visible = True

'navega a la página de aribnb
ie.navigate "https://www.airbnb.com/"

'espera a que la página cargue
Do
DoEvents
Loop Until ie.readyState = READYSTATE_COMPLETE

'la página cargada la asignamos a la variable "pagina"
Set pagina = ie.document

Interrumpo el código para explicar algo: Para ir llenando los campos que pide la página, con hacer click en el boton derecho e "inspeccionar elemento" podemos identificar los nombres de cada campo:



El campo de la ciudad, que se llama "location":

El campo para la fecha de check in, se llama "checkin":

El campo de check out es "checkout":

La lista de huéspedes, tiene un id ("guests") y a su vez varias opciones dentro de si:

Y el botón de enviar, que tiene el id "submit_location":

Ahora que ya sabemos como ubicarlos, procedemos a pasarles valores los cuales tomamos del libro de excel:


'asignamos el valor de una ciudad
pagina.getElementById("location").Value = Range("B1").Value

'esperamos un segundo para que puedas visualizar los cambios que estas realizando
Application.Wait (Now + TimeValue("0:00:02"))

'pasamos a "checkin" la fecha de ingreso
pagina.getElementById("checkin").Value = Range("B2").Value

Application.Wait (Now + TimeValue("0:00:02"))

'pasamos la fecha de check out
pagina.getElementById("checkout").Value = Range("B3").Value

Application.Wait (Now + TimeValue("0:00:02"))

'pasamos el "value" que nos interesa a la lista "guests"
pagina.getElementById("guests").Value = Range("B4").Value

Application.Wait (Now + TimeValue("0:00:02"))

'seleccionamos el botón de buscar y hacemos click
pagina.getElementById("submit_location").Click

'asignamos a una variable el estado de la página
stat = pagina.readyState

'Espera a que la página cargue
Do While stat = "loading"
    Application.Wait (Now + TimeValue("0:00:01"))
    stat = pagina.readyState
Loop


En la página siguiente vemos los precios de todas las habitaciones, lo que nos interesa es el valor del elemento que contiene la suma en dólares.

Como queremos todos los precios, hay que buscar la manera de recogerlos todos. Vemos que el elemento no tiene un "id",  pero todos tienen en común un nombre de "class". Con el método getElementsByClassName, buscamos ese nombre de clase y así obtendremos una colección de todos los campos:



'creamos la lista de precios

Set precios = pagina.getElementsByClassName("h3 text-contrast price-amount")

'comenzaremos a llenar el excel en la fila 7
fila = 7

'hacemos un loop por cada elemento de la lista de precios y lo agregamos al excel:
For Each precio In precios
    Range("A" & fila).Value = precio.innerText
    fila = fila + 1
Next


End Sub

Y listo, este es el resultado final:

Para aprender un poco mas sobre como extraer información de paginas web, prueba con este otro caso: Buscar definiciones de palabras en la pagina de la RAE



Cada pagina web es diferente, si la macro no funciona como esperabas, enviame un mail y si no es muy complicado el asunto quizás pueda darte una ayuda extra.

lunes, 5 de octubre de 2015

Test super sencillo sobre el uso de los INCOTERMS



Los que estudiaron Comercio Exterior, o los que trabajamos en ello, llevamos tanto tiempo tratando con los Incoterms, que ya ni les hacemos mucho caso... Tendemos a asumir muchas cosas sobre ellos y damos respuestas casi automáticas y condescendientes cuando alguien de otra área nos molesta con preguntas 'tan básicas'.

El único problema que le veo a esta actitud es que ya ni pensamos realmente en lo que cada uno significa. Para nostros está TAN sobreentendido que 'FOB es sobre la borda del buque' y que 'CIF incluye flete y seguro' que pensamos que ya sabemos todo sobre los Incoterms (o al menos lo mas importante) pero lo mas probable es que NO sea así...

Las 5 preguntas que vienen a continuación se las hice a algunos amigos que trabajan en Comercio Exterior y la mayoria no pudo responderlas correctamente. Si las contestas todas sin mucho inconveniente, pues te felicito por ser parte de una minoría con buen entendimiento del correcto manejo de los Incoterms:

1. Describe dos Incoterms de tu preferencia.
2. ¿Cual es el Incoterm mas fácil para el importador y cual es el más difícil para el importador?
3. Los incoterms DAP, DAT y DDP no incluyen seguro, ¿por que?
4. ¿Por qué un país en desarrollo preferiría que sus importaciones sean CFR o CPT y no CIF o CIP?
5. Una empresa de comercio internacional exige siempre que el exportador le entregue la carga en terminos FCA fabrica del exportador. ¿Cual sería el principal motivo?

miércoles, 30 de septiembre de 2015

Cursos para mejorar tu hoja de vida.

Muchas veces he escuchado de conocidos que hacen cursos, diplomados, maestrías para 'mejorar su currículum', casi nadie me ha dicho "porque quiero aprender X, Y...". Siempre me ha parecido que ir por el título es una motivación incorrecta y hoy leí algo que de cierta forma suma a mi punto. Dice así:

"Esto va a sonar controversial pero ahí va: si eres sobresaliente, sorprendente o simplemente espectacular en tu trabajo probablemente ni siquiera deberías tener un curriculum. Si tienes experiencia haciendo las cosas que te vuelven indispensable pues bien un curriculum esconde ese hecho. Un curriculum da al empleador todo lo que necesita saber para descartarte. Si no tienes un curriculum, ¿que tienes?. ¿Que tal tres extraordinaras cartas de recomendación de gente que el empleador conozca o respete?, O ¿un proyecto muy sofisticado que El empleador pueda ver o incluso tocar?, o ¿una reputación que te preceda? Algunos dirán 'eso suena bien, pero no tengo ninguna de ellas'. Sí, ese es mi punto. Si no tienes estas cosas que nos llevan a creer que eres una persona sobresaliente suena para mí que lo único que tienes es un curriculum. Busca una empresa que no utilice una computadora para escanear currículums, una empresa que contrate gente no papel." -Seth Godin. 

Suena bien eso de "soy tan bueno que no necesito una hoja de vida", pero en la realidad de nuestro mercado laboral eso está muy lejos de ser aceptado. 

Y si lo piensas bien, ser todo lo que Godin propone no es nada fácil, de hecho es más fácil obtener un título. ¿Dónde me inscribo?

miércoles, 23 de septiembre de 2015

VBA Excel: Como eliminar las celdas vacias en un rango.

Fue mucho mas facil de lo que imaginaba, la clave fue el metodo SpecialCells del objeto Range:

'Defino el rango que contiene las celdas en blanco
set rango = Thisworkbook.Sheets("Sheet1").Range("A1", "A500")

'Con el metodo SpecialCells genero un rango que agrupa las celdas vacias
Set celdasVacias = rango.SpecialCells(xlCellTypeBlanks)

'Elimino las filas
celdasVacias .EntireRow.Delete

miércoles, 2 de septiembre de 2015

VBScript: Como enviar un reporte por correo automáticamente

"Por favor envíame tu reporte..." Si no es la frase más detestada para cualquiera que trabaje en un área administrativa, de seguro debe estar en el top 5 fijo...

Aunque bueno, no debería molestarnos porque se supone que es nuestra responsabilidad que la información sea oportunamente distribuida al equipo de trabajo, por lo que este tipo de solicitudes nunca deberían presentarse. 

La persona organizada y disciplinada establecería uno o dos momentos en el día para realizar esta tarea. El vago hace un script que se encargue de eso. 

Pequemos de vagos entonces:

Crea un archivo de texto con el block de notas, por ejemplo enviarReporte.txt

Dentro del archivo escribe el siguiente texto, en el cual vas a modificar el texto en azul según tus necesidades:

para = "mail1@empresa.com; mail2@empresa.com; mail3@empresa.com"
asunto = "Reporte"
mensaje = "Estimados, adjunto reporte."
adjunto = "C:\reportes\reporte.xlsx"
Set outlook = CreateObject("Outlook.Application")
Set correo = outlook.CreateItem(olMailItem)
correo.To = para 
correo.Subject = asunto
correo.Body = mensaje
correo.Attachments.Add(adjunto)
correo.Send 

Ahora cambia la extensión del archivo de ".txt" a ".vbs".

Qué cosa? No sabes? Mr MBA?! Bueno ya aquí te explico cómo hacerlo

Ya tienes un script de Visual Basic, basta con hacer doble click sobre este para enviar un correo a los destinatarios que especificaste con tu reporte como adjunto.

Pero yo no quiero tener que hacer click, nadie quiere. La idea es que todo esto se haga automáticamente. 

En esta parte nos ayuda el programador de tareasAllí vas a indicar la hora y los días de la semana en que quieres que se ejecute el script, y listo nunca más tendrás que escuchar la espantosa frase con la que comenzamos el post.


Fundamentos: Usar el programador de tareas

Para ejecutar un script automáticamente a una determinada hora, se utiliza el programador de tareas:

  • Inicio
  • Control Panel
  • System and Security
  • Administrative Tools >>> Schedule Tasks

Se abre el Task Scheduler, entonces:

  • Action >>> Create Basic Task
  • Se pone un nombre de la tarea y una descripcion para saber que es lo que hará
  • Click en siguiente.
  • Luego se especifica si se quiere que la tarea se ejecute diario, semanal, mensual etc...
  • Click en siguiente.
  • Se especifica la fecha y la hora en la que comenzará la tarea. 
  • Click en siguiente.
  • En la accion seleccionamos "Start a Program"
  • Click en siguiente.
  • Buscamos con browse la direccion del script y lo seleccionamos. 
  • Click en siguiente y luego en Finish.

Fundamentos: Como cambiar la extension de un archivo


  • Entrar a la carpeta que contiene el archivo.
  • Ir a tools > folder options
  • Ir a View
  • En la seccion de Advanced Settings, buscarla opcion 'Hide extensions for known file types' y deseleccionarla.
  • Hit Ok.

Ahora si, ir al archivo, click derecho y cambiar la extension.

lunes, 24 de agosto de 2015

VBA Outlook: Como ejecutar una macro sobre un correo nuevo (entrante)

Como identificas el ultimo correo recibido? con el metodo GetLast del objeto Items

Esta macro lee el titulo del ultimo mail y busca si contiene la palabra "EMAILTEST".
De ser así, ejectuta un proceso. En este caso toma el nombre del remitente, elimina los espacios y lo envia como argumento a un programa de Python.

Sub BOQCOST()

Set ns = Application.GetNamespace("MAPI")
Set fold = ns.GetDefaultFolder(olFolderInbox) 'selecciona la carpeta Inbox
Set mensajenuevo = fold.Items.GetLast 'Obtiene el nuevo email que ingresa

If mensajenuevo.Subject = "EMAILTEST" Then 'Testea la plabra clave en el titulo 
    Set user = mensajenuevo.Sender.GetExchangeUser
    user = Replace(user.Name, " ", "")'elimina los espacios
    Shell ("python D:\myScripts\script.py " & user)
End If

End Sub 
 
Ahora, como ejecutamos esta macro sobre cada mail entrante?
Vamos a ThisOutlookSession, seleccionamos "Application" y "NewMail" 
Allí escribimos un call a la macro, de esta manera:
 

Private Sub Application_NewMail()
    Call BOQCOST
End Sub

Python: Funcion para enviar un correo desde outlook

'''
Envia un correo, se pueden incluir un archivo adjunto
de manera opcional, los argumentos son todos strings
'''
from win32com import client

#en la funcion, el mensaje y adjunto son opcionales
def enviarCorreo(destinatario, titulo, copy = None, mensaje = None, adjunto = None):
    ol = client.Dispatch("Outlook.Application")
    mail = ol.CreateItem(0)
    mail.To = destinatario
    mail.Subject = titulo
    if not copy is None:
        mail.CC = copy
    if not mensaje is None:
        mail.Body = mensaje
    if not adjunto is None:
        mail.Attachments.Add(adjunto)
    mail.Send()

if __name__ == '__main__':
    enviarCorreo(destinatario, titulo, copy = None, mensaje = None, adjunto = None)


domingo, 9 de agosto de 2015

Python: Manipular una pagina web con Selenium


La libreria selenium tiene controles que permiten manipular una pagina web como si una persona la estuviera ex

#Descarga facturas desde el sistema

from selenium import webdriver
from selenium.webdriver.support.ui import Select


#Para crear el explorador, de Firefox en este caso
browser = webdriver.Firefox()

#navega a la pagina
browser.get('http://www.cualquierpagina.com')

#ubica los campos de usuario y contrasena por su ID
user = browser.find_element_by_id('uid')
pswd = browser.find_element_by_id('password') 
 
#escribe los valores con el metodo 'send_keys'
user.send_keys("r00715649")
pswd.send_keys('Huawei?2')

#asi se ejectutan los scripts, como los de los botones 'ingresar'
browser.execute_script('javascript:form_submit();')

#a veces un script abre una ventana pop up
#la propiedad 'window_handles' enlista las ventanas abiertas 
#cambia el focus a la segunda ventana abierta en la lista (la del pop up)
browser.switch_to.window(browser.window_handles[1])

#ubico cualquier elemento en la ventana del pop up
role = browser.find_element_by_id('user_role/user_role_xid')

#puedo borrar el contenido de un campo
#puedo pasar otro valor, ejecutar una funcion y cerrar el pop up.
role.clear()
role.send_keys('REGIONAL_VIEW_ALL')
browser.execute_script("javascript:submitUserRole('set');")
browser.close()

#vuelvo a la ventana inicial
browser.switch_to.window(browser.window_handles[0])
browser.refresh()

#puedo seleccionar elementos de una lista
#primero creo un objeto 'Select' con el elemento de lista por su nombre o ID
lista = Select(browser.find_element_by_name('P_ARRIVE_AT_PORT_DATE_operator'))
 
#luego paso el metodo 'select_by_value' y listo
lista.select_by_value('gt')
browser.execute_script("javascript:if(nextdate()){disableButtonByName('submit_report',Generating); document.management_main.submit();}")

jueves, 6 de agosto de 2015

Python: Como instalar Pandas (y paquetes con la extension .whl y .egg)

Estuve sufriendo un buen rato con esto. Primero instalé una distribucion llamada Anaconda, pero me causó algunos conflictos con mis scripts viejos, por lo que desisntalé.

Así que seguí investigando y descrubrí los archivos tipo "Wheel".

En Windows, normalmente uno baja el paquete, extrae la carpeta, ingresa a la carpeta con el terminal y digita C:\Python27>python setup.py install

Tambien hay una forma mucho mas facil de instalar los paquetes de Python, que es con "pip". Bastaría solo con ejecutar este comando en el terminal:

C:\Python27>pip install pandas

Pero mi máquita presentó problemas para conectarse al servidor por lo que me rebotaba el siguente error:

C:\Python27>pip install pandas
Downloading/unpacking django-autotranslate
  Cannot fetch index base URL https://pypi.python.org/simple/
  Could not find any downloads that satisfy the requirement pandas

Bueno pues, como "pip" no pudo acceder al servidor y descargar los paquetes, me tocó hacerlo manualmente.

Con los paquetes "Wheel" solo hay que descargarlos en la carpeta de Pyhton, ingresar con el terminal y digitar C:\Python27>pip install nombre_del_paquete.whl lo cual es tedioso pero no complicado.

Pandas necesita que otros módulos estén instalados, por lo que tuve que ir en este orden:

six 1.9.0
python-dateutil 2.4.2,
pytz 2015.4 (descargué el archivo .egg en el directorio de Python y luego lo instalé con c:\Python27>easy_install pytz-2015.4-py2.7.egg)
NumPy
Matplotlib
Scipy

Se imaginarán mi satisfacción cuando pude descargar el wheel de Pandas e instalarlo con este comando:

C:\Python27>pip install pandas-0.16.2-cp27-none-win32.whl

Ahora si, el camino está despejado para calcular todos esos KPIs de manera automática aprovechando las herramientas que proporciona esta librería.

 

viernes, 31 de julio de 2015

VBA Outlook: Como extraer una tabla de un email y guardarla en un libro nuevo de Excel

Para utilizar esta macro se necesita abrir el correo que contiene la tabla y especificar la direccion donde se guardará el archivo de excel.

Las claves son:
-La ventana abierta de outlook (el email) es in objeto "Inspector"
-El objeto inspector tiene un metodo "WordEditor" que convierte al mail en un objeto de Word
-El objeto de Word tiene la propiedad "Tables"


Sub guardarTabla()

'El correo abierto lo convierte a un objeto de word
Set correo = ActiveInspector.WordEditor

'Creo un objeto de excel y creo un libro nuevo
Set xl = CreateObject("Excel.Application")
Set reporte = xl.Workbooks.Add()

'Extrae la primera tabla del conjunto de tablas en el documento
'Si hubere mas tablas se especifica el numero
Set tabla = correo.Tables(1)

'Encuentra el numero de filas
numeroFilas = tabla.Rows.Count

'Encuentra el numero de columnas
numeroColumnas = tabla.Columns.Count

'Comienza a navegar por cada celda de la tabla
'Primero toma cada fila
For r = 1 To numeroFilas
    'Luego va por cada columna
    For c = 1 To numeroColumnas
        celda = tabla.Rows(r).Cells(c)
        celda = Left(celda, Len(celda) - 1) 'borra el ultimo caracter del texto
        'pega el valor en la celda del archivo de excel.
        reporte.Sheets(1).Cells(r, c) = celda
    Next c
    
Next r

'ahora creo un numero secuencial para agregar al nombre de archivo
'basado en la fecha y tiempo actual
numeroSecuencial = Format(Now(), "YYMMDDhhss")

'finalmente guardo el archivo.
reporte.SaveAs ("D:\OutlookGeneratedFile" & numeroSecuencial & ".xlsx")

End Sub

jueves, 23 de julio de 2015

Fundamentos de VBA Excel: Donde escribir el código?

Antes vimos que el primer paso para trabajar con VBA era habilitar las macros en Excel. Ahora para poder comenzar a escribir codigo hay que ingresar al Editor de Visual Basic:

El Editor es el lugar donde escribimos todos los comandos o instrucciones que componen la macro. Para poder acceder al Editor basta con teclear Alt+F11 o ir al menú Tools/Macro/Visual Basic Editor

En la parte superior izquierda de la pantalla aparecerá el siguiente recuadro:



Hacemos click derecho sobre VBAProject("Nombre de Archivo") e insertamos un nuevo Modulo.




Vemos que en la carpeta de "Modules" se ha creado un "Module1", hacemos click sobre este, y ya estamos listos para escribir código.




martes, 21 de julio de 2015

Python: Como convertir imagenes .tiff a texto


Excelente material en este link.

3 Razones para aprender a crear Macros con VBA

En resumen, porque tu trabajo se vuelve más rápido, más preciso y mucho menos tedioso.

Si tu trabajo es de escritorio, es casi seguro que implica alguna forma de manipulación de datos con Excel, Word y Outlook. VBA es un lenguaje de programación que permite crear Macros para manipular todos esos datos velozmente. En muchos casos algunas tareas que normalmente toman horas, al realizarlas con una Macro se reducen a segundos.

La rapidez no lo es todo, también es súper importante la precisión. Con un par de líneas de código, puedes realizar miles de operaciones matemáticas, copiado e ingreso de datos, búsquedas, ediciones y más sin preocuparte de errores de escritura, borrado accidental o errores de cálculo.

Y que satisfacción es ver que el trabajo aburrido se hace prácticamente solo! De un momento a otro te encuentras con una gran cantidad de tiempo libre, el cual puedes entonces dedicarlo a tareas mucho más importantes.

Si tienes una tarea que involucra una hoja de cálculo, parámetros de búsqueda o evaluación y que se repite constantemente, es una candidata perfecta a ser automatizada. Para comenzar a usar macros, en este post está el primer paso a seguir.

Fundamentos de VBA Excel: Habilitar el uso de Macros

Primer paso para programar en VBA

No se neceista instalar ningún software adicional para programar en VBA, todo viene ya incorporado en Excel. Solo debemos poner atención a las configuraciones siguientes:

La viñeta de Developer

Lo primero que debemos revisar es si se encuentra activada la viñeta de "Developer/Desarrollador":

Si no se encuentra activada, debemos ir a File/Options/Customize Ribbon y seleccionar la opcion "Developer":

Las opciones de seguridad de Excel

Para poder ejecutar las Macros sin que Excel nos haga una advertencia de seguridad a cada instante, es necesario ir a las opciones de seguridad, y seleccionar la opción para habilitar Macros:

Guardar el archivo con la extensión correcta

Normalmente, los archivos de Excel tienen la extensión .xlsx la cual no permite que se guarde ninguna macro el archivo. Por lo que nuestros archivos que contengan código VBA deben guardarse con la extensión .xlsm que significa "Macro Enabled":

Una cuestión muy importe: Si envías tu archivo con macros a otro usuario, el destinatario deberá permitir la ejecución al momento de abrir el documento, de lo contrario las macros no se ejecutarán.

lunes, 20 de julio de 2015

Python para Excel: Como insertar hipervinculos

El objeto "Sheet" del modelo de objetos de Excel, tiene una propiedad Hyperlinks. Hyperlinks tiene un metodo llamado Add, que acepta 5 parametros, de los cuales solo uso 3, los que no utilizo los dejo en blanco con comillas.

En este ejemplo, en mi hoja de calculo tengo una columna donde quiero insertar hipervinculos y poner como referencia la palabra "documents"

import os, re, traceback
from win32com import client
try:
    #Rutas de archivos y posiciones de referencia
    pathServidor = '//servidor/'
    pathReporte= 'C:/reporte.xls'
    columaPedidos = "C" #en que columna se encuentran los numeros de pedido
    primeraFilaPedidos = "8" #la primera fila de los pedidos

    #crear listado con los numeros de pedido (solo el primer PL en caso de haber multiples)
    pedidos = []
    xl = client.Dispatch("Excel.Application")
    #itera por cada hoja del reporte
    for sheetNumber in range(1,5):
        reporte = xl.workbooks.open(pathReporte)
        lastRow = reporte.Sheets(sheetNumber).usedrange.rows.count #ultima fila del reporte
        for c in reporte.Sheets(sheetNumber).Range(columaPedidos+primeraFilaPedidos, columaPedidos+str(lastRow)): #itera por cada celda de pedidos
            pedido = unicode(c.value)
            #elimina los dahses del pedido y agrega solo el primer pl al listado
            if "/" in pedido:
                pedidos.append(pedido.split("/")[0])
            else:
                pedidos.append(pedido.split()[0])

    #itera por cada numero de pedido en el listado
    #tomar el path al servidor y combinarlos con cada numero de pedido
    #ver si el path que resulta existe en el servidor
    #si el path existe busca el numero de pedido en el reporte
    #ubicado el pedido, inserta hipervinculo en la columna N
            
    n= len(pedidos)
    for pedido in pedidos:
        if os.path.exists(pathServidor+pedido): #si existe el file path
            for sheetNumber in range(1,5): #itera por cada hoja
                if reporte.Sheets(sheetNumber).usedrange.find(pedido): #busca el pedido en cada hoja
                    print "\rArchivando %s en %s, %i files remaining." %(pedido, reporte.Sheets(sheetNumber).Name,(n-1)),
                    print " ",
                    #sys.stdout.flush()
                    documentsColumn = reporte.Sheets(sheetNumber).usedrange.find("Documents").Column #ubica la columna de documentos
                    pedidoRow = reporte.Sheets(sheetNumber).usedrange.find(pedido).Row
                    hyperlinkCell = reporte.Sheets(sheetNumber).Cells(pedidoRow,documentsColumn)#encuentra la celda donde insertar el hipervinculo
                    hyperlinkPath = pathServidor+pedido #crea el path del hipervinculo
                    reporte.Sheets(sheetNumber).Hyperlinks.Add(hyperlinkCell, hyperlinkPath,"","","documents")
                    #print "Archivado."
                    break
        #print "\rFiles Remaining... %i" %(n-1),
        #sys.stdout.flush()
        n-=1
    reporte.Save
    reporte.Close
except:
    traceback.print_exc()
print "Terminado."
raw_input()

martes, 14 de julio de 2015

Python para Excel: Como explorar los objetos de la libreria win32com

Lo correcto es buscar en la referencia de desarrolladores de Microsoft, pero si se quiere ojear en python se debe hacer click en este archivo:

C:\Python27\pywin32-219\com\win32com\client\combrowse.py

Vamos a 'Registered Typre Libraries' y buscamos 'Microsoft Excel 15.0 Object Library':

Los objetos que buscamos aparecen con una 'I' adelante mas la palabra 'Interfase', por ejemplo 'IRange - Interfase':


sábado, 11 de julio de 2015

Python: Como obtener la fecha de hoy (Y cambiar el formato de fecha)

 
Con el modulo datetime ha sido super sencillo! incluso se puede especificar la forma en que  queremos que se presente la fecha, mes dia año o viceversa.
Aqui un ejemplo:  

 
>>> import datetime
>>> fecha = datetime.date.today()
>>> fecha
datetime.date(2015, 7, 11)
>>> fecha.day
11
>>> fecha.month
7
>>> fecha.year
2015
>>> fecha.strftime('%d-%m-%y')
'11-07-15'
>>> fecha.strftime('%Y/%m/%d')
'2015/07/11'
>>> 

miércoles, 8 de julio de 2015

Python para Excel: Script para registrar actividades

Este script escanea varias hojas de mi reporte contando cuantas veces aparece la palabra "documents" en una columna. Cada vez que se ejecuta el programa, registra los resultados en un archivo de texto:


import time, re
from  win32com import client

#the log file
f = open('C:/Users/Ruben Torres/Desktop/Scripts/KPIs/filinglog.txt', 'a')

#open report
xl = client.Dispatch("Excel.Application")
report = xl.workbooks.open('D:/RubenBK/REPORTS/cctableruben.xlsm')

#file records counters
guayaquilCount = 0
quitoCount = 0
expressCount = 0
sparesCount = 0

lastrow = report.sheets("Guayaquil").usedrange.Rows.Count
for cel in report.sheets("Guayaquil").Range("N8", "N" + str(lastrow)):
    if re.search(r'^[dD]\w+[sS]', str(cel.value)):
        guayaquilCount += 1

lastrow = report.sheets("Quito").usedrange.Rows.Count
for cel in report.sheets("Quito").Range("N8", "N" + str(lastrow)):
    if re.search(r'^[dD]\w+[sS]', str(cel.value)):
        quitoCount += 1

lastrow = report.sheets("Express").usedrange.Rows.Count
for cel in report.sheets("Express").Range("K8", "K" + str(lastrow)):
    if re.search(r'^[dD]\w+[sS]', str(cel.value)):
        expressCount += 1

lastrow = report.sheets("Spare Parts").usedrange.Rows.Count
for cel in report.sheets("Spare Parts").Range("N8", "N" + str(lastrow)):
    if re.search(r'^[dD]\w+[sS]', str(cel.value)):
        sparesCount += 1

t = time.localtime()        
f.write("\nFecha: %s-%s-%s" %(t.tm_year, t.tm_mon, t.tm_mday) +  " Archivado en Guayaquil: %i; Quito: %i; Express: %i; Spares: %i " %(guayaquilCount, quitoCount, expressCount, sparesCount))

f.close
f = open('C:/Users/Ruben Torres/Desktop/Scripts/KPIs/filinglog.txt')

for l in f.readlines():
    print l

f.close
raw_input()

viernes, 3 de julio de 2015

Python para Excel: Como encontrar la ultima fila utilizada en una columna (Con Openpyxl)

Con get_highest_row() se puede encontrar la ultima fila de toda la hoja de calculo, pero y si quiero la ultima fila de una columa especifica?

Hago un for loop por la columna deseada, y cuando encuentre una celda vacia (None) guarda el numero e interrumpe el loop.



import openpyxl

reporte = openpyxl.load_workbook('d:/test.xlsx')
hoja = reporte.get_sheet_by_name('Sheet1')
ultimafilahoja = hoja.get_highest_row()
ultimafila = 1
for r in range (1, ultimafilahoja):
    if not hoja.cell(row = r, column= 3).value is None:
        ultimafila = r + 1
    else: break

print ultimafila
 
El resultado es 12.

Python para Excel: Buscar un patron de texto en un rango de celdas

 
import re
from win32com import client

xl = client.Dispatch("Excel.Application")

reporte = xl.workbooks.open("C:/miReporte.xls")
for c in reporte.sheets(1).Range("G4:G117"):
    if re.search(r'HTM\d{13}', str(c.value)):
        c.offset(1,4).value = re.search(r'HTM\d{13}', str(c.value)).group()
        print re.search(r'HTM\d{13}', str(c.value)).group()
 
 
Que significa cada cosa: 
import re = Importo la libreria de expresiones regulares from win32com import client = de la libreria win32com =  importo el modulo client
xl = representa a la aplicacion de excel
reporte = es el reporte que vamos a abrir
re.search(r'HTM\d{13}', str(c.value)) = busca un patron de texto que comience con "HTM" seguido de 13 digitos

lunes, 11 de mayo de 2015

Python: Como imprimir los errores en el programa

 
Así de sencillo, con el modulo "traceback":  
 
import traceback
try:
    for a in 10:
        print 'hello'
except:
    print 'the following error occured: '
    traceback.print_exc()
    raw_input()

viernes, 27 de marzo de 2015

VBA Excel: Como utilizar expresiones regulares para encontrar patrones de texto

Excelente explicacion en en este post de StackOverflow:

Private Sub simpleRegex()
    Dim strPattern As String: strPattern = "^[0-9]{1,2}"
    Dim strReplace As String: strReplace = ""
    Dim regEx As New RegExp
    Dim strInput As String
    Dim Myrange As Range

    Set Myrange = ActiveSheet.Range("A1")

    If strPattern <> "" Then
        strInput = Myrange.Value
        strReplace = ""

        With regEx
            .Global = True
            .MultiLine = True
            .IgnoreCase = False
            .Pattern = strPattern
        End With

        If regEx.Test(strInput) Then
            MsgBox (regEx.Replace(strInput, strReplace))
        Else
            MsgBox ("Not matched")
        End If
    End If
End Sub

domingo, 22 de marzo de 2015

Como ser más productivo.

La perfección es enemiga de la productividad. La perfección es muy poco notada por las demás personas. Las tendencias perfeccionistas evitan que completes una tarea, y producir es lo verdaderamente importante en la vida.

Una lista diaria de tareas te da concentración. Escribe una lista diaria de objetivos desde la noche anterior de manera que puedas examinar objetivamente que es lo que se debe completar en el día y en que deberías enfocar tu tiempo.

Toma notas constantemente. La productividad puede venir como una inspiración repentina, así que asegúrate de tomar notas y no dejar que las grandes ideas queden en el olvido.

Comprometerse públicamente. Si compartes tus objetivos con tus amigos te sentirás presionado a cumplirlos, y a sentirte avergonzado si no lo haces. Éste es un motivador muy efectivo 

Agrupa tus tareas, y tus interrupciones con el fin de ahorrar tiempo y no cambiar  constantemente de una tarea a otra.

Sugestionate de forma positiva. Define claramente tu recompensas a corto y largo plazo.

Mira a las tareas complejas como una colección de otras más pequeñas, las cuales serán mucho más fáciles de manejar y e ir eliminando.

Después de levantarte, hazte la rutina de realiza revisar tus objetivos diarios, comenzando una tarea importante y no revisando tu correo, ni Twitter, ni Facebook, ni Youtube hasta que hayas completado la primera cosa en tu lista.

Haz una lista de cosas que NO debes hacer. Identifica cuáles son las cosas que te hacen perder el tiempo e inclúyelas en tu lista para rechazarlas. Esto acelerará tu productividad aumentará tu concentración.

Si te das cuenta de que has perdido la concentración en lo que haces, toma un descanso en lugar de seguir a la fuerza con una tarea. A veces simplemente lo que se necesita es un break.

Crea primero, edita después. No te atasques en los detalles de la edición, completar una tarea es lo más importante, luego puedes regresar y revisar lo que has hecho para maximizar tu producción y tu productividad.

La multitarea es para las computadoras. No puedes hacer varias cosas a la vez de forma efectiva. Tú no eres la excepción. Hacer una tarea 100% concentrado siempre será mejor que hacer tres tareas a media llave.

Si divides tu lista de tareas en categorías  serás mucho más organizado y ahorrarás tiempo no debiendo decidir cual tarea viene después de otra. Las categorías recomendadas son: atención,en progreso, seguimiento, porvenir, ideas.

Cómo hacer que los demás respeten tu tiempo. Haz que la gente actúe primero antes de pedirte algo. Si se acercan a ti a pedirte algo o te llaman y quieren un reporte o algo, pídeles un correo. Somételos a la carga de la acción antes de que monopolicen tu tiempo.

Evita enfrascarte en pequeños detalles e ideas sin importancia. No pierdas de vista la tarea principal. Eso es una señal de procrastinacion.

Aprende a decir que no a las personas que te distraen. Entiende que hacerlo no es de por sí no es de mala educación pero sí te ahorrará horas a la semana.

Comienza el día con una tarea que hayas dejado pendiente desde hace algún tiempo o con una que parezca compleja y difícil. De esta manera te aseguras de que el día haya sido productivo y el resto de las cosas por hacer parecerán mas sencillas.

Y el principio de Pareto aplicado a la productividad: El 20% del esfuerzo inicial puesto en una tarea representará el 80% de los resultados.

Notas Basadas en el libro:



martes, 10 de marzo de 2015

VBA Outlook: Como guardar los adjuntos de un mail en una carpeta



Sí, sí, quizás sea DEMASIADA vagancia, pero yo recibo muchos mails que van a la misma carpeta y me fastidia hacer click derecho, guardar como, seleccionar la carpeta y etc... con esta macro para Outlook solo tengo que hacer Alt+F8 y ENTER
Para utilizarla primero hay que permitir que las macros se ejecuten en outlook, vayan a File/Options/Trust Center/Trust Center Settings/Macro Settings/ y selecciona "Enable All Macros". Luego reinicia Outlook.
Sí se que da pereza hacer todos estos pasos, pero no seas ordinario, piensa en todo el tiempo y las molestias que te ahorrarás de ahora en adelante.
Ahora ingresa a Outlook y presiona Alt+F11, sobre el nombre del proyecto (por lo general "Project 1") haz click derecho Insert/Module así como se ve en la imagen:

Ahora si en el espacio en blanco pega este código:
Sub guardar()

Dim mensaje As MailItem
Dim adjunto As Attachment
Dim carpeta As String

'escribo el nombre de la carpeta
carpeta = "D:\miCarpeta\"

'primero verifica si la ventana activa es del tipo inspector
If TypeName(Application.ActiveWindow) = "Inspector" Then
    Set mensaje = Application.ActiveWindow.CurrentItem 'selecciona el mail abierto
    If mensaje.Attachments.Count > 0 Then
        For Each adjunto In mensaje.Attachments 'explora cada adjunto en el mensaje
            adjunto.SaveAsFile (carpeta & adjunto.FileName)
        Next
        MsgBox "Adjuntos guardados."
    Else
        MsgBox "Sorry, no hay adjuntos que guardar."
    End If
Else
    MsgBox "Hello, no se guardó es NADA!"
    
End If
End Sub
Ya casi está, ahora solo tienes que poner entre comillas, el nombre de tu carpeta de archivos y reemplazarlo en la línea que dice carpeta = "D:\miCarpeta\" por ejemplo puede quedar como carpeta = "D:\misArchivos\" o "C:\MisDocumentos\" no se cual sea tu caso.
Y listo, ya está. Ahora cada vez que te llegue un mail, solo dale Alt+F8, se te abrirá una ventana, solo daleENTER
Parece que la macro hiciera algo muy sencillo pero este codigo tiene muchas posibilidades, puedes modificarlo para que vacie carpetas y guarde solo los nuevos adjuntos, puedes crear varias macros para cada carpeta, en fin lo que te imagines...

jueves, 5 de marzo de 2015

Cual es la partida arancelaria de un Drone para uso comercial

Uno de los nombres con el que se conoce a estas naves no tripuladas es UAV (Unnamed Aerial Vehicle).




La Federacion Aeronautica Internacional los define de la siguiente manera:

Un aerodyne con un medio de propulsión, que no transporta humanos, el cual ha sido diseñado para investigación científica o propósitos comerciales, gubernamentales o militares.

Por lo que, sí su peso en vacío es inferior o igual a 2000kg me parece que la partida arancelaria debe ser la 8802.11

martes, 24 de febrero de 2015

HTML y CSS: Varias formas de alinear un DIV dentro de otro DIV

Esto es lo que hay, tres elementos dentro de un contenedor:
Este es el HTML:
Este es el CSS:
#container{
 height: 400px;
 width: 700px;
 background-color: orange;
}

#item{
 height: 100px;
 width: 200px;
 background-color: yellow;
 border: 1px solid black;

}

Primero hay que agregar la propiedad de display:inline-block; a los items para que se ordenen en una sola linea
Ahora podemos alinear verticalmente aplicando display:flex; align-items:center en el contenedor y margin:0 auto; en los elementos internos para alinear horizontalmente. El resultado:
Y aqui el CSS:
#container{
 height: 400px;
 width: 700px;
 background-color: orange;
        display:flex;
        align-items:center;
}

#item{
 height: 100px;
 width: 200px;
 background-color: yellow;
 border: 1px solid black;
 display: inline-block;
        margin: 0 auto;
}

lunes, 23 de febrero de 2015

CSS: Como alinear horizontalmente dos DIVs sin dejar espacio entre ellos.

La forma mas sencilla que encontré es mediante el uso de la propiedad display:table para el contenedor y display:table-cell para el elemento.

Y para que exista cero espacio entre ellos, en el contenedor se utiliza tambien la propiedad border-spacing:0px

 En el ejemplo el borde rojo representa el ancho de la pagina:

Este es el HTML:

<div id="body">
      <div id="contenedor">
                <div id="elemento">
                         <h3> Elemento 1</h3>
                  </div>
                <div id="elemento">
                          <h3>Elemento 2</h3>
                </div>
       </div>
</div>


El CSS:

#body{
        height: 500px;
        border:2px solid red;
    }
    #contenedor{
        height:300px;
        width: 100%;
        margin:0px;
        display:table;
        border-spacing:0px;
    }
    #elemento{
        height:100%;
        width:50%;
        border: 1px solid black;
        display:table-cell;
    }


Y el resutado:



Elemento 1

Elemento 2

viernes, 13 de febrero de 2015

Una idea nueva para practicar todo lo aprendido

Para mezclar todos esos conceptos basicos que he estudiado de HTML, CSS, Javascript, y VBA voy a crear una página que cuyo contenido será un mini curso de VBA.
Este es el "pensum" que se ma ha ocurrido hasta ahora:


Bueno solo falta lo mas facil, desarrollar cada punto, ja! Acepto sugerencias...

viernes, 6 de febrero de 2015

Python: Como extraer texto de entre varias lineas

Me plantearon este problema, mas de mil registros similares a este:


DSP BRDMFRINFO:CN=0,SRN=80,SN=0;
CDLAGATAZOW08
+++    CDLAGATAZOW08        2015-02-06 09:58:08
O&M    #356423
%%/*36154325*/DSP BRDMFRINFO:CN=0,SRN=80,SN=0;%%
RETCODE = 0  Operation succeeded.

Display Board Manufacturing Information
---------------------------------------
               Type  =  WD5MJRUCC50
      Serial Number  =  210231964410C3000394
        Description  =  DBS3900,WD5MJRUCC50,MRRU V2,Multi-mode Multi-carries Remote Radio Unit(TX869-894MHz/RX824-849MHz,-48VDC,2.5G)
Date of Manufacture  =  2012-03-19
             Vendor  =  Huawei
       Issue Number  =  00
(Number of results = 1)


---    ENDDSP BRDMFRINFO:CN=0,SRN=80,SN=0;

Y de cada regisstro debe quedar una linea asi:

CDLAGATAZOW08,  WD5MJRUCC50

Como decirle a Python que extraiga lo que está despues de "+++" y lo que está despues de "Type"?
Bueno con una expresion regular basta, pero el problema es que se encuentran en diferentes líneas.

Lo resolví utilizando un "flag" que se encendiera cuando encontrara el "+++" en una linea, y que se apagara cuando encontrara "ENDDSP"

Mientras el flag estuviera "on" grabaría el contenido de la linea en una lista. Luego busco los patrones de texto y los escribo en otro archivo. Aqui el codigo:

import re
inFile = open("d:/byron/type.txt")
outFile = open("d:/byron/typeResponse.txt", "w")
siteList = []

#un listado con los nombres de los sitios

for line in inFile:
    match = re.search(r'^\+{3}\s{4}\w+W08', line)
    if match:
        siteName = match.group()[7:]
        siteList.append(siteName)

inFile.close()

#convierte la lista a set para evitar duplicados
siteList = set(siteList)

#crea listas con los nombres de los sitios y agrega las lineas ente +++ y ---

for site in siteList: #toma cada nombre de sitios
    inFile = open("d:/byron/type.txt")
    flag = "off"
    sList = [] # crea una lista con los datos del sitio
    for line in inFile: #lo busca en cada linea del archivo
        if ("+++" in line) and (site in line): #si encuentra el comando enviado al sitio
            #print "Flag on " + line
            flag = "on" #enciende la grabacion
        if "ENDDSP" in line:
            flag = "off" #apaga la grabacion
            #print "flag off " + line
            #deja grabar las lineas

        if flag == "on":
            sList.append(line)

    for element in sList: #toma cada dato grabado del sitio
        if "Type" in element:
            match = re.search(r'=\s\s.+', element)
            if match:
                print site +", "+ match.group()[3:] + "\n"
                outFile.write(site +", "+ match.group()[3:] + "\n")
     

    #una vez llenada la lista de datos del sitio
    #busca si existe BoardType

    inFile.close()
 
outFile.close()

viernes, 30 de enero de 2015

VBA Excel: Enviar mail automaticamente cuando ocurra un error en la Macro

La clave es err.Description

sub x ()

On Error GoTo oops:

'CODIGO VA AQUI

Exit Sub

oops:
Dim ol As Outlook.Application
Set ol = New Outlook.Application
Set mail = ol.CreateItem(olMailItem)

With mail
    .to = "ruben.torres@huawei.com"
    .Subject = "Error in HTM Status Report."
    .Body = "An error was detected in the application. Please check it: " & vbNewLine & "'" & err.Description & "'"
    .Send
End With

MsgBox ("There was a problem with the execution, the server may be turned off. An error report has been sent to ruben.torres@huawei.com")

End Sub

domingo, 25 de enero de 2015

Cuanto consumen las cocinas de inducción.

Cocinas de Inducción: Calculadora de consumo.

Efecto sobre la planilla de luz.

Cuanto aumentaría mi cuenta de electricidad si instalara una cocina de induccion? Aqui les dejo una
calculadora hecha con lo que he aprendido de Javascript.

El cálculo se realiza seleccionado un rango de valores y generando los escenarios mas probables
basándonse en una simulación "Monte Carlo". El texto de referencia utilizado: How to Measure Anything
de Douglas W. Hubbard.

El resultado está expresado en un rango de valores con un 95% de probabilidad, lo que es mas útil y
realista que buscar un valor exacto, puesto que el propósito es simplemente reducir la incertidumbre
para tomar una decision mas informada.

Se han proporcionado algunos valores por default, pero pueden modificarlo segun sea necesario.

Tiempo de cocción por alimento (En horas)
Tiempo Mínimo:
Tiempo Máximo:



Consumo según modelo de cocina (Kwh)
Consumo Mínimo:
Consumo Máximo:



Numero de alimentos preparados por dia:
Mínimo:
Máximo:



Uso del Horno (Horas por mes)
Mínimo:
Máximo:






Consumo Mensual Promedio (Kwh):

Consumo con subsidios:

Consumo sin subsidios:


Supuestos aplicados en el cálculo:

No acepto críticas... Mentira, para cualquier sugerencia acá --->e-mail