Document vs Database (in ActiveX)

Document vs Database (in ActiveX)

Moshe-A
Mentor Mentor
1,816 Views
12 Replies
Message 1 of 13

Document vs Database (in ActiveX)

Moshe-A
Mentor
Mentor

hi guys,

 

1. What is the difference between Document and Database? more specific i mean, when do i use Database? whereas to have a Database pointer i need a Document pointer and the Document pointer has all the properties and method needed.

 

2. Opening an xref Document with ObjDBX, how can i retrieve a sysvar saved in the document? when

 (vla-GetVariable) is not available?

 

thanks

Moshe

0 Likes
Accepted solutions (3)
1,817 Views
12 Replies
Replies (12)
Message 2 of 13

CodeDing
Advisor
Advisor
Accepted solution

@Moshe-A ,

 

1) The difference between Document and Database is the different items that they hold. The Object Model for AutoCAD will tell you whether items are located in the Document or Database (use the Legend to help).

 

2) Since ObjectDBX only relates to database items, and the System Variables are stored in the Document object then you will not be able to access them via ObjectDBX.

 

Does that help?

Best,

~DD

0 Likes
Message 3 of 13

Moshe-A
Mentor
Mentor

@CodeDing hi,

 

Thank you for responding to this.

 

From what you said i understand that opening an XREF with ObjDBX i actually gets a database object (not a document) so the question still remains how can i access sysvars on xref from AutoLISP\ActiveX?

 

On my developing 'desk' is an application that copies layers properties (for example) from the xrefs up to host and i bumped at plot style and needed to check pstylemode from xref which i couldn't. maybe along the way i will need to check some others?!

 

Moshe

 

0 Likes
Message 4 of 13

john.uhden
Mentor
Mentor

Moshe,

I just checked (in C3D 2020).  Please follow the following example...

