viernes, 16 de octubre de 2020

¿Excel culpable de contagios de Covid-19? ¡Para nada!

Hace ya algunos días muchos fuimos sorprendidos con noticias que llegaban del Reino Unido de la Gran Bretaña e Irlanda del Norte acerca de un problema sobre la Covid-19, pero ¿Cuál es la relación de eso con un blog de Excel? Pues los titulares, tendenciosos creo yo, decían que por culpa de Microsoft Excel se había dejado de hacer seguimiento a casos de personas afectadas por dichos virus ¿Por culpa de Excel? Sí, no es exageración, así lo daban a entender.

¿Qué ocurrió realmente? La semana pasada la agencia Public Health England (PHE) informó que 15,841 casos confirmados de personas con Covid-19 no se incluyeron en las cifras diarias que se informan de manera pública. Los datos correspondían a casos reportados entre el 25 de septiembre y el 2 de octubre del presente año. Si bien los datos fueron agregados de forma posterior la explicación no fue más allá de decir que había ocurrido un "fallo técnico". Después desde el PHE se confirmó que el dilema había ocurrido al importar, a su sistema, datos enviados desde los laboratorios. También se dijo que los datos de los laboratorios eran enviados en archivos del tipo *.csv, es decir “Comma separated values” (Valores separados por comas), que es un tipo de archivo de texto. Por cierto, se puede decir, exagerando la frase, que dicho tipo de archivos no tiene límite en el número de filas posibles de contener.

Desde la BBC se dijo que el dilema radicaba en que esos archivos csv habían sido ingresados en dicho formato al sistema del PHE y luego exportados en archivos Excel para ser enviados a los equipos de rastreo con el dilema que se usó el formato de archivo de Libro de Excel 97-2003, es decir, archivos con la extensión *.xls cuyas hojas tienen un máximo de 65,536 filas, y al hacer eso se habían perdido miles de contactos en cada reporte emitido. Otras fuentes informaban que los archivos csv habían sido abiertos en alguna versión actual de Excel (*.xlsx) cuyas hojas tienen 1’048,576 filas, pero que cada archivo csv tenía más y por ende ser perdieron datos al hacer la importación ya con los archivos de Excel. Desde la agencia PHE no han confirmado ni una ni otra versión, pero sí que fue un problema relacionado a Excel.

Entonces ¿fue culpa de Excel? Para nada, no sé si hablar de culpables, pero en todo caso si hay responsabilidades que asumir, definitivamente nuestro querido Excel no tienen responsabilidad y los problemas se debieron, sea uno u otro de los comentados el real dilema, a que los técnicos y/o trabajadores/as no conocían realmente Excel, así como sus distintos tipos de archivos y sus límites. Finalmente, de haberlos conocido, o incluso el uso de Power Query y/o Power Pivot, Gran Bretaña su PHE y muchos otros, se hubiesen ahorrado varios problemas y más en un contexto d pandemia como el que vive el mundo. Así que ya lo saben ¡a seguir estudiando y aprendiendo sobre Excel! Que no les pase, que no nos pase, lo que en Gran Bretaña. Saludos. Para todos y todas.

Abraham Valencia
Lima, Perú

sábado, 15 de agosto de 2020

Datos masivos desde Excel (VBA) hacia una Hoja de Cálculo de Google: El dilema de las tildes y eñes

Hace algunas semanas aprendimos cómo enviar datos masivos desde Excel, usando VBA, hacia una Hoja de Cálculo de Google como si fuese nuestra base datos en línea (Enlace). ¿Cuál fue el problema que encontramos? Al enviar vocales con tilde o letras eñe, sean mayúsculas o minúsculas, la Hoja de Cálculo no las reconocía y no las consideraba, es decir, hacía como que no existían pues ni siquiera dejaba espacios en blanco en su reemplazo.

El problema era la codificación que usa Google para los caracteres Ascii extendidos. Como no es difícil identificarlos, en este caso vamos a resolverlo con una Función Definida por el Usuario (UDF por sus siglas en inglés) que convierte los caracteres que nos interesan en esta ocasión, en códigos que Google pueda identificar. Entonces, copien y peguen la siguiente UDF en un módulo del archivo:

Function Cambiacodificacion(Textoinicial) As String 

Dim Base(1 To 12) As String, CodigoG(1 To 12) As String 
Dim TextoFinal$, Codificado$ 
Dim x As Integer, y As Integer 

Base(1) = "Á": CodigoG(1) = "%C3%81" 
Base(2) = "É": CodigoG(2) = "%C3%89" 
Base(3) = "Í": CodigoG(3) = "%C3%8D" 
Base(4) = "Ó": CodigoG(4) = "%C3%93" 
Base(5) = "Ú": CodigoG(5) = "%C3%9A" 
Base(6) = "á": CodigoG(6) = "%C3%A1" 
Base(7) = "é": CodigoG(7) = "%C3%A9" 
Base(8) = "í": CodigoG(8) = "%C3%AD" 
Base(9) = "ó": CodigoG(9) = "%C3%B3" 
Base(10) = "ú": CodigoG(10) = "%C3%BA" 
Base(11) = "Ñ": CodigoG(11) = "%C3%91" 
Base(12) = "ñ": CodigoG(12) = "%C3%B1" 

For x = 1 To Len(Textoinicial)
     Codificado = Mid$(Textoinicial, x, 1)
         For y = 1 To 12
             If Codificado = Base(y) Then Codificado = CodigoG(y): Exit For
         Next y
     TextoFinal = TextoFinal + Codificado
 Next x

Cambiacodificacion = TextoFinal 

End Function 
Una vez hecho eso y como se supone vieron el artículo anterior, debemos cambiar la línea respectiva de este modo:
misDatos = "entry.734588322=" & Range("A" & x) & "&entry.1744113014=" & Cambiacodificacion (Range("B" & x)) & "&entry.283729869=" & Range("C" & x) & "&entry.1406906612=" & Range("D" & x)            

¿Notaron el cambio? Una vez hecho eso, podemos usar vocales con tilde, en nuestros datos de Excel, o la letra eñe ya sean mayúsculas o minúsculas y al enviar todo a Google, no tendremos dilema alguna y las veremos tal cual lo enviado. Todo se vería así:

Y listo amigos/as, resuleto el problema ya si desean usar más caracteres queda como tarea de todos/as agregarlos, no es difícil esa parte. ¡Hasta la próxima!

Abraham Valencia
Lima, Perú

domingo, 12 de julio de 2020

Datos masivos desde Excel (VBA) hacia una Hoja de Cálculo de Google como si fuese nuestra base datos.

Hoy en día en que compartimos mucha información a través de internet y sobre todo usando “nubes” tipo Google Drive, OneDrive o DropBox, la necesidad de tener alternativas para intercambiar datos y/o actualizarlos haciendo uso de esas y otras herramientas, sin duda cada vez es mayor. Para bases de datos sin duda las alternativas son diversas como el caso de Oracle, MySQL o SQL Server; claro, para poder tener los datos en internet y conectarnos desde cualquier lugar, esas alternativas son de pago y no siempre se puede acceder por motivos, justamente, económicos (las ediciones gratuitas son de conexión local o de poder configurarlas para sesiones remotas, tiene limitaciones). Retomando lo de la “nube”, si bien permite trabajar en distintas PC, laptops, móviles, etc. ingresando a través de internet o descargando la aplicación requerida, básicamente lo que hacen es mantener varios archivos iguales y actualizarlos mediante sincronización, lo que como seguro ya saben, también tiene sus limitaciones, más aún cuando se quiere trabajar con usuarios distintos cada uno “logueado” con su propia cuenta.

