[英]How can I run a SQL query within an Excel Workbook saved to OneDrive?
我想对包含在单个 Excel 工作簿中的表运行 SQL 查询。 我的 VBA 代码使用 ADODB 运行这些 SQL 查询。
将工作簿保存在 OneDrive 中时打开连接失败,但将工作簿保存到本地驱动器时可以正常工作。
如何在单个 excel 工作簿中的表上运行 SQL,同时保存在 OneDrive 上?
当书籍保存在本地但不在 OneDrive 上时,该代码有效。 唯一的变化是在每种情况下看起来完全不同的文件路径:
OneDrivePathExample = "https://d.docs.live.net/....xlsb"
LocalPathExample = "C:\My Documents\....xlsb"
我已经在连接字符串中的文件路径周围尝试了一些东西,但不出所料,它们没有工作:
原来的
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";
将“/”替换为“\”
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";`
在路径周围添加方括号
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";
在路径周围添加引号
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,但如果可能的话,我想避免这种情况。
I also realize that I can write VBA code that does what I'm trying to do with SQL, however I did that originally but switched to the SQL method because SQL was way faster.
这是我的代码:
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)';
object '_Connection' 的方法 'Open' 失败
谢谢!
这是我获取文件路径的解决方案。
'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
您可以使用以下函数将OneDrivePath
转换为LocalPath
。
对于这个问题,网上有很多解决方案,但几乎没有一个适用于所有不同类型的 OneDrive 帐户和文件夹......(个人、商业、 SharePoint业务、来自其他人的 OneDrives 的同步文件夹等)
这就是为什么我编写了这个函数来处理我迄今为止遇到的各种 OneDrive 挂载。
Private Function GetLocalPath(path As String) As String
Const HKEY_CURRENT_USER = &H80000001
Dim objReg As Object
Dim regPath As String
Dim subKeys() As Variant
Dim subKey As Variant
Dim strValue As String
Dim strMountpoint As String
Dim strSecPart As String
Static pathSep As String
If pathSep = "" Then pathSep = Application.PathSeparator
Set objReg = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\default:StdRegProv")
regPath = "Software\SyncEngines\Providers\OneDrive\"
objReg.EnumKey HKEY_CURRENT_USER, regPath, subKeys
For Each subKey In subKeys
objReg.GetStringValue HKEY_CURRENT_USER, regPath & subKey, _
"UrlNamespace", strValue
If InStr(path, strValue) > 0 Then
objReg.GetStringValue HKEY_CURRENT_USER, regPath & subKey, _
"MountPoint", strMountpoint
strSecPart = Replace(Mid(path, Len(strValue)), "/", pathSep)
GetLocalPath = strMountpoint & strSecPart
Do Until Dir(GetLocalPath, vbDirectory) <> "" Or _
InStr(2, strSecPart, pathSep) = 0
strSecPart = Mid(strSecPart, InStr(2, strSecPart, pathSep))
GetLocalPath = strMountpoint & strSecPart
Loop
Exit Function
End If
Next
GetLocalPath = path
End Function
请注意,理论上您可以只使用"\"
而不是Application.PathSeparator
,因为此问题仅发生在 Windows 上,因此此功能仅在 Windows 系统上是必需的。
将 html: 替换为“”。 这会让你更进一步。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.