vb.net Cannot update. Getting error "Database or object is read-only." when just trying to READ from excel file - excel

I'm more than willing to accept other suggestions on ways to accomplish what I want to do. I am trying to read some lines from an excel spreadsheet that the user uploads to my application. The web server where this will eventually reside does not have excel installed on it, which makes referencing things like Microsoft.Office.Interop.Excel.dll in my project impossible. So I've been looking for ways to read the excel file so that will work with this situation. The best way I've found so far is to use Microsoft.Jet.OLEDB.4.0 to connect to the excel file like a datasource. Here is a small snippet of I've put together so far:
Dim excelFileName As String = "C:\\Import\\K12Mercury.xlsx"
Dim conn As New OleDb.OleDbConnection(String.Format("provider=Microsoft.Jet.OLEDB.4.0; Data Source=" & excelFileName & "; Extended Properties='Excel 8.0;HDR=YES;'"))
conn.Open()
The program fails on the conn.Open() line with the error:
cannot update. database or object is read-only
I don't know why this is happening or if this is even the best route to use to be able to read from an excel file in an environment where excel is not installed. Will someone please help me? Thanks in advance.

Related

Do the DSOFile functions only apply to the non-binary Excel Document types?

Using Windows 10 (Build 1903 if that's relevant?) and 64bit Office 365 (probably relevant?) I've implemented a system that allows me to version control Excel VBA code.
I'm using the Workbook_BeforeSave method to check whether the current file is saved or not, and if it is saved, where it is saved to.
This works fine and will prompt the user as to whether they want to update the code contained within. I then thought that maybe I should in fact check if the code "needs" to be updated prior to prompting the user.
First off, I found the following question/solution: Using VBA to read the metadata or file properties of files in a SharePoint doc library
which I couldn't use without DSOFile.dll that I was able to install from here:
https://www.microsoft.com/en-us/download/details.aspx?id=8422
Here follows the code I have which doesn't work:
Private Function CheckTemplateIsNewerThanCurrentFile(ByVal templatePath As String) As Boolean
Dim templateName As String
Dim fso As New FileSystemObject
templateName = ActiveWorkbook.CustomDocumentProperties("TemplateName").Value
If fso.FileExists(templatePath & "\" & LocalTemplateName) Then
Dim objDSO As New DSOFile.OleDocumentProperties
objDSO.Open templatePath & "\" & LocalTemplateName, True, dsoOptionDefault
If Not objDSO.CustomProperties("LastCommitDate") = ActiveDocument.CustomDocumentProperties("LastCommitDate").Value Then
CheckTemplateIsNewerThanCurrentFile = False
Else
CheckTemplateIsNewerThanCurrentFile = True
TemplateLastCommitDate = objDSO.CustomProperties.Item("LastCommitDate")
End If
End If
End Function
And here (highlighted) is the error I receive trying to run the method above on an .xlsb file:
(FWIW: the reason for use of the .xlsb format is because we're working with 500K+ rows of data in the process we're carrying out. Yes, I know Excel is ABSOLUTELY NOT the tool for this but we're lumbered with it now)
I know I could have already tried changing the file format to .xlsm but because this file is version controlled that is a pain to do if the method is still likely to fail.
Thanks in advance,
Alex.

ODBC Driver has become erratic when making connection and processing SQL query

I have an Excel Macro Workbook (binary extension) that suddenly has developed 2 issues occasionally (sometimes it runs fine).
#1 Issue - Occasionally there is an error on Line 5
It appears the connection does not open. We get the error:
Microsoft][ODBC Microsoft Access Driver]General error Unable to open registry key Temporary (volatile) Ace DSN for process 0x7f8 Thread 0x1174 DBC
#2 Issue - Occasionally there is an error on Line 7
It appears the SQL can not run. It indicates the Worksheet tab can not be found even though it does exist. Note for this error we have no issue with Line 5 (Open Connection). The error that displays is:
[Microsoft][ODBC Excel Driver] The microsoft jet database engine could not find the object 'Worksheet Name'. Make sure the object exists...
For Issue #2 once we close the error dialog box and THE MACRO GETS DELETED !!!
Notes
The code module has not been changed in years Some days we get no errors/issues
This issue occurs for multiple Excel workbooks run by multiple people that run different VBA code blocks. However 1 of the code blocks is the same across all these macros which is the code snippet above.
The source data has not changed in years in terms of formatting or volume.
All these workbooks are on a Network server.
We are on Windows7/Excel 2010/ODBC Excel Driver (xls xlsx xlsm xlsb)
14.00.7180.5000
Code Snippet
1-Set adoConn = Nothing
2-Set adoRS = Nothing
3-Application.EnableCancelKey = xldisabled
4-strConn = "Driver={Microsoft Excel Driver (*.xls,*.xlsx,*.xlsm,*.xlsb)};DriverId=1046;Dbq=" & strFileName & ";IMEX=1;"
5-Set adoConn = New ADODB.Connection: adoConn.Open strConn
6-Application.EnableCancelKey = xlInterrupt
7-Set adoRS = New ADODB.Recordset:adoRS.Open Source:=strSQL,ActiveConnection:=adoConn
I'm curious as to why you're using ODBC to connect Excel to another Excel file, as opposed as to linking the data directly.
Intermittent connection problems point to a network issue. I would suggest removing and re-creating the ODBC connection, but I'd first want to confirm the value of strFileName as referred to in the connection string. Is it an actual server on your internal network, or an external source? (ie, is it a UNC path?)
An intermittent Unable to open registry key error likely sounds worse than it is; when having connection problems, Windows & Excel will easily get confused as to what the real problem is.
It sounds like your setup has been in place, possibly un-maintained, for a long time. When is the last time the client and server were rebooted? (Should be nightly.) Defrag, disk cleanup, etc?
As for the issue of the macro "getting deleted" when you close an error dialog, I'd need to see proof of that. I think you're misunderstanding something, unless you're re-writing the macro from scratch each time this happens..

Embedded MS Query connection in Excel

The original task I had was to combine two worksheets dynamically. I discovered Microsoft Query lets me do it by building queries to pull data from the worksheets. However, the data connection stored in the file has references to my local computer. Is there a way to make this "embedded" in the file instead, such that I can share the file and anyone can refresh it? Here's the connection string.
DSN=Excel Files;DBQ=C:\Users\nana\Documents\Model\Project x Model - DRAFT 2015 07 13 0410 - Copy.xlsx;DefaultDir=C:\Users\nana\Documents\Model;DriverId=1046;MaxBufferSize=2048;PageTimeout=5;
I think you can set the DSN in the code so something like this should work
currentDir = Replace(WScript.ScriptFullName,WScript.ScriptName,””)
which will give you the directory the excel file was run from and then you can change your DNS params to reflect the variable:
DSN=Excel Files;DBQ=" & currentDir & "Source.xls;DefaultDir=" & currentDir & ";DriverId=1046;FIL=excel 12.0;MaxBufferSize=2048;PageTimeout=5;
That should mean the dsn always references the same workbook...
*edit I should mention this came from here http://www.experts-exchange.com/Software/Office_Productivity/Office_Suites/MS_Office/Excel/Q_26514035.html

loading csv "Could not find installable ISAM"

Im building a program in Excel VBA to automate a process and I require data stored in a csv file to be imported. So, I'm trying to use a query table to import specific columns in a csv file.
Im using ADO to interface with the csv file using the Jet Provider OLE DB. In the connection string I have specified the provider, data source, and extended properties. Im using windows xp and office 2003, so my Excel version is 8.0. I specified the provider as Microsoft.Jet.OLEDB.4.0. My code is pasted below. When the code executes I get the error "Could not find installable ISAM" at the last line that I included in the below code. I cant find anything wrong with the syntax so I was wondering if this error could be because I dont have the correct version of Jet installed? Please see code below. Thanks
Sub Excel_QueryTable()
Dim oCn As ADODB.Connection
Dim oRS As ADODB.Recordset
Dim ConnString As String
Dim SQL As String
Dim qt As QueryTable
ConnString = "Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=C:\testfile.csv;" & _
"Extended Properties=Excel 8.0;HDR=Yes; FMT=Delimited; IMEX=1"","
Set oCn = New ADODB.Connection
oCn.ConnectionString = ConnString
oCn.Open
Try this:
ConnString = "Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=C:\directory\where\csv\file\is\;" & _
"Extended Properties=""text;HDR=Yes;FMT=Delimited"""
I don't think you want to use the "Excel 8.0" portion, but you aren't actually connecting to an Excel worksheet; you're connecting to a text file. Also, you had extra spaces, and connection strings are REALLY picky about those, so I've deleted them.
Note that you can set the delimiter here:
HKLM\SOFTWARE\Microsoft\Jet\4.0\Engines\Text\Format
Mine is currently CSVDelimited; other options are TabDelimited and Delimited(;)
I found this info at: http://www.connectionstrings.com/textfile
-- EDIT --
Instead of pointing to a specific .csv file, you actually point the data source to a target directory. Note my changes above, in the connection string: the filename has been removed, and the path now ends in a \.
In order to use this type of data source, you actually need to teach the driver how the file is laid out. You do this through the use of a schema.ini file.
You can create the .ini file one of two ways:
Manually edit the file by hand, in notepad, using the above link to provide usage.
Use the tool built into the ODBC Data Source Admin.
In order to use the tool, you need to actually go through the steps of creating a data source. You don't actually need the data source, but as far as I can tell, it's the only way to get to the create schema.ini creation tool.
To get there:
Go to the ODBC control panel.
Add a new DSN, type: Microsoft Text Driver (*.txt, *.csv), click Finish
On "ODBC Text Setup", uncheck Use Current Directory and select the directory where your file lives.
Click on the options button, and click on the Define Format button.
Click on the file that you want to work with, and click "Guess" to get you started, then refine the data types as necessary.
When done, click OK, and you should see a schema.ini file in the directory where your .csv file is. Open it in notepad, and make sure it looks right.
The above connection string should now work correctly, using ONLY the directory where your csv lives, not the full path to the .csv.

Excel Object SaveAs, error happens when Existing File is Open

Excel_Obj = CREATE OleObject
Excel_Obj.ConnectToNewObject( 'excel.application' )
Excel_Obj.Workbooks.Add
Excel_Obj.Application.ActiveWorkbook.WorkSheets.Add
Excel_Sheet = Excel_Obj.Application.ActiveWorkbook.WorkSheets[1]
//EXAMPLE
Excel_Sheet.Cells[1,1] = 45
Excel_Obj.Application.ActiveWorkbook.SaveAs(ls_file,56) //csv
//where ls_file = the Opened File
error happened after / during saveas.
try catch throw "error calling external object..in click..line.. saveas.."
--
i want to state to the user that the excel file is open therefore cannot be overwritten properly. I used a try catch and throwed a proper message but before the messagebox for the catch event happens, the PB execution error R0035 happens. any solutions or proper way to know if the excel file is open.
You might be able to check if the file is open first, have a look at this answer:
how to check if file is opened in excel using OLE (leaves excel process open)
I'd try a PowerScript FileOpen () call with a LockReadWrite! parameter to see if it can be opened, followed immediately by a FileClose () if it was successful. (I think this is a PowerScript-specific variation on the DXL solution Colin linked to.)
Good luck,
Terry
Have you tried approaches similar to these?
Using Win32 API:
http://www.rgagnon.com/pbdetails/pb-0030.html
Using PB function fileopen()with the (default) exclusive rights set:
http://www.tek-tips.com/viewthread.cfm?qid=1610670
In other words, see if the file can be opened exclusively before connecting to Excel or making the CSV?
You will have to turn off the option to break into the debugger for that exception to see the exception handling work in the IDE. Look for the Help topic "Exception Settings dialog box" for details. Once you see it's working I recommend you set it back to break into the debugger, since you'd normally want to see what threw the error.
You cannot use ole when document is open( even you set lock write) by the user and not by apllication.
my approach, I have been using many times till now:
Check excel is open or not, use use can use api or wsh script in the internet to check app opened. If opened do not run save as and tell user to close excel and not run it for while for while.
if you user run excel and your program still running active workbook and worksheet application will be switch to excel that opened by user ( imagine it wrong written data).
Change your code as below
if Excel_Obj.ConnectToNewObject( 'excel.application' ) <> 0 then
messagebox("warning", "could connect to excel", stopsign!)
RETURN
end if
just for knowledge another technique is DDE call, but not common today and most complicated.
Happy coding From pb developer.

Resources