Как обновить мою базу данных Access из текстовых полей - PullRequest
0 голосов
/ 30 мая 2020

Я создал экран, на котором я могу редактировать детали в базе данных. но как только я нажимаю кнопку обновления, появляется сообщение об отсутствии значения для одного или нескольких обязательных параметров. Я прикрепил свой код ....

Обновить BUtton ...

Private Sub SimpleButton5_Click(sender As Object, e As EventArgs) Handles SimpleButton5.Click

    Try

        Access.AddParam("@UId", TextBox1.Text)
        Access.AddParam("@ImagePic", PictureBox1.Image)
        Access.AddParam("@Barcod", TextBox2.Text)
        Access.AddParam("@BrandName", TextBox3.Text)
        Access.AddParam("@StockName", TextBox4.Text)
        Access.AddParam("@Category", TextBox5.Text)
        Access.AddParam("@SubCat", TextBox6.Text)
        Access.AddParam("@Subcat2", TextBox7.Text)
        Access.AddParam("@Discrip", TextBox8.Text)
        Access.AddParam("@StockLvl", TextBox9.Text)
        Access.AddParam("@CustomAmount", TextBox10.Text)
        Access.AddParam("@CostPrice", TextBox11.Text)
        Access.AddParam("@Markup", TextBox12.Text)
        Access.AddParam("@TaxAmount", TextBox13.Text)
        Access.AddParam("@SellingPrice", TextBox14.Text)
        Access.AddParam("@BeforTax", TextBox15.Text)
        Access.AddParam("@AfterTax", TextBox16.Text)
        Access.AddParam("@TaxPer", TextBox17.Text)
        Access.AddParam("@MarkupPer", TextBox18.Text)
        Access.AddParam("@LastDate", TextBox19.Text)
        Access.AddParam("@LastUser", TextBox20.Text)

        Access.ExecQuery("UPDATE Inventory " &
                         "SET [Image]=PictureBox1.image, BarCode=Textbox2.text, " &
                         "BrandName=@BrandName, StockName=@StockName, Category=@Category, SubCategory=@SubCat, " &
                         "SubCategory2=@SubCat2, Description=@Discrip, StockLevels=@StockLvl, CustomAmount=@Customamount, " &
                         "CostPrice=@CostPrice, MarkupAmount=@Markup, SellingPrice=@SellingPrice, ProfirBefore=@BeforeTax, " &
                         "ProfitAfter=@AfterTax, TaxAmount=@TaxAmount, taxPer=@TaxPer, MarkupPer=@MarkupPer, LastDateupdated=@LAstDate, " &
                         "UpserUpdated=@LastUser WHERE ID=@UId")

        If NoErrors(True) = False Then Exit Sub

        RefreshData()

    Catch ex As Exception
        MsgBox(ex.Message)
    Finally

    End Try

End Sub

My Access.ExecQuery --- (Class ...)

Imports System.Data.OleDb

Public Class DBControl
    Private DBCon As New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=Database1.accdb;")
    Private DBCmd As OleDbCommand
    Public DBDA As OleDbDataAdapter
    Public DBDT As DataTable
    Public Params As New List(Of OleDbParameter)
    Public RecordCount As Integer
    Public Exception As String

    Public Sub ExecQuery(Query As String)
        RecordCount = 0
        Exception = ""

        Try
            DBCon.Open()
            DBCmd = New OleDbCommand(Query, DBCon)

            Params.ForEach(Sub(p) DBCmd.Parameters.Add(p))

            Params.Clear()

            DBDT = New DataTable
            DBDA = New OleDbDataAdapter(DBCmd)
            RecordCount = DBDA.Fill(DBDT)
        Catch ex As Exception
            Exception = ex.Message
        End Try

        If DBCon.State = ConnectionState.Open Then DBCon.Close()
    End Sub

    ' INCLUDE QUERY & COMMAND PARAMETERS
    Public Sub AddParam(Name As String, Value As Object)
        Dim NewParam As New OleDbParameter(Name, Value)
        Params.Add(NewParam)
    End Sub
End Class

Я играл с этим уже 2 дня, но где-то я что-то упускаю или что-то не замечаю

thx

Jaco

Ответы [ 2 ]

