Excel 到 SQL 表与 VB.net
Posted
技术标签:
【中文标题】Excel 到 SQL 表与 VB.net【英文标题】:Excel to SQL Table with VB.net 【发布时间】:2014-04-17 14:36:55 【问题描述】:我已阅读其他用户关于此主题的所有文章和帖子,但我仍然陷入困境。
基本上我拥有的是一个带有本地 SQL 后端的 VB.net 程序。我创建了一个名为“consolDump”的表,我希望将 Excel 工作表导入其中。我觉得我很接近从其他有类似问题的人那里得到的帮助。澄清一下,我没有能力向我正在使用的机器添加软件(它受到 IT 的严格限制),也无权访问 SQL Server 导入实用程序。
这是我的代码。任何帮助,将不胜感激。
Imports System.Data.SqlClient
Public Class formImport
Private Sub buttonConsolImport_Click(sender As Object, e As EventArgs) Handles buttonConsolImport.Click
Dim MyConnection As System.Data.OleDb.OleDbConnection
Dim DtSet As System.Data.DataSet
Dim MyCommand As System.Data.OleDb.OleDbDataAdapter
Dim fBrowse As New OpenFileDialog
Dim fname As String
Try
With fBrowse
.Filter = "Excel files(*.xls)|*.xls|All files (*.*)|*.*"
.FilterIndex = 1
.Title = "Import data from Excel file"
End With
If fBrowse.ShowDialog() = Windows.Forms.DialogResult.OK Then
fname = fBrowse.FileName
MyConnection = New System.Data.OleDb.OleDbConnection _
("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & fname & ";" & "Extended Properties=""Excel 8.0;HDR=NO;IMEX=1""")
MyCommand = New System.Data.OleDb.OleDbDataAdapter("A1, B1, C1, D1, E1, F1, G1, H1, I1, J1, k1, L1 from [consol_data$]", MyConnection)
MyCommand.TableMappings.Add("Table", "consolDump")
DtSet = New System.Data.DataSet
MyCommand.Fill(DtSet)
For Each Drr As DataRow In DtSet.Tables(0).Rows
Execute_Local("INSERT INTO consolDump(PO_Number, Consol_ID, Status, Contractor, UTAS_Owner, Description, Start_Date, End_Date, Total_Spend, ) VALUES ('" & Drr(0).ToString & "','" & Drr(1).ToString & "','" & Drr(2).ToString & "'),'" & Drr(3).ToString & "','" & Drr(4).ToString & "','" & Drr(5).ToString & "','" & Drr(6).ToString & "','" & Drr(7).ToString & "','" & Drr(8).ToString & "','" & Drr(9).ToString & "','" & Drr(10).ToString & "','" & Drr(11).ToString & "'")
Next
MsgBox("Success")
MyConnection.Close()
End If
Catch ex As Exception
MessageBox.Show(ex.ToString)
End Try
End Sub
好的,为了补充我的问题,我正在尝试使用此代码从 Excel 工作表中导入一个 csv 文件,它工作正常。
'Converts consol data to csv file===========================
Dim excelApplication As New Excel.Application
Dim excelWrkBook As Excel.Workbook
excelApplication.Visible = False
excelApplication.DisplayAlerts = False
excelWrkBook = excelApplication.Workbooks.Open("R:\PECOE-WLOX\QuEST\Torres\sqlProjects\consol_data.xls")
excelWrkBook.SaveAs(Filename:="R:\PECOE-WLOX\QuEST\Torres\sqlProjects\consol_data.csv", FileFormat:=Microsoft.Office.Interop.Excel.XlFileFormat.xlCSV)
excelWrkBook.Close()
excelApplication.DisplayAlerts = True
excelApplication.Quit()
MessageBox.Show("Converted to CSV")
'============================================================
现在我正在尝试将 csv 文件导入新数据表,但我收到一个奇怪的错误,提示“system.data.sql 是一个命名空间,不能用作表达式”。现在这可能是我的经验不足,因为我从另一个站点提取了代码,并且有几个人说他们可以正常工作。我已经修改它以适合我的数据。任何帮助,将不胜感激。该错误在“Dim cmd As New SqlClient.SqlCommand(Sql, connection)”上显示为语法错误。它将括号中的 Sql 突出显示为命名空间。
Dim consolDump1 As New DataTable()
consolDump1.Columns.Add("PO_Number")
consolDump1.Columns.Add("Consol_ID")
consolDump1.Columns.Add("Status")
consolDump1.Columns.Add("Contractor")
consolDump1.Columns.Add("UTAS_Owner")
consolDump1.Columns.Add("Description")
consolDump1.Columns.Add("Start_Date")
consolDump1.Columns.Add("End_Date")
consolDump1.Columns.Add("Total_Spend")
consolDump1.Columns.Add("Job_Title")
consolDump1.Columns.Add("Location")
consolDump1.Columns.Add("Type")
Dim parser As New FileIO.TextFieldParser("R:\PECOE-WLOX\QuEST\Torres\sqlProjects\consol_data.csv")
parser.Delimiters = New String() "," ' fields are separated by comma
parser.HasFieldsEnclosedInQuotes = True ' each of the values is enclosed with double quotes
parser.TrimWhiteSpace = True
parser.ReadLine()
Do Until parser.EndOfData = True
consolDump1.Rows.Add(parser.ReadFields())
Loop
Dim strSql As String = "INSERT INTO consolDump(PO_Number,Consol_ID,Status,Contractor,UTAS_Owner,Description,Start_Date,End_Date,Total_Spend,Job_Title,Location,Type) VALUES (@PO_Number,@Consol_ID,@Status,@Contractor,@UTAS_Owner,@Description,@Start_Date,@End_Date,@Total_Spend,@Job_Title,@Location,@Type)"
Dim SqlconnectionString As String = "Data Source=(LocalDB)\v11.0;AttachDbFilename=|DataDirectory|\consolData.mdf;Integrated Security=True;Connect Timeout=30"
Using connection As New SqlClient.SqlConnection(SqlconnectionString)
Dim cmd As New SqlClient.SqlCommand(Sql, connection)
' create command objects and add parameters
With cmd.Parameters
.Add("@PO_Number", SqlDbType.VarChar, 15, "PO_Number")
.Add("@Consol_ID", SqlDbType.BigInt, "Consol_ID")
.Add("@Status", SqlDbType.Text, "Status")
.Add("@Contractor", SqlDbType.Text, "Contractor")
.Add("@UTAS_Owner", SqlDbType.Text, "UTAS_Owner")
.Add("@Description", SqlDbType.Text, "Description")
.Add("@Start_Date", SqlDbType.Date, "Start_Date")
.Add("@End_Date", SqlDbType.Date, "End_Date")
.Add("@Total_Spend", SqlDbType.Money, "Total_Spend")
.Add("@Job_Title", SqlDbType.Text, "Job_Title")
.Add("@Location", SqlDbType.Text, "Location")
.Add("@Type", SqlDbType.Text, "Type")
End With
Dim adapter As New SqlClient.SqlDataAdapter()
adapter.InsertCommand = cmd
'--Update the original SQL table from the datatable
Dim iRowsInserted As Int32 = adapter.Update(consolDump1)
End Using
End Sub
【问题讨论】:
请澄清您的问题到底是什么。还包括您收到的所有(如果有)错误或其他消息。 我很抱歉。我在写我的原始帖子时被跟踪了。我需要导入一个 Excel 表并将该数据转储到名为 consolDump 的数据表中。 现在我在 For 循环中的“execute_local”上遇到语法错误。 【参考方案1】:在你的 sql 查询的列列表末尾多了一个逗号:
End_Date、Total_Spend、)
你需要这个:
End_Date, Total_Spend)
此外,列列表有 9 个项目,但您的值列表有 12 个。您可能缺少几列吗?
最后,对于本节,个人使用的代码无关紧要,但是您使用字符串连接将 excel 数据放入查询中的做法被认为是不好的做法。如果您在产品代码中这样做,您将创建一个巨大的安全漏洞。相反,请了解参数化查询。
在后面的示例中,您可以这样定义 sql 字符串:
Dim strSql As String
但请尝试以这种方式包含在您的命令中:
Dim cmd As New SqlClient.SqlCommand(Sql, ...
你应该这样做:
Dim cmd As New SqlClient.SqlCommand(strSql, ...
另外,根据其他代码,如果这是一个 access 数据库,您应该仍然使用 System.Data.OleDb
命名空间中的 OleDbCommand
和 OleDbConnection
对象。
我要做的是介于您的第一个样本和第二个样本之间:
Imports System.Data.SqlClient
Private Sub buttonConsolImport_Click(sender As Object, e As EventArgs) Handles buttonConsolImport.Click
Dim fBrowse As New OpenFileDialog
With fBrowse
.Filter = "Excel files(*.xls)|*.xls|All files (*.*)|*.*"
.FilterIndex = 1
.Title = "Import data from Excel file"
End With
If fBrowse.ShowDialog() <> Windows.Forms.DialogResult.OK Then Exit Sub
Dim fname As String = fBrowse.FileName
Dim sql As String = "INSERT INTO consolDump(PO_Number,Consol_ID,[Status],Contractor,UTAS_Owner,Description,Start_Date,End_Date,Total_Spend,Job_Title,Location,Type) VALUES (@PO_Number,@Consol_ID,@Status,@Contractor,@UTAS_Owner,@Description,@Start_Date,@End_Date,@Total_Spend,@Job_Title,@Location,@Type)"
Try
Dim parser As New FileIO.TextFieldParser(fname)
parser.Delimiters = New String() "," ' fields are separated by comma
parser.HasFieldsEnclosedInQuotes = True ' each of the values is enclosed with double quotes
parser.TrimWhiteSpace = True
parser.ReadLine() 'skip column headers
Using cn As New SqlConnection("Data Source=(LocalDB)\v11.0;AttachDbFilename=|DataDirectory|\consolData.mdf;Integrated Security=True"),
cmd As New SqlCommand(sql, cn)
With cmd.Parameters
.Add("@PO_Number", SqlDbType.VarChar, 15)
.Add("@Consol_ID", SqlDbType.BigInt)
.Add("@Status", SqlDbType.Text) 'I doubt that "Text" is the right type for all of these
.Add("@Contractor", SqlDbType.Text) 'If it is, you may want to examine your table schema
.Add("@UTAS_Owner", SqlDbType.Text)
.Add("@Description", SqlDbType.Text)
.Add("@Start_Date", SqlDbType.Date)
.Add("@End_Date", SqlDbType.Date)
.Add("@Total_Spend", SqlDbType.Money)
.Add("@Job_Title", SqlDbType.Text)
.Add("@Location", SqlDbType.Text)
.Add("@Type", SqlDbType.Text)
End With
cn.Open()
Do Until parser.EndOfData = True
Dim fields() As String = parser.ReadFields()
For i As Integer = 0 To 11
cmd.Parameters(i).Value = fields(i)
Next
cmd.ExecuteNonQuery()
Loop
End Using
MsgBox("Success")
Catch ex As Exception
MessageBox.Show(ex.ToString)
End Try
End Sub
【讨论】:
谢谢。第一个包含计算错误的列的代码块和诸如此类的东西不再在项目中。 csv 转换后的所有内容现在都在那里。也就是说,在 cmd 中更改为“Dim cmd As New SqlClient.SqlCommand(strSql, ...”清除了语法错误,因此它现在运行。导入时抛出“未处理的 'System.InvalidCastException' 异常发生在Microsoft.VisualBasic.dll”。它不喜欢“状态”字段。它认为我正在尝试转换为整数。 哦,谢谢。我将花一些时间研究参数化查询以获取我自己的知识。对于这个项目,csv 导入应该足够了。它是一个程序的一部分,该程序将离线并在内部使用在严密保护的网络上,并且无法从外部访问,因此安全不是问题。 @CTTKDKing 我添加了一些代码。它经过了几次修改,所以如果您之前看到过,值得再看一遍。 添加了我在您的代码中遇到的错误的屏幕截图。否则它运行良好,没有错误,非常感谢您的帮助。 @CTTKDKing 你必须调试这个。我在没有测试的情况下直接在回复窗口中输入了我的答案,因为我没有你的测试材料。查看错误,这似乎是基本的调试问题。您应该能够单步调试 Visual Studio 中的代码以查看问题所在。以上是关于Excel 到 SQL 表与 VB.net的主要内容,如果未能解决你的问题,请参考以下文章
使用 vba TransferSpreadsheet 将 Aaccess 表与 Excel 链接
想筛选出excel表格A表与B表内姓名与身份证号码相同的数据,那个啥函数不会用