Entonces ¿Tenemos posibilidades económicas o gratuitas de tener una base de datos en línea y poder conectarla desde Excel? Comenzaré diciendo algo que afirmó por años: Excel no es un sistema gestor de base de datos, es una hoja de cálculo, pero entiendo que mucha gente lo usa como si fue tal. Dicho eso, paso a responder la pregunta: Sí, considero que existe una alternativa ¿Cuál es? Pues considero que una alternativa es usa una Hoja de Cálculo de Google y, a través de VBA, enviarle los datos que deseamos desde la PC que queramos, así esté ubicada en cualquier lugar del mundo, claro, siempre que tenga conexión a internet. Y no, no es necesario entrar a Google Drive o descargar e instalar la aplicación. Ah, claro, así como Excel, las Hojas de Cálculo de Google también tienen límites de capacidad, pero ya les toca a ustedes averiguar cuáles son si es que se decantan por la opción de la que hablaremos hoy.

Para comenzar, lo que usaremos serán los Formularios de Google, probablemente ustedes ya hayan visto algo parecido, la diferencia es que Google ya ha variado las propiedades de sus objetos de dichos formularios y hoy veremos cómo se puede hacer ahora y, además, como mandar varios datos a la vez sin problema alguno. Entonces, comencemos.

Como este no es un tutorial sobre el uso de los formularios que usaremos, asumiré que ya saben cómo crearlos así que podrían comenzar con uno así:

Para todos los campos usé objetos de “Respuesta corta”, pero en el caso de ID y Edad, además, la “validación de respuesta” es tipo “Número”. No olviden este detalle para que, a la hora de enviar los datos, el tipo coincida en cada campo.

Ahora, en la pestaña “Respuestas” activen el botón “Crear hoja de cálculo” (el verde con rauas blancas)..

En las opciones que te salen, elige “Crear una hoja de cálculo” y dale clic a “Crear”. Si deseas previamente coloca un nombre en la opción correspondiente al lado de “Crear una hoja de cálculo”, tal como he hecho yo.

En pantalla tendremos algo como esto. No olviden que el campo “Marca temporal” lo agrega Google, no hay problema.

Ahí mismo elige el menú “Formulario” y luego “Ir al formulario publicado”.

En esta parte es muy importante que copien el enlace de la web del formulario. Por ejemplo, en mi caso es el siguiente:

https://docs.google.com/forms/d/e/1FAIpQLSfhc8fyp2InjqYpUJiZEKdyI2ABYudFu07JUPKAoz-cJ87dTA/viewform

Continuando en la web del formulario, como ya mencioné líneas arriba van a encontrar varias publicaciones acerca de cómo llenarlo desde Excel con VBA, en todas usan la propiedad “Name” de los objetos del formulario, pero si ustedes ven el código HTML del formulario, verán que ya Google no necesariamente usa dicha propiedad.

Entonces ¿Qué usaremos? No hay problema, solo es cuestión de revisar todo el código del formulario y encontrar lo siguiente (En Chrome, por ejemplo, se puede hacer con las opciones “inspeccionar” o “Ver código fuente de la página”):

¿Ven la línea resaltada? Desplieguen la opción de la izquierda (el triángulo) y deberían tener lo siguiente, o algo así, en su pantalla:

Si ven con detalle, se darán cuenta que ahí están los nombres de los cuatro campos que usé en el formulario (Id, nombre, sexo, edad) y a la derecha de cada uno la palabra “null”, un cero (0) y dos corchetes ¿Ven los números al lado de los corchetes? Eso son los que copiarán. En mi caso son: 734588322, 1744113014, 283729869 y 1406906612.

Ahora sí vamos a Excel. En una hoja de Excel tenemos que tener lo siguiente, para mi caso, claro.  

Ahora entra al editor de VBA y lo primero que debes hacer ahí es activar las referencias a “Microsoft XML, v6.0” (el número 6 puede variar dependiendo de tu versión de Office). Como en otras ocasiones, recomiendo usar el objeto MSXML2.XMLHTTP60, que se usa para realizar solicitudes HTTP. Dichas solicitudes nos permiten interactuar con un servicio web, API y similares. Con dicho objeto usaremos el método “Post” para poder enviar la información necesaria que queremos publicar/insertar en nuestra Hoja de Google (ya hemos hablado de dicho método y sus parámetros en otros artículos, por ende, no los volveré a explicar hoy aquí). Para finalizar usaremos el método “Send” para abrir la conexión y enviar la solicitud al servidor. Entonces, vamos declarando las siguientes variables.

'Para declarar y crear el objeto 
Dim WebXML As New MSXML2.XMLHTTP60 
'Para detectar la última fila 
Dim UltimaFila As Long 
'Para enviar el parámetro de la URL al POST y al Send 
Dim miURL As String, misDatos As string 

Como vamos a hacer que se envíe todo a la Hoja de Cálculo de Google, vamos a detectar la última fila llena y con un bucle “For – Next” recorreremos todo el rango y al final borraremos los datos.  Para ello también vamos a declarar la variable correspondiente.

Dim x as Long

Para comenzar a dar valores a las variables, recordemos que guardamos/copiamos la url del formulario, pero si lo vuelven a ver, verán que terminar con “vieform”, pues esa parte cámbienla por “formResponse”. En mi caso quedaría así:

UltimaFila = Cells(Rows.Count, 1).End(xlUp).Row 
miURL = "https://docs.google.com/forms/d/e/1FAIpQLSdhhL-3DomHpEnXufpdCJPYbLsdurtLRQpB0MhVbqqGIC2UPw/formResponse" 

Con el método “Send” vamos a enviar los datos ¿Recuerdan los números que copiamos que correspondían a los campos del formulario?  Pues para que funcione, en la cadena vamos a anteceder cada uno de esos números de la palabra “entry” y un punto (.), de tal modo que queden así, por ejemplo: “entry.734588322”. Sin las comillas, obviamente. Como vamos a recorrer los datos con un bucle, vamos a ir tomando el valor correspondiente para cada campo del formulario, de tal modo que nuestra cadena quedaría así:

misDatos = "entry.734588322=" & Range("A" & x) & "&entry.1744113014=" & Range("B" & x) & "&entry.283729869=" & Range("C" & x) & "&entry.1406906612=" & Range("D" & x)

Y ya con el bucle sería así:

For x = 2 To UltimaFila
     misDatos = "entry.734588322=" & Range("A" & x) & "&entry.1744113014=" & Range("B" & x) & "&entry.283729869=" & Range("C" & x) & "&entry.1406906612=" & Range("D" & x)
     
     With WebXML
         .Open "POST", miURL, False
         .setrequestheader "Content-type", "application/x-www-form-urlencoded"
         .send (misDatos)     
     End With      

Next

Juntando todo y ordenando, deberíamos tener esto:

Option Explicit
 'Todo Sobre Excel
 'Abraham Valencia
 'https://abrahamexcel.blogspot.com/
 'https://www.facebook.com/TodosobreExcelAV/
 'https://twitter.com/Todosobre_Excel
 'Lima, Perú
 'Julio del 2020

 Sub EnviaraGoogle()     

 'Para declarar y crear el objeto 
Dim WebXML As New MSXML2.XMLHTTP60 
'Para detectar la última fila 
Dim UltimaFila As Long 
'Para enviar el parámetro de la URL al POST y al Send 
Dim miURL As String, misDatos As String 
Dim x As Long 

UltimaFila = Cells(Rows.Count, 1).End(xlUp).Row 
miURL = "https://docs.google.com/forms/d/e/1FAIpQLSfhc8fyp2InjqYpUJiZEKdyI2ABYudFu07JUPKAoz-cJ87dTA/formResponse" 

