Excel Imports way more rows than expected - excel

with my code below I'm importing an excel file that contains 5 worksheets, but I'm only wanting data from 3 of them. I'm getting about 7 times as many rows as expected. How do I ensure I only get populated rows from each sheet? no dupes.
Dim strConnection As String = ConfigurationManager.ConnectionStrings("conn").ToString
Dim excelConnString As String = String.Format("Provider=Microsoft.ACE.OLEDB.12.0; Data Source=" & Server.MapPath(excelFile) & "; Extended Properties=""Excel 12.0 Xml; HDR=Yes""")
Dim conn As OleDbConnection = New OleDbConnection(excelConnString)
Dim cmd As OleDbCommand = New OleDbCommand()
cmd.Connection = conn
Dim da As OleDbDataAdapter = New OleDbDataAdapter(cmd)
Dim dt As DataTable = New DataTable()
conn.Open()
Dim dtSheet As DataTable = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, Nothing)
For Each sheet As System.Data.DataRow In dtSheet.Rows
Dim sheetName As String = sheet("table_name").ToString()
If sheetName = "UT$" Or sheetName = "XRAY$" Or sheetName = "FLANGE$" Then
cmd.CommandText = "select * from [" & sheetName & "] WHERE [Drawing] Is Not NULL"
da.SelectCommand = cmd
da.Fill(dt)
Dim myImportFinding As New ImportFinding
For i As Integer = 0 To dt.Rows.Count - 1
If dt.Rows(i)("Platform") Is Nothing OrElse IsDBNull(dt.Rows(i)("Platform")) Then
myImportFinding.PLATFORM = ""
Else
myImportFinding.PLATFORM = dt.Rows(i)("Platform")
End If

Yes, there was a whole lot of code missing, but the important parts are there. I decided to refactor and have it working now. Each time I looped through it inserted all the rows from the three worksheets. I decided to move the actual import out into a new method and started off with a fresh data table, command and data adapter for each workbook. Seems to work fine now.

Related

how to read excel column names with special characters with visual studio and oracle

Good night friends,
I am uploading an excel to oracle and I found that some columns of the excel have special characters in the name of the column, these are:
"FECHA/CONV" AND "N°CODIGO"
If I remove the special characters it works fine, but I can't edit the excel file, I just have to read it,
how can I do so that visual does not generate an error in the mappeo and in the select to the excel sheet.
I will appreciate any help.
The exact error I have is:
no values ​​have been set for some of the set parameters.
Thanks,
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim _connString As String = "Data Source=(DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = 10.10.100.1)(PORT = 1521)))(CONNECT_DATA =(SERVICE_NAME = ORACLE))); User Id=USER; password=PASS;"
Dim rutacarpeta As String
Dim NombreArchivo As String
Dim tablaBBDD As String
'Dim ot As OracleTransaction = conn.BeginTransaction(IsolationLevel.ReadCommitted)
Using conn As OracleConnection = New OracleConnection(_connString)
conn.Open()
Dim ot As OracleTransaction = conn.BeginTransaction(IsolationLevel.ReadCommitted)
Try
rutacarpeta = "C:\2021\"
NombreArchivo = "FILE_0.xlsx"
tablaBBDD = "FILE_TEST"
Dim xlsxConn As String = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties='Excel 12.0 Xml;HDR=Yes;IMEX=1;';"
xlsxConn = String.Format(xlsxConn, rutacarpeta + NombreArchivo).Trim()
Using excel_con As OleDbConnection = New OleDbConnection(xlsxConn)
excel_con.Open()
'Dim hoja As String = excel_con.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, Nothing).Rows(0)()
Dim command As OleDbCommand = New OleDbCommand("SELECT FECHA/CONV,CODIGO,ACUERDO FROM [FILE$]", excel_con)
Dim dr As OleDbDataReader
dr = command.ExecuteReader()
Using bulkCopy As OracleBulkCopy = New OracleBulkCopy(conn)
bulkCopy.BulkCopyTimeout = 90000
bulkCopy.DestinationTableName = tablaBBDD
bulkCopy.ColumnMappings.Add(New OracleBulkCopyColumnMapping("FECHA/CONV", "FECHA"))
bulkCopy.ColumnMappings.Add(New OracleBulkCopyColumnMapping("N°CODIGO", "CODIGO"))
bulkCopy.ColumnMappings.Add(New OracleBulkCopyColumnMapping("ACUERDO", "ACUERDO"))
bulkCopy.WriteToServer(dr)
ot.Commit()
bulkCopy.Close()
End Using
End Using
Catch ex As Exception
Try
ot.Rollback()
Catch ex1 As Exception
MessageBox.Show(ex1.Message)
End Try
MessageBox.Show(ex.Message)
End Try
End Using
End Sub
You'll probably kick yourself when I point out that you've quoted the table name, because it contains a special character, and that works.. you've just forgotten to quote the column names
SELECT [FECHA/CONV],[CODIGO],[ACUERDO] FROM [FILE$]
They don't all need quoting but it won't hurt. Also if you get any errors on the oracle side when you set up your bulk copy column mapping, perhaps consider aliasing the excel names to something simpler, and using that
SELECT [FECHA/CONV] as A,CODIGO,ACUERDO FROM [FILE$]
...
...Add(New OracleBulkCopyColumnMapping("A", "FECHA"))

