在导出到 Excel 文件之前将列添加到 DataTable

Add Column to DataTable before exporting to Excel file

我有一个这样构建的数据表:

Dim dt As New DataTable()
dt = SqlHelper.ExecuteDataset(connString, "storedProcedure", Session("Member"), DBNull.Value, DBNull.Value).Tables(0)

然后转换为DataView并导出到Excel,像这样:

Dim dv As New DataView()
dv = dt.DefaultView
Export.CreateExcelFile(dv, strFileName)

我想在导出到 Excel 之前添加另一列并用数据填充它。这是我现在正在做的添加列的操作:

Dim dc As New DataColumn("New Column", Type.GetType("System.String"))
dc.DefaultValue = "N"
dt.Columns.Add(dc)

然后填充它:

For Each row As DataRow In dt.Rows
    Dim uID As Integer = Convert.ToInt32(dt.Columns(0).ColumnName)
    Dim pID As String = dt.Columns(0).ColumnName
    Dim qry As String = "SELECT * FROM [MyTable] WHERE [UserID] = " & uID & " AND [PassID] = '" & pID & "'"
    Dim myCommand As SqlCommand
    Dim myConn As SqlConnection = New SqlConnection(ConfigurationSettings.AppSettings("connString"))

    myConn.Open()
    myCommand = New SqlCommand(qry, myConn)
    Dim reader As SqlDataReader = myCommand.ExecuteReader()

    If reader.Read() Then
        row.Item("New Column") = "Y"
    Else
        row.Item("New Column") = "N"
    End If
Next row

但是当我 运行 应用程序时出现 "System.FormatException: Input string was not in a correct format." 错误。它似乎不喜欢这些行:

Dim uID As Integer = Convert.ToInt32(dt.Columns(0).ColumnName)
Dim pID As String = dt.Columns(0).ColumnName

我认为这里有不止一个问题,因为即使我注释掉填充数据的循环,我创建的列也不会显示在 Excel 文件中。任何帮助将非常感激。谢谢!


编辑:

好吧,我抓取的是列名而不是列中的实际数据...因为我是个白痴。 导出的 Excel 文件中仍未显示新列。 这是更新后的代码:

    Dim dt As New DataTable()
    dt = SqlHelper.ExecuteDataset(connString, "storedProcedure", Session("Member"), DBNull.Value, DBNull.Value).Tables(0)

    Dim dc As New DataColumn("New Column", Type.GetType("System.String"))
    dc.DefaultValue = "N"
    dt.Columns.Add(dc)

    'set the values of the new column based on info pulled from db
    Dim myCommand As SqlCommand
    Dim myConn As SqlConnection = New SqlConnection(ConfigurationSettings.AppSettings("connString"))
    Dim reader As SqlDataReader

    For Each row As DataRow In dt.Rows
        Dim uID As Integer = Convert.ToInt32(row.Item(0))
        Dim pID As String = row.Item(2).ToString
        Dim qry As String = "SELECT * FROM [MyTable] WHERE [UserID] = " & uID & " AND [PassID] = '" & pID & "'"

        myConn.Open()
        myCommand = New SqlCommand(qry, myConn)
        reader = myCommand.ExecuteReader()

        If reader.Read() Then
            row.Item("New Column") = "Y"
        Else
            row.Item("New Column") = "N"
        End If

        myConn.Close()
    Next row

    dt.AcceptChanges()

    Dim dv As New DataView()
    dv = dt.DefaultView
    Export.CreateExcelFile(dv, strFileName)

我想你想搜索你的 MyTable 如果它包含一个记录,其中包含你的 dt 中存在的每一行的 uid 和 pid table。

如果这是你的意图,那么你可以这样写

Dim qry As String = "SELECT UserID FROM [MyTable] WHERE [UserID] = @uid AND [PassID] = @pid"
Using  myConn = New SqlConnection(ConfigurationSettings.AppSettings("connString"))
Using myCommand = new SqlCommand(qry, myConn)
    myConn.Open()
    myCommand.Parameters.Add("@uid", OleDbType.Integer)
    myCommand.Parameters.Add("@pid", OleDbType.VarWChar)
    For Each row As DataRow In dt.Rows
        Dim uID As Integer = Convert.ToInt32(row(0))
        Dim pID As String = row(1).ToString()
        cmd.Parameters("@uid").Value = uID
        cmd.Parameters("@pid").Value = pID
        Dim result = myCommand.ExecuteScalar()
        If result IsNot Nothing Then
            row.Item("New Column") = "Y"
        Else
            row.Item("New Column") = "N"
        End If
    Next
End Using
End Using

当然,使用新列更改的 DataTable 导出到 Excel 应该在添加列和更新它的代码之后完成

在此代码中,连接的打开和命令的创建是在进入行循环之前完成的。参数化查询保存从您的 ROWS 中提取的新值,而不是从您的列名中提取的新值,而不是更昂贵的 ExecuteReader,只需使用 ExecuteScalar。如果找到记录,ExecuteScalar 只是 returns UserID 而不是完整的 reader.

问题出在我的 CreateExcelFile() 方法中。我继承了我正在修改的应用程序,并假设该方法动态读取 DataTable 中的数据并构建电子表格。实际上,它是在 DataTable 中搜索特定值并忽略其他所有内容。

2行代码后,我完成了。