简体   繁体   English

如何使用 Visual Studio 2019 (VB.NET) 按钮在 Access 数据库中创建新记录

[英]How to Create a New Record in an Access Database using Visual Studio 2019 (VB.NET) Button Click

DISCLAIMER: I'm very new to coding and programming;免责声明:我对编码和编程非常陌生; sorry if the coding is subpar.抱歉,如果编码低于标准。

My goal is to have my Visual Studio 2019 project (named Detailing Error Log) add a new record/ row into my Microsoft Access Database table (accdb file named Database1, table named Data Collection) based on which checkboxes are checked.我的目标是让我的 Visual Studio 2019 项目(名为 Detailing Error Log)根据选中的复选框将新记录/行添加到我的 Microsoft Access 数据库表(名为 Database1 的 accdb 文件,名为 Data Collection 的表)中。 I would only like rows to be added, not deleted, whenever the "Import" button is clicked.每当单击“导入”按钮时,我只想添加行,而不是删除行。 The Database will then be saved and the checkboxes in my Visual Studio project unchecked.然后将保存数据库,并且取消选中我的 Visual Studio 项目中的复选框。 The Database will be used to store that data until it is used by a coordinating visual studio program to count the occurrences of specific text within a specific month.数据库将用于存储该数据,直到协调的 Visual Studio 程序使用它来计算特定月份内特定文本的出现次数。 From there it will be displayed in graphs.从那里它将以图表的形式显示。

I had successfully done this using Excel;我已经使用 Excel 成功地做到了这一点; but experienced too much lag whenever there were multiple entries.但是每当有多个条目时都会经历太多的延迟。

My problem is that I am getting this error from my " dsnewrow " variable:我的问题是我从我的“ dsnewrow ”变量中得到这个错误:

System.NullReferenceException: 'Object reference not set to an instance of an object.' System.NullReferenceException:“对象引用未设置为 object 的实例。” System.Data.DataTableCollection.this[string].get returned Nothing. System.Data.DataTableCollection.this[string].get 没有返回任何内容。

So I was looking around on Google and programming forums, and I didn't really find any posts that I believe matched what I'm trying to accomplish: the adding of a new record each time the "Import" button is clicked.所以我在谷歌和编程论坛上四处寻找,我并没有真正找到任何我认为与我想要完成的工作相匹配的帖子:每次单击“导入”按钮时添加一条新记录。 Is my code to add a new record correct?我添加新记录的代码是否正确? I saw a couple of different ways new records were "added", but by looking at the similar posts I thought this one was my best option.我看到了几种“添加”新记录的不同方式,但是通过查看类似的帖子,我认为这是我最好的选择。

Below is my code, thanks for the help::以下是我的代码,感谢您的帮助::

NEATOL = No Entries At the Time Of Log NEATOL = 记录时没有条目

Private Sub ConnectionPrep(sender As System.Object, e As System.EventArgs) Handles MyBase.Load

    Dim dbProvider As String
    Dim dbSource As String
    Dim sql As String
    Dim inc As Integer
    Dim MaxRows As Integer
    Dim con As New OleDb.OleDbConnection
    dbProvider = "PROVIDER=Microsoft.ACE.OLEDB.12.0;"
    dbSource = "Data Source = S:\software\Melton System\DPD & DEL (KPI)\Database1.accdb; Persist Security Info = False"
    con.ConnectionString = dbProvider & dbSource
    con.Open()
End Sub

