【问题标题】:How do I get my VBA project reference to an Excel Workbook on OneDrive to use the local drive path rather than the OneDrve URL Path?如何让我的 VBA 项目引用 OneDrive 上的 Excel 工作簿以使用本地驱动器路径而不是 OneDrive URL 路径?
【发布时间】:2023-03-06 06:18:01
【问题描述】:

2021-03-20 更新:我发现即使我将要引用的文件从我的 OneDrive 复制到不属于 OneDrive 的本地文件夹并引用它,也会发生同样的事情。只有在我也重命名文件之后,我才能引用它,而不会将其路径变成 URL(假设指向我的在线 OneDrive)。这不符合我的需求。我正在尝试找到一种方法来在不同设备上不同位置的不同应用程序之间共享我的 VBA 代码库。如果我不明白这一点,我可能会就此提出一个单独的问题。

原问题: 当我向存储在 OneDrive 本地副本上的 Excel xlsm 文件添加引用(在 VBA 中,工具-> 引用)时,路径被转换为 url,我无法再加载我的 VBA 项目而不会收到错误消息它找不到文件。如何使引用始终指向我的本地同步 OneDrive 路径?

例如,

  1. 打开一个 xlsm 项目

  2. 打开 VBA IDE

  3. 从 VBIDE 菜单中选择工具 -> 参考

  4. 浏览以添加对另一个 xlsm 文件的引用。
    一种。例如,C:\Users\Andbio\OneDrive\Code Libraries\RYTEwayCode (XLSM).xlsm

    b.确保在打开的“添加引用”文件打开对话框中选择 xlsm 类型。

    c。选择要引用的xlsm文件,点击“打开”。

    d。请注意,在“参考”对话框底部的“位置:”字段中,它显示了本地路径。

  5. 单击“确定”以添加对项目的新引用。

此时,一切正常,您可以在刚刚引用的文件中执行代码。所以,参考有效。

  1. 再次从 VBIDE 菜单中选择工具 -> 参考
  2. 选择您刚刚添加的参考。
  3. 现在请注意,在“位置:”字段中,您所引用文件的本地路径已替换为 URL。就我而言,它现在显示:“https://d.docs.live.net/8e13263ac9cf0594/Code Libraries/RYTEwayCode (XLSM).xlsm”。

如果我现在保存并关闭 XLSM 文件,然后尝试重新打开它,我会收到一条错误消息,指出在上面第 8 步中显示的 URL 路径中找不到文件。我必须在安全模式 (/s) 下重新打开它才能再次打开文件以删除引用。

我知道为什么会发生这种情况以及为什么会这样设计,我只需要一种方法来解决它(如果有的话)。是否仍然能够将我的引用文件存储在 OneDrive 上,而不是将我的 XLSM 文件存储在同一个 OneDrive 上?

