.NET
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Save some variables into DWG file - how? C#.

22 REPLIES 22
SOLVED
Reply
Message 1 of 23
GrzesiekGP
5649 Views, 22 Replies

Save some variables into DWG file - how? C#.

Hello!

 

Please let me know if I'm able to save some variables into current DWG?

 

I would like to provide availability for user to save some data which is different for each DWG file.

 

Thanks.

Tags (2)
22 REPLIES 22
Message 2 of 23
arcticad
in reply to: GrzesiekGP
Message 3 of 23
StephenPreston
in reply to: arcticad

Further to arcticad's reply, you'd typically store global data on the Named Objects Dictionary, and data related to a particular entity as xdata on that entity or as an xrecord in its extension dictionary.

 

But if you're storing 'variables' (sysvars), then you migh prefer to use the Autodesk.AutoCAD.Runtime.Variable class. You can specify whether the variable is per session, per user, per profile or per database.

 

 

Cheers,

Stephen Preston
Autodesk Developer Network
Message 4 of 23
arcticad
in reply to: StephenPreston

I don't seem to find any information on how to use Autodesk.AutoCAD.Runtime.Variable

Can you point me in the direction.

Thanks.

---------------------------



(defun botsbuildbots() (botsbuildbots))
Message 5 of 23

I used LispVariable to store data in file so user could use them in Text Field.

Here are examples how to get and set Lisp Variables I used.

http://www.theswamp.org/index.php?topic=35714.0

 

Richard.

Message 6 of 23

I forgot to say then these variables are not saved in drawing.

Richard

Message 7 of 23
GrzesiekGP
in reply to: GrzesiekGP

Thank you for the links.

 

Following the first, I have question - am I able to set my XData without selecting an entity?

Message 8 of 23
_gile
in reply to: arcticad

Hi articad,

 

You can see this thread about custom Variables.

IMO, the main issue with Autodesk.AutoCAD.Runtim.Variable is the variable has to be registered in HKLM which most often requires administrator user account.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 9 of 23

Use DBDictionary to save data (XRecord) in file.

Try to search for   NamedObjectsDictionary (NOD) you should find many examples in this forum.

 

Richard

Message 10 of 23
_gile
in reply to: GrzesiekGP

Hi GrzesiekGP,

 

If you want to go the Xdata route without selecting an entity, you can set your Xdata on any DBObject (i.e. layer "0", model space BlockTableRecord) but, IMO, you'd rather use a DBDictionary and Xrecord.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 11 of 23
GrzesiekGP
in reply to: _gile

Do you have some example of code for XRecords and DBDictionary?

 

I'm searching, but it hard to find what I need.

Message 12 of 23
_gile
in reply to: GrzesiekGP

Here're two little example to set and get xrecord data (ResultBuffer as for Xdata) in a named dictionary child of the root NamedObjectsDictionary (NOD).

        /// <summary>
        /// Add or edit a Xrecord data in a named dictionary (the dictionary and xrecord are created if not already exist)
        /// </summary>
        /// <param name="dictName">The dictionary name</param>
        /// <param name="key">the xrecord key</param>
        /// <param name="resbuf">the xrecord data</param>
        public void SetXrecord(string dictName, string key, ResultBuffer resbuf)
        {
            Document doc = acadApp.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                DBDictionary NOD = 
                    (DBDictionary)tr.GetObject(db.NamedObjectsDictionaryId, OpenMode.ForRead);
                DBDictionary dict;
                if (NOD.Contains(dictName))
                {
                    dict = (DBDictionary)tr.GetObject(NOD.GetAt(dictName), OpenMode.ForWrite);
                }
                else
                {
                    dict = new DBDictionary();
                    NOD.UpgradeOpen();
                    NOD.SetAt(dictName, dict);
                    tr.AddNewlyCreatedDBObject(dict, true);
                }
                Xrecord xRec = new Xrecord();
                xRec.Data = resbuf;
                dict.SetAt(key, xRec);
                tr.AddNewlyCreatedDBObject(xRec, true);
                tr.Commit();
            }
        }

        /// <summary>
        /// Gets an xrecord data in a named dictionary
        /// </summary>
        /// <param name="dictName">The dictionary name</param>
        /// <param name="key">The xrecord key</param>
        /// <returns>The xrecord data or null if the dictionary or the xrecord do not exist</returns>
        public ResultBuffer GetXrecord(string dictName, string key)
        {
            Document doc = acadApp.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                DBDictionary NOD = 
                    (DBDictionary)tr.GetObject(db.NamedObjectsDictionaryId, OpenMode.ForRead);
                if (!NOD.Contains(dictName))
                    return null;
                DBDictionary dict = tr.GetObject(NOD.GetAt(dictName), OpenMode.ForRead) as DBDictionary;
                if (dict == null || !dict.Contains(key))
                    return null;
                Xrecord xRec = tr.GetObject(dict.GetAt(key), OpenMode.ForRead) as Xrecord;
                if (xRec == null)
                    return null;
                return xRec.Data;
            }
        }

 

 

 



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 13 of 23
GrzesiekGP
in reply to: _gile