For x = 2 To UltimaFila

     misDatos = "entry.734588322=" & Range("A" & x) & "&entry.1744113014=" & Range("B" & x) & "&entry.283729869=" & Range("C" & x) & "&entry.1406906612=" & Range("D" & x)
     
      With WebXML
         .Open "POST", miURL, False
         .setrequestheader "Content-type", "application/x-www-form-urlencoded"
         .send (misDatos)
     End With     

 Next 

MsgBox "Datos enviados a Google", vbOKOnly, "Todo Sobre Excel" 

End Sub 

Si todo salió bien, en nuestra Hoja de Cálculo de Google deberíamos tener lo siguiente:

Si después desea ver los datos en Excel ya compilado, escribí sobre eso hace meses, denle un vitazo: Enlace. Y ahora sí, eso es todo en esta ocasión ¡Hasta la próxima!

Abraham Valencia
Lima, Perú

Nota: Hay un dilema con las letras con tilde, la eñe y algunos otros caracteres, haré pruebas sobre eso y actualizaré el artículo.

domingo, 5 de julio de 2020

Interactuando con Microsoft Word (IV): Enviar datos de celdas de Excel hacia objetos de un archivo Word

¡Hola nuevamente! En esta ocasión seguiremos interactuando con Word y lo que toca hacer es enviar, nuevamente, datos, pero ya no una tabla completa sino, datos específicos a cajas de texto en el archivo de Word, como si fuera un reporte y Excel nuestra base de datos. Para mí es más práctico usar la herramienta “Combinar correspondencia” desde el mismo Word, pero sé que para muchos es mejor hacer todo desde Excel, así que, manos a la obra.

Lo primero es tener datos, por ejemplo, del siguiente modo:

Ojo que en la celda B1 hay una lista desplegable de los datos de la columna “Id” de la Tabla (Asumo que saben cómo hacerla).

En Word tendremos un documento así:

Por si no lo saben, aquellas partes del Word en donde dice “Haga clic o pulse aquí para escribir texto”, cada uno es un “Control de contenido de texto sin formato” que serán los campos en donde insertemos el texto que tenemos en Excel. Para usarlos, activen la pestaña “Programador” de su Word y en el grupo “Controles” los encontrarán.

Para que sea fácil su identificación en el archivo Word vamos a modificar la propiedad “Título” de cada control, no será difícil si vamos seleccionado cada uno y presionamos el botón “Propiedades” del mismo grupo “Controles” y agregamos el título que elijamos.

En mi caso elegí TxtId, TxtNombres, TxtSexo, etc.

Ahora sugiero releer un par de artículos sobre las referencias a activar y el objeto Word (Enlace1) y otro sobre cómo detectar archivos abiertos (Enlace2). Del segundo enlace copiaremos en nuestro archivo Excel la UDF “IsFileOpen”.

Luego vamos a declarar las variables y abrir el archivo Word al que enviaremos los datos. Ya que enviaremos solo un registro a la vez, es importante que previamente se haya elegido un dato en la lista desplegable de la celda B1..

 If Range("B1") = "" Then
     MsgBox "Elija un dato de la lista", vbOKOnly, "Todo Sobre Excel"
     Exit Sub
 End If 

strArchivo = ThisWorkbook.Path & "\Formulario de datos.docx" 

If Dir(strArchivo) = "" Then
      MsgBox "No existe el archivo", vbOKOnly, "Todo Sobre Excel"
      Exit Sub 
End If 

If IsFileOpen(strArchivo) Then
      'si está abierto el archivo word
      Set objDoc = GetObject(strArchivo)
      Set MiappWord = objDoc.Application
 Else
      'si está cerrado el archivo Word
      Set MiappWord = CreateObject("Word.Application")
      MiappWord.Documents.Open strArchivo
      MiappWord.Visible = True 
End If 

Algo que no hicimos al inicio es declarar las variables que usaremos para los datos que enviaremos a Word. Asimismo, como en Excel nuestros datos están como Tabla, declararemos una variable para dicha tabla. En un momento veremos para qué es todo eso

Dim strNombre$, strSexo$, strDireccion$, strPrograma$ 
Dim FechaN as Date 
Dim MiTabla as ListObjects 

Para hallar los valores que corresponda al ID que elijamos en la celda B1, vamos a usar la WorkSheetFunction llamada VlookUp, de funcionamiento similar a BuscarV. Yo prefiero usar Find, pero para el ejercicio considero que será más fácil entender la función elegida. Esos sí, como buscaremos los datos en una Tabla, primero asignaremos el objeto Tabla a la variable respectiva y ya después usaremos el VLookUp.

Set miTabla = Hoja1.ListObjects("Tabla1")

With Application.WorksheetFunction
     strnombre = .VLookup(Range("B1"), miTabla.Range, 2, 0)
     strsexo = .VLookup(Range("B1"), miTabla.Range, 3, 0)
     fechan = .VLookup(Range("B1"), miTabla.Range, 4, 0)
     strdireccion = .VLookup(Range("B1"), miTabla.Range, 5, 0)
     strprograma = .VLookup(Range("B1"), miTabla.Range, 6, 0) 
End With 

Como ya tenemos los valores en nuestras variables, ahora sí comenzaremos a trabajar con el objeto Word y con los controles que ahí tenemos. Como vamos a trabajar con el documento activo, y hemos colocado nuestros propios títulos a cada control de nuestro archivo Word, usaremos también el método SelectContentControlsByTitle así como el objeto Range del control, que representa su área continua. Por último, a través de la propiedad Text le daremos el valor de nuestras variables de Excel. Ah, ojo con los nombres de los títulos de los controles ya que son sensibles a mayúsculas y minúsculas. El resultado en Word debe verse así:

Juntando todo y ordenando, deberíamos tener esto:

Option Explicit
 'Todo Sobre Excel
 'Abraham Valencia
 'https://abrahamexcel.blogspot.com/
 'https://www.facebook.com/TodosobreExcelAV/
 'https://twitter.com/Todosobre_Excel
 'Lima, Perú
 'Julio del 2020

 Sub EnviarDatosaWord() 

Dim MiappWord As Word.Application 
Dim objDoc As Object 
Dim strArchivo$, strnombre$, strsexo$, strdireccion$, strprograma$ 
Dim fechan As Date 
Dim miTabla As ListObject 

If Range("B1") = "" Then
     MsgBox "Elija un dato de la lista", vbOKOnly, "Todo Sobre Excel"
     Exit Sub 
End 

If strArchivo = ThisWorkbook.Path & "\Formulario de datos.docx" If Dir(strArchivo) = "" Then
      MsgBox "No existe el archivo", vbOKOnly, "Todo Sobre Excel"
      Exit Sub 
End If 

Set miTabla = Hoja1.ListObjects("Tabla1") 

With Application.WorksheetFunction
     strnombre = .VLookup(Range("B1"), miTabla.Range, 2, 0)
     strsexo = .VLookup(Range("B1"), miTabla.Range, 3, 0)
     fechan = .VLookup(Range("B1"), miTabla.Range, 4, 0)
     strdireccion = .VLookup(Range("B1"), miTabla.Range, 5, 0)
     strprograma = .VLookup(Range("B1"), miTabla.Range, 6, 0) 
End With 

If IsFileOpen(strArchivo) Then
      'si está abierto el archivo word
      Set objDoc = GetObject(strArchivo)
      Set MiappWord = objDoc.Application 
Else
      'si está cerrado el archivo Word
      Set MiappWord = CreateObject("Word.Application")
      MiappWord.Documents.Open strArchivo
      MiappWord.Visible = True 
End If 