1 голос
/ 30 мая 2020

Сообщение об ошибке довольно очевидно. Некоторые параметры отсутствуют, либо вы их забыли, либо написаны с ошибками.

Вам нужно перепроверить свой код, он содержит довольно много опечаток.

  • Вы определяете параметр @ImagePic, но он не используется в вашем запросе.
  • То же самое для @Barcod, вместо этого вы помещаете это в свой SQL: BarCode=Textbox2.text. Просто назовите его @Barcode, зачем вы так сокращаете имена. Это только создает путаницу. Используйте правильное написание английского sh и будьте последовательны.
  • Еще одна опечатка: Access.AddParam("@BeforTax", TextBox15.Text). В вашем SQL: ProfirBefore=@BeforeTax. ProfirBefore - тоже опечатка.
  • Пожалуйста, сделайте себе одолжение и переименуйте и текстовые поля: TextBox1–20 не является хорошей практикой именования. Существует большая вероятность того, что вы перепутаете поля после копирования ваших утверждений. Textbox20 совсем не интуитивно понятен и не сообщает вам, какие данные вы обрабатываете.

Я играл с этим уже 2 дня, но где-то я что-то упускаю или что-то упускаю

Возможно, не хватает очков :) Я не знаю о вашей среде разработки. Я вставил ваш код в Notepad ++ и, щелкнув ключевое слово, он выделит все вхождения этого ключевого слова в коде. Быстро стало очевидно, что некоторые ключевые слова нигде не упоминаются.

0 голосов
/ 02 июня 2020

Я создал простой класс для вашего объекта Inventory, чтобы не передавать все свойства в качестве параметров. Я могу просто передать объект Inventory методу UpdateDatabase.

Public Class Inventory
    Public Property Picture As Byte()
    Public Property BarCode As String
    Public Property BrandName As String
    Public Property StockName As String
    Public Property Category As String
    Public Property SubCategory As String
    Public Property SubCategory2 As String
    Public Property Description As String
    Public Property StockLevels As Integer
    Public Property CustomAmount As Decimal
    Public Property CostPrice As Decimal
    Public Property MarkupAmount As Decimal
    Public Property SellingPrice As Decimal
    Public Property ProfitBefore As Decimal
    Public Property ProfitAfter As Decimal
    Public Property TaxAmount As Decimal
    Public Property taxPer As Decimal
    Public Property MarkupPer As Decimal
    Public Property LastDateupdated As Date
    Public Property UpserUpdated As String
    Public Property ID As Integer
End Class

Чтобы получить изображение вашего графического блока в надлежащем формате для хранения, у меня есть небольшая функция, которая принимает Image в качестве параметра и возвращает массив байтов.

'This Function requires Imports System.Drawing
Private Function GetByteArrayFromImage(img As Image) As Byte()
    Dim convert As New ImageConverter
    Dim arr = DirectCast(convert.ConvertTo(img, GetType(Byte())), Byte())
    Return arr
End Function

Устанавливается каждое свойство объекта Inventory. Как видите, здесь поможет присвоение значимых имен элементам управления. Текстовые поля CInt, CDec и CDate должны быть проверены до того, как будет достигнут этот код.

Я помещаю здесь Try ... Catch, чтобы вы могли показать сообщение пользователю.

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    Dim img As Image = PictureBox1.Image
    Dim imgArray = GetByteArrayFromImage(img)
    Dim inv As New Inventory With
    {
        .Picture = imgArray,
        .BarCode = TextBox2.Text,
        .BrandName = TextBox3.Text,
        .StockName = TextBox4.Text,
        .Category = TextBox5.Text,
        .SubCategory = TextBox6.Text,
        .SubCategory2 = TextBox7.Text,
        .Description = TextBox8.Text,
        .StockLevels = CInt(TextBox9.Text),
        .CustomAmount = CDec(TextBox10.Text),
        .CostPrice = CDec(TextBox11.Text),
        .MarkupAmount = CDec(TextBox12.Text),
        .SellingPrice = CDec(TextBox14.Text),
        .ProfitBefore = CDec(TextBox15.Text),
        .ProfitAfter = CDec(TextBox16.Text),
        .TaxAmount = CDec(TextBox13.Text),
        .taxPer = CDec(TextBox17.Text),
        .MarkupPer = CDec(TextBox18.Text),
        .LastDateupdated = CDate(TextBox19.Text),
        .UpserUpdated = TextBox20.Text,
        .ID = CInt(TextBox1.Text)
    }
    Try
        UpdateDatabase(inv)
    Catch ex As Exception
        MessageBox.Show(ex.Message)
    End Try
