VBA: abrir ficheiro do OneDrive no Excel sem erro “ficheiro não encontrado”

Abordagem prática para abrir automaticamente um ficheiro do Excel guardado no OneDrive usando VBA, evitando o erro “ficheiro não encontrado” quando o caminho de origem é um URL (https). Inclui código completo, alternativas e checklist de resolução.

Índice

Contexto e problema

Um cenário comum em ambientes Microsoft 365 é ter um livro com macros (VBA) e outro livro de dados na mesma pasta do OneDrive. O objetivo é simples: se Book.xlsx já estiver aberto, reutilizar a instância; caso contrário, abrir automaticamente. O obstáculo surge porque ThisWorkbook.Path (ou ActiveWorkbook.Path) pode devolver um endereço HTTPS do OneDrive/SharePoint, e Workbooks.Open não aceita URLs. Resultado: o Excel acusa “ficheiro não encontrado”.

A solução passa por traduzir o URL para o caminho local sincronizado (a pasta OneDrive no disco) — ou garantir desde logo que trabalha sempre com o caminho local.

O que acontece tecnicamente

  • OneDrive sincronizado: existe uma cópia local em C:\Users<utilizador>\OneDrive – <Organização>\ (conta corporativa) ou C:\Users<utilizador>\OneDrive\ (conta pessoal). É este caminho que o Workbooks.Open entende.
  • OneDrive na nuvem (sem download): o caminho é um linkhttps://.... O Excel no desktop não abre diretamente com .Open. Precisa de:
    • usar o caminho local sincronizado; ou
    • usar um esquema especial (ms-excel:ofe|u|) via FollowHyperlink (alternativa).

Resumo (TL;DR) — solução direta

Se já sabe em que subpasta do OneDrive está o ficheiro, use as variáveis de ambiente para chegar ao caminho local e abra o ficheiro daí:

Option Explicit

Sub AbrirLivroOneDrive\_TLDR()
Const NOME\_FICHEIRO As String = "Book.xlsx"
Dim od As String, filePath As String, wb As Workbook
```
' Tenta OneDrive empresarial, depois genérico e por fim o pessoal
od = Environ$("OneDriveCommercial")
If Len(od) = 0 Then od = Environ$("OneDrive")
If Len(od) = 0 Then od = Environ$("OneDriveConsumer")

filePath = JuntarCaminhos(od, "Subpasta", NOME_FICHEIRO) ' ajuste a Subpasta, se existir

' Se já estiver aberto, reutiliza; se não, abre
Set wb = ProcurarWorkbookAberto(NOME_FICHEIRO, filePath)
If wb Is Nothing Then
    If Len(Dir$(filePath, vbNormal)) &gt; 0 Then
        Set wb = Workbooks.Open(filePath)
    Else
        MsgBox "O ficheiro não está sincronizado localmente: " & filePath, vbExclamation
    End If
End If
```
End Sub

Private Function JuntarCaminhos(ParamArray parts() As Variant) As String
Dim i As Long, p As String, s As String
For i = LBound(parts) To UBound(parts)
s = CStr(parts(i))
If Len(s) > 0 Then
s = Replace\$(s, "/", "")
If p = "" Then
p = s
Else
If Right\$(p, 1) <> "" Then p = p & ""
If Left\$(s, 1) = "" Then s = Mid\$(s, 2)
p = p & s
End If
End If
Next
JuntarCaminhos = p
End Function

Private Function ProcurarWorkbookAberto(ByVal nome As String, ByVal fullPath As String) As Workbook
Dim wb As Workbook
For Each wb In Application.Workbooks
If LCase\$(wb.Name) = LCase\$(nome) Then
Set ProcurarWorkbookAberto = wb
Exit Function
End If
If LCase\$(wb.FullName) = LCase\$(fullPath) Then
Set ProcurarWorkbookAberto = wb
Exit Function
End If
Next wb
End Function 

Guia passo a passo

O quadro abaixo traz as etapas essenciais, com explicações e exemplos prontos para colar.