With MiappWord.ActiveDocument
     .SelectContentControlsByTitle("TxtId").Item(1).Range.Text = Hoja1.Range("B1").Value
     .SelectContentControlsByTitle("TxtNombres").Item(1).Range.Text = strnombre
     .SelectContentControlsByTitle("TxtSexo").Item(1).Range.Text = strsexo
     .SelectContentControlsByTitle("TxtFechaN").Item(1).Range.Text = fechan
     .SelectContentControlsByTitle("TxtDirección").Item(1).Range.Text = strdireccion
     .SelectContentControlsByTitle("TxtPrograma").Item(1).Range.Text = strprograma
     .SelectContentControlsByTitle("TxtFechaI").Item(1).Range.Text = Date     
 End With

 'Dejamos el cursor al final de la página 
MiappWord.Selection.EndKey Unit:=wdStory 

MsgBox "Todo listo", vbOKOnly, "Todo Sobre Excel" 

'Esta línea no es necesaria, pero por costumbre algunos la usamos 
Set MiappWord = Nothing 

End Sub 

Y listo, eso es todo por hoy. Ah, por supuesto que si quieren pueden mejorar el formato del Word, al ser este un ejemplo pues no le dedico tiempo a ese tipo de detalles ¡Hasta la próxima!

Abraham Valencia
Lima, Perú

Descargue el ejemplo de aquí

jueves, 25 de junio de 2020

Interactuando con Microsoft Word (III): Abrir archivos de Word, o detectar si ya están abiertos, para trabajar con ellos desde Excel usando VBA.

En los artículos anteriores de cómo interactuar con Microsoft Word (Enlace1, Enlace2), vimos básicamente la forma de enviar datos desde una hoja de Excel a un archivo de Word nuevo, pero ¿Qué pasa si queremos enviar nuestros datos a un archivo que ya existe? La primera respuesta que quizá se les viene a la mente es “pues lo abrimos ¡obvio!”, claro, eso es lo que haremos, aunque iremos un poquito más allá y veremos que hacer si ya está abierto el archivo en cuestión.

Ya saben ustedes que lo primero es activar las referencias respectivas a Microsoft Word en el editor de VBA, después de eso vamos a declarar las variables que vamos a usar. Una para crear un objeto que nos ayudará a trabajar con el archivo Word si ya está abierto, una para crear el objeto Word y otra para la ruta del archivo.

Dim objDoc As Object 
Dim MiappWord As Word.Application 
Dim strArchivo$ 

Ahora vamos a darle valor a la variable con la ruta del archivo, asumiendo que el archivo Word y el de Excel están en la misma carpeta.

strArchivo = ThisWorkbook.Path & "\ArchivoEjemploWord.docx " 

Como para que no quede duda de que todo saldrá bien, usando Dir nos aseguramos que el archivo exista.

If Dir(strArchivo) = "" Then
     MsgBox "No existe el archivo", vbOKOnly, "Todo Sobre Excel"
     Exit Sub
 End If 

De no existir el archivo, un MsgBox nos lo indicará y se terminará el proceso.

Ahora algo importante, para saber si el archivo está abierto vamos a usar una UDF que Microsoft puso a disposición pública hace año (ahora la página no existe), se puede mejorar, claro, pero dado que hay algo ya hecho ahorremos tiempo. Pueden ponerla en el mismo módulo de la rutina que estamos haciendo o en otro, no hay problema.

' This function checks to see if a file is open or not. If the file is
' already open, it returns True. If the file is not open, it returns 
' False. Otherwise, a run-time error occurs because there is 
' some other problem accessing the file. 
' Código de macro para comprobar si un archivo ya está abierto 
' http://support.microsoft.com/kb/291295/es 

' Function IsFileOpen(filename As String) 
Dim filenum As Integer, errnum As Integer 
' 
On Error Resume Next   ' Turn error checking off. 
filenum = FreeFile()   ' Get a free file number. 
' Attempt to open the file and lock it. 
Open filename For Input Lock Read As #filenum 
Close filenum          ' Close the file. 
errnum = Err           ' Save the error number that occurred. 
On Error GoTo 0        ' Turn error checking back on. 
' Check to see which error occurred. 
Select Case errnum     
' No error occurred.     
' File is NOT already open by another user. 
Case 0
     IsFileOpen = False
     ' Error number for "Permission Denied."
     ' File is already opened by another user. 
Case 70
     IsFileOpen = True
     ' Another error occurred.
 Case Else
     Error errnum 
End Select 
End Function 

Entonces, ya con nuestra UDF y un If, vamos a detectar si el archivo está abierto, y de estarlo, con la función GetObject vamos a hacer la referencia respectiva al archivo (objDoc) y como lo que haremos es crear un objeto, vamos luego a convertirlo en nuestro objeto Word (MiappWord). De estar cerrado (Else), crearemos un objeto Word, abriremos el documento del ejemplo y lo haremos visible. Miren y analicen el código.

If IsFileOpen(strArchivo) Then
     'si está abierto
     Set objDoc = GetObject(strArchivo)
     Set MiappWord = objDoc.Application 
Else
     'si está cerrado
     Set MiappWord = CreateObject("Word.Application")
     MiappWord.Documents.Open strArchivo
     MiappWord.Visible = True 
End If 

Sea abierto o cerrado, una vez que tengamos el control del archivo, y para que se vea como se puede hacer cosas en él, dejaré una línea simple que lo único que hará es llevar el cursor al final del archivo Word.

MiappWord.Selection.EndKey Unit:=wdStory

Nuestra rutina completa debe de quedar así:

Option Explicit
'Todo Sobre Excel 
'Abraham Valencia 
'https://abrahamexcel.blogspot.com/ 
'https://www.facebook.com/TodosobreExcelAV/ 
'https://twitter.com/Todosobre_Excel 
'Lima, Perú 
'Junio del 2020 

Sub AbrirWord() 

Dim MiappWord As Word.Application 
Dim objDoc As Object 
Dim strArchivo$ 

strArchivo = ThisWorkbook.Path & "\ArchivoEjemploWord.docx " 

If Dir(strArchivo) = "" Then
     MsgBox "No existe el archivo", vbOKOnly, "Todo Sobre Excel"
     Exit Sub 
End If 

If IsFileOpen(strArchivo) Then
     'si está abierto
     Set objDoc = GetObject(strArchivo)
     Set MiappWord = objDoc.Application 
Else
     'si está cerrado
     Set MiappWord = CreateObject("Word.Application")
     MiappWord.Documents.Open strArchivo
     MiappWord.Visible = True
 End If 

MiappWord.Selection.EndKey Unit:=wdStory 

End Sub 

Y listo, eso es todo en esta ocasión y la prometo que continuaremos con más sobre interactuar con Word desde Excel a través de VBA ¡Hasta la próxima!

Abraham Valencia
Lima, Perú

Descargue el ejemplo de aquí

domingo, 21 de junio de 2020

Interactuando con Microsoft Word (II): Enviar datos de Excel a Word (VBA) y darles formato.

Hace varias semanas le comenté sobre cómo comenzar a interactuar entre Excel y Word usando VBA. (Enlace). En aquella ocasión sobre todo nos centramos en enviar tablas hacia Word en diversos formatos. En esta ocasión iremos un poco más allá y enviaremos datos y modificaremos su formato en el archivo de Word creado, entonces ¡Manos a la obra!

Para el ejemplo vamos a usar una cosa muy simple de datos en Excel, así:

Ahora, lo primero, como ya saben, será activar las referencias a “Microsoft Word 16.0 Object Library”, hecho eso corresponde declarar nuestras variables, en donde la primera será la de nuestro objeto Word.

Dim MiappWord As Word.Application

