#c# #sql-server #excel #vb.net #export-to-excel
#c# #sql-сервер #excel #vb.net #экспорт в Excel
Вопрос:
Я хочу создать программное обеспечение для создания отчетов, в котором дата извлекается на дату, указанную пользователем, с помощью инструмента выбора даты в форме пользователя. Я хочу знать, как реализовать код, чтобы получить результат.
Это мой код… Пожалуйста, помогите мне. Я новичок в этом
Imports System.Data
Imports System.Data.SqlClient
Public Class Form1
Private conn As New SqlConnection
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Try
conn.ConnectionString = "Data Source=ROGSQLEXPRESS;Initial Catalog=GKEAPL;Integrated Security=True;"
conn.Open()
MsgBox("Connected")
Catch ex As Exception
MsgBox("Could Not connect")
End Try
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Try
Dim officeexcel As New Microsoft.Office.Interop.Excel.Application
officeexcel = CreateObject("Excel.Application")
Dim workbook As Object = officeexcel.Workbooks.Add("D:GKEAPLproject 1gk format.xltx")
officeexcel.Visible = True
Dim da As New SqlDataAdapter
Dim ds As New DataSet
da = New SqlDataAdapter("SELECT FeedWaterTankLevelFWST101,
FeedFlowFT101,
ClearWaterTankLevelCWST201,
TMFilPressurePT201,
TMFolPressurePT202,
HPPilPressurePT203,
MembraneilPressurePT204,
MembraneolPressurePT205,
PermeateFlowFT201,
RejectFlowFT202
FROM DATA1 WHERE(DATEnTIME >='2020-12-18 11:06:30.000' AND DATEnTIME <= '2020-12-19 10:07:31.000')", conn)
da.Fill(ds, "DATA1")
For i As Integer = 0 To ds.Tables("DATA1").Rows.Count - 1
With officeexcel
.Range("Sheet2!B" (i 7).ToString).Value = ds.Tables("DATA1").Rows(i).Item(0).ToString
.Range("Sheet2!C" (i 7).ToString).Value = ds.Tables("DATA1").Rows(i).Item(1).ToString
.Range("Sheet2!D" (i 7).ToString).Value = ds.Tables("DATA1").Rows(i).Item(2).ToString
.Range("Sheet2!E" (i 7).ToString).Value = ds.Tables("DATA1").Rows(i).Item(3).ToString
.Range("Sheet1!F" (i 7).ToString).Value = ds.Tables("DATA1").Rows(i).Item(4).ToString
.Range("Sheet1!G" (i 7).ToString).Value = ds.Tables("DATA1").Rows(i).Item(5).ToString
.Range("Sheet1!H" (i 7).ToString).Value = ds.Tables("DATA1").Rows(i).Item(6).ToString
.Range("Sheet1!I" (i 7).ToString).Value = ds.Tables("DATA1").Rows(i).Item(7).ToString
.Range("Sheet1!J" (i 7).ToString).Value = ds.Tables("DATA1").Rows(i).Item(8).ToString
.Range("Sheet1!K" (i 7).ToString).Value = ds.Tables("DATA1").Rows(i).Item(9).ToString
End With
Next
officeexcel = Nothing
workbook = Nothing
Catch ex As Exception
End Try
End Sub
Private Sub Report_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
DateTimePicker1.CustomFormat = "YYYY-MMMM-DD"
End Sub
End Class
Комментарии:
1. В чем проблема? Вы получили сообщение об ошибке? Где и что? Если это просто не сработало должным образом, объясните, как.
2. Соединения должны быть закрыты и удалены, поэтому их следует создавать только в тех методах, в которых они используются.
3. Не записывайте пустые блоки Catch. Они только проглатывают ошибки.
4. Вы никогда не используете дополнительные функции, предоставляемые адаптером данных и набором данных. Просто используйте команду и DataTable.
5. @Mary на самом деле, я не знаю, как реализовать средство выбора даты и времени. Я получал выходные данные, когда вводил дату непосредственно в запрос, но при вводе переменной вместо даты я не получаю выходные данные в Excel
Ответ №1:
Не открывайте соединение в Form.Load
. Соединения — это ценные ресурсы. Сохраняйте их локальными для метода, в котором они используются. Откройте непосредственно перед .Execute...
строкой и закройте как можно скорее.
Если вы посмотрите на SQLConnection
класс в MS docs https://learn.microsoft.com/en-us/dotnet/api/system.data.sqlclient.sqlconnection?view=dotnet-plat-ext-3.1 вы увидите .Dispose
метод. Когда вы видите это, это означает, что он должен быть вызван для освобождения неуправляемых ресурсов, используемых классом. К счастью, vb.net предоставляет Using...End Using
блоки для обработки этого для нас.
Я перенес ваш код доступа к данным в отдельную функцию. Насколько это возможно, метод должен выполнять только одно.
В вашем предложении sql string WHERE я изменил ваши литералы на параметры и использовал BETWEEN.
Я думаю, что у вас тоже есть проблемы с кодом Excel, но ваш вопрос касался доступа к данным. Вкратце, не отключайте рабочую книгу как объект, диапазон не является членом Excel.Application
и включите параметр Strict сейчас и всегда.
Private Function GetTankData() As DataTable
Dim dt As New DataTable
Dim strSql = "SELECT FeedWaterTankLevelFWST101,
FeedFlowFT101,
ClearWaterTankLevelCWST201,
TMFilPressurePT201,
TMFolPressurePT202,
HPPilPressurePT203,
MembraneilPressurePT204,
MembraneolPressurePT205,
PermeateFlowFT201,
RejectFlowFT202
FROM DATA1 WHERE DATEnTIME BETWEEN @StartDate AND @EndDate"
Using conn As New SqlConnection("Data Source=ROGSQLEXPRESS;Initial Catalog=GKEAPL;Integrated Security=True;"),
cmd As New SqlCommand(strSql, conn)
cmd.Parameters.Add("@StartDate", SqlDbType.DateTime).Value = DateTimePicker1.Value
cmd.Parameters.Add("@EndDate", SqlDbType.DateTime).Value = DateTimePicker2.Value
conn.Open()
dt.Load(cmd.ExecuteReader)
End Using 'Closes and disposes the connection and command
Return dt
End Function
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim officeexcel As New Microsoft.Office.Interop.Excel.Application
officeexcel = CreateObject("Excel.Application")
Dim workbook As Object = officeexcel.Workbooks.Add("D:GKEAPLproject 1gk format.xltx")
Try
officeexcel.Visible = True
Dim dt = GetTankData()
For i As Integer = 0 To dt.Rows.Count - 1
With officeexcel
.Range("Sheet2!B" (i 7).ToString).Value = dt.Rows(i).Item(0).ToString
.Range("Sheet2!C" (i 7).ToString).Value = dt.Rows(i).Item(1).ToString
.Range("Sheet2!D" (i 7).ToString).Value = dt.Rows(i).Item(2).ToString
.Range("Sheet2!E" (i 7).ToString).Value = dt.Rows(i).Item(3).ToString
.Range("Sheet1!F" (i 7).ToString).Value = dt.Rows(i).Item(4).ToString
.Range("Sheet1!G" (i 7).ToString).Value = dt.Rows(i).Item(5).ToString
.Range("Sheet1!H" (i 7).ToString).Value = dt.Rows(i).Item(6).ToString
.Range("Sheet1!I" (i 7).ToString).Value = dt.Rows(i).Item(7).ToString
.Range("Sheet1!J" (i 7).ToString).Value = dt.Rows(i).Item(8).ToString
.Range("Sheet1!K" (i 7).ToString).Value = dt.Rows(i).Item(9).ToString
End With
Next
Finally
officeexcel = Nothing
workbook = Nothing
End Try
End Sub
Комментарии:
1. спасибо за ваш ценный ответ. часть Excel работает нормально. с вашей стороны будет очень полезно и любезно, если вы опубликуете весь код с предложенными вами изменениями, поскольку я новичок, и я сталкиваюсь с множеством проблем при внесении предложенных вами изменений. с нетерпением жду положительного ответа. Заранее спасибо
2. @AnkithKarthik Я изменил код вашей кнопки, чтобы включить метод GetTankData. Я не менял код Excel, но мне это кажется неправильным.