Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vb.net/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net 序列或批处理项目DataGridView_.net_Vb.net_Datagridview - Fatal编程技术网

.net 序列或批处理项目DataGridView

.net 序列或批处理项目DataGridView,.net,vb.net,datagridview,.net,Vb.net,Datagridview,我有940000行的大DataGridView…哎哟,从分析csv文件填充,DataGridView有一个名为序列号1到940000的列。我试图做的是对序列进行重新编号,以将DataGridView中的行数拆分为1到7000的序列。对序列列重新排序最有效的方法是什么 Using reader As New Microsoft.VisualBasic.FileIO.TextFieldParser(fileName) reader.TextFieldType = FileIO.Fie

我有940000行的大DataGridView…哎哟,从分析csv文件填充,DataGridView有一个名为序列号1到940000的列。我试图做的是对序列进行重新编号,以将DataGridView中的行数拆分为1到7000的序列。对序列列重新排序最有效的方法是什么

Using reader As New Microsoft.VisualBasic.FileIO.TextFieldParser(fileName)
        reader.TextFieldType = FileIO.FieldType.Delimited
        reader.SetDelimiters(",")
        Dim currentRow As String()
        Dim serial As String
        Dim sequence As Integer = 0
        Dim RollId As String

        'pbUploadFile.Maximum = serialAmmount / quantityBreak
        pbUploadFile.Maximum = serialAmmount
        pbUploadFile.Step = 1
        pbUploadFile.Value = 0

        For i = 1 To serialAmmount / quantityBreak
            For j = 1 To quantityBreak
                Try
                    currentRow = reader.ReadFields()
                    serial = currentRow(0).ToString
                    sequence += 1
                    EnterDataIntoDatabase(serial, sequence, nextRollNumber, ddSelectPartNumber.Text)
                    pbUploadFile.Increment(1)
                Catch ex As Microsoft.VisualBasic.FileIO.MalformedLineException
                    MsgBox("Code " & ex.Message & "is not valid and will be skipped check csv file")
                End Try
            Next j

            sqlCmd = New SqlClient.SqlCommand("SELECT * FROM serials WHERE Sequence=@sequence AND RollNo=@rollNo ", sqlCon)
            sqlCmd.CommandType = CommandType.Text
            sqlCmd.Parameters.AddWithValue("@sequence", 1)
            sqlCmd.Parameters.AddWithValue("@rollNo", nextRollNumber)
            sqlCon.Open()
            Dim readRollId As SqlClient.SqlDataReader = sqlCmd.ExecuteReader()
            If readRollId.Read() Then
                RollId = readRollId.Item("Code")
            End If
            sqlCon.Close()


            UpdateAvailableRolls(ddSelectPartNumber.Text, nextRollNumber, RollId)
            nextRollNumber += 1
            UpdateRollNo(nextRollNumber)
            sequence = 0
            'pbUploadFile.Increment(1)
        Next i
        SaveFile()
    End Using

通常最好考虑如何使用数据,以及在决定如何做某事以及使用什么工具来做某事时如何使用数据。没有一种正确、快速、有效的方式来做大多数事情

也就是说,做事情有一些不好的方式。使用
DataGridView
作为数据容器似乎是不明智的(尽管我在代码中看不到任何与DGV相关的内容)。A) 数据没有自动进入的方式-您必须编写代码才能进入,2)数据没有自动进入其他地方的方式-您必须编写代码来循环通过它并将数据提取出来。然后是所有数据都可能存储为字符串的问题

看起来还有更多的事情要做,而不仅仅是分批处理项目。下面将从CSV导入行,处理它们并将它们写回DB(我使用的是MySql,但概念是相同的)


首先,
TextFieldParser
是一个非常方便的工具,但它有一个主要缺点,即它只返回字符串。如果CSV中包含价格、日期、布尔值等,则该类型将丢失。在许多情况下,CSVHelper将是一个更好的选择

在本例中,由于数据是发送给数据库的,因此我将使用OleDB将CSV读入
数据表
,对其进行批处理,然后将其发送到数据库