Ahora vamos a crear el objeto Word y un documento nuevo en blanco.

Set MiappWord = CreateObject("Word.Application") 
MiappWord.Documents.Add 
Como ya está creado nuestro objeto y ya tenemos un archivo nuevo en él, así no lo veamos, copiaremos nuestros datos de Excel.
Hoja1.Range("A1:C11").Copy

A partir de aquí empezaremos a usar el objeto Word por lo que usaremos la instrucción With para ahorrarnos algunas líneas de código.

With MiappWord 

Luego pegaremos nuestros datos en Word pero manteniendo el formato de origen.

  .Selection.PasteExcelTable False, False, False

Como es un archivo nuevo, la tabla pegada tendrá el índice 1, por lo que para referirnos a ella usaremos dicho índice como tabla dentro del documento activo (ActiveDocument) de Word y por ende, para seguir facilitándonos escribir un poco menos, usaremos otro With, ya que los formatos a aplicar estarán dentro de celdas de dicha tabla.

With .ActiveDocument.Tables(1)

Como en la tabla tenemos objetos Cell, lo que haremos es cambiar las propiedades respectivas de cada uno de los objetos que requerimos. Voy a dejar las líneas en VBA comentadas para que se sepa qué hace cada una.

         'Fuente de color rojo
         .Cell(2, 3).Range.Font.ColorIndex = wdRed
         'Fondo de color verde obtenido con constante de Word
         .Cell(3, 3).Shading.BackgroundPatternColor = wdColorGreen
         'Fondo de color verde gris obtenido con RGB
         .Cell(4, 3).Shading.BackgroundPatternColor = RGB(184, 183, 153)
         'Fuente en negrita
         .Cell(5, 3).Range.Font.Bold = wdToggle
         'Fuente en cursiva
         .Cell(6, 3).Range.Font.Italic = wdToggle
         'Fondo en rojo para toda una fila
         .Rows(7).Shading.BackgroundPatternColor = wdColorRed
         'Escribir hola en una celda
         .Cell(Row:=8, Column:=3).Range = "Hola"
 End With 

Para seguir aprendiendo sobre este tema, también vamos a ver cómo hacer cambios a varias celdas de la tabla que son contiguas, pero están en distintas filas y columnas.  Lo primero es definir dicho rango de celdas. En este caso iniciaremos en la fila 9, columna 1 y terminaremos en la fila 11, columna 3.

With .ActiveDocument
    Set mirango = .Range(Start:=.Tables(1).Cell(9, 1).Range.Start, End:=.Tables(1).Cell(11, 3).Range.End)
End With 

Para que no se mareen con los With, tranquilos/as, al final veremos todo junto. Volviendo a lo anterior, ya definido el rango, a través de un For-Each vamos a colocar la misma palabra en dichas celdas.

For Each miCelda In mirango.Cells
     miCelda.Range = "Repetir"
Next miCelda  

Quizás si tenemos todo junto nos sea más fácil entenderlo:

Option Explicit
'Todo Sobre Excel 
'Abraham Valencia 
'https://abrahamexcel.blogspot.com/ 
'Lima, Perú 
'Junio del 2020 

EnviardatosaWord() 

Dim MiappWord As Word.Application 
Dim mirango As Word.Range, miCelda As Word.Cell 

Set MiappWord = CreateObject("Word.Application") 
MiappWord.Documents.Add Hoja1.Range("A1:C11").Copy 

With MiappWord

          .Selection.PasteExcelTable False, False, False

          With .ActiveDocument.Tables(1)
              'Fuente de color rojo
              .Cell(2, 3).Range.Font.ColorIndex = wdRed
	            'Fondo en verde con constante de Word         
              .Cell(3, 3).Shading.BackgroundPatternColor = wdColorGreen
              'Fondo en verde gris con función RGB         
              .Cell(4, 3).Shading.BackgroundPatternColor = RGB(184, 183, 153)
              'Fuente en formato negrita
              .Cell(5, 3).Range.Font.Bold = wdToggle
              'Fuente en formato cursiva
              .Cell(6, 3).Range.Font.Italic = wdToggle
              'Fondo de color rojo para toda una fila
              .Rows(7).Shading.BackgroundPatternColor = wdColorRed
              'Escibir hola en una celda
              .Cell(Row:=8, Column:=3).Range = "Hola"
           End With

           With .ActiveDocument
               Set mirango = .Range(Start:=.Tables(1).Cell(9, 1).Range.Start, End:=.Tables(1).Cell(11, 3).Range.End)
           End With

          .Visible = True 
End With 

'Escribir la palabra Repetir en todas las celdas del rango elegido
For Each miCelda In mirango.Cells
     miCelda.Range = "Repetir" 
Next miCelda 

Application.CutCopyMode = False 
Set MiappWord = Nothing 

End Sub  

Si todo salió bien, en su Word deben tener algo como esto:

Y eso es todo en esta ocasión, espero que hayan aprendido un poco más sobre interactuar con Word desde Excel. Hasta la próxima.

Abraham Valencia
Lima, Perú

Descargue el ejemplo de aquí

 

viernes, 12 de junio de 2020

Publicando en Facebook desde Excel con VBA (II)

Hace algunos días vimos como publicar un post de texto en nuestras páginas de Facebook (Enlace). Además, ahí explicamos cómo obtener la clave token de nuestra página, la cual es necesaria para poder seguir publicando diversas cosas como imágenes, que es lo que haremos en esta oportunidad.

Como asumo que ya todos/as leyeron el artículo anterior, ahora me centrare en las características que debe tener la imagen que vamos a usar. Ah, eso sí, la imagen debe estar ya en internet de manera previa, es decir, vamos a usar una imagen que hayamos colocado en alguna web o de alguna web que lo permita. Sobre el formato, pueden usarse los siguientes: JPG/JPEG, BMP, PNG, GIF y TIFF. “Facebook For Developers” recomienda que los archivos PNG tengan un tamaño menor a 1 MB, asimismo, para otros formatos recomiendan imágenes de menos de 4 MB.

Para lograr nuestro cometido, nuevamente usaremos el objeto MSXML2.XMLHTTP60 y el método POST. Para ello los parámetros que usaremos en esta ocasión serán los siguientes:

"https://graph.facebook.com/[Aquí_el_ID_de_la_página]/photos?&url=[Aquí_la_URL_de_tu_imagen]&caption=[Aquí_el_texto_que_queremos_con_la_foto]&access_token=[Aquí_tu_clave_token]"

Por si acaso, una forma fácil de conseguir el URL de una imagen es darle clic derecho y elegir la opción “Copiar dirección de imagen” o “Copiar vínculo de la imagen” (el mensaje exacto dependerá del navegador d que uses).

Ahora sí vamos a lo que les gusta, el VBA. Lo primero será declarar nuestras variables. No ovliden activar las referencias a “Microsoft XML, v6.0” (el 6 puede variar dependiendo de tu versión de Office).

Dim WebXML As New MSXML2.XMLHTTP60 
Dim miURL As String
Ahora a la variable miURL, le vamos a asignar la cadena dar con parámetros que necesitamos y habíamos comentado líneas arriba.  Como verán los parámetros deben ser reemplazados en la cadena (sin los corchetes, por si acaso.). Una vez conseguida la cadena, se la asignamos a la variable, quedando en mi caso así:
miURL = "https://graph.facebook.com/ 389999999905731/photos?&url=https://1.bp.blogspot.com/9TKACuCKzyA/XtmyFrZXGNI/AAAAAAAADzc/YofqAsYp1SHGi9U9reyxtitmzOIQCK4BGAsYHg/w400h330/Face11.jpg&caption=Imagen de prueba&access_token=EAAkUiClZCzDgBAB0ZA2P4iGZBdNjC1O999JvsI8AeZBufiwUw18jAAOZAF9nZB30QEIeEZCfXh6ZC1KsE9yNXad7rTnZCpOkRURpbbIt1SU35P2z4GXhBMNtdwZB8HggZBL1LZBwXAyeSpo844y1n4a3U8KcdZCHsjyPCAZAuSrHyLYjgZDZD"