PassoExplicaçãoExemplo de código
Obter o caminho local sincronizado do OneDriveQuando o OneDrive está sincronizado, há uma cópia local (normalmente em C:\Users<utilizador>\OneDrive – <Organização>\). Use variáveis de ambiente: Environ("OneDrive"), Environ("OneDriveCommercial") ou Environ("OneDriveConsumer"), consoante o tipo de conta.Dim odPath As String odPath = Environ$("OneDriveCommercial") ' ou OneDrive / OneDriveConsumer If Len(odPath) = 0 Then odPath = Environ$("OneDrive") If Len(odPath) = 0 Then odPath = Environ$("OneDriveConsumer")
Construir o caminho completo do ficheiroJunte o caminho local ao subdiretório e ao nome do ficheiro. Evite barras mistas (/ e \).Dim filePath As String filePath = odPath & "\Subpasta\Book.xlsx"
Verificar se o livro já está abertoAntes de abrir, confirme se o ficheiro está na coleção Workbooks. Caso positivo, reutilize a instância; caso negativo, chame .Open.Dim wb As Workbook On Error Resume Next Set wb = Workbooks("Book.xlsx") On Error GoTo 0 If wb Is Nothing Then Set wb = Workbooks.Open(filePath) End If
Alternativa: converter URL em caminho localSe ThisWorkbook.Path devolver um URL do OneDrive/SharePoint, substitua-o pelo caminho local do OneDrive (via variáveis de ambiente ou registo do Windows). Para OneDrive pessoal, o URL https://d.docs.live.net/<CID>/... mapeia para a pasta local cuja CID consta no Registo.Ver módulo completo abaixo
Garantir que o ficheiro está sincronizadoWorkbooks.Open falha se o documento existir apenas na nuvem (ícone de nuvem). Ative “ficheiros sempre disponíveis” na pasta ou verifique com Dir(filePath, vbNormal) antes de abrir.If Len(Dir$(filePath, vbNormal)) = 0 Then MsgBox "O ficheiro ainda não está disponível offline.", vbExclamation Else Set wb = Workbooks.Open(filePath) End If
Boas práticas adicionaisUse Option Explicit. Normalize barras para \. Trate erros com On Error. Prefira comparar .FullName ao confirmar se um livro está aberto.Option Explicit ' ... ' Compare wb.FullName com o caminho esperado para evitar ambiguidade

Módulo completo (robusto) para abrir ficheiros do OneDrive

O código abaixo cobre cenários correntes (conta pessoal, empresarial, múltiplas contas) e tenta resolver um URL do OneDrive para o respetivo caminho local sincronizado. Inclui também detecção de livro já aberto e validação de disponibilidade offline.

' ===============================================
'  Abrir ficheiro do OneDrive (local) com VBA
'  Funciona em Windows + Excel desktop
' ===============================================
Option Explicit

' --------- API opcional (não obrigatória) ---------
' Pode usar este módulo sem API. Mantida aqui para evoluções.
#If False Then
#If VBA7 Then
    Private Declare PtrSafe Function GetFinalPathNameByHandle Lib "kernel32" Alias "GetFinalPathNameByHandleW" (ByVal hFile As LongPtr, ByVal lpszFilePath As LongPtr, ByVal cchFilePath As Long, ByVal dwFlags As Long) As Long
#Else
    Private Declare Function GetFinalPathNameByHandle Lib "kernel32" Alias "GetFinalPathNameByHandleW" (ByVal hFile As Long, ByVal lpszFilePath As Long, ByVal cchFilePath As Long, ByVal dwFlags As Long) As Long
#End If
#End If

