How to add information to a table that already has information in it

How to add information to a table that already has information in it

mecoman6GF27
Advocate Advocate
742 Views
9 Replies
Message 1 of 10

How to add information to a table that already has information in it

mecoman6GF27
Advocate
Advocate

Hi everyone.

As per the title of the post, I need to add new information to an existing table which already contains information. I tried this code but it doesn't add the new information and it doesn't give me any errors.

 

    Private Sub B_OK_Click(sender As Object, e As EventArgs) Handles B_OK.Click
        Dim Dwg_Doc = Application.DocumentManager.MdiActiveDocument
        Dim Dwg_DB = Dwg_Doc.Database

        Try
            Using Trans_Write_Dict = Dwg_DB.TransactionManager.StartTransaction()
                Dim NOD = CType(Trans_Write_Dict.GetObject(Dwg_DB.NamedObjectsDictionaryId, OpenMode.ForRead), DBDictionary)
                Dim Dict As DBDictionary
                Dim Info As New ResultBuffer

                If NOD.Contains("Named_Obj_Dict") Then
                    Dict = CType(Trans_Write_Dict.GetObject(NOD.GetAt("Named_Obj_Dict"), OpenMode.ForWrite), DBDictionary)

                    Dim XRec_Existing_Info As Xrecord = CType(Trans_Write_Dict.GetObject(Dict.GetAt("Informations"), OpenMode.ForWrite), Xrecord)
                    Dim XRec_Existing_Info_Data = XRec_Existing_Info.Data

                    Dim XRec_New_Info As Xrecord = New Xrecord
                    XRec_New_Info = CType(Trans_Write_Dict.GetObject(Dict.GetAt("Informations"), OpenMode.ForWrite), Xrecord)

                    For a As Integer = 0 To XRec_Existing_Info_Data.AsArray.Count - 1
                        Info.Add(New TypedValue(1, XRec_Existing_Info_Data.AsArray(a).Value.ToString))
                    Next

                    Info.Add(New TypedValue(1, TB1.Text))
                    Info.Add(New TypedValue(1, TB2.Text))
                    Info.Add(New TypedValue(1, TB3.Text))
                    Info.Add(New TypedValue(1, CB1.Text))
                    Info.Add(New TypedValue(1, CB2.Text))

                    XRec_New_Info.Data = Info

                    Trans_Write_Dict.Commit()
                Else
                    MsgBox("Error! The NOD does not exist", MsgBoxStyle.Exclamation)
                    Me.Close()
                End If
            End Using

            Me.Close()
        Catch ex As Exception
            MsgBox("General error!!!", MsgBoxStyle.Critical, "Error!!!")
        End Try
    End Sub

 

Where do you think I'm wrong?

Thank you all very much, bye.

0 Likes
743 Views
9 Replies
Replies (9)
Message 2 of 10

norman.yuan
Mentor
Mentor
If NOD.Contains("Named_Obj_Dict") Then
    Dict = CType(Trans_Write_Dict.GetObject(NOD.GetAt("Named_Obj_Dict"), OpenMode.ForWrite), DBDictionary)

    Dim XRec_Existing_Info As Xrecord = CType(Trans_Write_Dict.GetObject(Dict.GetAt("Informations"), OpenMode.ForWrite), Xrecord)
    Dim XRec_Existing_Info_Data = XRec_Existing_Info.Data

    '' ========== Remove following 2 lines ==========
    '' Dim XRec_New_Info As Xrecord = New Xrecord
    '' XRec_New_Info = CType(Trans_Write_Dict.GetObject(Dict.GetAt("Informations"), OpenMode.ForWrite), Xrecord)

    For a As Integer = 0 To XRec_Existing_Info_Data.AsArray.Count - 1
        Info.Add(New TypedValue(1, XRec_Existing_Info_Data.AsArray(a).Value.ToString))
    Next

    Info.Add(New TypedValue(1, TB1.Text))
    Info.Add(New TypedValue(1, TB2.Text))
    Info.Add(New TypedValue(1, TB3.Text))
    Info.Add(New TypedValue(1, CB1.Text))
    Info.Add(New TypedValue(1, CB2.Text))

     '' ==== Change this line ====
     '' XRec_New_Info.Data = Info
     XRec_Existing_Info.Data = info

     Trans_Write_Dict.Commit()
  Else
     MsgBox("Error! The NOD does not exist", MsgBoxStyle.Exclamation)
     Me.Close()
  End If

 