Reading from Excel getting prompts instead of string on occasion

The issue i am having right now is that the first row of the data i get from the excel documents sometimes come back as prompts instead of their proper data types(only some of the cells). i have tried remaking the spreadsheets and redoing all the formatting on the excel side so i'm left to assume its something to do with the oledb class? Any information or a push in the right direction would be greatly appreciated.
Imports Microsoft.Office.Interop
Public Class Form1
Dim ExTable1 As New DataTable
Dim ExTable2 As New DataTable
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
OpenFileDialog1.ShowDialog()
ExTable1 = ConnectToFile(OpenFileDialog1.FileName)
Table1.DataSource = ExTable1
End Sub
Function ConnectToFile(path)
Dim dt As DataTable = New DataTable
Dim selStr As String = "SELECT * FROM [{0}]"
Dim dtSchema
Dim drSchema
Dim con As OleDb.OleDbConnection = New OleDb.OleDbConnection
con.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & path & ";Extended Properties=Excel 12.0 Xml;"
con.Open()
dtSchema = con.GetOleDbSchemaTable(OleDb.OleDbSchemaGuid.Tables, New Object() {Nothing, Nothing, Nothing, "TABLE"})
drSchema = dtSchema.Rows(0)
Dim Sheet1 = drSchema("TABLE_NAME")
Dim cmd As OleDb.OleDbCommand = New OleDb.OleDbCommand(String.Format(selStr, Sheet1))
cmd.Connection = con
Dim da As OleDb.OleDbDataAdapter = New OleDb.OleDbDataAdapter
da.SelectCommand = cmd
da.Fill(dt)
Table1.DataSource = dt
con.Close()
con.Dispose()
Return dt
End Function
End Class

Why is my code is getting second row as header instead of first row

My code is getting second row records treating them as header while i want it to get first row records as hearder (code is skiping first row)
Note: am looping through columns
I have written my code to loop through an excel sheet to get headers of the sheet.It works fine but instead of getting the first row records,it skips and get the second row records
Note: am looping through columns
Dim path As String = txtPath.Text
Dim excel_connection As OleDbConnection
Dim dt As DataTable
Dim cmd As OleDbDataAdapter
'Dim sql As String
'Dim result As Boolean
Dim emp_type_id As String = ""
Dim branch_id As String = ""
Dim bank_id As String = ""
excel_connection = New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + path + ";Extended Properties=Excel 12.0 Xml;")
cmd = New OleDbDataAdapter("SELECT * FROM [sheet$]", excel_connection)
dt = New DataTable
cmd.Fill(dt)
For Each column As DataColumn In dt.Columns
Dim columnName As String = dt.Rows(0)(column.ColumnName).ToString()
If columnName = "" Then
Else
MsgBox(columnName)
End If
Next
I want it to loop through the first row
Note: am looping through columns
Try adding HDR=No into OleDbConnection Extended Properties. Like below:
excel_connection = New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + path + ";Extended Properties='Excel 12.0 Xml;HDR=No;IMEX=1;';")

Importing excel into datagridview WITH verification

