Manipulando Excel con Python – Parte II

Estándar

En esta ocasión mostrare como obtener los valores únicos de un listado de una hoja de Excel, al mismo tiempo que mostrare algunas técnicas un poco avanzadas de la programación en Python.

Primero que nada para que el ejemplo funcione debemos tener Python y las extensiones Win32 de las cuales ya he hablado previamente en:  Instalación de Python y las extensiones win32

Este es el código de nuestro script en Python:

##Importacion de modulos a utilizar
import win32com.client
import win32clipboard
import win32con
import time

ini = time.time() ##registra el tiempo de inicio
xl = win32com.client.Dispatch(‘Excel.Application’) ##crea una nueva instancia de Excel y la asigna a xl
xl.Visible = True ##hace visible la instancia
sh = xl.ActiveSheet ##asigna a sh la hoja activa
sh.Range(‘A2:A100000’).Copy() ##se copia al portapapeles el rango de datos a analizar

win32clipboard.OpenClipboard() ##se abre el portapapeles
data = win32clipboard.GetClipboardData(win32con.CF_TEXT) ##se asigna a data el contenido del portapapeles (data es una cadena de texto)
win32clipboard.CloseClipboard() ##se cierra el portapapeles

data = data.split(‘\r\n’) ##data se convierte en una lista, utilizando como separador ‘\r\n’ ()algo asi como el texttocolumns en VBA/Excel
data = data[0:-1] ##se asigna a data nuevamente el contenido de data, pero descartando el ultimo elemento (de 0 a -1) -1 representa el ultimon elemento
unicos = {} ##se crea un diccionario vacio en el cual se almacenaran los valores unicos como llaves

for i in data: ##bucle en el cual se recorre cada elemento de data y se le asigna a i
if not unicos.has_key(i): ##en caso de que el diccionario no tenga la llave indicada (en este caso i)…
unicos[i] = None ##se crea la llave y se leasigna un None (algo asi como un Null)

x = len(unicos) ##se asigna a x la lantidad de elementos que conforman el diccionario (en este caso los elementos unicos)
llaves = unicos.keys() ##llaves es una lista que contiene las llaves que conforman el diccionario
data = ‘\n’.join([i for i in llaves]) ##se asigna a data la concatenacion de todos los elementos de la lista que conforma a llaves (data es una cadena)

win32clipboard.OpenClipboard() ##se abre el portapapeles
win32clipboard.EmptyClipboard() ##se vacia el portapapeles (ummm… creo que esta no sirve! jajajaja)
win32clipboard.SetClipboardData(win32con.CF_TEXT, data) ##se pone en el portapales el contenido de data
win32clipboard.CloseClipboard() ##se cierra el portapapeles

sh.Cells(2,5).PasteSpecial() ##se pega en E2 el contenido del portapapeles
xl.CutCopyMode = False ##se desabilita el pegado

fin = time.time() ##se registra el tiempo de termino
cad = “Tiempo Requerido: %.2f segundos! Elementos Unicos: %d” %((fin-ini),x) ##cad contiene el tiempo transcurrido y el numero de elementos unicos
sh.Cells(1,5).Value = cad ##se pone cad en la celda E1

Ahora a descargar el archivo Excel que contiene el listado de valores: Listado de Numeros y el script python (les recomiendo descarguen el script, ya que si copian y pegan el código que se muestra en el blog no funcionará).

Una vez descargado el listado, damos doble clic sobre nuestro script unicos.py (yo le asigne ese nombre) y seguramente no hará nada! jajaja, bueno hay que abrir Excel manualmente y abrir el archivo que contienen el listado, una vez echo esto volvemos a dar doble clic sobre nuestro script y debería funcionar! Si es así, en la celda E1 nos aparecera un mensaje del tiempo qu se necesito para la extracción y el número de  elementos únicos y debajo los valores únicos (los cuales no están ordenados).

El listado Excel incluye una macro que hace los mismo, en mi maquina se traba (no se si deba asustarme de que mi maquina sea muy lenta o el filtro avanzado de plano se queda corto ante tantos elementos a procesar).

Todo el código python esta comentado para su mejor comprensión, creo que la única linea que puede ser confusa es la siguiente:

data = '\n'.join([i for i in llaves])

En esa instrucción se hace uso de una lista de comprensión para ser utilizada por el método de cadena join, la cual concatena todos los elementos de una lista o tupla, poniendo como separador en este caso entre cada elemento un ‘\n’ (salto de linea) algo así como un TextToColumns pero a la inversa!

Espero sea de utilidad este ejemplo!

Anuncios

13 comentarios en “Manipulando Excel con Python – Parte II

  1. Para obtener los elementos ordenados sólo era necesario convertir el diccionario a una lista y luego aplicar el metodo list.sort() que ordena dentro de la misma lista. Aquí comentando!

    Sin embargo se me hace muy interesante tu solución al respecto!

    Salu2+

    • En efecto tienes toda la razon, me parece que cuando hice ese ejemplo lo deje asi para no aumentar la complejidad ya que comparti un link de este post en un foro de vba/excel para apreciaran la potencia de este gran lenguaje!

  2. Alejandro:
    Yo por mas que lo intente hacer no me funcionó. Lo malo es que no dice donde esta el error. Parece, parece que el error viene de una mala asignación de esta linea:
    sh.Range(‘A2:A100000′).Copy()

  3. ok Genial!!! No se si has notado por ejemplo que a veces ejecuta bien la macro y otras veces no, a manera de ejemplo: recortemos los datos a solo 10 celdas rango A2:A11 y ejecutemos el codigo varias veces, a veces falla y a la siguiente ejecucion lo hace bien, ¿no se si lo hayamos notado o es solo mi imaginación?.
    Saludos.

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s