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" 

lunes, 7 de octubre de 2019

Interactuando con Microsoft Word (I): Enviar datos de Excel a Word (VBA)

En innumerables ocasiones he visto que mucha gente pregunta como enviar datos de Excel a Word, he de ser sincero y lo primero que se me viene a la cabeza es “que lo hagan desde Word usando Combinar Correspondencia”, pero en muchas de esas mismas ocasiones quieren y/o necesitan hacerlo desde Excel o en todo caso no solo enviar datos por partes sino más bien enviar incluso tablas o rangos completos. ¿Cuál es la solución? Definitivamente usar macros (VBA).

Para empezar, es importante aclarar que, si bien vamos a realizar la programación desde el entorno del VBA de Excel, como vamos a interactuar con Microsoft Word, lo que haremos es hacer referencias a los objetos de dicho programa, es decir, casi como usar el VBA desde el mismo Word. Dicho eso, lo primero que haremos es suponer que tenemos los siguientes datos:

Luego, como la idea es trabajar con Word, declararemos una variable respectiva y crearemos dicho objeto Word.

Dim MiappWord As Object 
Set MiappWord = CreateObject("Word.Application") 

Luego, como ya tenemos el Word listo, lo que haremos es crear un documento nuevo en blanco.

MiappWord.Documents.Add

Una vez hecho eso vamos a copiar el rango que necesitamos enviar a Word:

Hoja1.Range("A1:E97").Copy

Como ven ahí, en esta ocasión uso el nombre del módulo de la hoja para hacer referencia al rango de dicha hoja, no estoy usando ni Sheets ni WorkSheets ¿por qué? En realidad, es una buena forma de hacer referencia a las hojas sobre todo cuando más de una persona usa el archivo ya que si cambian el nombre de la hoja, y por ejemplo dice Sheets(“Hoja1”), dicha instrucción de VBA dejaría de servir, haciendo referencia al módulo de la hoja hay mayor garantía de que no se cambie (no es que nadie sapa como hacerlo, claro). Pero mejor volvamos a lo nuestro.

Como ya tenemos los datos en el portapapeles, ahora lo que haremos es pegarlos en Word, para ello utilizaremos el método PasteExcelTable que pega celdas de Excel en Word. Más referencias aquí: Enlace. Entonces, usaremos lo siguiente:

MiappWord.Selection.PasteExcelTable False, False, False

Ahora haremos visible el Word para ver el resultado.

MiappWord.Visible = True

Si leyeron el enlace recomendado, verán que lo que hemos hecho es pegar las celdas de Excel copiadas, manteniendo el formato de origen, por lo que debemos tener lo siguiente en nuestro archivo Word:

Vamos a probar diversas opciones del método sugerido, pero en cada ocasión vamos a insertar una página nueva en Word para que se note cada vez que pegamos los datos. Al método sugerido, vamos a agregarle un par más para que prueben. Comentaré en el código que es lo que hace cada uno.

With MiappWord
     'usar estilos de destino
     .Selection.PasteExcelTable False, True, False
     .Selection.InsertNewPage
     'vincular y mantener formato de origen
     .Selection.PasteExcelTable True, False, False
     .Selection.InsertNewPage
     'vincular y usar estilos de destino
     .Selection.PasteExcelTable True, True, False
     .Selection.InsertNewPage
     'imagen
     .Selection.PasteSpecial Link:=False, DataType:=wdPasteEnhancedMetafile, _
         Placement:=wdInLine, DisplayAsIcon:=False
     .Selection.InsertNewPage
     'conservar solo texto
     .Selection.PasteAndFormat (wdFormatPlainText)
 End With 

Para que esta última parte funcione sin mayor dilema, activen la siguiente referencia a Microsoft Word:

Si deseamos también podemos guardar el archivo.

MiappWord.ActiveDocument.SaveAs Filename:=ThisWorkbook.Path & "\miarchivo.docx"

Por último, podríamos tener una macro así ya con todo ordenado:

Sub EnviardatosaWord()

Dim MiappWord As Object 

Set MiappWord = CreateObject("Word.Application") 

MiappWord.Documents.Add 
Hoja1.Range("A1:E97").Copy 

With MiappWord
     'mantener el formato de origen
     .Selection.PasteExcelTable False, False, False
     .Selection.InsertNewPage
     'usar estilos de destino
     .Selection.PasteExcelTable False, True, False
     .Selection.InsertNewPage
     'vincular y mantener formato de origen
     .Selection.PasteExcelTable True, False, False
     .Selection.InsertNewPage
     'vincular y usar estilos de destino
     .Selection.PasteExcelTable True, True, False
     .Selection.InsertNewPage
     'imagen
     .Selection.PasteSpecial Link:=False, DataType:=wdPasteEnhancedMetafile, _
         Placement:=wdInLine, DisplayAsIcon:=False
     .Selection.InsertNewPage
     'conservar solo texto
     .Selection.PasteAndFormat (wdFormatPlainText)
     .ActiveDocument.SaveAs Filename:=ThisWorkbook.Path & "\miarchivo.docx"
     .Visible = True
 End With 

Application.CutCopyMode = False
Set MiappWord = Nothing 
MsgBox "Todo listo" 

End Sub 
Espero les sea útil. Hasta la próxima.

Abraham Valencia
Lima, Perú

Descargue el ejemplo de aquí

lunes, 30 de septiembre de 2019

Usando SOLVER para hallar los sumandos de un total