End Sub

В Access порядок, в котором параметры отображаются в операторе sql, должен соответствовать порядку, в котором они добавляются в коллекцию параметров.

Мне показалось странным, что все ваши поля имена пишутся с большой буквы, кроме taxPer. Проверьте свою базу данных.

Using...End Using блоки гарантируют, что ваши объекты базы данных будут закрыты и удалены даже в случае ошибки.

Метод .Add превосходит метод, который вы использовали, потому что он включает типы данных и размер. Мне пришлось угадывать типы и размеры, поэтому проверьте свою базу данных. Там, где я ошибся, вам придется исправить метод .Add, тип свойства в классе Inventory и преобразование текстовых полей в свойство .Text. (3 места для изменения)

Private Sub UpdateDatabase(inv As Inventory)
    Dim sql = "UPDATE Inventory SET  
                [Image]=@Picture, 
                BarCode= @BarCode,
                BrandName=@BrandName, 
                StockName=@StockName, 
                Category=@Category, 
                SubCategory=@SubCat, 
                SubCategory2=@SubCat2, 
                Description=@Discrip, 
                StockLevels=@StockLvl, 
                CustomAmount=@Customamount,
                CostPrice=@CostPrice, 
                MarkupAmount=@Markup, 
                SellingPrice=@SellingPrice, 
                ProfirBefore=@BeforeTax, 
                ProfitAfter=@AfterTax, 
                TaxAmount=@TaxAmount, 
                taxPer=@TaxPer,      
                MarkupPer=@MarkupPer, 
                LastDateupdated=@LAstDate,
                UpserUpdated=@LastUser 
                WHERE ID=@UId"
    Using cn As New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=Database1.accdb;"),
            cmd As New OleDbCommand(sql, cn)
        With cmd.Parameters
            .Add("@Picture", OleDbType.LongVarBinary).Value = inv.Picture
            .Add("@BarCode", OleDbType.VarChar, 100).Value = inv.BarCode
            .Add("@BrandName", OleDbType.VarChar, 100).Value = inv.BrandName
            .Add("@StockName", OleDbType.VarChar, 100).Value = inv.StockName
            .Add("@Category", OleDbType.VarChar, 100).Value = inv.Category
            .Add("@SubCat", OleDbType.VarChar, 100).Value = inv.SubCategory
            .Add("@SubCat2", OleDbType.VarChar, 100).Value = inv.SubCategory2
            .Add("@Discrip", OleDbType.VarChar, 100).Value = inv.Description
            .Add("@StockLvl", OleDbType.Integer).Value = inv.StockLevels
            .Add("@Customamount", OleDbType.Decimal).Value = inv.CustomAmount
            .Add("@CostPrice", OleDbType.Decimal).Value = inv.CostPrice
            .Add("@Markup", OleDbType.Decimal).Value = inv.MarkupAmount
            .Add("@SellingPrice", OleDbType.Decimal).Value = inv.SellingPrice
            .Add("@BeforeTax", OleDbType.Decimal).Value = inv.ProfitBefore
            .Add("@AfterTax", OleDbType.Decimal).Value = inv.ProfitAfter
            .Add("@TaxAmount", OleDbType.Decimal).Value = inv.TaxAmount
            .Add("@TaxPer", OleDbType.Decimal).Value = inv.taxPer
            .Add("@MarkupPer", OleDbType.Decimal).Value = inv.MarkupPer
            .Add("@LAstDate", OleDbType.Date).Value = inv.LastDateupdated
            .Add("@LastUser ", OleDbType.VarChar, 100).Value = inv.UpserUpdated
            .Add("@UId", OleDbType.Integer).Value = inv.ID
        End With
        cn.Open()
        cmd.ExecuteNonQuery()
    End Using
End Sub
...