' ====== Entrada principal ===================================================
Public Sub AbrirLivroOneDrive(Optional ByVal NomeFicheiro As String = "Book.xlsx", _
                              Optional ByVal Subpasta As String = "")
    Dim caminhoBase As String, alvo As String, wb As Workbook

    ' 1) Tenta caminho local a partir de variáveis OneDrive
    caminhoBase = GetOneDriveRoot()

    ' 2) Se não encontrou, tenta resolver a partir do ThisWorkbook.Path (que pode ser https)
    If Len(caminhoBase) = 0 Then
        caminhoBase = ResolverPastaLocalAPartirDoPathAtual()
    End If

    ' 3) Se ainda assim não encontrou, tenta resolver diretamente um URL conhecido
    If Len(caminhoBase) = 0 And Left$(ThisWorkbook.Path, 8) = "https://" Then
        alvo = ResolverCaminhoLocalDeUrl(CombineUrl(ThisWorkbook.Path, NomeFicheiro))
    End If

    ' 4) Constrói o caminho final
    If Len(alvo) = 0 Then
        caminhoBase = IIf(Len(caminhoBase) = 0, "", caminhoBase)
        alvo = JuntarCaminhos(caminhoBase, Subpasta, NomeFicheiro)
    End If

    ' 5) Se já estiver aberto, reutilizar
    Set wb = ProcurarWorkbookAberto(NomeFicheiro, alvo)
    If Not wb Is Nothing Then Exit Sub

    ' 6) Verifica disponibilidade local e abre
    If Len(Dir$(alvo, vbNormal)) = 0 Then
        MsgBox "Ficheiro não encontrado localmente (não sincronizado?):" & vbCrLf & alvo, vbExclamation
        Exit Sub
    End If

    On Error GoTo TratarErro
    Set wb = Workbooks.Open(alvo)
    Exit Sub

TratarErro:
    MsgBox "Não foi possível abrir o ficheiro:" & vbCrLf & alvo & vbCrLf & _
           "Detalhe: " & Err.Number & " - " & Err.Description, vbCritical
End Sub

' ====== Utilitários =========================================================

' Raiz local do(s) OneDrive(s) a partir de variáveis de ambiente
Private Function GetOneDriveRoot() As String
    Dim candidatos(1 To 3) As String, i As Long, c As String
    candidatos(1) = Environ$("OneDriveCommercial")
    candidatos(2) = Environ$("OneDrive")          ' pode ser empresarial ou pessoal
    candidatos(3) = Environ$("OneDriveConsumer")  ' pessoal

    For i = LBound(candidatos) To UBound(candidatos)
        c = candidatos(i)
        If Len(c) &gt; 0 Then
            If Dir$(c, vbDirectory) &lt;&gt; "" Then
                GetOneDriveRoot = c
                Exit Function
            End If
        End If
    Next
End Function

