2013-05-03

Unir ficheros de texto con VBA Excel

En ocasiones necesitamos unir varios ficheros de texto (.txt o .csv). Por ejemplo, para consolidar dos ficheros descargados en distintos momentos.

Modificamos un ejemplo publicado por Jim Rech en google groups. Hemos transformado la referencias absolutas en relativas. Tan sólo hay que copiar el código en un módulo de Excel y guardar el fichero si es nuevo (o devolvería error pues la propiedad Application.ThisWorkbook.Path está vacía hasta que no se guarda el fichero).

Copiamos los dos ficheros (.txt o .csv) que deseamos unir, Fichero1 y Fichero2, en la misma ruta del Excel con el código. En esa ruta se creará el Fichero3 de salida, con la unión del 1 y el 2, y se sobreescribirá si ya existe.
Sub UnirFicherosTexto()
  
    Dim r As String
    r = Application.ThisWorkbook.Path
    Dim SrcFiles, CurrSrc As String
    Dim DestFile As String, Counter As Integer
    Dim TextLine As String
    SrcFiles = Array(r & "\Fichero1.txt", r & "\Fichero2.txt")
    Open r & "\Fichero3.txt" For Output As #1
    For Counter = 0 To UBound(SrcFiles)
        Open SrcFiles(Counter) For Input As #2
        Do While Not EOF(2)
            Line Input #2, TextLine
            Print #1, TextLine
        Loop
        Close #2
    Next
    Close #1
    
End Sub
Para unir más de dos ficheros, los añadimos en el Array.
SrcFiles = Array(r & "\Fichero1.txt", r & "\Fichero2.txt", r & "\Fichero3.txt")

Entradas relacionadas

2013-04-25

Mensaje emergente al abrir un fichero Ms Excel

La función MsgBox en VBA muestra un cuadro de diálogo al usuario y, si lo necesitamos, captura su respuesta (por ejemplo: Sí, No o Cancelar). Uno de los múltiples usos es desplegar este mensaje de texto al abrir un fichero de Excel.

Para ello necesitamos abrir el editor de Visual Basic Alt+F11 e insertar el código en ThisWorkBook. En el menú desplegable Objeto, selecciona Workbook. Por defecto Excel crea:
Private Sub Workbook_Open() ....[Inserta el código aquí] ... End Sub




La sintaxis en español es MsgBox(texto[, botones] [, título] [, archivoayuda, contexto])

Ejemplo 1-Mensaje simple

Private Sub Workbook_Open()
  MsgBox "1-El libro está en cálculo manual" & vbCrLf & _
  "2-Haz clic en F9 para recalcular fórmulas" & vbCrLf & _
  "", vbInformation, "INFORMACION"
End Sub
Escribimos el texto del mensaje, Chr(13) o vbCrLf, para insertar saltos de línea. VbInformation muestra el icono de mensaje de información y en el argumento título "INFORMACION".


 Ejemplo 2-Captura respuesta del usuario

Private Sub Workbook_Open()
    Dim Respuesta As VbMsgBoxResult
    Respuesta = MsgBox("¿Conoces la sintaxis de MsgBox?", _
    vbQuestion + vbYesNo, "Nube de datos")
    If respuesta = vbYes Then 'Haz X
        MsgBox "Perfecto. ¿Usas la función frecuentemente?", vbInformation
        Else                  'Haz Y
        MsgBox "Quizá deberías ir al enlace propuesto" & Chr(13) & _
        "o leer la ayuda de Excel", vbExclamation
    End If
End Sub
Capturamos la respuesta del usuario con la variable Respuesta. Con vbQuestion + vbYesNo mostramos el icono de pregunta de advertencia y los botones Sí y No, en el argumento título "Nube de datos". La respuesta la manejamos con un If. vbInformation para el icono del sí y vbExclamation para el del no
.

Otra alternativa a If, quizá más clara y eficiente, es usar Select Case

Private Sub Workbook_Open()
    Dim Respuesta As VbMsgBoxResult
    Respuesta = MsgBox("¿Conoces la sintaxis de MsgBox?", _
    vbQuestion + vbYesNoCancel, "Nube de datos")
    Select Case Respuesta
     Case vbYes 'Haz X
         MsgBox "Perfecto. ¿Usas la función frecuentemente?", vbInformation
     Case vbNo  'Haz Y
         MsgBox "Quizá deberías ir al enlace propuesto" & Chr(13) & _
        "o leer la ayuda de Excel", vbExclamation
     Case vbCancel
         Exit Sub 'Haz Z
    End Select
End Sub

Cambiamos el argumento [botones] para mostrar , No y Cancelar.

Información detallada de la función MsgBox en: Ayuda de Excel/Referencia del lenguaje de Visual Basic/Funciones/M-P/MsgBox (Función)

2013-04-23

Importar una especificación de importación/exportación en Ms Access: dos métodos

