Храните объекты базы данных локально, чтобы вы могли быть уверены, что они закрыты и удалены.Включение этих объектов с помощью `Using ... End Использование блоков выполнит это даже в случае ошибки.Вам не нужны переменные для DataAdapters, DataSets или DataReaders.Я предлагаю только одну переменную уровня формы для строки подключения Excel, поскольку она используется в 2 методах.
Немного Linq получит имена извлеченных листов из DataTable
и заполнит массив.Затем массив можно передать в поле со списком .AddRange
.
. Я бы не использовал событие SelectedIndexChanged
, поскольку пользователь может слишком легко щелкнуть по неправильному листу или передумать.Я использовал событие Button.Click, чтобы заполнить сетку.
Строка подключения Sql выглядит странно для меня.Я предлагаю вам проверить это отдельно.Если это не работает, это хороший ресурс.https://www.connectionstrings.com/
Я бы специально указал имена столбцов в операторе Insert.Замените FirstColumnName
и SecondColumnName
реальными именами столбцов.Имена параметров могут быть любыми, если имена в операторе совпадают с именами в методе Parameters.Add
.Я догадался о типах данных и размере.Проверьте правильность значений в вашей базе данных.
Мы добавляем параметры только один раз за пределы цикла, затем меняем только значения внутри цикла.
Private ExcelConString As String
Private Sub BtnImpExcelFile_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BtnImpExcelFile.Click
Dim strFileName As String
Dim dtSheets As DataTable
OpenFileDialog1.Filter = "(* .xls) | * .xls | (*. Xlsx) | *. xlsx | All files (*. *) | *. * "
OpenFileDialog1.ShowDialog()
strFileName = OpenFileDialog1.FileName
ExcelConString = "provider = Microsoft.ace.OLEDB.12.0; data source =" & strFileName & "; Extended Properties = Excel 8.0;"
Using connexcel = New OleDbConnection(ExcelConString)
connexcel.Open()
dtSheets = connexcel.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, Nothing)
End Using
Dim exSheets() As Object = (From dRow In dtSheets.AsEnumerable() Select dRow("TABLE_Name")).ToArray
ExcelSheetList.Items.AddRange(exSheets)
End Sub
Private Sub DisplayData_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles DisplayData.Click
Dim dt As New DataTable
Using cn As New OleDbConnection(ExcelConString)
'In older versions of Visual Studio you may have to use String.Format instead of the interpolated string.
Using cmd As New OleDbCommand($"select * from [{ExcelSheetList.Text}];", cn)
cn.Open()
dt.Load(cmd.ExecuteReader)
End Using
End Using
DGVImpData.DataSource = dt
DGVImpData.ReadOnly = True
End Sub
Private Sub BtnSaveImpData_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BtnSaveImpData.Click
Using cn As New SqlConnection("data source =. \ MSSMLBIZ; initial catalog = MyInvoice; integrated security = true")
Using cmd As New SqlCommand("Insert Into InvoiceData (FirstColumnName, SecondColumnName) Values (@FirstColumn, @SecondColumn);", cn)
cmd.Parameters.Add("@FirstColumn", SqlDbType.VarChar, 100)
cmd.Parameters.Add("@SecondColumn", SqlDbType.VarChar, 100)
cn.Open()
For line As Integer = 0 To DGVImpData.RowCount - 2
cmd.Parameters("@FirstColumn").Value = DGVImpData.Rows(line).Cells(0).Value
cmd.Parameters("@SecondColumn").Value = DGVImpData.Rows(line).Cells(1).Value
cmd.ExecuteNonQuery()
Next
End Using
End Using
MsgBox("data saved successfully")
DGVImpData.Columns.Clear()
End Sub
Что касается обработки ошибок ... On Error Resume Next
isкак правило, не используется в новом коде.У нас есть Try...Catch...Finally
блоков.После запуска кода добавьте эти блоки там, где это необходимо.
EDIT
Чтобы использовать String.Format ...
Using cmd As New OleDbCommand(String.Format("select * from [{0}];", ExcelSheetList.Text))
Первый параметрэто строка, в которую вы хотите поместить переменные.Он содержит индексированные заполнители, заключенные в фигурные скобки.Следующие параметры - это переменные, которые вы хотите использовать для замены заполнителя.