Currently, I am able to import an excel file into my datagridview with a button. I have tried many different codes found online to import and finally found one that works, with minor touches. The biggest issue I am having is 'reading' the contents of the cells within the excel file and if there is a certain verification step that is something that I do not want, the program does not import the file.
for example, in column 1, if there is a number less than 0, the import should cancel.
or another example, if a column (that is only supposed to be numbers), has an entry of a letter, import should be cancelled.
In other languages, I can picture this to be simple If statements, but I am new to VB.
if someone could lead me in the right direction, that would be much appreciated
Main page that I used was;
Importing Excel Data in Datagridview using VB.Net
my current code;
Dim dbconnect As OleDb.OleDbConnection
Dim dta As OleDb.OleDbDataAdapter
Dim dts As DataSet
Dim excel As String
Dim OpenFileDialog As New OpenFileDialog
OpenFileDialog.InitialDirectory = My.Computer.FileSystem.SpecialDirectories.MyDocuments
OpenFileDialog.Filter = "All Files (*.*)|*.*|Excel files (*.xlsx)|*.xlsx|CSV Files (*.csv)|*.csv|XLS Files (*.xls)|*xls"
If (OpenFileDialog.ShowDialog(Me) = System.Windows.Forms.DialogResult.OK) Then
Dim file As New FileInfo(OpenFileDialog.FileName)
Dim FileName As String = OpenFileDialog.FileName
' Dim selectedrowcount As Integer = DataGridView1.Rows.GetRowCount(DataGridViewElementStates.Selected)
excel = file.FullName
dbconnect = New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + excel + ";Extended Properties='Excel 12.0;HDR=NO;IMEX=1'")
dta = New OleDbDataAdapter("select * from [Feuil1$]", dbconnect)
' dta = New OleDbDataAdapter("select * from [Sheet1$]", dbconnect)
dts = New DataSet
dta.Fill(dts, "[Feuil1$]")
' dta.Fill(dts, "[Sheet1$]")
DataGridView1.DataSource = dts
DataGridView1.DataMember = "[Feuil1$]"
dbconnect.Close()
DataGridView1.DefaultCellStyle.Format = "N2"
DataGridView1.ColumnHeadersDefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter
' MsgBox("Data has been imported")
End If
End Sub
Here's a basic example from my comment. Note that the close command was moved up.
In this case, the data is only bound to the grid if the data appears the way you want it to.
' Fill Data Set and Close Connection (I Moved the Close)
dts = New DataSet
dta.Fill(dts, "[Feuil1$]")
dbconnect.Close()
' Loop Through the Data And Make Sure Its Good
Dim dataSuccess as Boolean = True
Dim rowIndex as Integer = 0
For Each row as DataRow in dts.Tables(0).Rows
If Convert.ToInt32(row(0)) < 0 Then
System.Windows.Forms.MessageBox.Show("Invalid Data in Row: " + rowIndex + " - 1st Column is Less Than Zero", "Data Import")
dataSuccess = False
Exit For
End If
rowIndex = rowIndex + 1
Next
' If Its Good, Bind It
If dataSuccess Then
DataGridView1.DataSource = dts
DataGridView1.DataMember = "[Feuil1$]"
End If

VB6 insert data into excel from database

I have been looking for a solution to inserting data into excel using vb6 code and access database. There are many cases where I need to write to an excel spreadsheet multiple times with different records of data. I have an existing workbook that I am trying to open and "save as" when I am complete. I have been able to open the excel workbook, access the sheet I am writing to, and the cells I am writing to, however I can only write to the workbook once and when I leave the scope of the open workbook the connection is closed.
I have a sub routine that creates the workbook object, opens the existing workbook and work sheet, writes to a specified cell number to insert the new data. I have looked at official support pages and it doesn't seem to have what I am looking for at this time.
Am I making this too complicated or is there a solution for this? Please help.
My current code:
Row Arrays
Private oldDataRowArray(3 To 21) As Integer
Private updatedDataRowArray(5 To 2) As Integer
Loop logic
Dim i As Integer
Dim n As Integer
i = 3
n = 5
Do While i <= UBound(oldDataRowArray) And n <= UBound(updatedDataRowArray)
EditExcelSheet txtWorkbookFileName.Text, i, n //sub routine
i = i + 3 //skip number of cells
n = n + 3 //skip number of cells
Loop
Sub Routine to Insert data into Excel
Private Sub EditStakingSheet(ByVal workbook As String, ByVal oldDataRowIndex As Integer, ByVal newDataRowIndex As Integer)
Dim objExcel As Object
Dim objWorkBook As Object
Dim objSheet As Object
Set objExcel = New Excel.Application
Set objWorkBook = objExcel.Workbooks.Open(workbook)
Set objSheet = objWorkBook.Worksheets(1)
objExcel.Visible = True
//insert old value
objSheet.Cells(oldDataRowIndex , 26).Value = "old Value"
//insert new value
objSheet.Cells(newDataRowIndex , 26).Value = "new Value"
End Sub
You could use adodb objects.
This video is a good tutorial for this.
Here is an example how you can use adodb. You need to install the activeX Data Objects Libary for this.
For .source= you can use any sql-query.
Public Function get_Value(table As String, order_by As String) As Variant
Set db_data = New ADODB.Recordset
Set db1 = New ADODB.Connection
pDB_path = "#enter db-path here"
db1.ConnectionString = _
"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & pDB_path & ";Persist Security Info=False;"
db1.Open
With db_data
.ActiveConnection = db1
.Source = "SELECT * FROM " & table & " ORDER BY " & order_by & " ASC"
.LockType = adLockReadOnly 'read only access to db
.CursorType = adOpenStatic 'how to update the database
.Open
End With
get_Value = TransposeArray(db_data.GetRows)
db_data.Close
End Function

Resources