Thank you very much for help.

 

Please tell me one more thinkg. Am I able to get specified TypedValue from ResultBuffer?

If not I suppose that the best way would be to put all values into dictionary<int,string>. Am I right?

Message 14 of 23
_gile
in reply to: GrzesiekGP

As for Xdata you have to use a ResultBuffer to set data in a Xrecord and the Xrecord.Data property is a ResultBuffer.

Assuming your xrecord contains a single data of type String, you can get the data this way:

 

ResultBuffer resbuf = GetXrecord(theDictName, theXrecKey);

string theFirstData =(string) resbuf.AsArray()[0].Value;



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 15 of 23
GrzesiekGP
in reply to: _gile

Thank you for the help Smiley Happy

Message 16 of 23
GrzesiekGP
in reply to: _gile

Please let me know one more thing.

 

Am I able to get all keys from my dictionary?

 

I would to allow user to select from which Key in my dictionary user want to see his variables.

 

In example:

 

SetXrecord("myDict", "keysFirst", rb);

SetXrecord("myDict", "keysSecond", rb);

SetXrecord("myDict", "keysThird", rb);

 

And now I want to list: keysFirst,keysSecond,keysThird.

 

Ok, I've got it:

 List<string> _keys = new List<string>();
                foreach (DBDictionaryEntry entry in dict)
                {
                    _keys.Add(entry.Key);
                }
                return string.Join(",", _keys.ToArray());

 

 

Message 17 of 23
GrzesiekGP
in reply to: GrzesiekGP

One more to do 🙂 Removing keys 😛

 

I have this code:

 

public static void RemoveXrecord(string dictName, string key)
        {
            Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            DocumentLock dl = doc.LockDocument(DocumentLockMode.ProtectedAutoWrite, null, null, true);
            using (dl)
            {
                using (Transaction tr = db.TransactionManager.StartTransaction())
                {
                    DBDictionary NOD = (DBDictionary)tr.GetObject(db.NamedObjectsDictionaryId, OpenMode.ForRead);
                    if (!NOD.Contains(dictName))
                        return;
                    DBDictionary dict = tr.GetObject(NOD.GetAt(dictName), OpenMode.ForWrite) as DBDictionary;
                    if (dict == null || !dict.Contains(key))
                        return;
                    dict.Remove(key);
                }
            }
        }

 But key still exist after removing 😞

Message 18 of 23
_gile
in reply to: GrzesiekGP

It looks like you forgot to call: tr.Commit();



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 19 of 23
GrzesiekGP
in reply to: _gile

Lol, I'm blind Smiley Tongue

 

Thank you!

Message 20 of 23

Once you work with Dictionaries very useful is ArxDbd utility for testing.

http://otb.manusoft.com/2009/09/arxdbg-utility.htm

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk DevCon in Munich May 28-29th


Autodesk Design & Make Report

”Boost