Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vb.net/16.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
Sql ds.Tables.Rows.Add()在一次调用时生成3行_Sql_Vb.net_Ms Access_Datagridview_Oledb - Fatal编程技术网

Sql ds.Tables.Rows.Add()在一次调用时生成3行

Sql ds.Tables.Rows.Add()在一次调用时生成3行,sql,vb.net,ms-access,datagridview,oledb,Sql,Vb.net,Ms Access,Datagridview,Oledb,[注:更新:] 我的愿望是,向datagridview(DGV)添加新行的用户将能够在Access数据库中创建该行,并且能够创建多行并对这些新行进行非同步编辑。DGV由一个数据集表填充,我发现在DGV和数据库之间设置数据集是最佳实践(或者至少允许灵活性) 要编辑多个用户创建的新行,数据集需要能够从数据库检索自动递增主键,然后用新行的更新键值重新填充DGV。或者,至少这是我找到的唯一一种完成这项工作的方法。问题是,当我尝试向datatable添加一行时,它最终会生成三行而不是一行 [为简洁起见删

[注:更新:]

我的愿望是,向datagridview(DGV)添加新行的用户将能够在Access数据库中创建该行,并且能够创建多行并对这些新行进行非同步编辑。DGV由一个数据集表填充,我发现在DGV和数据库之间设置数据集是最佳实践(或者至少允许灵活性)

要编辑多个用户创建的新行,数据集需要能够从数据库检索自动递增主键,然后用新行的更新键值重新填充DGV。或者,至少这是我找到的唯一一种完成这项工作的方法。问题是,当我尝试向datatable添加一行时,它最终会生成三行而不是一行


[为简洁起见删除了旧帖子]

以下是如何首先填充DGV并将其绑定到数据集:

Dim ConMain As New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & MasterPath)
Dim ds As New DataSet

Public Sub UniversalFiller(ByVal QueryStringFill As String, ByVal DGV As DataGridView, ByVal AccessDBTableName As String)
    If IsNothing(ds.Tables(AccessDBTableName)) Then
    Else
        ds.Tables(AccessDBTableName).Clear()
    End If
    ConMain.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & MasterPath
    Dim daZZ As New OleDbDataAdapter(QueryStringFill, ConMain)
    Try
        daZZ.Fill(ds, AccessDBTableName)
        DGV.DataSource = ds
        DGV.DataMember = AccessDBTableName
        DGV.AutoResizeColumns()
    Catch ex As Exception
        WriteToErrorLog(ex.Message, ex.StackTrace, ex.GetHashCode, ex.Source, ex.ToString)
        ds.Clear
        MsgBox("There was an error filling the DGV, ds.cleared") 'this is for my notes, not user error'
    End Try

End Sub

更新: 我还是搞不懂这个问题。当处理
DGV.UserAddedRow
时调用此函数。原始代码可能不是添加一行的最佳方式,但即使创建新行也会遇到同样的问题:

Dim daZZ As New OleDbDataAdapter(DBSelectQuery, ConMain)
Dim CurrentCellPoint As Point = DGV.CurrentCellAddress
Dim CurrentCellText As String = DGV.CurrentCell.Value.ToString
Dim cmdBldr As New OleDbCommandBuilder(daZZ)
cmdBldr.QuotePrefix = "["
cmdBldr.QuoteSuffix = "]"
MsgBox("1")
Dim DaZZDataRow As DataRow = ds.Tables(DTName).NewRow
MsgBox("2")
DaZZDataRow(CurrentCellPoint.X) = CurrentCellText
MsgBox("3")
ds.Tables(DTName).Rows.Add(DaZZDataRow)
MsgBox("4")
daZZ.InsertCommand = cmdBldr.GetInsertCommand()
MsgBox("5")
daZZ.Update(ds.Tables(DTName))
MsgBox("6")
ds.Tables(DTName).Clear()
daZZ.Fill(ds, DTName)
MsgBox("5")
daZZ.Update(ds.Tables(DTName))
DGV.CurrentCell = DGV(CurrentCellPoint.X, CurrentCellPoint.Y)
问题总是出现在
ds.Tables(DTName).Rows.Add()步骤中。无论在
.Add()
的括号中放了什么,都无关紧要。它可以是一个数或任何一个整数,包括0,它将有3行。它不会被多次调用。只需调用
ds.Tables(DTName).Rows.Add()

