🚀The world's best VBA AI has evolved. ExcelMaster is now an autonomous Agent.Read more →
Back to Blog

VBA Environ en Excel — lee rutas de Windows sin codificar a fuego una carpeta de usuario

|

VBA Environ en Excel — lee rutas de Windows sin codificar a fuego una carpeta de usuario

TL;DREnviron("USERPROFILE"), Environ("TEMP") y Environ("USERNAME") leen las variables que Windows da a cada programa, así que nunca codificas a fuego C:\Users\John\... — una ruta que se rompe en cualquier otra máquina. La pega es silenciosa: un nombre que falta o está mal escrito devuelve una cadena vacía, no un error, así que Environ("TMEP") & "\out.txt" se convierte en "\out.txt" y acaba en la raíz del disco. Trata cada resultado de Environ como posiblemente vacío.

Sub EnvironDemo()
    Debug.Print Environ("USERPROFILE")   ' C:\Users\Ann
    Debug.Print Environ("TEMP")          ' C:\Users\Ann\AppData\Local\Temp
    Debug.Print Environ("USERNAME")      ' Ann
    Debug.Print Environ("TMEP")          ' "" - mal escrito, sin error, solo vacio
End Sub

A cada programa de Windows se le entrega una pequeña tabla de cadenas NAME=VALUE — el bloque de entorno — que registra dónde vive el perfil del usuario, adónde van los archivos temporales, quién ha iniciado sesión, y más. Environ es la ventana de VBA a esa tabla. Es la forma correcta y portable de encontrar carpetas específicas de la máquina, y tiene exactamente una costumbre que debes respetar: cuando pides un nombre que no tiene, responde con vacío en lugar de quejarse.

Lo que aprenderás

  • El modelo mental — Environ lee la tabla viva NAME=VALUE de Windows para este programa
  • El objetivo de fondo: rutas portables en lugar de un C:\Users\<nombre>\... codificado a fuego
  • Por qué una variable que falta o está mal escrita devuelve "" — el bug silencioso — y cómo protegerte
  • Las dos formas de llamada: Environ("NAME") por nombre frente a Environ(n) por índice numérico
  • Por qué el bloque es una instantánea tomada cuando Excel arrancó, y qué significa aquí que esté obsoleta
  • Lo que Environ no puede hacer — escribir variables, o leer una cambiada tras el arranque

El modelo mental: Environ lee la tabla nombre=valor de Windows

Cuando Windows inicia un programa, copia un conjunto de pares NAME=VALUE en la memoria de ese programa — el entorno del proceso. Contiene entradas como USERPROFILE=C:\Users\Ann, TEMP=C:\Users\Ann\AppData\Local\Temp, COMPUTERNAME=DESK-01 y docenas más. Environ simplemente busca un nombre en esa tabla y devuelve su valor como texto:

Dim tempDir As String
tempDir = Environ("TEMP")     ' pide a la tabla el valor guardado bajo "TEMP"

Ese es el modelo completo. Environ es una lectura de una tabla de búsqueda que Windows rellenó antes de que Excel abriera. No es una consulta viva de la configuración de Windows, ni el registro, ni el directorio de trabajo actual — esas son cosas distintas. En cuanto lo ves como «busca un nombre en una tabla», las reglas de abajo se deducen solas.

Reemplazar las rutas de usuario codificadas a fuego — el objetivo de fondo

La razón para usar Environ en absoluto: deja de escribir rutas que solo funcionan en tu máquina. Esta línea es una macro clásica que se rompe en cuanto la ejecuta otra persona:

Open "C:\Users\John\AppData\Roaming\MyApp\log.txt" For Append As #1   ' solo funciona para John

No hay ningún usuario llamado John en el PC de nadie más. Reconstruye la ruta desde el entorno y funciona en todas partes:

Dim p As String
p = Environ("APPDATA") & "\MyApp\log.txt"      ' C:\Users\<quien sea>\AppData\Roaming\MyApp\log.txt
Open p For Append As #1

Las variables a las que echarás mano más a menudo: USERPROFILE (la carpeta personal del usuario), APPDATA y LOCALAPPDATA (datos de aplicación por usuario), TEMP (archivos temporales), USERNAME (quién ha iniciado sesión), COMPUTERNAME y PUBLIC. Pasa el resultado a Open, Dir o a un comando Shell y tu macro viaja a cualquier máquina sin ediciones.

Una variable que falta devuelve vacío, no un error

