As of now im reading all version of excel files using oledbreader. i referred a dll for reading Excel 2010 files. but i cannot read some excel 2010 files using oledbreader. so i would like to use openxml for reading all excel files. is ter any performance issue in this?
which is better?
I have had very good luck using the following code to retrieve table names(worksheet names) and column names from Excel spreadsheets.
Private Sub GetWorksheetData
Dim xlBaseConnStr1 As String = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=XLS;Extended Properties=""Excel 8.0;HDR=Yes"""
Dim xlBaseConnStr2 As String = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=XLS;Extended Properties=""Excel 12.0 Xml;HDR=YES"""
Dim xlName As String
Dim conStr As String
Dim oDia As New OpenFileDialog
oDia.ShowDialog()
xlName = oDia.FileName
If xlName = "" Then
Exit Sub
End If
Dim extType As String = Path.GetExtension(xlName)
Select Case extType
Case ".xls"
conStr = xlBaseConnStr1.Replace("XLS", xlName)
Case ".xlsx"
conStr = xlBaseConnStr2.Replace("XLS", xlName)
Case Else
MessageBox.Show("Unrecognized file type")
Exit Sub
End Select
Dim dtSheets As New DataTable
Using cn As New OleDbConnection(conStr)
cn.Open()
dtSheets = cn.GetSchema("Columns")
End Using
DataGrid1.ItemsSource = dtSheets.DefaultView
End Sub
The above chunk of code returns the following data from a random Excel spreadsheet that I had laying around.
You will need to import the following namespaces for this to work:
Imports System.Data.OleDb
Imports System.Data
Imports Microsoft.Win32
Imports System.IO
If the spreadsheet that you are trying to access has macros, the above code may fail.
Related
I am using an Excel macro to define a data range in Excel and then call "objAccess.DoCmd.TransferSpreadsheet" to import the data from this range into an Access table. This import does not work all of the time.
I have come to the conclusion that the macro works fine when there is only one instance of Excel open. However, the data import fails when another instance is already open. In the latter case the Access database opens up and the Excel file from which I run the macro is being reopened (in read-only mode) in the other Excel instance. There is no actual error but the desired import is not being carried out. Why does this happen?
Sub Excel_2_Access()
Dim strPath As String
Dim strwbPath As String
Dim strRange As String
Dim objAccess As Access.Application
Dim wbActive As Workbook
'get database path
strPath = Worksheets("error").Range("Access_DB_Path").Value & "\" & Worksheets("error").Range("Access_DB").Value
'open database
Set objAccess = New Access.Application
Call objAccess.OpenCurrentDatabase(strPath)
objAccess.Visible = True
'access import
Worksheets("error").Columns("P:P").Calculate
Set wbActive = ActiveWorkbook
strwbPath = Application.ActiveWorkbook.FullName
strRange = "error!M2:M" & (Worksheets("error").Range("WKN_count").Value + 2)
Call objAccess.DoCmd.TransferSpreadsheet(acImport, 8, "WKN_Mapping", strwbPath, True, strRange)
objAccess.Forms("MX_Import").Refresh
End Sub
As the macro is fairly short I have included the entire code for your reference. However, I don't think the way the range is specified or names are provided is really relevant to the question.
The desired outcome would be to have an Excel macro in place that carries out the transfer from Excel to Access no matter if there are other instances of Excel open or not.
Is there such a thing as the primary instance of Excel (the first one that was opened) which has a special status? Is there a way to provide the specific Excel instance the workbook is in when calling the Access function from Excel? Or is there a more reliable way to transfer the data which generally avoids this problem with multiple instances?
I tested approach that opens Access db and runs TransferSreadsheet. Don't need to set a workbook object (your code sets but then doesn't even utilize). It ran without error every time. I tried setting the Access object Visible but the database appears and immediately closes anyway, although the data import does happen. Set reference libarary: Microsoft Access x.x Object Library.
Sub test()
Dim ac As Access.Application, strRange As String
Set ac = New Access.Application
strRange = "Sheet1!A1:E3"
ac.OpenCurrentDatabase "C:\Users\June\LL\Umpires.accdb"
ac.DoCmd.TransferSpreadsheet acImport, acSpreadsheetTypeExcel12Xml, "Rates", ThisWorkbook.FullName, True, strRange
End Sub
Example Excel VBA code that exports all rows of worksheet to existing table in Access without opening Access file. Setting an ADODB connection makes the Execute method available. This approach runs faster. Set reference library: Microsoft ActiveX Data Objects x.x Library.
Sub test()
Dim cn As ADODB.Connection
Set cn = New ADODB.Connection
cn.Open "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & ThisWorkbook.FullName & ";Extended Properties=Excel 8.0"
cn.Execute "INSERT INTO Rates(RateLevel, Rate, Pos, EffDate) IN 'C:\Users\June\LL\Umpires.accdb' " & _
"SELECT RateLevel,Rate,Pos,EffDate FROM [Sheet1$];"
cn.Close
Set cn = Nothing
End Sub
I am importing excel worksheets to a datagridview using the following code:
Private Sub Browsimportbtn_Click(sender As Object, e As EventArgs) Handles Browsimportbtn.Click
Dim textpath As String
Dim textpath1 As String
Dim opf As New OpenFileDialog
If opf.ShowDialog = 1 Then
textpath = opf.FileName
textpath1 = opf.SafeFileName
textpath1 = textpath1.Remove(textpath1.Length -4,4)
Dim cnexcell As New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & textpath & "; Extended Properties = ""Excel 12.0 Xml;HDR=YES"";")
Dim cmdE As New OleDbCommand("SELECT * FROM Feuil1", cnexcell)
Try
Dim daoledb As New OleDbDataAdapter
Dim dset As New DataSet
daoledb.SelectCommand = cmdE
daoledb.Fill(dset, "Feuil1")
DGVmodele.DataSource = dset.Tables("Feuil1")
Catch ex As Exception
MsgBox(ex.Message)
End Try
End If
End Sub
The code above is working well with .XLSX files (office 2007,2010...) but do not with .XLS and i don't know where is the issue.
Any suggestions?
The issue is in the connectionstring.
You are specifying the Excel 12 as a version in the connection string which is related to 2007 or higher. Try using this function to build the connectionstring
Public Function BuildConnectionString(Byval m_strExcelPath as String) As String
If m_strExcelPath.Substring(m_strExcelPath.LastIndexOf(".")).ToLower = ".xlsx" Then
Return "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & m_strExcelPath & ";Excel 12.0;HDR=YES;IMEX=1"
Else
Return "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & m_strExcelPath & ";Excel 8.0;HDR=YES;IMEX=1"
End If
End Function
Try using this instead.
"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & m_strExcelPath & ";Extended Properties='Excel 12.0;HDR=Yes;IMEX=1;'"
It is unadvisable to use the JET OLEDB because it is outdated. If you really want to use it, you might need to reinstall Access Database Engine 2003.
Also, I heard there's also a bug regarding this.
How can I create a Table link within a MS Access *.accdb file, linking to another table in an MS Access *.accdb file, but from VBA code within an MS Excel *.xlsx file.
Database1 in file1
Database2 in file2
Excel VBA Code in file3
Execute code in file3 to link a table of file2 to file1, so that it appears as linked table within file1.
Details:
I have a complex script creating a large table and join mappings based on a MS Excel Design, since it is more user friendly to design the things in an MS Excel Table. Everything works great so far, but I need the last step, LINK the original table.
Within MS Access I would do
DoCmd.TransferDatabase TransferType:=acLink, _
DatabaseType:="Microsoft Access", _
DatabaseName:=SRC_FILE_PATH, _
ObjectType:=acTable, _
Source:=SRC_TABLE_NAME, _
Destination:=DESTINATION_TABLE_NAME
But since I am executing VBA Code within Excel, only using the connection to the database via a DAO.Database object, this command doesn't work.
Using the DAO reference library in Excel
Dim wrkDAOWorkspace As DAO.Workspace
Dim dbsDAODatabase As DAO.Database
Dim tdfNewLinkedTable As DAO.TableDef
Set wrkDAOWorkspace = CreateWorkspace("WorkspaceForLinkCreation", "Admin", "", dbUseJet)
Set dbsDAODatabase = wrkDAOWorkspace.OpenDatabase("c:\file1.accdb")
Set tdfNewLinkedTable = New DAO.TableDef
With tdfNewLinkedTable
.Name = "TestTableLinked"
.Connect = ";DATABASE=c:\file2.accdb"
.SourceTableName = "TestTableLinkTo"
End With
dbsDAODatabase.TableDefs.Append tdfNewLinkedTable
Something like this should do it for you. Modify to suit your needs...
Private Sub Command1_Click()
DoCmd.SetWarnings False
Dim InputFile As String
Dim InputPath As String
InputPath = "C:\your_path_here\"
InputFile = Dir(InputPath & "*.xls")
Do While InputFile <> ""
DoCmd.TransferSpreadsheet acImport, , InputFile, InputPath & InputFile, True '< The true is for column headers
InputFile = Dir
Loop
End Sub
I would extract the content of excel document. It's possible with devexpress 13.2? Does anybody have any suggestion?
Thanks a lot in advance
Take a look at the DevExpress Spreadsheet Document Server (non-visual component with complete spreadsheet functionality available via its API). It allows developers to create, modify, save and print Excel documents, even when Microsoft Excel or Microsoft Office is not installed on the system. Supported File Formats - XLS, XLSX, XLSM, CSV and TXT;
Example: How to: Load a Document to a Workbook
I have done an import of an excel-file to update a SQL server table in the last days (with the DevExpress Grid only to show the imported data).
I my example, I:
ask the user for the filename (not necessary if you already know the
file name and path)
load the excel-file in a datatable (no devexpress needed for that)
show the datatable in a DevExpress Grid then
Note: in real live, I use the grid only to view/control the loaded data.
I then update an existing datatable on a SQL server from the loaded data in the datatable (code not included here).
Note: In the example, the sheet name always is "Sheet1" - maybe you want to make the sheet name also variable for your scenario...
Note: You don't need DevExpress, if you only want to import an Excel file into a DataTable (see ImportTable = ReadExcelIntoDataTable(cFileName, "Sheet1") and function ReadExcelIntoDataTable()) in code below.
' Chose the Excel-File over Open FileDialog()
' If you don't know the filename & path allready
Dim cFileName As String = ""
Dim filedialog As OpenFileDialog = New OpenFileDialog()
filedialog.Title = "Chose the File"
filedialog.DefaultExt = ".XLSX"
filedialog.ShowDialog()
cFileName = filedialog.FileName
'
If Not cFileName = "" Then
ImportTable = ReadExcelIntoDataTable(cFileName, "Sheet1")
If ImportTable.Rows.Count > 0 Then
Grid_Datenimport.DataSource = ImportTable
' Do some format (if you like)..
GridView2.Columns("ColumnX").DisplayFormat.FormatType = DevExpress.Utils.FormatType.DateTime
GridView2.Columns("ColumnX").DisplayFormat.FormatString = "dd/MM/yyyy HH:mm:ss"
GridView2.Columns("ColumnX").Width = 160
End If
End If
Public Shared Function ReadExcelIntoDataTable(ByVal FileName As String, ByVal SheetName As String) As DataTable
Dim RetVal As New DataTable
Dim strConnString As String
strConnString = "Driver={Microsoft Excel Driver (*.xls, *.xlsx, *.xlsm, *.xlsb)};DBQ=" & FileName & ";"
Dim strSQL As String
strSQL = "SELECT * FROM [" & SheetName & "$]"
Dim y As New Odbc.OdbcDataAdapter(strSQL, strConnString)
y.Fill(RetVal)
Return RetVal
End Function
We have been using VBA code for years with Excel 2003. I have about 70 files that I pull information from and compile it into one spreadsheet. This time, it only recognizes 3 of the 70. I do not get any errors. I noticed that all 3 recognized are the old version ".xls." and all not being recognized are the ".xlsx". The portion of the code that I think is causing the problem is below. Can anyone help?
Public currApp As String
Public i As String
Public recordC As String
Public excelI As Integer
Public intFileHandle As Integer
Public strRETP As String
Public errFile As String
Public Function loopFiles(ByVal sFolder As String, ByVal noI As Integer)
'This function will loop through all files in the selected folder
'to make sure that they are all of excel type
Dim FOLDER, files, file, FSO As Object
excelI = noI
'MsgBox excelI
i = 0
'Dim writeFile As Object
'writeFile = My.Computer.FileSystem.WriteAllText("D:\Test\test.txt", "sdgdfgds", False)
Dim cnn As Connection
Set cnn = New ADODB.Connection
currApp = ActiveWorkbook.path
errFile = currApp & "\errorFile.txt"
If emptyFile.FileExists(errFile) Then
Kill errFile
Else
'Do Nothing
End If
'cnn.Open "DSN=AUTOLIV"
'cnn.Open "D:\Work\Projects\Autoliv\Tax workshop\Tax Schedules\sox_questionnaire.mdb"
cnn.Open ("DRIVER={Microsoft Access Driver (*.mdb)}; DBQ=" & currApp & "\tax_questionnaire.mdb")
With Application
.Calculation = xlCalculationManual
.ScreenUpdating = False
End With
Set FSO = CreateObject("Scripting.FileSystemObject")
'Upon each found excel file it will make a call to saveFiles.
If sFolder <> "" Then
Set FOLDER = FSO.getfolder(sFolder)
Set files = FOLDER.files
For Each file In files
'ONLY WORK WITH EXCEL FILES
If file.Type = "Microsoft Excel Worksheet" Then
Workbooks.Open fileName:=file.path
xlsx is a "macro-free" workbook. To use VBA in the new file format, the file must be saved as an xlsm file.
EDIT: I read the question too hastily. If you want to identify excel files from the FSO object, use file.Type LIKE "Microsoft Excel *" or similar. Or, check the file's extension against ".xls*"
EDIT
The whole concept of identifying the file type by looking at the file name is fundamentally flawed. It's too easily broken by changes to file extensions and/or the "type" texts associated with those descriptions. It's easily broken by, say, an image file named "file.xls". I would just try opening the file with Workbooks.Open and catch the error. I'd probably put this logic in a separate function:
Function OpenWorkbook(strPath As String) As Workbook
On Error GoTo ErrorLabel
Set OpenWorkbook = Workbooks.Open(strPath)
ExitLabel:
Exit Function
ErrorLabel:
If Err.Number = 1004 Then
Resume ExitLabel
Else
'other error handling code here
Resume ExitLabel
End If
End Function
Then you can consume the function like this:
Dim w As Workbook
Set w = OpenWorkbook(file.Path)
If Not (w Is Nothing) Then
'...
The problem you're having has to do with this line:
If file.Type = "Microsoft Excel Worksheet" Then
Try adding and replacing it with this:
// add these lines just AFTER the line 'For Each file In files'
IsXLFile = False
FilePath = file.path
FilePath2 = Right(FilePath, 5)
FilePath3 = Mid(FilePath2, InStr(1, FilePath2, ".") + 1)
If UCase(Left(FilePath3, 2)) = "XL" Then IsXLFile = True
// replace faulty line with this line
If IsXLFile = True Then
Let me know how it works. Yes, it'd be possible to compress the statements that start with FilePath into one expression but I left it like that for clarity. Vote and accept the answer if good and follow-up if not.
Have a nice day.