使用OleDB导入数据 Schema.INI

OleDb包含一个文本文件驱动程序,可用于解析CSV。它可以根据前几行的上下文“猜测”数据类型,但也可以定义它们。在CSV所在的文件夹/目录中,创建一个名为
Schema.INI
的新文本文件。按如下方式定义CSV和列:

[Capitals.Csv]
ColNameHeader=True
Format=CSVDelimited
textdimiter=
小数符号=。
CurrencySymbol=$
Col1=“Country”文本宽度254
Col2=“首都”文本宽度254
Col3=“总体”单个
Col4=“Rank”整数
Col5=“国庆节”日期

  • 在一个文件中可以有多个csv定义,每个定义都以
    […]
  • […]
    将是CSV的名称
  • 如果CSV有标题行,则可以将其用作列名
  • 如果列也用引号括起来(“像这样”、“在”、“csv中”),请使用
    textdimiter=“
  • 每个
    Col#=
    条目定义数据类型并可以覆盖名称。这允许您将CSV中名为“Foo”的列“映射”到DB中名为“Bar”的列
  • 可以指定其他选项,如十进制和货币符号以及文件中使用的代码页
连接字符串

要使用的连接字符串为:

ACEImportStr = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source='{0}';Extended Properties='TEXT'"

<代码>数据源<代码>将是CSV和Schema.INI都存在的文件夹,“text”元素告诉它使用文本驱动程序。使用文件夹名填写空白:

ACEImportConnStr = String.Format(ACEImportConnStr, "C:\Temp")
OLEDB.12有时可能很挑剔,如果您有问题,请使用
Microsoft.Jet.OLEDB.4.0作为提供程序

现在,要加载数据,只需从CSV文件名(无文件夹)中选择:

DataAdapter
将读取定义的模式,并在几秒钟内将CSV加载到数据表中。处理其他任务还有很多工作要做,但这就是概念

Dim sSQL = "SELECT * FROM YOUR_CSVFILE_NAME.CSV"
Dim sw As New Stopwatch

Dim rowsLoaded As Int32
Dim rowsUpdated As Int32

sw.Start()
ACEImportConnStr = String.Format(ACEImportConnStr, "C:\Temp")

' create Destination MySQL conn, Src and Dest dataadapters,
' and a command builder (because I am lazy...and fallible)
Using mysqlCon As New MySqlConnection(MySQLConnStr),
    daSrc As New OleDbDataAdapter(sSQL, ACEImportConnStr),
    daDest As New MySqlDataAdapter("SELECT * FROM Sample", mysqlCon),
    cb As New MySqlCommandBuilder(daDest)

    ' important!
    daSrc.AcceptChangesDuringFill = False

    dtSample = New DataTable
    rowsLoaded = daSrc.Fill(dtSample)

    ' csv lacks an ID column - add it
    Dim dc As New DataColumn("Id", GetType(Int32))
    dc.DefaultValue = 1
    dtSample.Columns.Add(dc)
    dc.SetOrdinal(0)

    ' MY csv also lacks a BATCH column
    dc = New DataColumn("Batch", GetType(Int32))
    dc.DefaultValue = 1
    dtSample.Columns.Add(dc)
    dc.SetOrdinal(1)

    ' set the batch number
    ' each 5k rows == a batch
    Dim batch As Int32 = 1
    Dim counter As Int32 = 1
    For Each dr As DataRow In dtSample.Rows
        dr("Batch") = batch
        counter += 1
        If counter > 5000 Then
            counter = 0
            batch += 1
        End If
    Next

    ' now save the data to MySQL
    mysqlCon.Open()
    ' inserting 250k rows takes a while,
    ' use a transaction
    Using t As MySqlTransaction = mysqlCon.BeginTransaction
        rowsUpdated = daDest.Update(dtSample)
        t.Commit()
    End Using

End Using

' show the IMPORT in a dgv
dgv1.DataSource = dtSample
dgv1.Columns("Id").Visible = False