' Junta segmentos de caminho (normaliza "\" e remove duplicados)
Private Function JuntarCaminhos(ParamArray parts() As Variant) As String
    Dim i As Long, p As String, s As String
    For i = LBound(parts) To UBound(parts)
        s = CStr(parts(i))
        If Len(s) &gt; 0 Then
            s = Replace$(s, "/", "\")
            If p = "" Then
                p = s
            Else
                If Right$(p, 1) &lt;&gt; "\" Then p = p & "\"
                If Left$(s, 1) = "\" Then s = Mid$(s, 2)
                p = p & s
            End If
        End If
    Next
    JuntarCaminhos = p
End Function

' Junta partes de URL (para cenários https)
Private Function CombineUrl(ByVal base As String, ByVal tail As String) As String
    Dim b As String, t As String
    b = base: t = tail
    If Right$(b, 1) &lt;&gt; "/" Then b = b & "/"
    If Left$(t, 1) = "/" Then t = Mid$(t, 2)
    CombineUrl = b & t
End Function

' Procura workbook já aberto (por nome e por FullName)
Private Function ProcurarWorkbookAberto(ByVal nome As String, ByVal fullPath As String) As Workbook
    Dim wb As Workbook
    For Each wb In Application.Workbooks
        If LCase$(wb.Name) = LCase$(nome) Then
            Set ProcurarWorkbookAberto = wb
            Exit Function
        End If
        If Len(fullPath) &gt; 0 Then
            If LCase$(wb.FullName) = LCase$(fullPath) Then
                Set ProcurarWorkbookAberto = wb
                Exit Function
            End If
        End If
    Next wb
End Function

' Se ThisWorkbook.Path for https, tenta mapeá-lo para a pasta local sincronizada
Private Function ResolverPastaLocalAPartirDoPathAtual() As String
    Dim p As String, url As String, local As String
    p = ThisWorkbook.Path
    If Len(p) = 0 Then Exit Function

    If Left$(p, 8) = "https://" Then
        ' OneDrive pessoal (d.docs.live.net/&lt;CID&gt;/...)
        If InStr(1, p, "d.docs.live.net", vbTextCompare) &gt; 0 Then
            local = ResolverLocalPessoalComCID(p)
            If Len(local) &gt; 0 Then ResolverPastaLocalAPartirDoPathAtual = local: Exit Function
        End If

        ' OneDrive Empresarial / SharePoint: tentar a partir de Business#\UserFolder
        local = ResolverLocalBusinessDocumentos(p)
        If Len(local) &gt; 0 Then ResolverPastaLocalAPartirDoPathAtual = local: Exit Function
    Else
        ' Já é local
        ResolverPastaLocalAPartirDoPathAtual = p
    End If
End Function

' Converte um URL completo do OneDrive num caminho local, se conseguir
Private Function ResolverCaminhoLocalDeUrl(ByVal url As String) As String
    Dim local As String
    If InStr(1, url, "d.docs.live.net", vbTextCompare) &gt; 0 Then
        local = ResolverLocalPessoalComCID(url)
        If Len(local) &gt; 0 Then
            If Right$(local, 1) &lt;&gt; "\" Then local = local & "\"
            ResolverCaminhoLocalDeUrl = local
            Exit Function
        End If
    End If
    local = ResolverLocalBusinessDocumentos(url)
    If Len(local) &gt; 0 Then ResolverCaminhoLocalDeUrl = local
End Function

' ---------- OneDrive Pessoal: usa a CID do registo ----------
Private Function ResolverLocalPessoalComCID(ByVal url As String) As String
    On Error GoTo Fim
    Dim sh As Object, cid As String, base As String, parts() As String
    Set sh = CreateObject("WScript.Shell")

    cid = sh.RegRead("HKCU\SOFTWARE\Microsoft\OneDrive\Accounts\Personal\CID")
    base = sh.RegRead("HKCU\SOFTWARE\Microsoft\OneDrive\Accounts\Personal\UserFolder")

    If Len(cid) = 0 Or Len(base) = 0 Then GoTo Fim

    ' URL típico: https://d.docs.live.net/&lt;CID&gt;/Documents/...
    parts = Split(url, "/")
    If UBound(parts) &gt;= 3 Then
        If LCase$(parts(3)) = LCase$(cid) Then
            Dim rel As String, pos As Long
            pos = InStr(1, url, "/" & cid & "/", vbTextCompare)
            If pos &gt; 0 Then
                rel = Mid$(url, pos + Len(cid) + 2) ' depois de /&lt;cid&gt;/
                rel = Replace$(rel, "/", "\")

                ' Lidar com espaços codificados
                rel = Replace$(rel, "%20", " ")

                ResolverLocalPessoalComCID = JuntarCaminhos(base, rel)
            End If
        End If
    End If
Fim:
End Function

' ---------- OneDrive Empresarial/SharePoint ----------
' Tenta localizar a pasta local "UserFolder" e junta o segmento /Documents/... (ou variantes)
Private Function ResolverLocalBusinessDocumentos(ByVal url As String) As String
    Dim col As Collection, i As Long, userFolder As String
    Set col = OneDriveBusinessFolders()
    If col Is Nothing Then Exit Function
    If col.Count = 0 Then Exit Function

    Dim rel As String
    rel = ExtrairRelativoBiblioteca(url)
    If Len(rel) = 0 Then Exit Function

    For i = 1 To col.Count
        userFolder = col(i)
        If Dir$(userFolder, vbDirectory) &lt;&gt; "" Then
            ResolverLocalBusinessDocumentos = JuntarCaminhos(userFolder, rel)
            Exit Function
        End If
    Next i
End Function

' Lê Business1..Business9 + Business (sem sufixo)
Private Function OneDriveBusinessFolders() As Collection
    On Error Resume Next
    Dim sh As Object: Set sh = CreateObject("WScript.Shell")
    Dim col As New Collection, i As Long, p As String, val As String

    For i = 1 To 9
        p = "HKCU\SOFTWARE\Microsoft\OneDrive\Accounts\Business" & i & "\UserFolder"
        Err.Clear: val = sh.RegRead(p)
        If Err.Number = 0 Then If Len(val) &gt; 0 Then col.Add val
    Next i

    Err.Clear: val = sh.RegRead("HKCU\SOFTWARE\Microsoft\OneDrive\Accounts\Business\UserFolder")
    If Err.Number = 0 Then If Len(val) &gt; 0 Then col.Add val

    Set OneDriveBusinessFolders = col
End Function

' Extrai o segmento relativo após a biblioteca ("Documents", "Documentos", "Shared Documents")
Private Function ExtrairRelativoBiblioteca(ByVal url As String) As String
    Dim candidatos As Variant, k As Long, u As String, pos As Long, rel As String
    u = url
    u = Replace$(u, "%20", " ")

    candidatos = Array("/Documents/", "/Documentos/", "/Shared Documents/", "/Shared%20Documents/")
    For k = LBound(candidatos) To UBound(candidatos)
        pos = InStr(1, u, candidatos(k), vbTextCompare)
        If pos &gt; 0 Then
            rel = Mid$(u, pos + Len(candidatos(k)))
            rel = Replace$(rel, "/", "\")
            ExtrairRelativoBiblioteca = rel
            Exit Function
        End If
    Next k
End Function

Como utilizar o módulo

  1. Coloque o código num módulo padrão (por exemplo, Module1) do seu projeto VBA.
  2. Se o Book.xlsx estiver na mesma pasta do livro com as macros, chame simplesmente: Sub Exemplo() AbrirLivroOneDrive "Book.xlsx" End Sub
  3. Se estiver numa subpasta, indique-a: Sub ExemploSubpasta() AbrirLivroOneDrive "Book.xlsx", "Subpasta" End Sub

Descobrir o subcaminho correto (sem adivinhar)

Para evitar enganos na composição do caminho:

  • Abra o Explorador de Ficheiros na pasta do OneDrive onde está o ficheiro.
  • Shift + clique direito no ficheiro e escolha Copiar como caminho. Cole num bloco de notas para ver o caminho completo.
  • Remova o nome do ficheiro para obter apenas a pasta. A diferença entre “Documents” e “Documentos” depende do idioma; o módulo acima trata ambas as variantes.

Verificar sincronização e disponibilidade offline

O recurso “Ficheiros a pedido” do OneDrive permite placeholders de ficheiros que só são descarregados quando abertos. Se o ícone do ficheiro for uma nuvem, Workbooks.Open pode falhar. Boas práticas:

  • No Explorador, clique direito na pasta (ou ficheiro) e escolha Sempre manter neste dispositivo.
  • No código, verifique a existência com Dir$(caminho, vbNormal) antes de abrir.
  • Durante testes, abra manualmente o ficheiro uma vez pelo Explorador para forçar a sincronização.

Alternativas úteis

Abrir diretamente a partir do URL (sem Workbooks.Open)

Se não precisar obrigatoriamente de Workbooks.Open, pode usar o esquema do Office para URL:

Sub AbrirPorUrl()
    Dim url As String
    url = "https://<tenant>-my.sharepoint.com/personal/<user>/Documents/Subpasta/Book.xlsx"
    Application.FollowHyperlink "ms-excel:ofe|u|" & url
End Sub

Vantagens: funciona com https://. Limitações: menos controlo sobre parâmetros como ReadOnly e tratamento de erros mais “web-like”.

Unidade de rede/WebDAV (opcional)

Mapear uma biblioteca SharePoint como unidade de rede pode permitir caminhos tipo \\sharepoint\..., mas a performance e fiabilidade variam. A abordagem via pasta local do OneDrive (sincronizada) é geralmente mais estável.

FAQ — Perguntas frequentes

e se tiver várias contas OneDrive?
O módulo tenta OneDriveCommercial, OneDrive e OneDriveConsumer, além de ler pastas de contas Business múltiplas no Registo (Business1..Business9). Se necessário, ajuste manualmente a raiz preferida.

Posso comparar por Workbooks("Book.xlsx") apenas?
Funciona na maioria dos casos, mas pode dar conflitos se houver livros com o mesmo nome abertos de pastas diferentes. Comparar também .FullName diminui o risco.

Funciona no macOS?
As variáveis e o Registo usados são específicos do Windows. Para macOS, o caminho do OneDrive costuma estar em /Users/<utilizador>/Library/CloudStorage/OneDrive-.../. Adapte os utilitários conforme o ambiente.

Há risco de caracteres especiais?
Sim: espaços e acentos em URLs surgem codificados (%20, etc.). O módulo decodifica os mais comuns e normaliza \.

E se o ThisWorkbook.Path já for local?
Ótimo — o módulo usa-o tal como está, sem tentar resolver.

Checklist para o erro “ficheiro não encontrado”

  1. O caminho que está a passar ao Workbooks.Open é local (começa por C:\ ou \\), não https://?
  2. O ficheiro aparece com ícone de nuvem? Se sim, marque como Sempre manter neste dispositivo.
  3. As barras estão normalizadas (\ no Windows)?
  4. Existe alguma diferença de idioma na biblioteca (Documents vs Documentos)?
  5. O nome do ficheiro é exatamente Book.xlsx (atenção a espaços e maiúsculas/minúsculas)?
  6. Há outro livro com o mesmo nome já aberto? Verifique por .FullName.

Exemplo completo minimalista para “mesma pasta do macro”

Se o livro com a macro e o Book.xlsx vivem lado a lado na mesma pasta do OneDrive, o seguinte costuma bastar:

Option Explicit

Sub AbrirDaMesmaPasta()
Const NOME As String = "Book.xlsx"
Dim base As String, alvo As String
```
base = ResolverPastaLocalAPartirDoPathAtual() ' converte https -&gt; local (quando necessário)
If Len(base) = 0 Then base = GetOneDriveRoot()

alvo = JuntarCaminhos(base, NOME)

If Len(Dir$(alvo, vbNormal)) = 0 Then
    MsgBox "Ficheiro não disponível localmente: " & alvo, vbExclamation
    Exit Sub
End If

If ProcurarWorkbookAberto(NOME, alvo) Is Nothing Then
    Workbooks.Open alvo
End If
```
End Sub 

Boas práticas finais

  • Prefira sempre o caminho local sincronizado do OneDrive ao URL https:// quando usar Workbooks.Open.
  • Use as variáveis de ambiente para descobrir rapidamente a raiz local; para casos complexos (pessoal vs empresarial), recorra ao Registo como mostrado.
  • Antes de abrir, verifique se o ficheiro já está aberto e se existe localmente.
  • Quando necessário, a alternativa Application.FollowHyperlink "ms-excel:ofe|u|..." abre diretamente da nuvem.

Conclusão

O erro “ficheiro não encontrado” em cenários OneDrive+VBA raramente é um problema do Excel; quase sempre é a tentativa de alimentar Workbooks.Open com um URL. Ao trabalhar sistematicamente com o caminho local sincronizado, ao normalizar os separadores e ao confirmar a disponibilidade offline, o processo torna‑se previsível, robusto e rápido. Os trechos de código deste artigo fornecem tanto a solução rápida para quem já conhece a subpasta, como um módulo “anti‑surpresa” que resolve automaticamente o caminho correto — incluindo contas pessoais, empresariais e múltiplas.


Principais lições

  • Workbooks.Open não aceita endereços HTTPS — use o caminho local sincronizado.
  • As variáveis de ambiente do Windows fornecem a raiz local do OneDrive (empresarial e pessoal).
  • Verifique sempre se o ficheiro está aberto e se existe no disco antes de chamar Open.
  • Garanta que a opção de manter ficheiros disponíveis offline está ativa para evitar falhas por ausência física.
Índice