Also, the Dictionary itself does not have to be opened for writing, because you are not adding new Xrecord to the Dictionary, but only modify existing Xrecord, which is to be opened for writing.

 

Norman Yuan

Drive CAD With Code

EESignature

0 Likes
Message 3 of 10

mecoman6GF27
Advocate
Advocate

Hi norman.yuan, thanks for your reply.

Even opening the dictionary for reading and the XRecord for writing I get the same result as before.

I noticed one thing: with both my solution and yours the new data is stored in 'XRec_Existing_Info' but it is not stored in 'Dict'.

Other ideas?
Thanks a lot, bye.

0 Likes
Message 4 of 10

mecoman6GF27
Advocate
Advocate

No idea? 😭

0 Likes
Message 5 of 10

_gile
Consultant
Consultant

Hi,

My two cents, try to make things as simple as possible.

This should work:

If NOD.Contains("Named_Obj_Dict") Then
    Dict = CType(Trans_Write_Dict.GetObject(NOD.GetAt("Named_Obj_Dict"), OpenMode.ForWrite), DBDictionary)

    Dim XRec_Existing_Info As Xrecord = CType(Trans_Write_Dict.GetObject(Dict.GetAt("Informations"), OpenMode.ForWrite), Xrecord)
    Dim XRec_Existing_Info_Data = XRec_Existing_Info.Data

    XRec_Existing_Info.Data.Add(New TypedValue(1, TB1.Text))
    XRec_Existing_Info.Data.Add(New TypedValue(1, TB2.Text))
    XRec_Existing_Info.Data.Add(New TypedValue(1, TB3.Text))
    XRec_Existing_Info.Data.Add(New TypedValue(1, CB1.Text))
    XRec_Existing_Info.Data.Add(New TypedValue(1, CB2.Text))

    XRec_Existing_Info.Data = XRec_Existing_Info.Data

    Trans_Write_Dict.Commit()

 

You could also use a generic method works to add data (TypedValues) to an existing Xrecord as the following one.

 

        public static void AddData(Database db, string dictName, string xrecName, params TypedValue[] values)
        {
            using (var tr = db.TransactionManager.StartTransaction())
            {
                var NOD = (DBDictionary)tr.GetObject(db.NamedObjectsDictionaryId, OpenMode.ForRead);
                if (NOD.Contains(dictName))
                {
                    var dict = (DBDictionary)tr.GetObject(NOD.GetAt(dictName), OpenMode.ForRead);
                    if (dict.Contains(xrecName))
                    {
                        var xrec = (Xrecord)tr.GetObject(dict.GetAt(xrecName), OpenMode.ForWrite);
                        var data = xrec.Data;
                        foreach (TypedValue typedValue in values)
                        {
                            data.Add(typedValue);
                        }
                        xrec.Data = data;
                    }
                }
                tr.Commit();
            }
        }

 

And simply call:

 

Private Sub B_OK_Click(sender As Object, e As EventArgs) Handles B_OK.Click
    Dim Dwg_Doc = Application.DocumentManager.MdiActiveDocument
    Dim Dwg_DB = Dwg_Doc.Database
	
    AddData("Named_Obj_Dict", "Informations", New TypedValue(1, TB1.Text), New TypedValue(1, TB2.Text), New TypedValue(1, TB3.Text), New TypedValue(1, CB1.Text), New TypedValue(1, CB2.Text))

 



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 6 of 10

mecoman6GF27
Advocate
Advocate

Hello _Gile and thanks for the reply.

I tried your solutions but the result is still the same. The data is stored in "xrec" but not in the dictionary.

0 Likes
Message 7 of 10

_gile
Consultant
Consultant

A DBDictionary cannot directly contain data as strings, numbers, points ...

Typically, these kind of data are stored in Xrecords (or DataTables) which can be entries of the DBDictionary.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 8 of 10