MÉTODO 1

1. Abrir la base de datos Access que necesita las especificaciones.

2. En la ficha Datos externos,en el grupo Importar, haz clic en Access.

3. Seleccionar la base de datos Access que contiene las especificaciones y hacer clic en aceptar


4. En el menú Importar Objetos, hacer clic en Opciones >>























5. Desactivar la casilla de verificación de las Relaciones, activar la casilla de verificación de Especificaciones de importación/exportación y hacer clic en Aceptar.














 


MÉTODO 2

Otro método menos ortodoxo, que no he encontrado documentado:

1. Abrir la base de datos Access que contiene las especificaciones.

2. En la ficha Datos externos,en el grupo Importar, hacer clic en Archivo de texto.

3. Seleccionar la base de datos Access que contiene las especificaciones y hacer clic en aceptar


 
4. En el Asistente para la importación de texto, clic sobre Avanzado, y en el menú emergente, clic sobre Especificaciones para abrir la especificación que queremos copiar. En Información del campo, clic en la esquina superior izquierda de la tabla y Ctrl + C, para copiar la tabla con las especificaciones.


5. Abrir la base de datos Access que necesita las especificaciones y repetir pasos 1, 2, 3. En el paso 4, en lugar de copiar la tabla con las especificaciones, pegarla con Ctrl + V. Confirmar que desea pegar los registros.

























Aprende a  importar o vincular a los datos de un archivo de texto

2013-04-22

Etiquetar en Ms Excel registros que contienen un determinado carácter o cadena

En una entrada anterior, vimos cómo crear en Ms Access un campo calculado para etiquetar los registros que incluyen un determinado carácter o cadena. Si tenemos el mismo problema en Ms Excel, creamos una columna que nos  identifique si el campo Cargo del contacto es Gerente, Representante o, si no es ninguno de los dos, Otros.

Dos opciones serían, copiar en la celda L2:
=SI(ESNUMERO(ENCONTRAR("Ger";D2));"Gerente";
SI(ESNUMERO(ENCONTRAR("Rep";D2));"Representante";"Otros"))
=SI(ESNUMERO(HALLAR("Ger";D2));"Gerente";
SI(ESNUMERO(HALLAR("Rep";D2));"Representante";"Otros"))

La función ENCONTRAR o HALLAR devuelve la posición de la cadena indicada (Ger o Rep) en la celda especificada. Con SI se evalua si lo anterior es verdadero, y lo etiquetaría como "Gerente" o pasaría al siguiente SI anidado. Usamos la función ESNUMERO porque la función ENCONTRAR o HALLAR, si no encuentra la cadena indicada, devuelve el error #¡VALOR!.

Copiamos cualquiera de las dos fórmulas anteriores y arrastramos hacia abajo. El resultado final sería:


En otra ocasión examinaremos las diferencias entre ENCONTRAR y HALLAR.

Entradas relacionadas: 
  1. Etiquetar en Ms Access registros que contienen un determinado carácter o cadena

2013-04-19

Menú emergente con las 15 primeras hojas de un libro de Excel

Normalmente, para desplazarnos entre las hojas de un libro de Excel, hacemos clic sobre la hoja deseada, utilizamos los comandos Ctrl + Av Pág o Ctrl + Re Pág, o los botones de desplazamiento:

Botones de desplazamiento
Una alternativa, cuando tenemos muchas hojas, es hacer clic con el botón secundario del ratón sobre los botones de desplazamiento. Aparecerá un menú emergente con las 15 primeras hojas:

Si hubiera más de 15 hojas habría que seleccionar Más hojas... para acceder a la lista completa:


2013-04-12

Etiquetar en Ms Access registros que contienen un determinado carácter o cadena

Por ejemplo, a la tabla de Proveedores de la base de datos Neptuno (Bases de datos de muestra incluida en Access), queremos añadir un nuevo campo que identifique si el campo Cargo del contacto es Gerente, Representante o, si no es ninguno de los dos, Otros.








1.Creamos una consulta basada en la tabla Proveedores
2.Agregamos un campo calculado, Tipo de cargo.

 En el generador de expresiones escribimos:


Usamos SiInm anidados. La función EnCad, busca sucesivamente en el campo [Proveedores]![CargoContacto] la cadena que le indicamos (Gerente y Representante), y la etiqueta con el nombre correspondiente, y si no encuentra ninguna de las dos, escribe Otros.

3.El resultado de la consulta, con el campo Tipo de cargo que etiqueta los registros, sería:


Si queremos etiquetar también las abreviaturas Ger. como Gerente y Repr. como Representantes, modificaríamos la expresión anterior para que no aparezcan como Otros:
Tipo de cargo: SiInm(EnCad([Proveedores]![CargoContacto];"Ger");"Gerente";
SiInm(EnCad([Proveedores]![CargoContacto];"Repr");"Representante";"Otros"))

