使用 VB.NET 表单从 SQL Server 到 Excel 的日期数据检索

Posted

技术标签:

【中文标题】使用 VB.NET 表单从 SQL Server 到 Excel 的日期数据检索【英文标题】:Date wise data retrieval from SQL Server to Excel using VB.NET form 【发布时间】:2021-01-31 13:51:58 【问题描述】:

我想创建一个报告软件,在其中通过用户表单中的 datepicker 工具在用户指定的日期检索日期。我想知道如何实现代码以获得结果。

这是我的代码...请帮助我。我是新手

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=ROG\SQLEXPRESS;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:\GKEAPL\project 1\gk 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

【问题讨论】:

有什么问题?你收到错误了吗?在哪里和什么?如果它根本没有按预期执行,请说明原因。 连接必须被关闭和释放,所以它们只能在使用它们的方法中创建。 不要写空的 Catch 块。他们只会吞下错误。 您永远不会使用 DataAdapter 和 DataSet 提供的额外功能。只需使用命令和数据表。 @Mary 实际上,我不知道如何实现日期时间选择器。当我将日期直接放在查询中时,我确实得到了输出,但是在放置变量而不是日期时,我没有在 excel 上得到输出 【参考方案1】:

不要在Form.Load 中打开连接。人脉是宝贵的资源。将它们保留在使用它们的方法的本地。在.Execute... 行之前打开并尽快关闭。

如果您查看 MS 文档 https://docs.microsoft.com/en-us/dotnet/api/system.data.sqlclient.sqlconnection?view=dotnet-plat-ext-3.1 中的 SQLConnection 类,您将看到 .Dispose 方法。当您看到它时,这意味着应该调用它来释放该类使用的非托管资源。幸运的是,vb.net 提供了Using...End Using 块来为我们处理这个问题。

我将您的数据访问代码移到了单独的函数中。一个方法应该尽可能只做一件事。

在您的 sql 字符串 WHERE 子句中,我将您的文字更改为参数并使用了 BETWEEN。

我认为您的 Excel 代码也有问题,但您的问题是关于数据访问的。简而言之,不要将工作簿作为对象进行调暗,Range 不是Excel.Application 的成员,并且现在并始终打开 Option 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=ROG\SQLEXPRESS;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:\GKEAPL\project 1\gk 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

【讨论】:

感谢您的宝贵回复。 excel部分运行良好。如果您发布整个代码以及您建议的更改,这将非常有用和友善,因为我是初学者,并且在进行您建议的更改时我面临很多问题。期待积极的答复。提前致谢 @AnkithKarthik 我已更改您的按钮代码以包含 GetTankData 方法。我没有更改 Excel 代码,但它看起来不合适。

以上是关于使用 VB.NET 表单从 SQL Server 到 Excel 的日期数据检索的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server查询参数用于将数据表复制到另一个表单ListView VB.net

从 vb.net 中的 datetime sql server 类型操作日期和时间

从 Sql Server 检索照片到 asp.net 和 Vb.net

从 VB.NET 中的 SQL Server 中提取值

VB.NET SQL Server 插入 - ExecuteNonQuery:连接属性尚未初始化

用于 SQL Server 和 VB.NET 应用程序的 MultipleActiveResultSets