Lo que toca ahora es usar la instrucción Open combinada con el método Post para configurar la solicitud (cadena URL) a la web y de inmediato usaremos el método Send para abrir la conexión y enviar la solicitud al servidor. Todo junto debe quedar así: 

Sub EnviaraFacebook()  

Dim WebXML As New MSXML2.XMLHTTP60  
Dim miURL As String 

miURL = "https://graph.facebook.com/ 389999999905731/photos?&url=https://1.bp.blogspot.com/9TKACuCKzyA/XtmyFrZXGNI/AAAAAAAADzc/YofqAsYp1SHGi9U9reyxtitmzOIQCK4BGAsYHg/w400h330/Face11.jpg&caption=Imagen de prueba&access_token=EAAkUiClZCzDgBAB0ZA2P4iGZBdNjC1O999JvsI8AeZBufiwUw18jAAOZAF9nZB30QEIeEZCfXh6ZC1KsE9yNXad7rTnZCpOkRURpbbIt1SU35P2z4GXhBMNtdwZB8HggZBL1LZBwXAyeSpo844y1n4a3U8KcdZCHsjyPCAZAuSrHyLYjgZDZD" 

WebXML.Open "POST", URL, False  
WebXML.send  

MsgBox "Listo"  

End Sub 

Al correr la macro, en nuestra página tendremos algo así:

¿Notan que, nuevamente, sale el nombre de la app creada para Facebook en el primer artículo? Ese post no lo borraré para que quede como una nueva prueba. Les recuerdo que el token les seguirá sirviendo para próximas publicaciones.

Eso es todo en esta oportunidad ¡Hasta la próxima!

Abraham Valencia
Lima, Perú

jueves, 4 de junio de 2020

Publicando en Facebook desde Excel con VBA (I)

Hoy veremos la primera entrega de cómo hacer publicaciones en Facebook desde Excel usando VBA. En esta ocasión comenzaremos con una forma de publicar post, de texto, en nuestra página de Facebook. Si les adelanto que por ser la primera entrega gran parte del artículo será sobre la forma para habilitar la cuenta de desarrolladores de Facebook y dar los permisos necesarios, y similares, para poder conectar a Excel con Facebook.

Comenzado, entonces lo primero que debemos hacer es habilitar nuestra cuenta de Facebook Developers, no necesitas crear algo nuevo, solo usa tu cuenta de Facebook ya existente. Para ello entra aquí: Enlace.  Una vez hecho eso, entra aquí: Enlace y activa la opción “Mis apps” – “Crear app”.

Elige el nombre que desees, yo usaré “AppExcel”

Dale clic a “Crear identificador de la app”. Si te sale un captcha, solo acepta. Te aparecerá una página como esta.

En el menú de la izquierda elige “Configuración” y luego “Básica”. Debes tener algo como lo siguiente en pantalla:

En “Categoría” sugiero colocar “Negocios y páginas” y dale clic a “Guardar cambios”. Ahora entra al siguiente enlace: Enlace. La página debe ser similar a esta:

En “Usuario o página” elige la opción “Obtener token de acceso a la página”. Lo más probable es que te salga una ventana emergente que te pregunte si deseas continuar con el mismo usuario de Facebook, obviamente acepta. Luego te saldrá algo como la siguiente imagen, solo elige la pagina que desees y dale clic al botón “Siguiente”.

Si te sale una ventana emergente más, tranquilo, son más permisos, solo dale clic al botón “Listo” y en la otra ventana al botón “Aceptar”. Ahora en la página en la que ya estabas, nuevamente expande las opciones de “Usuario o página” y aparecerá el nombre de la página que elegiste; elígela. Luego en la sección “Permisos” elige “Page_manage_post” y presiona el botón “Generate Access Token”.  

Aparecerán nuevamente las ventanas emergentes, acepta todas y vuelve a la página. En “Usuario o página” elige nuevamente tu página y ahora sí ya se generó el token que necesitas; cópialo. Verás que es bastante largo, pero es lo normal. Esa clave token es la llave para que podamos publicar en Facebook.

Ahora entra aquí: Enlace. Tendrás esto en pantalla:

En el cuadro de texto correspondiente pega tu clave token y luego dale clic al botón “Depurar”. El resultado será similar a lo que muestro a continuación:

Las claves token tienen un periodo corto de duración, pero si ven al final hay un botón “Ampliar token de acceso”, denle clic. Por protocolo quizás Facebook les pida su clave, ingrésenla sin miedo. Luego obtendrán lo siguiente:

Clic a “Depurar”. Copien el nuevo token y no lo pierdan que ya viene lo bueno, pero primero anda a tu página elige el menú “Información” y cuando cargue la página correspondiente, anda a la parte baja final y verás lo siguiente:

Copia el número identificador de tu página.

Ahora sí vamos a Excel. Anda al editor de VBA y lo primero que debes hacer es activar las referencias a “Microsoft XML, v6.0” (el 6 puede variar dependiendo de tu versión de Office).

Nosotros usaremos el objeto MSXML2.XMLHTTP60 que se usa para realizar solicitudes HTTP. Dichas solicitudes nos permiten interactuar con un servicio web, API y similares. Dicho eso, declararemos nuestras variables; solo vamos a usar dos:

Dim URL As String 
Dim WebXML As New MSXML2.XMLHTTP60 

Ahora vamos a recurrir a la “API Graph” de Facebook la cual nos dice que con el método POST podemos enviar información y publicarla, pero hay que seguir cierttos parámetros. En esta ocasión usaremos lo siguiente:

"https://graph.facebook.com/[Aquí_el_ID_de_la_página]/feed?message=[Aquí_el_texto_que_queremos_en_el_post]&access_token=[Aquí_tu_clave_token]"

Como ven los parámetros deben ser reemplazados en la cadena y son los que ya obtuvimos líneas arriba (sin los corchetes, por si acaso.). Una vez conseguida la cadena, será la que asignemos a nuestra variable URL. En mi caso quedaría así:

URL = "https://graph.facebook.com/389999999905731/feed?message=Hola, esto es una prueba&access_token=EAAkUiClZCzDgBAB0ZA2P4iGZBdNjC1O999JvsI8AeZBufiwUw18jAAOZCAF9nZB30QEIeEZCfXh6ZC1KsE9yNXad7rTnZCpOkRURpbbIt1SU35P2z4GXhBMNtdwZB8HggZBLO1LZBwXAyeSpo844y1n4a3U8KcdZCHsjyPCAZAuSrHyLYjgZDZD"

Ahora lo que haremos es usar la instrucción Open combinada con el método Post, para configurar la solicitud (cadena URL) a la web.

WebXML.Open "POST", URL, False

Para finalizar usaremos el método Send para abrir la conexión y enviar la solicitud al servidor.

WebXML.Send 

Si queremos ver todo junto tendremos esto:

Sub EnviaraFacbook() 

Dim WebXML As New MSXML2.XMLHTTP60 
Dim URL As String

 URL = "https://graph.facebook.com/389999999905731/feed?message=Hola, esto es una prueba&access_token=EAAkUiClZCzDgBAB0ZA2P4iGZBdNjC1O999JvsI8AeZBufiwUw18jAAOZCAF9nZB30QEIeEZCfXh6ZC1KsE9yNXad7rTnZCpOkRURpbbIt1SU35P2z4GXhBMNtdwZB8HggZBLO1LZBwXAyeSpo844y1n4a3U8KcdZCHsjyPCAZAuSrHyLYjgZDZD"

