如何在保存到OneDrive的Excel工作簿中运行SQL查询?

时间:2019-01-07 21:04:13

标签: sql excel vba onedrive adodb

我想对所有包含在单个Excel工作簿中的表运行SQL查询。我的VBA代码使用ADODB运行这些SQL查询。

将工作簿保存在OneDrive中时,打开连接失败,但是将工作簿保存到本地驱动器时,打开连接起作用。

在保存在OneDrive中的同时,如何在单个excel工作簿中的表上运行SQL?

当书籍保存在本地但不在OneDrive上时,该代码才有效。唯一的变化是文件路径在每种情况下看起来都大不相同:

OneDrivePathExample = "https://d.docs.live.net/....xlsb"

LocalPathExample = "C:\My Documents\....xlsb"

我已经在连接字符串中围绕文件路径进行了一些尝试,但是,毫无疑问,它们不起作用:

  1. 原始

    Provider=Microsoft.ACE.OLEDB.12.0;Data Source=https://d.docs.live.net/.../Documents/Financial Tracker.xlsb;Extended Properties="Excel 12.0;HDR=Yes;IMEX=1";
    
  2. 用“ \”替换“ /”

    Provider=Microsoft.ACE.OLEDB.12.0;Data Source=https:\\d.docs.live.net\...\Documents\Financial Tracker.xlsb;Extended Properties="Excel 12.0;HDR=Yes;IMEX=1";`
    
  3. 在路径周围添加方括号

    Provider=Microsoft.ACE.OLEDB.12.0;Data Source=[https://d.docs.live.net/.../Documents/Financial Tracker.xlsb];Extended Properties="Excel 12.0;HDR=Yes;IMEX=1";
    
  4. 在路径周围添加引号

    Provider=Microsoft.ACE.OLEDB.12.0;Data Source="https://d.docs.live.net/.../Documents/Financial Tracker.xlsb";Extended Properties="Excel 12.0;HDR=Yes;IMEX=1";
    

我意识到我可以通过在运行此代码时将其保存在本地,然后再将其保存回OneDrive来避免这种情况,但是我想尽可能避免这种情况。

我也意识到我可以编写VBA代码来完成我想用SQL进行的工作,但是我最初是这样做的,但是因为SQL更快,所以切换到了SQL方法。

这是我的代码:

Function OpenRST(strSQL As String) As ADODB.Recordset
''Returns an open recordset object

Dim cn As ADODB.Connection
Dim strProvider As String, strExtendedProperties As String
Dim strFile As String, strCon As String

strFile = ThisWorkbook.FullName

strProvider = "Microsoft.ACE.OLEDB.12.0"
strExtendedProperties = """Excel 12.0;HDR=Yes;IMEX=1"";"


strCon = "Provider=" & strProvider & _
     ";Data Source=" & strFile & _
     ";Extended Properties=" & strExtendedProperties

Set cn = CreateObject("ADODB.Connection")
Set OpenRST = CreateObject("ADODB.Recordset")

cn.Open strCon  ''This is where it fails

OpenRST.Open strSQL, cn

End Function

cn.Open strCon行上,出现以下错误:

  

运行时错误'-2147467259(80004005)';
  对象“ _Connection”的方法“打开”失败

谢谢!

2 个答案:

答案 0 :(得分:0)

用“”替换htpps :。这将使您更进一步。

答案 1 :(得分:0)

这是我获取文件路径的解决方案。

'This Function search root folder as C: ,D: ...
'Search into all OneDrive folders
Option Explicit
Private Const strProtocol   As String = "Http"
Private Const pathSeparator As String = "\"

Function MainFindFile(ByRef NullFilePath As String, Optional FileName As String) As Boolean
    
    Dim fso                 As FileSystemObject 'Necessary enable microsoft scripting runtime in references
    Dim UserRootFolder      As Folder
    Dim SecondSubFolders    As Folder
    Dim ThirdSubFolders     As Folder
    Dim InitialPath         As String
    Dim OneDriveFolderName  As String
    
    Set fso = New Scripting.FileSystemObject
    
    InitialPath = ActiveWorkbook.FullName
    If FileName = vbNullString Then FileName = ActiveWorkbook.Name

    If InStr(1, InitialPath, strProtocol, vbTextCompare) > 0 Then
        InitialPath = Environ("SystemDrive")
        InitialPath = InitialPath & Environ("HomePath")
        
        'Gets all folders in user root folder
        Set UserRootFolder = fso.GetFolder(InitialPath)
        
        For Each SecondSubFolders In UserRootFolder.SubFolders
            'Searches all folders of OneDrive, you may have how many Onedrive's folders as you want
            If InStr(1, SecondSubFolders.Name, "OneDrive", vbTextCompare) > 0 Then
                OneDriveFolderName = InitialPath & pathSeparator & SecondSubFolders.Name
                'Verifies if file exists in root of Onedrive Folder
                MainFindFile = SearchFile(OneDriveFolderName, FileName, NullFilePath)
                If MainFindFile Then Exit For

                'Uses recursive function to percur all subfolders in root of OneDrive
                For Each ThirdSubFolders In fso.GetFolder(OneDriveFolderName).SubFolders
                    MainFindFile = RecursiveFindFile(ThirdSubFolders, FileName, NullFilePath)
                    If MainFindFile Then Exit For
                Next ThirdSubFolders
            End If
            If MainFindFile Then Exit For
        Next SecondSubFolders
        
    End If
    
    MsgBox NullFilePath
    
End Function
Private Function RecursiveFindFile(Folder As Folder, FileName As String, ByRef NullFilePath As String) As Boolean

    Dim fso         As FileSystemObject
    Dim objFolder   As Folder
    Dim Result      As Boolean
    
    Set fso = New Scripting.FileSystemObject
    
    'Verifies if file exists in root of Onedrive Folder
    RecursiveFindFile = SearchFile(Folder.Path, FileName, NullFilePath)
    If RecursiveFindFile Then Exit Function
    
    For Each objFolder In Folder.SubFolders
        If Not SearchFile(objFolder.Path, FileName, NullFilePath) Then
            RecursiveFindFile = RecursiveFindFile(objFolder, FileName, NullFilePath)
            If RecursiveFindFile Then Exit For
        Else
            RecursiveFindFile = True
            Exit For
        End If
    Next objFolder
    
End Function
Private Function SearchFile(Path As String, FileName As String, ByRef NullFilePath As String) As Boolean
    
    'NullFilePath is a byref variable to be filled by this function
    Dim fso As New Scripting.FileSystemObject
    
    If fso.FileExists(Path & pathSeparator & FileName) Then
        NullFilePath = Path & pathSeparator & FileName
        SearchFile = True
    End If
    
End Function