Entradas relacionadas:
  1. Etiquetar en Ms Excel registros que contienen un determinado carácter o cadena

2013-03-22

Generar números aleatorios entre dos valores con decimales

Title

Excel para Microsoft 365

Utilizamos la función MATRIZALEAT con la que podemos elegir, entre un mínimo y un máximo, si queremos que nos devuelva números enteros o valores decimales. También podemos elegir el número de filas y columnas a rellenar. Si deseamos copiar o arrastrar la fórmula dejamos dichos argumentos vacíos:

=MATRIZALEAT(,,0,10)

Versiones anteriores

En Excel hay dos funciones para generar número aleatorios:

  1. ALEATORIO, que genera un número aleatorio entre 0 y 1, con hasta 15 decimales. 
  2. ALEATORIO.ENTRE, que genera un número aleatorio entre dos límites especificados.
Pero si necesitamos un número aleatorio entre dos valores con decimales, no podemos usar directamente ALEATORIO.ENTRE pues genera solamente números enteros. Para circunvenir esta limitación, siendo a el límite inferior y b el superior, podemos usar:

=a+ALEATORIO()*(b-a)
Otra opción es multiplicar los dos límites por un 1 seguido de tantos ceros como decimales necesitemos, y luego dividir el resultado por dicho número. Por ejemplo, si necesitamos dos decimales, por cien:

=ALEATORIO.ENTRE(a*100;b*100)/100 'O si no queremos repetir 3 veces 100
=ALEATORIO.ENTRE(a;b)+ALEATORIO.ENTRE(a;b)/100
Con ALEATORIO, encontramos la limitación opuesta, si deseamos generar números enteros. REDONDEAR permite especificar el número de decimales. Por ejemplo, si queremos obtener ceros o unos:

=REDONDEAR(ALEATORIO();0)'O simplemente
=ALEATORIO.ENTRE(0;1)
Porque si usamos:

=ENTERO(ALEATORIO())
obtendremos siempre ceros pues ENTERO redondea al entero inferior más próximo.

Entradas relacionadas

2013-03-15

Mensaje de error "No se pudo eliminar nada en las tablas especificadas"

En Access la siguiente consulta de eliminación trata de eliminar aquellos registros de la tblClientes cuyo País coincida con aquellos seleccionados en la consulta qryPaises.
























Si pasamos de Vista diseño a Ver, podemos ver los registros que eliminaría si la ejecutáramos.


Sin embargo, al ejecutar la consulta, nos aparecerá el siguiente error:



Si presionamos en ayuda, nos propondrá dos posibles causas: O bien no tenemos permisos para modificar la tabla, o la base de datos se abrió con acceso de sólo lectura. Ninguna de ellas es cierta en este caso.

Para solucionarlo tendremos que abrir la hoja de propiedades (F4 o Alt+ ENTRAR) y cambiar la propiedad de Registros únicos al valor .

2013-03-08

Contar elementos únicos en una lista (2/2)

Cuando el rango contenga alguna celda en blanco:












La fórmula utilizada en la entrada anterior nos daría un error, pues crearía una fracción 1/0 que genera el error #¡DIV/0! Para evitarlo utilizamos:

1. La sugerida por Microsoft válida para Excel 2003 y Excel 2007:
{=SUMA(SI(LARGO(B3:E7);1/CONTAR.SI(B3:E7;B3:E7)))}
2. O la más sencilla y directa, válida desde Excel 2007 en adelante:
{=SUMA(SI.ERROR(1/CONTAR.SI(B3:E7;B3:E7);0))}

La primera fórmula crea una matriz de verdaderos (número de caracteres de la cadena de texto de cada celda, 13 en este caso en todas) y falsos (ceros). Cuando es falso no calcula el 1/CONTAR.SI evitando generar la fracción 1/0. En la segunda fórmula, cuando 1/CONTAR.SI genera un error, lo sustituye por un cero, y continua con el cálculo.











2013-03-01

Contar elementos únicos en una lista (1/2)

Un problema bien documentado, incluido en la ayuda de microsoft y diversos blogs, es el de contar el número de elementos únicos en una lista o rango.












En este caso, 12 valores únicos :
{=SUMA(1/CONTAR.SI(B3:E7;B3:E7))}
Con menos éxito explican el funcionamiento de la fórmula matricial (Ctrl+Mayús+Entrar). Genera tantas fracciones como celdas tiene el rango y suma su valor. Cada fracción es igual a 1/nº repeticiones. Si es único 1/1, si está repetido cuatro veces habrá cuatro veces 1/4 . Un valor único sumará uno, y otro repetido n veces también sumará 1: n * (1/n). Así, al sumar todas las fracciones tendremos el total de valores únicos: 12 en este caso.












Entradas relacionadas: Contar elementos únicos en una lista (2/2)
Nube de datos