WebXML.Open "POST", URL, False 
WebXML.send 

MsgBox "Listo" 

End Sub 

Una vez que corremos la macro, en nuestra página tendremos algo así:


¿Notan que sale el nombre de la app creada para Facebook? Ese post no lo borraré para que quede como prueba. No olviden que el mensaje puede ser reemplazado por variables o datos de celdas u objetos ActiveX. No olviden que este token les servirá para las próximas publicaciones que enseñaremos.

Eso es todo en esta oportunidad, continuaré pronto con más sobre publicaciones en Facebook desde Excel y VBA ¡Hasta la próxima!

Abraham Valencia
Lima, Perú

sábado, 21 de marzo de 2020

Descargando datos del Coronavirus a través de Power Query

Lamentablemente una pandemia acecha al mundo y muchos/as nos hemos visto obligados a refugiarnos en nuestras casas. Muchos países, ante el temor de más contagios, han ordenado que solo salgan de sus casas los/as encargados/as de abastecer a las familias. En medio de esto el trabajo desde casa se ha incrementado y, asimismo, mucha gente comienza a querer conocer y/o ver datos sobre la afectación de Coronavirus no solo en su país, sino también en el mundo. Para lo primero, sin lugar a duda Excel debe ser una de los programas más usados, como siempre, pero ¿para lo segundo nos será útil? La respuesta casi obvia es: Sí. Ahora lo que veremos es cómo hacer para facilitarnos ver y/o trabajar con los datos del Coronavirus a nivel mundial. Comencemos.

Por suerte Google ha implementado una web en la cual coloca los datos a disposición de todos/as y en un formato tipo tabla que nos permite extraer los datos usando Power Query (Obtener y transformar datos) que es la herramienta que usaremos en esta ocasión. El enlace de dicha web es el siguiente, por cierto: Enlace

Ahora en nuestra hoja de Excel vamos a ir a la pestaña “Datos” y en el grupo “Obtener y transformar datos” vamos a darle clic al botón “Desde la web”.

En el cuadro de diálogo que sale ingresaremos el enlace comentado líneas arriba y le daremos clic al botón “aceptar”.

En el siguiente cuadro, no nos hagamos un mundo y solo démosle clic a “Conectar”.

En el cuadro “Navegador” vamos a elegir la segunda opción “Table 0” y le daremos clic al botón “Transformar datos”.

Se abrirá el editor de Power Query y ahí podemos elegir quitar las columnas que no nos interesen. Por ejemplo, yo no uso la columna “Case per 1M people”, así que basta darle clic derecho a su encabezado y elegir “Quitar”.

En mi caso quiero, también, cambiar el formato a algunas columnas. Por ejemplo, la columna “Recovered” está en formato texto, le doy clic al “ABC” y elijo la opción “Número entero” y listo:

Una vez hecho eso, vamos a la pestaña “Inicio” y le damos clic al botón “Cerrar y cargar”.

Si hicimos todo bien, en nuestra hoja tendremos algo así:

Para terminar, vamos a la pestaña “Datos” de nuestro Excel y en el grupo “Consultas y conexiones” dale clic al botón “Actualizar todo” y en la lista que se despliega dale clic a “Propiedades de conexión…” y en el diálogo que se mostrará vamos a ir a la pestaña “Uso” y ahí activen la opción “Actualizar cada” y coloquen 30 minuto (o lo que deseen).  También activen la opción “Actualizar al abrir el archivo”. Clic al botón “Aceptar” y listo, ya está listo nuestro archivo. Cada 30 minutos, o lo que hayamos elegido, y al abrir el archivo tendremos los datos del avance del Coronavirus en cada país.

Ah, por supuesto que se puede cambiar el formato, ordenar como queramos y sobre todo, trabajar los datos como necesitemos, pero eso ya es tarea para ustedes. Hasta la próxima.

Abraham Valencia
Lima, Perú

Descargue el ejemplo aquí

miércoles, 18 de marzo de 2020

Entrevista a Sergio Alejandro Campos Hernández - MVP Excel

Hace ya más de diez años conocí en los foros de Excel a Sergio Alejandro Campos Hernández. En aquel entonces Facebook no era tan usado y mucho menos para difundir Excel o responder preguntas acerca de aquel programa. Aún recuerdo cuando fue nombrado por primera vez MVP (2012), sinceramente me dio mucha alegría y le escribí para felicitarlo y me dijo que cuando yo había sido MVP, había sido una de las personas que lo inspiró. Aunque yo me retiré de los foros por mucho tiempo, él sí mantuvo el entusiasmo permanente, sigue siendo MVP y sin duda es una de los más conocidos y mejores conocedores de VBA y Excel que tiene Latinoamérica solo basta recordar que prácticamente no hay usuario/a de Excel que no conozca su web: Enlace

En esta época en que cada vez Excel acepta más datos y/o permite trabajar con más de ellos usando las herramientas Bi, y cuando vuelven muchos a anunciar la “muerte del VBA” o a creer que JavaScrit/TypeScript terminarán con dicho lenguaje, Sergio nos da su importante opinión y definitivamente nos sigue alentando a usar Excel y VBA y sobre todo a recordar que “el límite es tu imaginación”. Les dejo aquí una interesante entrevista que le hice y que sé los seguirá inspirando a aprender más de Excel.

1- ¿Cuándo comenzaste a usar Excel y cuándo es que te diste cuenta que era tu favorito?

Cuando tenía 17 años entré a trabajar de Auxiliar de almacén en una fábrica de calzado. En esas fechas no tenía conocimientos de computación y cualquier cosa que mis compañeros hicieran en la computadora que tenía Windows 95, se me hacía maravillosa.

Como todo lo que veía en la computadora se me había desconocido, pero a la vez interesante, fue que decidí tomar un curso de Informática básica, donde vimos desde Office, pasando por programación hasta diseño Web, una repasada de todo en año y medio.

Un día, cuando ya conocía algo de informática, pero muy poco de Excel, uno de mis compañeros abrió un archivo que tenía muchos botones. Me dijo “aquí vas a ingresar esta cantidad y luego aprietas este botón”. Cuando lo hice, vi que todo se movía, datos por aquí y por acá; pareciera que la computadora se había vuelto loca. Como en Office 95 la programación de macros estaba en una hoja de Módulo, fue que sin querer abrí esa hoja y vi muchas palabras en inglés. Era código VBA. Ese fue el momento.

2- ¿Qué es lo que más te gusta de Excel?

Me gustaría comenzar diciendo que realmente poco no me gusta de Excel, porque ha sido mi herramienta principal desde hace muchos años. Pero respondiendo la pregunta, te diría que me gusta que siempre va un paso adelante. Herramientas o funcionalidades que el mercado necesita, se implementan en Excel. Si bien no todo se puede hacer en Excel, Microsoft se encarga de hacer de alguna u otra manera pegárselo para que sí se pueda. Ya hemos visto cómo Excel se robó Power Pivot de SQL Server.

Tengo una máxima “cuando me piden algo, primero veo si lo puedo realizar en Excel”.

3- En el "eterno" debate de si Excel debe ser usado como base de datos o no ¿consideras que Excel ganó la batalla gracias a la incorporación de Power Query y Power Pivot?

No sé si decir que Excel ganó la batalla, pero sí se decir que Microsoft le está dando super poderes con los complementos Power. Es claro que Excel no es una base de datos, pero de cierto modo y para proyectos pequeños podemos hacer alguna serie de trucos con fórmulas Tablas dinámica, macros, para “simular” que nuestra información se guarda en una base de datos.