Aquí está la trampa que produce los fallos más confusos, y es consecuencia directa de que Environ sea una búsqueda en tabla: pide un nombre que no está, y obtienes una cadena vacía — sin error, sin aviso. Basta una errata de un solo carácter:

Dim p As String
p = Environ("TMEP") & "\out.txt"   ' TMEP no existe -> "" & "\out.txt" = "\out.txt"
Open p For Output As #1            ' crea C:\out.txt en la raiz del disco - no lo que querias

Nada se queja en la línea de Environ, porque «no encontrado» es una respuesta legítima para él. El daño aparece más tarde y en otro sitio — un archivo en la raíz del disco, una ruta que no abre, una carpeta creada en el lugar equivocado — lejos de la errata que lo causó. Protege las que importan:

Dim tempDir As String
tempDir = Environ("TEMP")
If tempDir = "" Then
    MsgBox "TEMP is not set - cannot continue.": Exit Sub
End If

La regla para llevarse a casa: un resultado vacío de Environ es normal, no excepcional — compruébalo siempre que un valor ausente pueda mandar un archivo al lugar equivocado. Este es el eco, en el bloque de entorno, del mismo fallo silencioso que hace peligrosas a tantas llamadas fuera de Excel: la respuesta a un error es un vacío callado, no una parada a voces.

Dos formas de llamada: por nombre y por índice

Environ tiene dos formas, y devuelven cosas distintas. Pasa una cadena y obtienes el valor de esa variable. Pasa un número y obtienes el par NAME=VALUE crudo completo en esa posición, lo que te permite enumerar el bloque entero:

Debug.Print Environ("PATH")     ' por nombre -> solo el valor: C:\Windows;C:\Windows\System32;...

Dim i As Integer, entry As String
i = 1
Do
    entry = Environ(i)          ' por indice -> el par crudo: "USERPROFILE=C:\Users\Ann"
    If entry = "" Then Exit Do  ' la cadena vacia marca el final de la lista
    Debug.Print entry
    i = i + 1
Loop

La forma por índice es cómo descubres qué variables existen en una máquina — útil para diagnósticos. Fíjate en la misma señal de cadena vacía haciendo doble función: para un nombre significa «no encontrado», y para un índice significa «pasado el final de la lista». Tanto los bucles como las búsquedas se apoyan en esa única convención.

La trampa de la instantánea, y lo que Environ no puede hacer

Dos límites pillan a quien espera que Environ sea una vista viva de Windows.

Es una instantánea del arranque. Excel copió el bloque de entorno cuando se lanzó. Si cambias una variable después — mediante Propiedades del sistema, un comando setx u otra herramienta — Environ en esa misma sesión de Excel no verá el nuevo valor. Refleja el mundo tal como estaba cuando Excel abrió; lo que lo refresca es un reinicio.

Solo lee; no puede escribir. No existe Environ("X") = "Y". Para fijar una variable, o para leer una que se cambió tras el arranque, necesitas la colección Environment del objeto WScript.Shell vía CreateObject:

Dim sh As Object
Set sh = CreateObject("WScript.Shell")
Debug.Print sh.Environment("Process")("TEMP")   ' el valor vivo del proceso
' sh.Environment("User")("MYVAR") = "hello"      ' esta forma SI puede escribir una variable de usuario

Environ tampoco puede decirte de qué ámbito vino un valor — usuario, sistema o proceso. Windows los fusiona en el único bloque que ves, y Environ informa solo del resultado fusionado. Para las rutas portables de cada día eso es exactamente suficiente; echa mano de WScript.Shell.Environment solo cuando debas escribir una variable o leer una recién cambiada.

El veredicto honesto: la herramienta de rutas portables, tratada como posiblemente vacía

Environ se gana su sitio por un trabajo y lo hace bien: convertir carpetas específicas de la máquina en rutas que viajan. Los errores se remontan todos a olvidar que una búsqueda puede fallar en silencio. Cuatro reglas lo cubren:

  • Úsalo para rutas portablesEnviron("APPDATA") & "\MyApp\...", nunca un C:\Users\<nombre>\... codificado a fuego.
  • Trata cada resultado como posiblemente vacío → un nombre que falta o está mal escrito devuelve "", no un error. Protege los valores cuya ausencia mandaría un archivo a un sitio equivocado.
  • Conoce las dos formasEnviron("NAME") devuelve el valor; Environ(n) devuelve el par NAME=VALUE crudo y te deja enumerar el bloque.
  • Es una instantánea del arranque, y de solo lectura → no verá una variable cambiada después de que Excel se lanzara, y no puede fijar ninguna. Para eso, usa WScript.Shell.Environment.