En ocasiones he visto en diversos foros y grupos (Facebook) de Excel que algunos/as usuarios/as tienen la necesidad de hallar los números cuya suma sirva para obtener un total buscado, es decir, necesitan hallar los sumandos de una suma o total.  Aunque hay varias formas de hacerlo (ninguna es simple) en esta ocasión vamos a usar el complemento SOLVER. Manos a la obra.

Empecemos colocando algunos valores en el rango A1:A10.

Por si no se dieron cuenta la suma de todos esos valores da 960 por ende, el total que buscaremos no debe superar ese número.

Ahora nos vamos a situar en A1 y le daremos un formato condicional con la opción de “Nueva regla de formato” y ahí vamos a elegir “Utilice una fórmula que determine las celdas para aplicar formato” y en “Dar formato a los valores donde esta fórmula sea verdadera” vamos a colocar lo siguiente:

=B1=1

Esto es lo que deberíamos tener hasta el momento:

Ahí mismo con el botón “Formato” podemos aplicar, por ejemplo, un fondo de color rojo.

Le damos clic al botón “Aceptar” y luego del mismo modo al cuadro de dialogo anterior. Para no estar dando Formato Condicional a celda por celda, solo copiaremos el formato de este modo:


Ahora, para nuestro ejemplo, vamos a introducir la siguiente fórmula en B11:


Ahora activaremos la herramienta SOLVER, y en el cuadro de dialogo correspondiente vamos a llenar así:

Yo he colocado 600, pero evidentemente ustedes elegirán el número total de su conveniencia. Ahora le daremos clic al botón “Agregar” y en el nuevo cuadro de diálogo dejaremos así las opciones:

Hemos elegido “bin” (de binario) para que los resultados sean 0 (cero) o 1 (uno). Démosle clic a “Aceptar” y obtendremos esto:


Ahora clic a “Resolver” y en el siguiente diálogo igual en “Aceptar”.

Si todo salió bien las celdas con los valores que suman 600, estarán resaltadas con fondo de color rojo.

Prueben con diversos totales y verán que consiguen resultados similares. Ah, eso sí, el total debe ser un número cuyos sumandos se encuentren sí o sí en las alternativas a marcar; asimismo, si hay más alternativas cuyos sumandos den el mismo resultado, la herramienta usada en esta ocasión solo nos brindará un grupo. Igual sé que les será útil.

Abraham Valencia
Lima, Perú

sábado, 14 de septiembre de 2019

Curiosidades en Excel: Valores ocultos en celdas combinadas

Pasan los años y diferentes versiones y nunca, pero nunca, Excel deja de sorprendernos. Hace pocos días en uno de los foros en los que siempre participo, un usuario mencionaba que, en unas celdas combinadas, al ver la celda y la barra de fórmulas, en ambos casos se mostraba un solo valor, pero que al usar macros y/o devolver con fórmulas el valor de ambas celdas por separado (como si no estuviesen combinadas), pues devolvía dos valores distintos ¿Qué cómo es eso? Para que se entienda mejor, antes de seguir con este artículo, descarguen y miren el siguiente archivo: Enlace.

Como ven, las celdas A1 y A2 están combinadas y en dicha combinación se observa la frase “Hola, yo soy visible”. A pesar de ello, en las celdas B1 y B2 verán dos frases distintas, en la primera la misma de las celdas combinadas y en la segunda “Hola, yo estoy oculto”, a pesar de que cada una de las segundas está vinculada a una de las primeras.

¿Vieron que en B2 hay un vínculo a A2 y que a pesar de que A2 está combinada con A1 tiene un valor propio?  Si aún tienen dudas, miren bien la celda combinada, no hay nada más que la primera frase.

Ah, si aún tienen dudas no olviden que al combinar celdas solo se mantiene el valor de la primera (superior y/o superior izquierda del grupo de celdas que se combina). Se supone que descargaron el archivo y están viéndolo, pero si aun así persisten las dudas, como ven no tiene macros y no hay más celdas con valores que las vistas hasta el momento… busquen si desean.

¿Ahora sí convencidos/as? Pues veamos cómo lo logré hacer. Primero en A1 (o en donde deseen) escriban algo, lo que sea.

Ahora inserten un TextBox (ActiveX) en la hoja (en cualquier lugar).

Luego en la propiedad “LinkedCell” del TextBox escriban “A2” (obviamente sin las comillas).


Ahora combinen A1 y A2. Como ven, la frase ingresada es el único valor en la celda(s).

Ahora, escriban lo que quieran en el TextBox (evidentemente previa salida del “Modo diseño”). Verán que el texto ingresado no se refleja en la celda combinada.

Ahora eliminen el Textbox, pero ¡sin borrar el texto que contiene antes! Solo elimínenlo tal cual lo habían dejado (no olviden facilitarse la vida eliminando el TextBox en “Modo diseño”). Ahora en la celda que deseen coloquen un vínculo a A1 (=A1).

El resultado será este

Ahora agreguen un vínculo a la celda A2 y miren el resultado:

Como ven, a pesar de haber eliminado el TextBox y de estar combinadas las celdas, en A2 se mantiene el valor ingresado en el TextBox dado que estaban vinculados, es más, al descombinar las celdas veremos esto:

Y listo, misterio resuelto, aunque más que misterio, una curiosidad más del gran Excel. Hasta la próxima.

Abraham Valencia
Lima, Perú