Sin embargo, con Excel sí podemos trabajar con datos provenientes de una base de datos, ya que tenemos la facilidad de usar conectores hacia los motores más famosos de base de datos, y hacer que Excel funcione como un Front End.

La información crece a niveles brutales y en ciertas ocasiones Excel es superado cuando deseamos trabajar con archivos o tabla de millones de registros, y por más que tengamos un buen equipo de cómputo o Excel de 64 bits, simplemente es imposible. Es aquí donde entran los complementos de Power Query para transformar datos y Power Pivot para modelarlos.

4- ¿Qué y/o quiénes te animaron a convertirte en MVP?

Me gusta esta pregunta. Fíjate que fue un proceso de auto motivación, te cuento. A raíz de que conozco Excel, a la par conozco los Foros de Microsoft. En la época de los 90’s y a principios de los 2 mil, los foros eran un lugar muy concurrido para hacer todo tipo de preguntas relacionadas con productos de Microsoft. No existía Facebook ni Youtube, por lo que para buscar expertos los lugares eran contados.

En los foros todos podían realizar preguntas y también todos podían contestar, pero Microsoft daba distintivos a los que respondían más preguntas.

No se me olvida que cada que preguntaba algo, había una persona que ‘siempre contestaba’ (literal usaba comillas simples a diestra y siniestra). Esa persona era Héctor Miguel Orozco. Para mí, Héctor era el super héroe, porque parecía que se sabía todas las respuestas. Pero Héctor no estaba solo, también estaba KL y obvio Abraham Valencia. Era como una lucha de poderes, a ver quién respondía más preguntas.


Junto a cada respuesta venía el nombre y un título. Hubo unas siglas que me llamaron la atención, MVP. Luego averigüé que era un tipo de galardón que Microsoft otorgaba a las personas que desinteresadamente apoyaban a la comunidad, para este caso, respondiendo preguntas en los foros. Luego supe que no era la única manera.

Pasado un tiempo ya tenía clarísimo qué era ser un MVP y yo quería formar parte de ese selecto grupo. Combinaba mi participación en los foros entre preguntando y respondiendo preguntas.

Para llegar a ser MVP comprendí que tenía que ayudar a la comunidad, y una de las maneras de hacerlo era teniendo un sitio. En el año 2010 decido crear un Blog en la plataforma de Wordpress y comenzar a subir tutoriales sobre las preguntas de los foros o preguntas que me hacían mis compañeros de oficina. Cuando tenía más de un año con el sitio, decido promoverme como MVP y para el 2012 ya lo había logrado.

 

5- ¿Qué recomiendas hacer a otras personas que quieren también ser MVP?

Ser MVP no es fácil, sobre todo porque se debe tener un compromiso de aportar conocimiento a la comunidad, sin esperar nada a cambio, es como un servicio social.

A mí me motiva el saber que pertenezco a un grupo de personas con la actitud de ayudar, de aportar con mi granito de arena al conocimiento masivo, pero también sé que tengo que ser disciplinado porque hay que tener una constancia en las contribuciones.

Mi recomendación es que sean pacientes y compartan conocimiento. Ah, y háganse amigo de un MVP, pero no para que sea quién les responda sus preguntas, sino para que sea su mentor en el camino hacia ser MVP.

6- Microsoft anunció el fin de VBA con su versión 6.3, pero luego sacaron VBA 7.0 y 7.1. Lo mismo ocurrió con la aparición de VSTO. Ahora con la aparente priorización de Microsoft por trabajar en la nube ¿crees qué VBA llegó ahora sí a su fin?

(Risas)

Sinceramente no creo. Ismael Romero, MVP, dijo que seguramente nos tocará jubilarnos y VBA seguirá vivo.

La fuerza de VBA es toda la comunidad de usuarios que estamos generando proyectos con este lenguaje, y creo que sería una decisión arriesgada matarlo.

Por otro lado, VBA actualmente es una opción más para desarrollar en Office. Con la llegada de .NET Microsoft decide impulsar VSTO para crear aplicaciones de Office desde Visual Studio y en años recientes, con el tema Nube, toma el camino correcto introduciendo lenguajes como JavaScipt, TypeScript y Phyton al set de plataformas para desarrolladores de Office.

Ya lo he visto en mis videos, independiente el tiempo de vida que le quede a VBA, debemos ser innovadores y mirar hacia el futuro, ver las nuevas necesidades y aprender cosas nuevas.

7- ¿Consideras qué quiénes programamos en VBA y Excel, ahora estamos obligados a aprender a hacerlo con leguajes como JavaScript y sus "derivados" como TypeScript y otros lenguajes habituales para web?

No lo veo como obligación, más bien como una alineación de objetivos. Si estás cómodo desarrollando en VBA y te es suficiente para lo que necesites en tu empleo o para tus clientes, no está mal quedarse ahí.

Por otro lado, si estás en un sector que es empujado hacia otras plataformas como la nube, no tenemos opción más que actualizarnos.

También todo dependerá de qué alcance quieras que tengan tus desarrollos. Si quieres que sean siempre para escritorio usa VBA y conoce algún lenguaje .NET como Visual Basic o C#; si quieres que tus desarrollos sean compatibles tanto en escritorio como Web, mira hacia JavaScript, TypeScript y cualquier otro lenguaje que nos permita tener este tipo de convergencia.

8- ¿Algún mensaje final para los aficionados a Excel?

En mi opinión, la clave para dominar Excel es ser creativos. Para un problema siempre hay más de una solución.

No escatimen en su desarrollo profesional y en su capacitación. Existen muchas maneras de aprender, tenemos sitios Web, canales de Youtube, plataformas de pago, etc.

Y como siempre digo “el límite es tu imaginación”.

--------------------------------------------------------------------

Abraham Valencia

miércoles, 15 de enero de 2020

Exportando archivos Excel a PDF (II)

Hace varios meses expliqué, para aquellos/as que recién inician en este mundo del VBA, cómo convertir archivos Excel en PDF (Enlace), pero considero que algunas cosas quedaron en el aíre y espero hoy sí no dejar nada de lado.


Una de las primeras cosas que la gente pregunta es si existe la posibilidad de que, a través del método ExportAsFixedFormat, se pueda cambiar la configuración de las páginas u hojas que queremos convertir en PDF. La respuesta es no. Dicho método no tiene parámetros para lograr eso porque las características de configuración de las hojas de Excel están determinadas por las de la impresora activa, es decir, depende de los driver de dicha impresota o impresoras. Entonces, cosas como los tamaños de página disponibles no dependen del Excel ni del ExportAsFixedFormat, sino, de la impresora. Entonces, para tener una hoja en vertical u horizontal, con el tamaño de márgenes que necesitemos o con páginas A4, A3, etc., tenemos que realizar dichos cambios antes de mandaar a exportar en PDF. Si queremos que dichos cambios sean a través de VBA, sugiero usar la grabadora de macros para obtener el códio (no olvidar depurarlo/mejorarlo), los colocamos previos a exportar y verán como el archivo PDF tendrá las mismas características que hemos dado previamente. Ah, repito, todo dentro de lo que permita la impresora; si la impresora no permite hojas A3, no podremos darle dicho tamaño, tendremos que usar una impresora que lo permita.


Otro de los temas habituales que veo en los foros y grupos es sobre cómo crear un archivo PDF pero solo usando algunas de las hojas del libro. Antes de ver la respuesta directa, miremos las opciones que nos da el mismo Excel. Vamos a la pestaña "Archivo", elijamos "Exportar", démosle clic al botón "Crear documento PDF/XPS"