(and
  (setq e (car (entsel "\nSelect an xref: ")))
  (setq Obj (vlax-ename->vla-object e))
  (= (vlax-get Obj 'ObjectName) "AcDbBlockReference")
  (vlax-property-available-p Obj 'Path)
  (vlax-property-available-p Obj 'Document)
  (setq Doc (vlax-get Obj 'Document))
  (setq psm (vlax-invoke Doc 'getvariable "pstylemode"))
)

 

John F. Uhden

0 Likes
Message 5 of 13

CodeDing
Advisor
Advisor

@john.uhden ,

 

I tested your example trying to retrieve PDMODE from an XREF and it was returning only the current PDMODE. Perhaps something is incorrect?

 

(and
  (setq e (car (entsel "\nSelect an xref: ")))
  (setq Obj (vlax-ename->vla-object e))
  (= (vlax-get Obj 'ObjectName) "AcDbBlockReference")
  (vlax-property-available-p Obj 'Path)
  (vlax-property-available-p Obj 'Document)
  (setq Doc (vlax-get Obj 'Document))
  (setq psm (vlax-invoke Doc 'getvariable "pdmode"))
)
0 Likes
Message 6 of 13

Moshe-A
Mentor
Mentor

@john.uhden 

 

for a few moments i was joyful you shine it 😀and  rushed to test it. here is the print of the xref document (which i got from a layer inside xref) as you can see GetVariable is not there - nice try dude 👍

 

Moshe

 

 

$ dbxdoc
#<VLA-OBJECT IAxDbDocument 000000003a44f4d0>
_$ (vlax-dump-object dbxdoc t)
; IAxDbDocument: IAxDbDocument Interface
; Property values:
;   Application (RO) = Exception occurred
;   Blocks (RO) = #<VLA-OBJECT IAcadBlocks 0000000042d3a588>
;   Database (RO) = #<VLA-OBJECT IAcadDatabase 00000000415b89b8>
;   Dictionaries (RO) = #<VLA-OBJECT IAcadDictionaries 0000000042d3c358>
;   DimStyles (RO) = #<VLA-OBJECT IAcadDimStyles 0000000042d38de8>
;   ElevationModelSpace = 0.0
;   ElevationPaperSpace = 0.0
;   FileDependencies (RO) = #<VLA-OBJECT IAcadFileDependencies 0000000042a912b8>
;   Groups (RO) = #<VLA-OBJECT IAcadGroups 0000000042d38f08>
;   Layers (RO) = #<VLA-OBJECT IAcadLayers 0000000043833d88>
;   Layouts (RO) = #<VLA-OBJECT IAcadLayouts 0000000042d3ba58>
;   Limits = (0.0 0.0 12.0 9.0)
;   Linetypes (RO) = #<VLA-OBJECT IAcadLineTypes 0000000042d3f718>
;   Materials (RO) = #<VLA-OBJECT IAcadMaterials 0000000042d3f688>
;   ModelSpace (RO) = #<VLA-OBJECT IAcadModelSpace 000000003b98f628>
;   Name = "C:\\Users\\user\\Documents\\46-2016-DGSH-D-TNUA MICHRAZ TASHTIOT23.dwg"
;   PaperSpace (RO) = #<VLA-OBJECT IAcadPaperSpace 0000000042a8f4b8>
;   PlotConfigurations (RO) = #<VLA-OBJECT IAcadPlotConfigurations 0000000042d38f98>
;   Preferences (RO) = #<VLA-OBJECT IAcadDatabasePreferences 0000000042a91278>
;   RegisteredApplications (RO) = #<VLA-OBJECT IAcadRegisteredApplications 0000000042d38ba8>
;   SectionManager (RO) = Exception occurred
;   SummaryInfo (RO) = #<VLA-OBJECT IAcadSummaryInfo 000000003a455058>
;   TextStyles (RO) = #<VLA-OBJECT IAcadTextStyles 0000000042d40498>
;   UserCoordinateSystems (RO) = #<VLA-OBJECT IAcadUCSs 0000000042d3a7c8>
;   Viewports (RO) = #<VLA-OBJECT IAcadViewports 0000000042d3c088>
;   Views (RO) = #<VLA-OBJECT IAcadViews 0000000042d3bff8>
; Methods supported:
;   CopyObjects (3)
;   DxfIn (2)
;   DxfOut (3)
;   HandleToObject (1)
;   ObjectIdToObject (1)
;   Open (2)
;   Save ()
;   SaveAs (2)
T
_$ 

 

 

0 Likes
Message 7 of 13

john.uhden
Mentor
Mentor
Ya know what?
I think the 'Document property of the xref object is in fact the current
document.
My apologies for the wild goose chase.
Perhaps the only way is to open the xref and grab whatever variables you
want and put them on the bulletin board.

John F. Uhden

0 Likes
Message 8 of 13

Moshe-A
Mentor
Mentor

yes you are right but this bring us to the same result.

and it's not settle with what  @CodeDing  indicate that open an xref with ObjDBX would return only database object. 

 

in the documentation under Database property it says: The contents of an XRef block.

 

and at bottom it has this remark:

This object provides access to the contents of an external reference block. It is only available on blocks whose  IsXref property is equal to True.

 

So my (temp) conclusion is when you call for a Document (prop) for an xref you actually gets a Database object. that is because in AutoCAD terms a Document is only an open (session) database.

 

hope some other Experts will join in cause it's starts getting interesting here 😀

 

thanks,

Moshe

 

 

0 Likes
Message 9 of 13

john.uhden
Mentor
Mentor
Accepted solution
@Moshe-A
That's why I replied to @Anonymous-Ding that you would have to open the xref as
another document and save whatever values you want to the bulletin board.
I'm just not up on how to continue AutoLisp/Vlisp from one document to
another and back again.

John F. Uhden

0 Likes
Message 10 of 13

doaiena
Collaborator
Collaborator
Accepted solution

I don't know if you are interested in a .NET solution, but with my extremely limited skills in that domain, i was able to assemble something sort of useful.

 

 

_$ (getvar "pdmode")
1
_$ (GetVarFromFile "C:\\Test\\test1.dwg" "pdmode")
("33")
_$ (GetVarFromFile "C:\\Test\\test2.dwg" "pdmode")
("0")
_$ 

 

 


.NET source:

 

 

using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Runtime;


namespace ACAD_Test
{
    public class MyCommands
    {
        [LispFunction("GetVarFromFile")]
        public static object GetVarFromFile(ResultBuffer resbuf)
        {
            try
            {
                Document doc = Application.DocumentManager.MdiActiveDocument;
                Editor ed = doc.Editor;
                Database db = doc.Database;
                ResultBuffer rb = new ResultBuffer();

                if (resbuf == null)
                {
                    return null;
                }

                TypedValue[] args = resbuf.AsArray();
                string extFile = (string)args[0].Value;
                string variable = (string)args[1].Value;

                using (Database extDB = new Database(false, true))
                {
                    extDB.ReadDwgFile(extFile, System.IO.FileShare.Read, false, "");
                    var result = extDB.GetType().GetProperty(variable, System.Reflection.BindingFlags.IgnoreCase | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance).GetValue(extDB, null);
                    rb.Add(new TypedValue((int)LispDataType.Text, result.ToString()));
                }

                return (rb.AsArray().Length > 0) ? rb : null;
            }
            catch (System.Exception Ex)
            {
                //Application.ShowAlertDialog("System exception:\n" + Ex.Message + "\n" + Ex.Source + "\n" + Ex.StackTrace);
                return null;
            }
        }//GetVarFromFile
    }
}

 

 



I will attach a compiled dll for those who can't compile it themselves. The target framework is "Net Framework 4.6".

Use "Netload" in ACAD to load the dll. Once the file is loaded, the "GetVarFromFile" function will become available.

 

Also, have in mind that you need to target the .NET property names ("pstylemode" in .NET is "PlotStyleMode"). Here is a reference to the database properties:

database properties 

0 Likes
Message 11 of 13

Sea-Haven
Mentor
Mentor

You can use a script to switch between dwgs you would write the script with the correct dwg xref name before running.

 

Trying to think if using the documents method will help

 

(defun openblk (blkname / adocs)
(setq acDocs (vla-get-documents (vlax-get-acad-object)))
(vla-open acDocs blkname)
(vla-activate (vla-item acdocs 1))
;(vla-put-activedocument (vlax-get-acad-object) (vla-item acdocs 1))
)

 

0 Likes
Message 12 of 13

Moshe-A
Mentor
Mentor

@doaiena  hi,

 

thanks you very much  for that C sharp dot net code. i also do not use dot net and i think it would be a little problematic cause i neeed a dll for each autocad version or i'm worng?

anyhow i'll keep that in safe place (who knows?!)

 

@Sea-Haven 

my second plan was to open the xref with documents object which i'll use if have no other option to do it.

 

@john.uhden 

mean time as i want to retrieve only pstylemode i use a workaround by checking the plot style name and if it starts with "Color_"than i assume not copy that (cause the color made the change)

 

so guys thank you all for this help it was a huge pleasure 😀

 

keep safe from COVID-19

Moshe

 

0 Likes
Message 13 of 13

john.uhden
Mentor
Mentor

@Moshe-A 

This is just AutoLisp.  If you can temporarily open the "other" dwg and know its name, then...

(defun @getdwgvariable (name var / docs doc var)
  (and
    (setq *acad* (vlax-get-acad-object))
    (setq docs (vlax-get *acad* 'documents))
    (vlax-for item docs
      (if
        (or
          (= (strcase name)(strcase (vlax-get item 'Name)))
          (= (strcase name)(strcase (vl-filename-base (vlax-get item 'Name))))
        )
        (setq doc item)
        1
      )
    )
    doc
    (setq val (vlax-invoke doc 'getvariable var))
  )
  val
)

John F. Uhden

0 Likes