TL;DR —
Environ("USERPROFILE"),Environ("TEMP")yEnviron("USERNAME")leen las variables que Windows da a cada programa, así que nunca codificas a fuegoC:\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í queEnviron("TMEP") & "\out.txt"se convierte en"\out.txt"y acaba en la raíz del disco. Trata cada resultado deEnvironcomo 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 —
Environlee la tabla vivaNAME=VALUEde 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 aEnviron(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
Environno 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 portables →
Environ("APPDATA") & "\MyApp\...", nunca unC:\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 formas →
Environ("NAME")devuelve el valor;Environ(n)devuelve el parNAME=VALUEcrudo 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
