I'm trying to use VBA to perform some SQL operations within an open workbook. If I open the file as a read only (i.e. from an email) the code runs without issue, but if I save it locally to my desktop I get a run-time error "Cannot update. Database or object is read-only". Below is a snippet of the code I'm trying to run
Set CSVconn = New ADODB.Connection
CSVconn.ConnectionString = _
"Provider=Microsoft.ACE.OLEDB.12.0;" & _
"Data Source=" & ThisWorkbook.FullName & ";" & _
"Extended Properties='Excel 12.0 Xml;HDR=yes';"
CSVConn.Open
tmprs.ActiveConnection = CSVconn
tmprs.Source = "SELECT DISTINCT [X] FROM [Range]"
tmprs.Open
Range(X).CopyFromRecordset tmprs
CSVconn.Close
I believe the problem lies with the "ThisWorkbook.FullName" portion of the connection string since the code works on my coworkers' PCs and off our company drive. The file is saved locally and the "Files On Demand" setting for OneDrive is turned off, but the file path is still listed as running through https://sharepoint.com. I've used the split function to rebuild the SharePoint address as a local C drive one (which will open the workbook if I paste the address in file explorer), but running it in VBA throws an error that the file path is not valid. I've tried switching the connection to a GUID, but Windows shut down the Scriptlet.TypeLib function as a security measure and I can't seem to get their workaround code to run. Anyone know how to fix the CSVConnection issue or how to assign a randomly generated GUID to an open workbook using VBA?
Related
when setting and running ADODB connection to SQL from VBA xls, I got a error message "Not able to find the ISAM file", I writting the following connection in a VBA Module :
"Provider= Microsoft.ACE.OLEDB.12.0
"Data Source=" & PWRQRYFilePath
Im usiging xls 2019 , 32 bits. Referencing to Microsoft ActiveX Data Objects 6.1 Library.,
check any thing but not able to create and open the connection would you please help me.
Im trying to create and open the connection so I can run SQL queries from VBA xls
Following is a simple query i want to run to obtain a join inner from two spread sheets
But Actually the Query is sending me the error message.
What is the content of the variable PWRQRYFilePath?
For the sake of completeness:
If you want to go the long way, or better spoken, if you need the query more times, as you know, you can put the code lines also in a function an pass the path to the file to it.... here its represented by the Workbook-Property ThisWorkbook.Fullname
Dim rs As Object 'or AS ADODB.Recordset for EarlyBinding/IntelliSense
With rs
.Open "SELECT * FROM [worksheetname$] WHERE [column]='value'", _
";Provider=Microsoft.Ace.OLEDB.12.0" & _
";Extended Properties""Excel 12.0 xml""" & _
";Data Source=" & ThisWorkbook.FullName
'*** do your stuff with recordsetresult
.Close
End With
If you need the query just once, you can use a anonym function call as well:
With CreateObject("ADODB.Recordset")
.OPEN ...
'*** do your stuff ...
.CLOSE
End With
I have a problem with Excel (ODBC / Access). I would like to refresh data from any folder in my computer. I have file which I use from Desktop, but I would like to refresh data from the same file when it will be move to documents, etc. Please could you provide what I should do?
I have a file connection as below:
DSN=Excel Files;DBQ=C:\Users\User\Desktop\Task1\SalesBudget2018.xlsx;DefaultDir=C:\Users\User\Desktop\Task1;DriverId=1046;MaxBufferSize=2048;PageTimeout=5;
Thank you.
EDIT1: Thank you. I tried use your solution and I received error: "run time error 2147467259 Database or object is read-only", my code below. The bug is related to ".Open" line:
Sub RefreshData()
Dim CreateNew As Object
Dim RunSELECT As Object
Dim Data As String
Dim SQL As String
FolderPath = ActiveWorkbook.path
Path = Left(FolderPath, InStrRev(FolderPath, "\") - 1)
Set CreateNew = CreateObject("ADODB.Connection")
With CreateNew
.Provider = "Microsoft.ACE.OLEDB.12.0"
.ConnectionString = "Data Source=" & Path & "\SalesBudget2018.xlsx" & ";" & "Extended Properties=""Excel 12.0 Xml;HDR=YES;"";"
.Open
End With
'Run SQL
SQL = "SELECT * FROM [twRynki$]"
Set RunSELECT = cn.Execute(SQL)
Do
output = output & RunSELECT(0) & ";" & RunSELECT(1) & ";" & RunSELECT(2) & vbNewLine
Debug.Print RunSELECT(0); ";" & RunSELECT(1) & ";" & RunSELECT(2)
rs.Movenext
Loop Until rs.EOF
End Sub
Your path actually is not relative at all. But ACE/JET data engine does not support relative paths anyway.
A relative path would be
\Data\mydb.mdb
So, above would be one folder up called data from current location. And one folder down using relative would be:
..\Data\mydb.mdb
However, with ACE/Access relative paths are not supported. However, what we do when we want software to work say from the current folder? We simple get and use the full path name ON APPLICATION start up. So, you can get/grab the current folder. In Excel VBA you can use this:
ActiveWorkbook.Path
So above will give you the current path. And thus you use that in code to set the connection string. So, even in access, if we want the software to work in any folder? We simply get/grab the full path name on startup. As a result, the software works in any folder and you effective get relative address in that you "don't care" where the software is placed, since you always get/grab the full path name anyway. So, with above, you could append a folder name called data
ActiveWorkbook.Path & "\Data\Mydb.accdb"
So, from the current workbook location, you could always have a folder called data, and inside that folder you can have your database. So, in effect you do get relative addressing, but you always pulling the full path name of the current workbook as per above.
The end result is you don't miss not having some form of relative addressing since you don't need to with this approach.
The above is for Excel VBA. To get current path from Access VBA? You can use this:
currentproject.Path
So, your connection string to Excel could be this:
dim strExcelPath as string
strExcelPath = CurrentProject.Path & "\Task1\SalesBudget2018.xlsx"
It not clear if the access application is in the SAME folder as task1?
Assuming yes, then this would work:
strExcelPath = CurrentProject.Path & "\SalesBudget2018.xlsx"
So, now the folder can be on the desktop, my documents - it will not matter. You can thus use above as part of your connection string. It not clear if you linking to Excel (linked table), or you using VBA and say ADO code. However, it really don't matter. On application startup, you get the above connection string, check it against the linked table -- if same then do nothing. If different, then you re-link that one table. Thus you ONLY re-link one time if the folder been moved. And no matter where you move the folder? As long as you assume the Excel sheet is in the same folder as the access app, then you good to go. And as noted, you could add a sub folder say ExcelSheets to above. And once again, no matter where you move this folder with the Access part, as long as the sub folder is in the same dir/folder, then this will work - despite you not having relative addressing.
I am trying to connect to Access Database using ADO DSN.
StrPath = Sheets("Sheet1").Range("DB_location")
strCon = "DSN=MS Access Database;DBQ=" & StrPath & ";"
Set con = New ADODB.Connection
con.Open strCon
I can connect to DB without any problem on my machine. However, when I tried running this exact macro on another PC, I ran into this issue on the last line:
I assumed it was due to Database Engine, but installing "Microsoft Access Database Engine 2010 Redistributable" from Microsoft's website didn't solve this problem. All the necessary references in VBA editor are present.
There is no problem with DB or the macro, as I checked on a different PC, but this specific computer runs into this problem.
Changing
strCon = "Provider = Microsoft.Jet.OLEDB.4.0; Data Source = " & StrPath & ";"
solved this problem, which means the problem was somehow due to DSN. Does anyone have a guess about where does this problem might come from?
I had this error and it ended up being my primary keys. WHen i fixed my primary keys in the table it worked like a charm.
Kind of a wordy title but I have a classic ASP application I am trying to write where a user uploads an Excel spreadsheet and then I take that spreadsheet and import the data into SQL.
I have everything working great but the one thing I'm running into is that after I open the spreadsheet using ODBC and close all the objects that reference it, if I try to delete the file, I get a permission denied error.
If I try to sweep the temp directory before uploading and I run into a previously uploaded file (say within the last two minutes), I get the permission denied error.
If I wait a minute or two, it seems like whatever lock was put on the file is released and I can delete it.
Here's some code:
sPath = Server.MapPath("/_temp/") & "\"
sFileName = Request.QueryString("filename")
Set objFile = Server.CreateObject("Scripting.FileSystemObject")
If objFile.FileExists(sPath & sFileName) Then
objFile.DeleteFile sPath & sFileName, True
End If
'Upload file occurs here
sConnectionString = "Driver={Microsoft Excel Driver (*.xls, *.xlsx, *.xlsm, *.xlsb)};DBQ=" & sPath & sFileName & ";"
adLockOptimistic = 3
sSQL = "SELECT * "
sSQL = sSQL & "FROM Range"
Set rsSystem = objExcel.Execute(sSQL)
'Do stuff
rsSystem.Close
Set rsSystem = Nothing
objExcel.Close
Set objExcel = Nothing
Set objFile = Nothing
Doesn't seem to matter if I try to delete the file before or after I do the import, if I try deleting the file right after a successful import, I get the permission denied error but if I wait a minute, I'm then able to delete it.
This is an issue as users are going to be supplied templates and they may make a correction and immediately re-upload.
Any ideas as to why the lock is not getting immediately released when I close all associated objects?
Thanks!
Edit:
Changing the connection string to use a different driver seems to have done the trick, now when I close the objects I can delete the file with no issue
sConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & sPath & sFileName & ";Extended Properties=Excel 8.0;"
I've actually found a number of ways to do this.
As stated in the comments of your OP, one option is to use SSIS and import your Excel spreadsheet using a stored procedure.
You can import directly using a stored procedure
Or use a check to test whether the file is locked
First time I'm using stackoverflow so here goes...
I've been getting errors intermittently when I try to run a macro in excel which I use for pulling in data from a CSV file. The error normally goes away if I start a fresh session, but this time it's been particularly persistant. It basically errors on the .Open line below, giving me a "Run-time error '2147467259' (80004005) Unspecified error":
Public Sub LoadFile()
file_path = Range("FlatFileLocation")
Set oConn = CreateObject("ADODB.Connection")
strcon = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & file_path & "; Extended Properties=""text;HDR=Yes;FMT=Delimited(,)"";"
oConn.Open strcon
.....
Other info:
1) the file I'm trying to access is not open by another user
2) I close my connections at the end of the sub. also, i just tried restarting my machine and the error happened the first time I tried running the file
3) When I open my session up without any of my existing addins it seems to work. Is there any way of checking whether there is some sort of addin conflict going on?
There were other posts that suggest using CSVReader. Questions I have before trying this route are:
1) can I use this CSVReader across multiple user machines? The problem I would have here is needing to install it on a number of machines. I might be able to put a file on a shared drive however.
2) Can I query the resultant file with a SQL string? At the moment I use something like this:
....
strsql = "SELECT * FROM ( " & strsql & " ) WHERE ( ABS(PrevRisk) + ABS(CurrRisk) >= " & RiskThreshold & " ) ;"
Set oResult = New ADODB.Recordset
oResult.Open strsql, oConn
....
Thanks in advance for your help!