mecoman6GF27
Advocate
Advocate

Hello _Gile.

It is clear to me what you say; as i said before (maybe i wasn't very clear) the new data is added to the variable "xrec" but only during the execution of the command. If I later try to retrieve them, they are not there.

0 Likes
Message 9 of 10

_gile
Consultant
Consultant

@mecoman6GF27  a écrit :

the new data is added to the variable "xrec" but only during the execution of the command. If I later try to retrieve them, they are not there.


This is not due to the upper codes. You should use a separate generic method as the one I purposed so that you can either call it from a simple testing command method (as I did and it worked as expected) or from your dialog box.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 10 of 10

mecoman6GF27
Advocate
Advocate

Hello everyone and sorry if I reply after a few days but I've been busy with work.

I managed to make some progress. Now with the code I wrote I can insert data and update them but I have a problem. The same code is present on 2 forms but it is executed only by the first form and not by the second one (from form2 I don't get any error).
Do you have any idea why this problem?
This is what I wrote:

 

 

    Private Sub B_OK_Click(sender As Object, e As EventArgs) Handles B_OK.Click
        Try
            Dim Dwg_Doc = Application.DocumentManager.MdiActiveDocument
            Dim Dwg_DB = Dwg_Doc.Database
' Transaction present only in form1
            Using Trans As Transaction = HostApplicationServices.WorkingDatabase.TransactionManager.StartTransaction()
                Dim NOD As DBDictionary = Trans.GetObject(HostApplicationServices.WorkingDatabase.NamedObjectsDictionaryId, OpenMode.ForWrite)
                Dim Dict As DBDictionary = New DBDictionary()

                If NOD.Contains("Named_Obj_Dict") = False Then
                    NOD.SetAt("Named_Obj_Dict", Dict)
                    Trans.AddNewlyCreatedDBObject(Dict, True)
                End If
                Trans.Commit()
            End Using

            Dim XRec As Xrecord
' Transaction present only in form1
            Using Trans1 As Transaction = Dwg_DB.TransactionManager.StartTransaction()
                Dim NOD1 As DBDictionary = Trans1.GetObject(Dwg_DB.NamedObjectsDictionaryId, OpenMode.ForRead)
                Dim Dict1 As DBDictionary

                If NOD1.Contains("Named_Obj_Dict") = True Then
                    Dict1 = Trans1.GetObject(NOD1.GetAt("Named_Obj_Dict"), OpenMode.ForRead)

                    If Dict1.Contains("Informations") = False Then
                        XRec = New Xrecord()

                        If Not Dict1.IsWriteEnabled Then
                            Trans1.GetObject(Dict1.ObjectId, OpenMode.ForWrite)
                            Dict1.SetAt("Informations", XRec)
                            Trans1.AddNewlyCreatedDBObject(XRec, True)
                        End If
                    End If
                End If

                Trans1.Commit()
            End Using
' Transaction present in form1 and form2
            Using Trans_Info As Transaction = Dwg_DB.TransactionManager.StartTransaction()
                Dim NOD1 As DBDictionary = Trans_Info.GetObject(Dwg_DB.NamedObjectsDictionaryId, OpenMode.ForRead)
                Dim Dict1 As DBDictionary

                If NOD1.Contains("Named_Obj_Dict") = True Then
                    Dict1 = Trans_Info.GetObject(NOD1.GetAt("Named_Obj_Dict"), OpenMode.ForRead)

                    If Dict1.Contains("Informations") Then
                        XRec = Trans_Info.GetObject(Dict1.GetAt("Informations"), OpenMode.ForWrite)

                        Dim XRec_Info As ResultBuffer = New ResultBuffer(
                            New TypedValue(1, "Info1"),
                            New TypedValue(1, "Info2"),
                            New TypedValue(1, "Info3"))

                            XRec.Data = XRec_Info
                    End If
                End If

                Trans_Info.Commit()
            End Using

            Me.Close()

        Catch ex As Exception
            MsgBox("Error!!!", MsgBoxStyle.Critical, "Error!!!")
        End Try
    End Sub

 

 

Thanks everyone, bye.

0 Likes