' report
sw.Stop()
Console.WriteLine(sw.ElapsedMilliseconds)
原理很简单:因为数据绑定到一个DB,所以尽快将数据放入一个
DataTable
中。这里的诀窍是有两个DB提供者参与:OleDB读取csv,MySql保存

  • 通常,当DataAdapter填充
    数据表时,所有行都设置为
    Unchanged
    AcceptChangesDuringFill=False
    将状态设置为
    Added
    ,以便MySql适配器可以插入这些行
  • CommandBuilder通过SELECT命令生成要使用的INSERT SQL
  • 我不知道serials rollno查询在做什么,但我不会在导入过程循环中运行查询。如果需要设置的某些值依赖于数据库中的值,请将它们加载到另一个DT中并从那里查询。有一些DataTable扩展方法使查找行变得容易
  • 同样,我不知道
    EnterDataIntoDatabase
    做什么,但您应该努力处理和准备
    DataTable
    中所有导入的数据,然后立即更新所有数据
你似乎有更多的事情要做,而不仅仅是对一堆行进行批处理或排序。上面的代码可以在1.2分钟内(几乎每秒3500行)导入250k行,分配批处理号,并将250k新行插入MySql


如果batch/sequencer与CSV中的每个X行的顺序类似,那么您可能一次只需加载7000行,设置值,保存该批,然后加载接下来的7k行。这将限制每次加载的行数,并减少应用程序使用的内存。但我不确定它是否适用

参考:

  • 在MSDN上

有效的方法是将数据存储在列表或数据表中,然后处理数据,而不是用户的视图。您是否在填充数据时设置了顺序?在加载数据时可以这样做吗?(标题与其余部分不匹配).Hi PUROTIX序列来自csv文件,该文件有两列序列号,序列号从1到940000。我试图将其分解为1到7000。我使用了数据
Dim sSQL = "SELECT * FROM YOUR_CSVFILE_NAME.CSV"
Dim sw As New Stopwatch

Dim rowsLoaded As Int32
Dim rowsUpdated As Int32

sw.Start()
ACEImportConnStr = String.Format(ACEImportConnStr, "C:\Temp")

' create Destination MySQL conn, Src and Dest dataadapters,
' and a command builder (because I am lazy...and fallible)
Using mysqlCon As New MySqlConnection(MySQLConnStr),
    daSrc As New OleDbDataAdapter(sSQL, ACEImportConnStr),
    daDest As New MySqlDataAdapter("SELECT * FROM Sample", mysqlCon),
    cb As New MySqlCommandBuilder(daDest)

    ' important!
    daSrc.AcceptChangesDuringFill = False

    dtSample = New DataTable
    rowsLoaded = daSrc.Fill(dtSample)

    ' csv lacks an ID column - add it
    Dim dc As New DataColumn("Id", GetType(Int32))
    dc.DefaultValue = 1
    dtSample.Columns.Add(dc)
    dc.SetOrdinal(0)

    ' MY csv also lacks a BATCH column
    dc = New DataColumn("Batch", GetType(Int32))
    dc.DefaultValue = 1
    dtSample.Columns.Add(dc)
    dc.SetOrdinal(1)

    ' set the batch number
    ' each 5k rows == a batch
    Dim batch As Int32 = 1
    Dim counter As Int32 = 1
    For Each dr As DataRow In dtSample.Rows
        dr("Batch") = batch
        counter += 1
        If counter > 5000 Then
            counter = 0
            batch += 1
        End If
    Next

    ' now save the data to MySQL
    mysqlCon.Open()
    ' inserting 250k rows takes a while,
    ' use a transaction
    Using t As MySqlTransaction = mysqlCon.BeginTransaction
        rowsUpdated = daDest.Update(dtSample)
        t.Commit()
    End Using

End Using

' show the IMPORT in a dgv
dgv1.DataSource = dtSample
dgv1.Columns("Id").Visible = False

' report
sw.Stop()
Console.WriteLine(sw.ElapsedMilliseconds)