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

时间:2015-06-05 16:50:26

标签: vb.net excel datatable type-conversion dataview

我有一个像这样构建的DataTable:

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:输入字符串的格式不正确。"我运行应用程序时出错。它似乎不喜欢这些界限:

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)

2 个答案:

答案 0 :(得分:0)

我想你想要搜索你的MyTable,如果它包含一个带有uid的记录和dt表中每一行的pid。

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

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

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

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

答案 1 :(得分:0)

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

后面有两行代码,我已经完成了。