Private Sub InputInformation(sender As System.Object, e As System.EventArgs) Handles ImporttBUT.Click
    Dim con As New OleDb.OleDbConnection
    Dim ds As New DataSet
    Dim da As OleDb.OleDbDataAdapter
    Dim cb As New OleDbCommandBuilder()
    Dim dsnewrow As DataRow
    dsnewrow = ds.Tables("Data Collection").NewRow()
    dsnewrow.Item("M/Y OF LOG") = Me.MonthList2021.SelectedItem
    dsnewrow.Item("TIME OF LOG") = DateTime.Now.ToString("MM/dd/yyyy HH:mm:ss")
    dsnewrow.Item("USER") = UserName
    dsnewrow.Item("STOCK NUMBER") = Me.StockNumberTXTB.Text
    If MissedPartCHKB.Checked = True Then
        dsnewrow.Item("MISSED PART") = Me.MissedPartCHKB.Text
    ElseIf MissedPartCHKB.Checked = False Then
        dsnewrow.Item("MISSED PART") = "NEATOL"
    End If
    If NotInEpicorCHKB.Checked = True Then
        dsnewrow.Item("NOT IN EPICOR") = Me.NotInEpicorCHKB.Text
    ElseIf NotInEpicorCHKB.Checked = False Then
        dsnewrow.Item("NOT IN EPICOR") = "NEATOL"
    End If
    If MissedBuyoutCHKB.Checked = True Then
        dsnewrow.Item("MISSED BUYOUT") = Me.MissedBuyoutCHKB.Text
    ElseIf MissedBuyoutCHKB.Checked = False Then
        dsnewrow.Item("MISSED BUYOUT") = "NEATOL"
    End If
    If NonStockCHKB.Checked = True Then
        dsnewrow.Item("MISSED NON STOCK ITEM") = Me.NonStockCHKB.Text
    ElseIf NonStockCHKB.Checked = False Then
        dsnewrow.Item("MISSED NON STOCK ITEM") = "NEATOL"
    End If
    If MissedSTKItemCHKB.Checked = True Then
        dsnewrow.Item("MISSED STOCK ITEM") = Me.MissedSTKItemCHKB.Text
    ElseIf MissedSTKItemCHKB.Checked = False Then
        dsnewrow.Item("MISSED STOCK ITEM") = "NEATOL"
    End If
    If MissedAutomatedPartCHKB.Checked = True Then
        dsnewrow.Item("MISSED AUTOMATED") = Me.MissedAutomatedPartCHKB.Text
    ElseIf MissedAutomatedPartCHKB.Checked = False Then
        dsnewrow.Item("MISSED AUTOMATED") = "NEATOL"
    End If
    If MissingPrintAfterQTYCHKB.Checked = True Then
        dsnewrow.Item("MISSING PRINTS AFTER QUANTITY") = Me.MissingPrintAfterQTYCHKB.Text
    ElseIf MissingPrintAfterQTYCHKB.Checked = False Then
        dsnewrow.Item("MISSING PRINTS AFTER QUANTITY") = "NEATOL"
    End If
    If MissedPrintsNOTSentChadCHKB.Checked = True Then
        dsnewrow.Item("MISSED PRINT NOT SENT TO CHAD") = Me.MissedPrintsNOTSentChadCHKB.Text
    ElseIf MissedPrintsNOTSentChadCHKB.Checked = False Then
        dsnewrow.Item("MISSED PRINT NOT SENT TO CHAD") = "NEATOL"
    End If
    If OtherCHKB.Checked = True Then
        dsnewrow.Item("OTHER") = Me.OtherTXTB.Text
    ElseIf OtherCHKB.Checked = False Then
        dsnewrow.Item("OTHER") = "NEATOL"
    End If
    If AddedMissingDimCHKB.Checked = True Then
        dsnewrow.Item("ADDED MISSING DIMENSION") = Me.AddedMissingDimCHKB.Text
    ElseIf AddedMissingDimCHKB.Checked = False Then
        dsnewrow.Item("ADDED MISSING DIMENSION") = "NEATOL"
    End If
    If FixedDimensionCHKB.Checked = True Then
        dsnewrow.Item("FIXED DIMENSION") = Me.FixedDimensionCHKB.Text
    ElseIf FixedDimensionCHKB.Checked = False Then
        dsnewrow.Item("FIXED DIMENSION") = "NEATOL"
    End If
    ds.Tables("Counting").Rows.Add(dsnewrow)
    da.Update(ds, "Counting")
    MsgBox("Entry succesfully added to database.")
    MissedPartCHKB.Checked = False
    MissedAutomatedPartCHKB.Checked = False
    NotInEpicorCHKB.Checked = False
    NonStockCHKB.Checked = False
    MissedSTKItemCHKB.Checked = False
    MissedBuyoutCHKB.Checked = False
    MissedPrintsNOTSentChadCHKB.Checked = False
    MissingPrintAfterQTYCHKB.Checked = False
    AddedMissingDimCHKB.Checked = False
    FixedDimensionCHKB.Checked = False
    OtherCHKB.Checked = False
    OtherTXTB.Text = ""
             MonthList2021.SelectedItem = False
End Sub

Ok, you are close.好的,你很接近。

So, data adaptor - you want to give it a VALID sql - not JUST a table name.所以,数据适配器 - 你想给它一个 VALID sql - 而不仅仅是一个表名。

sqlCommand builder - you declarer it - but it is connected and associated with NOTHING ELSE!! sqlCommand builder - 你声明它 - 但它与 NOTHING ELSE 相关联!

So, you need this:所以,你需要这个:

Dim con As New OleDb.OleDbConnection(My.Settings.TestDB)

So, you created connect object - but did not provide details of the connection.因此,您创建了连接 object - 但没有提供连接的详细信息。 I suggest you create that connections in the settings - use the connection builder.我建议您在设置中创建该连接 - 使用连接构建器。

Dim da As OleDb.OleDbDataAdapter

You create this adaptor - but NEEDS a connection and MORE important, it ALSO needs some sql.您创建此适配器 - 但需要连接,更重要的是,它还需要一些 sql。