【问题讨论】:

    标签: excel vba include onedrive include-path


    【解决方案1】:

    当您添加对 XLSM 文件的引用时,VBA 基本上会像您使用“打开文件”命令一样打开工作簿。因此,您可以做的是在触发第一个工作簿的 Open 事件时打开第二个工作簿。如果工作簿保存在 OneDrive 文件夹中,您可能会发现使用 ThisWorkbook.Path 获取工作簿的物理路径时会出现问题。我有一个辅助函数也可以帮助你。看看:

    Private Sub Workbook_Open()
        
        Workbooks.Open GetWorkbookPath & "\RYTEwayCode (XLSM).xlsm"
        
    End Sub
    

    您还需要GetWorkbookPath 函数。

    Function GetWorkbookPath(Optional wb As Workbook)
        '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        ' Purpose:  Returns a workbook's physical path, even when they are saved in
        '           synced OneDrive Personal, OneDrive Business or Microsoft Teams folders.
        '           If no value is provided for wb, it's set to ThisWorkbook object instead.
        ' Author:   Ricardo Gerbaudo
        ' Source:   https://github.com/ricardogerbaudo/vba-helpers
        '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        
        If wb Is Nothing Then Set wb = ThisWorkbook
        
        GetWorkbookPath = wb.Path
        
        If InStr(1, wb.Path, "https://") <> 0 Then
            
            Const HKEY_CURRENT_USER = &H80000001
            Dim objRegistryProvider As Object
            Dim strRegistryPath As String
            Dim arrSubKeys()
            Dim strSubKey As Variant
            Dim strUrlNamespace As String
            Dim strMountPoint As String
            Dim strLocalPath As String
            Dim strRemainderPath As String
            Dim strLibraryType As String
        
            Set objRegistryProvider = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\default:StdRegProv")
        
            strRegistryPath = "SOFTWARE\SyncEngines\Providers\OneDrive"
            objRegistryProvider.EnumKey HKEY_CURRENT_USER, strRegistryPath, arrSubKeys
            
            For Each strSubKey In arrSubKeys
                objRegistryProvider.GetStringValue HKEY_CURRENT_USER, strRegistryPath & "\" & strSubKey & "\", "UrlNamespace", strUrlNamespace
                If InStr(1, wb.Path, strUrlNamespace) <> 0 Or InStr(1, strUrlNamespace, wb.Path) <> 0 Then
                    objRegistryProvider.GetStringValue HKEY_CURRENT_USER, strRegistryPath & "\" & strSubKey & "\", "MountPoint", strMountPoint
                    objRegistryProvider.GetStringValue HKEY_CURRENT_USER, strRegistryPath & "\" & strSubKey & "\", "LibraryType", strLibraryType
                    
                    If InStr(1, wb.Path, strUrlNamespace) <> 0 Then
                        strRemainderPath = Replace(wb.Path, strUrlNamespace, vbNullString)
                    Else
                        GetWorkbookPath = strMountPoint
                        Exit Function
                    End If
                    
                    'If OneDrive Personal, skips the GUID part of the URL to match with physical path
                    If InStr(1, strUrlNamespace, "https://d.docs.live.net") <> 0 Then
                        If InStr(2, strRemainderPath, "/") = 0 Then
                            strRemainderPath = vbNullString
                        Else
                            strRemainderPath = Mid(strRemainderPath, InStr(2, strRemainderPath, "/"))
                        End If
                    End If
                    
                    'If OneDrive Business, adds extra slash at the start of string to match the pattern
                    strRemainderPath = IIf(InStr(1, strUrlNamespace, "my.sharepoint.com") <> 0, "/", vbNullString) & strRemainderPath
                    
                    strLocalPath = ""
                    
                    If (InStr(1, strRemainderPath, "/")) <> 0 Then
                        strLocalPath = Mid(strRemainderPath, InStr(1, strRemainderPath, "/"))
                        strLocalPath = Replace(strLocalPath, "/", "\")
                    End If
                    
                    strLocalPath = strMountPoint & strLocalPath
                    GetWorkbookPath = strLocalPath
                    If Dir(GetWorkbookPath & "\" & wb.Name) <> "" Then Exit Function
                End If
            Next
        End If
        
    End Function
    

    【讨论】:

    • 非常感谢您的出色回答。我很久以前就问过这个问题,但它仍然是您最终解决的问题。如果我将您的代码添加到我公开共享的个人库中可以吗?我会将您列为我的 cmets 中代码的作者。再次,谢谢你!我喜欢你的编码风格。易于阅读和维护。 〜赫里克安德鲁斯。 P.S.,该应用程序不会让我支持您的答案,否则肯定会。希望其他人会。
    • @SixSigmaGuy 非常欢迎您在您的个人库中分享此代码。乐意效劳! ;)
    • @SixSigmaGuy 如果您的问题已解决,请不要忘记将其标记为已回答。 ;)
    猜你喜欢
    • 1970-01-01
    • 2021-10-03
    • 1970-01-01
    • 2017-02-28
    • 1970-01-01
    • 1970-01-01
    • 2021-06-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多