Abrir un archivo de Excel en OneDrive con VBA (misma carpeta): guía completa y código

¿Necesitas que una macro abra otro libro de Excel ubicado en la misma carpeta sincronizada con OneDrive y te aparece “no se encuentra el archivo”? Aquí tienes una guía completa (con código) para detectar si el archivo existe, comprobar si ya está abierto y abrirlo de forma fiable.

Índice

Resumen de la pregunta

Se requiere abrir desde VBA un libro compañero (companion file) que está en la misma carpeta que el libro que contiene las macros, carpeta que está sincronizada con OneDrive. El código actual falla con el mensaje “no se encuentra el archivo”.

Respuesta y solución

El fallo suele deberse a que Excel intenta abrir una URL (https://...) en lugar de una ruta local, a separadores de carpeta incorrectos o a que se usa el libro activo en vez del que contiene la macro. La solución consiste en:

  1. Trabajar con la ruta local sincronizada de OneDrive (p. ej. C:\Users<usuario>\OneDrive...), no con la URL.
  2. Construir la ruta con ThisWorkbook.Path y Application.PathSeparator para evitar confusiones con el libro activo y los separadores.
  3. Comprobar que el archivo existe y que no está ya abierto antes de abrirlo.

Causas probables del error

  • Uso de URL: Workbooks.Open no es fiable con direcciones https:// (según versión y configuración). Con OneDrive/SharePoint puede funcionar a veces, pero es menos predecible que usar la ruta local sincronizada.
  • Separador incorrecto: en Windows el separador es \. Si usas /, la ruta puede romperse. Solución genérica: Application.PathSeparator.
  • Libro equivocado: ActiveWorkbook.Path puede apuntar al libro equivocado si hay varias ventanas. Usa ThisWorkbook.Path, que es el que contiene la macro.
  • Archivos bajo demanda: si OneDrive está con “Archivos a petición” y el archivo no está descargado, Windows lo trae al vuelo; si la sincronización está detenida o hay errores, Dir$ puede no encontrarlo.
  • Nombre mal escrito o extensión incorrecta (.xlsm vs .xlsx), espacios/acentos, o ruta demasiado larga.

Solución práctica

  1. Asegura la sincronización local: en el Explorador de Windows, clic derecho sobre la carpeta de tu proyecto en OneDrive → Mantener siempre en este dispositivo.
  2. Usa la ruta local de la carpeta de la macro: ThisWorkbook.Path + Application.PathSeparator + archivo.
  3. Verifica existencia con Dir$ y comprueba si ya está abierto recorriendo Application.Workbooks.
  4. Abrir solo si hace falta: si no está abierto, Workbooks.Open.

Código recomendado

Este bloque resuelve el 95% de los casos en Windows con OneDrive sincronizado:

Option Explicit

Sub OpenCompanionIfNeeded()
Dim base As String, target As String```
' Carpeta del libro que contiene la macro
base = ThisWorkbook.Path
' Archivo a abrir en la misma carpeta
target = base & Application.PathSeparator & "book.xlsx"

' 1) Comprobar que el archivo existe localmente
If Dir$(target, vbNormal) = "" Then
    MsgBox "No encuentro el archivo:" & vbCrLf & target & vbCrLf & _
           "Asegúrate de que la carpeta de OneDrive esté sincronizada localmente.", vbExclamation
    Exit Sub
End If

' 2) Si no está abierto, abrirlo
If Not IsWorkbookOpen(target) Then
    Workbooks.Open target
End If
```
End Sub

Private Function IsWorkbookOpen(fullName As String) As Boolean
Dim wb As Workbook
For Each wb In Application.Workbooks
If StrComp(wb.FullName, fullName, vbTextCompare) = 0 Then
IsWorkbookOpen = True
Exit Function
End If
Next wb
End Function </code></pre>

<h3>Por qué este enfoque es estable</h3>
<ul>
  <li><strong>Evita URLs</strong> y se apoya en la ruta local que OneDrive mantiene sincronizada.</li>
  <li><strong>No depende del libro activo</strong> (usa <code>ThisWorkbook</code>).</li>
  <li><strong>Controla existencia</strong> y <strong>estado abierto</strong> antes de actuar.</li>
</ul>

<h2>Notas útiles</h2>
<ul>
  <li>Si <code>ThisWorkbook.Path</code> devolviera una URL (<code>https://...</code>), significa que abriste el archivo desde la web. Abre la copia sincronizada o deriva la ruta local desde la raíz de OneDrive:
    <pre><code class="language-vba">Dim od As String
od = Environ$("OneDrive")
If od = "" Then od = Environ$("OneDriveCommercial")
If od = "" Then od = Environ$("OneDriveConsumer")
' A partir de od, construye tu ruta relativa.</code></pre>
  </li>
  <li>Usa siempre <code>ThisWorkbook</code> en lugar de <code>ActiveWorkbook</code> para no mezclar rutas si hay otros libros abiertos.</li>
  <li>En Windows, el separador es <code>\</code>. Para no pensar en ello, usa <code>Application.PathSeparator</code>.</li>
</ul>

<h2>Versión robusta (maneja URLs, varias cuentas de OneDrive y nombres con espacios)</h2>
<p>Si con frecuencia abres el archivo de la macro desde la web y no desde la copia local, te conviene este enfoque “a prueba de URLs”. Intenta convertir una ruta <code>https://...</code> de OneDrive/SharePoint en su ruta local sincronizada, e incluye utilidades de decodificación:</p>
<pre><code class="language-vba">Option Explicit

Public Sub OpenCompanionSmart(Optional ByVal companionName As String = "book.xlsx", \_
Optional ByVal readOnly As Boolean = False)
Dim base As String, target As String, msg As String```
base = ThisWorkbook.Path
' Si el Path es URL, intenta traducirlo a ruta local OneDrive
If InStr(1, base, "://", vbTextCompare) &gt; 0 Then
    base = UrlBaseToLocalOneDrive(base)
End If

If Len(base) = 0 Then
    MsgBox "No se pudo determinar la carpeta local de OneDrive. " &amp; _
           "Abre el libro desde la copia sincronizada o configura 'Mantener siempre en este dispositivo'.", vbExclamation
    Exit Sub
End If

target = base &amp; Application.PathSeparator &amp; companionName

If Dir$(target, vbNormal) = "" Then
    msg = "No encuentro el archivo:" &amp; vbCrLf &amp; target &amp; vbCrLf &amp; _
          "Comprueba que:" &amp; vbCrLf &amp; _
          " • La carpeta está sincronizada y disponible sin conexión" &amp; vbCrLf &amp; _
          " • El nombre de archivo es correcto (mayúsculas/acentos/espacios)" &amp; vbCrLf &amp; _
          " • La ruta no supera el límite de Windows (&gt; 260 caracteres sin LongPaths)."
    MsgBox msg, vbExclamation
    Exit Sub
End If

If IsWorkbookOpen(target) Then
    GetWorkbookByFullName(target).Activate
Else
    Workbooks.Open Filename:=target, ReadOnly:=readOnly
End If
```
End Sub

'-- Helpers --------------------------------------------------------------------

Private Function UrlBaseToLocalOneDrive(ByVal urlBase As String) As String
' Convierte una URL de OneDrive/SharePoint (carpeta) en posible ruta local sincronizada.
' Heurística: reemplaza segmentos típicos y decodifica %20, etc.
Dim roots As Collection, r As Variant, rel As String
Dim p As Long```
' Intenta localizar "Documents", "Shared Documents" o "Documentos"
p = InStr(1, urlBase, "/Documents", vbTextCompare)
If p = 0 Then p = InStr(1, urlBase, "/Shared%20Documents", vbTextCompare)
If p = 0 Then p = InStr(1, urlBase, "/Documentos", vbTextCompare)

If p > 0 Then
    rel = Mid$(urlBase, p + 1) ' Quitamos la barra inicial
Else
    rel = "" ' No se encontró un ancla reconocible
End If

rel = URLDecode(rel)
rel = Replace(rel, "/", Application.PathSeparator)

Set roots = GetOneDriveCandidateRoots()
For Each r In roots
    If Len(Dir$(CStr(r), vbDirectory)) > 0 Then
        ' Probamos con y sin "Documents" / "Documentos"
        If Len(rel) > 0 Then
            If Dir$(CStr(r) & Application.PathSeparator & rel, vbDirectory) > "" Then
                UrlBaseToLocalOneDrive = CStr(r) & Application.PathSeparator & rel
                Exit Function
            End If
        End If
    End If
Next r

' Fallback: si no hubo coincidencia, devuelve vacío
UrlBaseToLocalOneDrive = ""
```
End Function

Private Function GetOneDriveCandidateRoots() As Collection
Dim c As New Collection, v As Variant, k As Long, s As String
' Variables de entorno comunes
On Error Resume Next
v = Array("OneDrive", "OneDriveCommercial", "OneDriveConsumer")
For Each s In v
If Environ\$(s) <> "" Then c.Add Environ\$(s)
Next s
' Intento por registro (Personal/BusinessN)
For k = 1 To 5
s = RegReadString("HKEY\CURRENT\USER\Software\Microsoft\OneDrive\Accounts\Business" & k & "\UserFolder")
If s <> "" Then c.Add s
Next k
s = RegReadString("HKEY\CURRENT\USER\Software\Microsoft\OneDrive\Accounts\Personal\UserFolder")
If s <> "" Then c.Add s
On Error GoTo 0
Set GetOneDriveCandidateRoots = c
End Function

Private Function RegReadString(ByVal regPath As String) As String
On Error Resume Next
RegReadString = CreateObject("WScript.Shell").RegRead(regPath)
On Error GoTo 0
End Function

Private Function URLDecode(ByVal s As String) As String
Dim i As Long, ch As String, hexPair As String, out As String
i = 1
Do While i <= Len(s)
ch = Mid\$(s, i, 1)
If ch = "%" And i + 2 <= Len(s) Then
hexPair = Mid\$(s, i + 1, 2)
If hexPair Like "\[0-9A-Fa-f]\[0-9A-Fa-f]" Then
out = out & Chr\$(CLng("&H" & hexPair))
i = i + 3
Else
out = out & ch
i = i + 1
End If
Else
If ch = "+" Then
out = out & " "
Else
out = out & ch
End If
i = i + 1
End If
Loop
URLDecode = out
End Function

Private Function GetWorkbookByFullName(ByVal fullName As String) As Workbook
Dim wb As Workbook
For Each wb In Application.Workbooks
If StrComp(wb.FullName, fullName, vbTextCompare) = 0 Then
Set GetWorkbookByFullName = wb
Exit Function
End If
Next wb
End Function

Private Function IsWorkbookOpen(ByVal fullName As String) As Boolean
IsWorkbookOpen = Not (GetWorkbookByFullName(fullName) Is Nothing)
End Function 

Tabla de diagnóstico rápido

SíntomaCausa probableCómo comprobarSolución
“No se encuentra el archivo”Se usa URL https:// o ruta mal construidaDebug.Print de la ruta finalUsar ThisWorkbook.Path + PathSeparator; evitar URL
Se abre otro libroUso de ActiveWorkbook.PathRevisar ActiveWorkbook.NameCambiar a ThisWorkbook.Path
Rutas con /Separador de carpeta incorrectoInspeccionar la cadena construidaUsar Application.PathSeparator
Archivo visible en la web, no en localCarpeta no sincronizada o sin “siempre disponible”Icono de nube en Explorer“Mantener siempre en este dispositivo”
Nombre con espacios/acentosEncode/Decode de URL¿La ruta final tiene “%20”?URLDecode antes de construir la ruta

Buenas prácticas para trabajar con OneDrive + Excel desde VBA

  • Define nombres en constantes o parámetros (ej. companionName) para no “quemar” book.xlsx en el código.
  • Evita Select/Activate: accede al objeto directamente. En el ejemplo solo activamos si ya estaba abierto.
  • Controla lectura: si quieres abrir en solo lectura usa ReadOnly:=True.
  • Errores claros: muestra rutas completas en el mensaje (ya lo hace el código) para que el usuario sepa qué buscar.
  • LongPaths: si tu organización no habilita rutas largas, mantén rutas < 260 caracteres o coordina con TI.

Variantes útiles

Abrir en solo lectura

If Not IsWorkbookOpen(target) Then
    Workbooks.Open Filename:=target, ReadOnly:=True
End If

Si el archivo está en una subcarpeta de la macro

Dim target As String
target = ThisWorkbook.Path &amp; Application.PathSeparator &amp; "Data" &amp; _
         Application.PathSeparator &amp; "book.xlsx"

Buscar por nombre (cuando no sabes la subcarpeta exacta)

Function FindFileRecursive(ByVal root As String, ByVal fileName As String) As String
    Dim subF As String, f As String
    f = Dir$(root &amp; Application.PathSeparator &amp; fileName, vbNormal)
    If f &lt;&gt; "" Then
        FindFileRecursive = root &amp; Application.PathSeparator &amp; f
        Exit Function
    End If
    subF = Dir$(root &amp; Application.PathSeparator &amp; "*", vbDirectory)
    Do While subF &lt;&gt; ""
        If subF &lt;&gt; "." And subF &lt;&gt; ".." Then
            If (GetAttr(root &amp; Application.PathSeparator &amp; subF) And vbDirectory) = vbDirectory Then
                FindFileRecursive = FindFileRecursive(root &amp; Application.PathSeparator &amp; subF, fileName)
                If FindFileRecursive &lt;&gt; "" Then Exit Function
            End If
        End If
        subF = Dir$
    Loop
End Function

Mensajes de error típicos y cómo interpretarlos

  • Error en tiempo de ejecución 1004: Excel no puede abrir el archivo; casi siempre es una ruta inválida o un intento de abrir vía URL sin autenticación adecuada.
  • Error 53 “File not found”: Dir$ no lo encuentra; revisa sincronización, orthografía del nombre y ruta.
  • Archivo bloqueado: si alguien lo tiene abierto con edición, Excel puede abrirlo en lectura. Usa ReadOnly:=True si esperas coautoría.

Checklist de verificación (rápido)

  • ¿La carpeta aparece bajo OneDrive en el Explorador y con marca de “Siempre disponible”?
  • ¿ThisWorkbook.Path devuelve ruta local (no URL)?
  • ¿La ruta final que muestra el mensaje existe si la pegas en la barra de direcciones del Explorador?
  • ¿El nombre y extensión coinciden exactamente (incluyendo mayúsculas/acentos)?
  • ¿No hay rutas > 260 caracteres o caracteres prohibidos (: * ? " < > |)?

Preguntas frecuentes

¿Puedo usar Workbooks.Open "https://..." directamente?
A veces funciona (según versión, autenticación y directivas), pero no es fiable en todos los equipos. Para macro robusta, apunta a la ruta local sincronizada.

¿Y si trabajo en Mac?
En Mac el separador es / y la ruta de OneDrive cambia (/Users/<usuario>/Library/CloudStorage/OneDrive-...). El uso de Application.PathSeparator sigue evitando errores; adapta las funciones de búsqueda de raíz.

¿Cómo cierro el archivo luego?
Guárdalo según corresponda y cierra: Workbooks("book.xlsx").Close SaveChanges:=True.

Conclusión

Para abrir archivos ubicados en la misma carpeta de un proyecto Excel sincronizado con OneDrive, la clave es trabajar siempre con la ruta local, construir las rutas con ThisWorkbook.Path + Application.PathSeparator, y comprobar existencia y estado antes de abrir. Con el código ofrecido tendrás una macro sólida y portable entre equipos.

Índice