because we are ONLY going to add rows, lets give the adaptor a sql statement - but one that returns NO records - but we STILL need to fill out this adaptor.因为我们只打算添加行,所以让我们给适配器一个 sql 语句——但它不会返回任何记录——但我们仍然需要填写这个适配器。

So, use this:所以,使用这个:

Dim da As OleDb.OleDbDataAdapter("SELECT * from [Data Collection] WHERE ID = 0",con)

Next up, you create a command builder (this is good), but you left out it being connected or assocated with ANY thing else, so you need/want this:接下来,您创建了一个命令构建器(这很好),但是您忽略了它与其他任何东西的连接或关联,因此您需要/想要这个:

Dim cb As New OleDbCommandBuilder()

Becomes this:变成这样:

Dim cb As New OleDbCommandBuilder(da)

When you execute the above, then the insert, delete, update and select commands will be built for you (nice.!).当您执行上述操作时,将为您构建插入、删除、更新和 select 命令(很好。!)。

Now, to add a new data row?现在,要添加一个新的数据行?

After we done all above, then we need to load up our datatable (again, it just sitting there - not connected to anything).完成上述所有操作后,我们需要加载我们的数据表(同样,它只是坐在那里 - 没有连接到任何东西)。 So, do this:所以,这样做:

However, you have但是,你有

Dim ds As New DataSet

No, we dont' need a "set" of tables - you need ONE table.不,我们不需要“一组”桌子——你需要一张桌子。

So change above to所以把上面改成

dim ds as New DataTable将 ds 暗淡为新数据表

Now, lets fill (and more imporant) associate our table with our data connciton objects.现在,让我们填充(更重要的是)将我们的表与我们的数据连接对象相关联。

da.Fill(ds)

Now you CAN edit rows in ds (but we don't' have any.!!).现在您可以在 ds 中编辑行(但我们没有。!!)。

Now we can create a whole new separate row object (as you did), but I tend to just do this:现在我们可以创建一个全新的单独行 object (就像你做的那样),但我倾向于这样做:

With ds.Rows.Add
   .item("Some Field Name") = "your value goes here"
   .etc .etc
End With

But, you can if you wish create a whole new seperate row.但是,如果您希望创建一个全新的单独行,则可以。 Again that row can't just be "all by itself" here.同样,该行在这里不能只是“完全独立”。

So, you create the blank row this way:因此,您可以这样创建空白行:

        Dim myRow As DataRow = rstTable.Rows.Add

Or in your case: dsnewrow = ds.Rows.Add或者在您的情况下: dsnewrow = ds.Rows.Add

After you add one row, or several?添加一行或几行之后?

Then you have to send back these new rows to the database.然后您必须将这些新行发送回数据库。

 da.Update(ds)

Now note how I am using "ds", but it is a datatable and not a dataset.现在请注意我是如何使用“ds”的,但它是一个数据表而不是数据集。 You "can" use a dataset - but really, you don't need one.您“可以”使用数据集 - 但实际上,您不需要数据集。

Also, last but not least?另外,最后但并非最不重要的是?

Well, the adaptor, the reader, the connection object and the sql?那么,适配器、阅读器、object 和 sql 的连接?

You can use ONE object that contains ALL 3 of the above.您可以使用包含以上所有 3 个的 object。 This will save your fingers, and also several variables.这将节省您的手指,以及几个变量。

So, I suggest this setup - since connection object, and sql, and sql command are ALL in one object.所以,我建议这种设置 - 因为连接 object 和 sql 和 sql 命令都在一个 ZA8CFDE6331BD54B66AC96F8911C 中。

So, this is the 'template' I use:所以,这是我使用的“模板”:

   Using cmdSQL As New OleDbCommand("SELECT * from tblHotels WHERE ID = 0",
                    New OleDbConnection(My.Settings.TestDB))

        Dim da As New OleDbDataAdapter(cmdSQL)
        Dim sqlBuild As New OleDbCommandBuilder(da)

        Dim rstTable As New DataTable
        da.Fill(rstTable)

        With rstTable.Rows.Add
            .Item("HotelName") = "The zoo Hotel."
        End With

        ' add one more row - but with  row var
        Dim MyOneRow As DataRow = rstTable.Rows.Add

        MyOneRow("HotelName") = "The Barn Hotel"
        MyOneRow("City") = "My City"

        ' write BOTH ROWS back to database - all data rows were AND ARE added to rstTable

        da.Update(rstTable)


    End Using

Edit - answers to comments question编辑 - 评论问题的答案

What do you dimension cmdSQL as?您将 cmdSQL 定义为什么?

I have either this:我有这个:

    Dim cmdSQL As New OleDbCommand
    or I have this
    Dim cmdSQL As OleDbCommand = New OleDbCommand