如果这不是添加一个空行的正确方法,那么是什么?我可以发布SQLINSERT/update命令,但这不是问题所在,因为add生成了三行,而不是一行。为了清楚起见,它只会在
MsgBox
项中运行一次,并产生3行

同样令我好奇的是,InsertAt命令产生了相同的结果:

ds.Tables(DTName).Rows.InsertAt(DaZZDataRow,CurrentCellPoint.Y)
而不是
ds.Tables(DTName).Rows.Add()
仍然生成3个新行。我也在一个新的scratchdb-from-Access上尝试过这个方法,也遇到了同样的问题

,作为VS2012项目和虚拟数据库。这是非常简单的,即没有错误处理,但它显示了错误,并允许删除行作为一个额外的便利。感谢所有看过的人。

这是我的修订版了解您交易的某些部分

    daZZ.InsertCommand = cmdBldr.GetInsertCommand()
我仍然不认为需要InsertCommand。我认为这是创建您的3行之一

    ds.Tables(DTName).Rows.Add(DaZZDataRow)
这是创建第二行。这是有效的,但也不需要

由于数据绑定,DataGridView正在创建第三行。当您将表绑定到DataGridView并且允许DGV“添加行”时,它也会生成插入的行

尝试完全删除这两个项目,以及清晰的行(我认为不需要),我打赌您会添加一行,即当前正在DGV中添加的行


您仍然需要调用UPDATE and FILL来重新同步网格中的数据。

我对这个问题采取了回到基本的方法,更多地关注在添加新记录时让DataGridView显示生成的自动编号ID值的问题。我首先将DataGridView控件添加到表单中,并使用“添加项目数据源…”向导将其连接到Access数据库“Database1.accdb”中名为[Chemicals]的表。(问题中示例代码的早期版本引用了一个名为[Chemicals]的表,所以我使用了这个表。)

当我完成时,我的项目中有以下“东西”:

  • 窗体上的DataGridView控件(
    dataGridView1
    ),该控件已绑定到BindingSource(见下文)

  • 与我的Access数据库关联的数据集(
    database1DataSet

  • 绑定源(
    chemicalsBindingSource
    ),与
    database1DataSet
    中的[Chemicals]表关联,用作我的DataGridView的
    数据源

  • 用于管理数据集和实际数据库之间的数据流的TableAdapter(
    ChemicalStableApter

向导还在我的
Form1\u Load
方法中给了我以下代码行。(我使用了C#,但VB.NET将非常类似。)

//TODO:这行代码将数据加载到“database1DataSet.Chemicals”表中。您可以根据需要移动或删除它。
this.chemicalsTableAdapter.Fill(this.database1DataSet.Chemicals);
这就是运行应用程序并在DataGridView中查看现有记录所需的全部内容

现在,为了将DataGridView更新推回到数据库并检索新创建记录的自动编号值,我使用了
RowLeave
事件。我发现
UserAddedRow
事件触发得太快(在用户开始键入新行后立即触发),我想等到用户编辑完行后再对其执行任何操作

我最后使用的代码如下(同样是C#)

private void Form1\u加载(对象发送方,事件参数e)
{
fillErUp();
}
私有无效填充()
{
//(从Form1_Load移动到它自己的方法,因此也可以从下面的_RowLeave调用它)
//TODO:这行代码将数据加载到“database1DataSet.Chemicals”表中。您可以根据需要移动或删除它。
this.chemicalsTableAdapter.Fill(this.database1DataSet.Chemicals);
}
私有void dataGridView1_RowLeave(对象发送方,DataGridViewCellEventArgs e)
{
DataGridView dgv=(DataGridView)发送方;
如果(dgv.IsCurrentRowDirty)
{
Cursor.Current=Cursors.WaitCursor;
dgv.EndEdit();//刷新从DataGridView到BindingSource的更改
chemicalsBindingSource.EndEdit();//刷新从BindingSource到DataSet的更改
this.chemicalsTableAdapter.Update(this.database1DataSet);//更新数据库
int currentRow=e.RowIndex;
如果