Acierta con esto y desaparece toda una familia de bugs de rutas del tipo «funciona en mi PC, se rompe en el suyo» — dejas de nombrar a un usuario concreto y empiezas a preguntarle a la máquina dónde están de verdad sus carpetas.

Cómo ayuda ExcelMaster

Los bugs de Environ que malgastan tiempo de verdad son los de rutas silenciosas: una macro codificada a fuego a C:\Users\John que falla para todos los demás, un nombre de variable con una errata que deja caer un archivo en la raíz del disco sin error, una ruta construida desde TEMP que dio por hecho que la variable estaba definida. Cada uno nace de no usar el entorno o de confiar en él sin comprobar.

ExcelMaster escribe la lógica de rutas portables correctamente. Describe el destino — «guarda un log en la carpeta AppData del usuario» o «escribe archivos temporales en su directorio Temp» — y construye la ruta a partir de la variable Environ correcta, valida que el valor volvió no vacío, y solo entonces abre o crea el archivo. Tú describes qué carpeta, no qué usuario, y él produce código que se ejecuta sin cambios en cualquier máquina.

Preguntas frecuentes

¿Cómo obtengo el nombre de usuario actual de Windows en VBA?

Usa Environ("USERNAME") — devuelve el nombre de inicio de sesión del usuario actual, por ejemplo Ann. Esta es la forma ligera de identificar quién ejecuta la macro sin una llamada a la API de Windows. Si necesitas el nombre completo para mostrar o el dominio en lugar del nombre de inicio de sesión, eso requiere una API como GetUserNameEx, pero para sellar un log o construir una ruta por usuario, Environ("USERNAME") es la respuesta estándar.

¿Cómo obtengo la ruta a la carpeta Temp o AppData del usuario en VBA?

Environ("TEMP") devuelve la carpeta temporal por usuario (normalmente C:\Users\<nombre>\AppData\Local\Temp), y Environ("APPDATA") devuelve la carpeta itinerante de datos de aplicación. Ambas son específicas del usuario, así que construir rutas a partir de ellas evita codificar a fuego C:\Users\<nombre>. Comprueba siempre que el resultado no está vacío antes de usarlo: t = Environ("TEMP") : If t = "" Then Exit Sub, ya que una variable que falta devuelve una cadena vacía en lugar de lanzar un error.

¿Por qué Environ devuelve una cadena vacía en VBA?

Porque el nombre de variable que pediste no está presente en el entorno del proceso — normalmente una errata (TMEP en vez de TEMP), una variable que solo existe en otro ámbito, o una creada después de que Excel arrancara. Environ trata «no encontrado» como una respuesta normal y devuelve "" sin error. Añade una protección: If Environ("NAME") = "" Then .... Si la variable se definió tras el arranque de Excel, reinicia Excel o léela en vivo con CreateObject("WScript.Shell").Environment("Process")("NAME").

¿Puede VBA Environ fijar o cambiar una variable de entorno?

No. Environ es de solo lectura — no hay forma de asignación. Para crear o cambiar una variable, usa el objeto WScript.Shell: CreateObject("WScript.Shell").Environment("User")("MYVAR") = "value" fija una variable de usuario persistente. Ten en cuenta que cualquier cambio que hagas no aparecerá en Environ en la sesión actual de Excel, porque Environ lee una instantánea tomada cuando Excel se lanzó; hace falta un reinicio para que vea los nuevos valores.

¿Cómo listo todas las variables de entorno en VBA?

Llama a Environ con un número en lugar de un nombre — Environ(1), Environ(2), etc. — y cada uno devuelve el par NAME=VALUE crudo en esa posición. Recorre en bucle hasta que devuelva una cadena vacía, que marca el final de la lista: i = 1 : Do : e = Environ(i) : If e = "" Then Exit Do : Debug.Print e : i = i + 1 : Loop. Esto enumera el bloque de entorno completo, lo que resulta práctico para diagnósticos cuando una ruta no se resuelve como esperabas.

Probado en

Probado en: Excel 365 (Windows 11), VBA 7.1 — última verificación el 30/08/2026.

Guías relacionadas: VBA Shell · VBA CreateObject y GetObject · VBA FreeFile y Open · VBA Dir · VBA CurDir y ChDir