The both amount to the same thing.两者等同于同一件事。 Note in some cases I used OleDb.OleDbCommand, and in SOME cases I used OleDBcommand (I left out the OleDB)注意在某些情况下我使用了 OleDb.OleDbCommand,在某些情况下我使用了 OleDBcommand(我省略了 OleDB)

I am ABLE to save some fingers and typing and not have to use the OleDB.我能够节省一些手指和打字,而不必使用 OleDB。 as a prefix because at the top of the module (before any code) I have this:作为前缀,因为在模块的顶部(在任何代码之前)我有这个:

Imports System.Data.OleDb

If I leave above out, then I HAVE to use OleDb., but with the above imports then I am free to leave out the OleDB.如果我忽略了上面的内容,那么我必须使用 OleDb。但是有了上面的导入,我可以自由地忽略 OleDB。 (OleDB(dot) prefix). (OleDB(点)前缀)。

>>Fill" is not a member of OleDbDataAdapter(), >>Fill" 不是 OleDbDataAdapter() 的成员,

It should be.它应该是。 I assume you do this:我假设你这样做:

    Using cmdSQL As OleDbCommand = New OleDbCommand("SELECT * from tblHotels WHERE ID = 0",
                    New OleDbConnection(My.Settings.TestDB))


        Dim da As New OleDbDataAdapter(cmdSQL)

Of course th above (declares) a cmdSQL object in the "using".当然,上面(声明)了“使用”中的 cmdSQL object。 You can't thus use cmdSQL outside of that using/end using block.因此,您不能在 using/end using 块之外使用 cmdSQL。

>>getting many errors associated with my variable "da"; >>得到许多与我的变量“da”相关的错误; BC3031 Value of type 'OleDbDataAdapter()' cannot be converted to 'OleDbDataAdapter' BC3031 类型“OleDbDataAdapter()”的值无法转换为“OleDbDataAdapter”

You are declaring da as您将 da 声明为

在此处输入图像描述

Note how in above I do get/have "fill" as a method of da in this case.请注意,在这种情况下,我如何在上面获取/拥有“填充”作为 da 的方法。

Since you note that the last "using" example of mine works, then something is messed up in your code.由于您注意到我的最后一个“使用”示例有效,因此您的代码中出现了一些问题。

For example, you have this:例如,你有这个:

Private Sub ConnectionPrep(.............

Ok, but that code is 100% separate and 100% isolated from the 2nd routine where your code is.好的,但是该代码是 100% 独立的,并且与您的代码所在的第二个例程 100% 隔离。 The 2nd routine can't see, nor use (nor does it) have anything to do with that 2nd posted routine.第二个例程看不到,也不使用(也没有)与第二个发布的例程有任何关系。

So how, when, where do you use the first routine?那么如何、何时、何地使用第一个例程?

And there is LITTLE need to put that connection string setup in code.并且几乎不需要将该连接字符串设置放入代码中。

Use the project settings for this.为此使用项目设置。

Eg this page:例如这个页面:

在此处输入图像描述

So, when you use the above connection builder?那么,当您使用上述连接构建器时呢? Then all of the provider and settings are now available ANYWHERE in code.然后,所有提供程序和设置现在都可以在代码中的任何地方使用。

You can use您可以使用

My.Settings.TestDB 

The above thus will return a valid working connection string - in this case for oleDB.因此,上面将返回一个有效的工作连接字符串 - 在这种情况下为 oleDB。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Visual Studio 2015 VB.net如何在MS Access数据库中查找记录并禁用表单中的按钮? - Visual Studio 2015 VB.net How to find record in MS Access database and disable button in form? 使用VB.Net向Microsoft Access数据库添加新记录? - Add a New Record to Microsoft Access Database using VB.Net? 使用Visual Studio 2015更新Access数据库-VB.net - Update Access database using Visual Studio 2015 - VB.net 在 VB.NET (Visual Studio 2013) 中使用 OLEDB 通过 DataGridView 更新访问数据库的按钮 - Update Button for Access Database via DataGridView Using OLEDB in VB.NET (Visual Studio 2013) 如何从 Visual Studio 将新记录添加到 Access 数据库。 (VB.NET) - How to Add New Records to An Access Database from Visual Studio. (VB.NET) 无法在 Visual Studio 2019 上为 VB.NET Web 应用程序创建新的构建配置 - Unable to create new build configuration on Visual Studio 2019 for VB.NET Web application 在 vb.net Visual Studio 2019 中创建条形码时出错 - Error while create barcode in vb.net Visual Studio 2019 如何使用 Visual Studio 计算 Access 数据库中的值 VB.NET - How to Count Values in Access Database using Visual Studio VB.NET 如何使用vb.net插入Visual Studio数据库 - How to insert into Visual Studio Database using vb.net Visual Studio(vb.net)无法加载访问数据库 - visual studio (vb.net) not able to load an access database
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM