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

reading strings from TEXT and MTEXT using VB.NET

12 REPLIES 12
Reply
Message 1 of 13
ConstantineS
10723 Views, 12 Replies

reading strings from TEXT and MTEXT using VB.NET

I'm trying to read text from TEXT and MTEXT objects in AutoCAD 2010 using VB.NET and have run into difficulties.  Here is my code:

 

    <Autodesk.AutoCAD.Runtime.CommandMethod("runTest", CommandFlags.Session)> _
Public Sub Test()

Dim acDocEd As Editor
Dim acTypValAr(3) As TypedValue
Dim acSelFtr As SelectionFilter
Dim acSSPrompt As PromptSelectionResult
Dim acSSet As SelectionSet
Dim selObj As SelectedObject
Dim textObj As Autodesk.AutoCAD.Interop.Common.AcadText
Dim mtextObj As Autodesk.AutoCAD.Interop.Common.AcadMText

acDocEd = Application.DocumentManager.MdiActiveDocument.Editor

acTypValAr.SetValue(New TypedValue(DxfCode.Operator, "<or"), 0)
acTypValAr.SetValue(New TypedValue(DxfCode.Start, "TEXT"), 1)
acTypValAr.SetValue(New TypedValue(DxfCode.Start, "MTEXT"), 2)
acTypValAr.SetValue(New TypedValue(DxfCode.Operator, "or>"), 3)

acSelFtr = New SelectionFilter(acTypValAr)
acSSPrompt = acDocEd.SelectAll(acSelFtr)

If acSSPrompt.Status = PromptStatus.OK Then
acSSet = acSSPrompt.Value
For Each selObj In acSSet
If selObj.GetType.ToString = "TEXT" Then
textObj = selObj
MsgBox("Text = " & textObj.TextString)
Else
mtextObj = selObj
MsgBox("Text = " & mtextObj.TextString)
End If
Next selObj
End If
End Sub

I realize that the ".TextString" method only works on TEXT and MTEXT objects and not a generic "SelectedObject", so I tried to detect the object type (my code does not work), then I need to convert the selected object to either TEXT or MTEXT (again my code doesn't work).

 

Is there a better way to do this?  Can it be done without using COM objects?

 

Thanks in advance,

Constantine

 

 

 

12 REPLIES 12
Message 2 of 13

Yes, it can be done without COM. 

 

One problem you have there is that selObj.GetType.ToString will always return the Fully Qualified Type Name (which will ALWAYS be "Autodesk.AutoCAD.EditorInput.SelectedObject")

 

The other problem is that you can't just cast from SelectedObject to things derived from DbObject. (or to COM AcadText or AcadMText) You have to use a Transaction and the ObjectId pointer provided by the SelectedObject, and open the object for read.  As you'll see below, the ObjectId also has an ObjectClass property which is useful for Type-Testing an object without opening it.

 

For the simplest change needed to make your code work, remove your declaration of textObj and mtextObj, and replace your For Each selObj...Next with this code:

 

Using trans As Transaction = HostApplicationServices.WorkingDatabase.TransactionManager.StartTransaction
    Try
	For Each selObj In acSSet
	    Select Case selObj.ObjectId.ObjectClass.Name
		Case "AcDbText"
		    Dim textObj As DBText = trans.GetObject(selObj.ObjectId, OpenMode.ForRead, False, True)
		    MsgBox("Text = " & textObj.TextString)
		    textObj.Dispose()
		Case "AcDbMText"
		    Dim mtextObj As MText = trans.GetObject(selObj.ObjectId, OpenMode.ForRead, False, True)
		    MsgBox("Text = " & mtextObj.Contents)
		    mtextObj.Dispose()
	    End Select
	Next selObj
    Catch ex As Exception
    Finally
	trans.Commit()
    End Try
End Using

 

Dave O.                                                                  Sig-Logos32.png
Message 3 of 13

Thanks Chief,

 

Thanks, that worked.  As I transition from VBA to VB.NET, I am lacking a fundamental understanding of VB.NET, such as when to use a transaction, and of the AutoCAD object model so that I can avoid using COM.  Do you know of good sources, on line or in book(s), for these topics?

 

Thanks,

Constantine

Message 4 of 13

When to use a transaction or not is based on the AutoCAD API, as opposed to VB, and basically, if you are using COM, (ie. methods/objects exposed under the Interop and Interop.Common namespace) you never use a transaction, because the COM wrappers take care of it for you.  If you are using the managed API, you need to use a transaction any time you want to access objects through the ObjectID.

 

As far as sources go, this is starting to get repetitive, but:

1) there is a blog by Kean Walmsley called Through the Interface

http://through-the-interface.typepad.com/through_the_interface/

 

It is a great reference, especially if you get the RSS feed, making it easier to search through his posts.

 

2) the ObjectARX Software developers kit contains some .NET examples and the ARX help files.  I use the ARX help files when the .NET help is less than helpful.

 

3) There is an online Developer Guide for .NET, but I don't have a handy link to post, because I don't use it.

 

There are also several people who frequent this discussion group who are also on 'The Swamp'.  I am not a member over there.

 

As far as books, there is one, which has earned mixed reviews on this group, by ....Jerry.... I'm drawing a blank on his last name. (sorry Jerry 😉 

Dave O.                                                                  Sig-Logos32.png
Message 5 of 13
arcticad
in reply to: ConstantineS

VB.NET For AutoCAD 2010

 http://www.vbcad.com/

Jerry Winters

 

I purchased the book, I'd recommend it. go buy it.

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



(defun botsbuildbots() (botsbuildbots))
Message 6 of 13
ConstantineS
in reply to: arcticad

Thanks guys.

Message 7 of 13

Hi,

 

I want to display string from autocad to datagridview. Can you help me?

Please see attachment.

Message 8 of 13
Hallex
in reply to: ditran7577

If you use windows form datagridview then you have  create

List<string, int> mtextcounts  which is include mtext string (unique) and number of count

then pass it as argument in your datagridview , say on button click:

 

this.DataGridView1,DataSource=mtextcounts

this.DataGridView1.DataMember="YourColumnName"

_____________________________________
C6309D9E0751D165D0934D0621DFF27919
Message 9 of 13
Hallex
in reply to: ditran7577

See how I would do it, with limited testing:

 

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.EditorInput;

namespace MtextTools
{
    public partial class Form1 : Form
    {
        // added button1, button2, datagridview1, label1 for test
        private  SortedList<string, int> dgvsource = new SortedList<string, int>();
        private BindingSource bind = new BindingSource();

        public Form1()
        {
            InitializeComponent();
            
        }

        private void btnSelect_Click(object sender, EventArgs e)
        {
            this.dataGridView1.Columns.Clear();
            this.label1.Text = "";
           // this.Hide();// if modeless


            testMtextCount();


            bind = new BindingSource();
            bind.DataSource = null;
            bind.DataSource = dgvsource;
            this.dataGridView1.DataSource = bind;
            this.dataGridView1.Columns[0].HeaderText = "MODEL";
            this.dataGridView1.Columns[1].HeaderText = "QUANTITY";
            this.dataGridView1.Columns[0].Width = 240;
            this.dataGridView1.Columns[1].Width = 120;
            this.dataGridView1.DataMember = bind.DataMember;
            this.label1.Text = "SUM RUNS: ";
            string runs = dgvsource.Values.Sum().ToString();
            this.label1.Text = this.label1.Text + runs;
            //clear data
            dgvsource.Clear();
            runs = "";
            // this.Show();// if modeless
        }

        private  void testMtextCount()
        {

            Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;

            Database db = doc.Database;

            Editor ed = doc.Editor;

            PromptSelectionOptions pso = new PromptSelectionOptions();

            pso.MessageForRemoval = "\nFailed to select mtexts!";

            pso.MessageForAdding = "\nPlease, select the mtexts on screen: ";

            // build filter to select the mtexts
            SelectionFilter filter =
                new SelectionFilter(new TypedValue[] { new TypedValue(0, "mtext") }  );

            // perform mtext selection
            PromptSelectionResult sres = ed.GetSelection(pso, filter);// might be SelectAll instead

            if (sres.Status != PromptStatus.OK) return;
            try
            {

                SelectionSet sset = sres.Value;

                using (Transaction tr = db.TransactionManager.StartTransaction())
                {

                    foreach (SelectedObject sobj in sset)
                    {
                        Entity ent = tr.GetObject(sobj.ObjectId, OpenMode.ForRead, false) as Entity;

                        MText mtx = ent as MText;
                     

                                object[] datum = new object[] { mtx.Text, 1};
                                if (!dgvsource.ContainsKey(mtx.Text))
                                {
                                    dgvsource.Add(mtx.Text, 1);
                                }
                                else
                                {
                                    dgvsource[mtx.Text]+=1;
                                }

                    }
         
                    tr.Commit();

                }

            }
            catch (System.Exception ex)
            {
                Autodesk.AutoCAD.ApplicationServices.Application.ShowAlertDialog(ex.Message + "\n" + ex.StackTrace);
            }
   
        }

        private void btnExit_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
        
 
            this.dataGridView1.AllowUserToOrderColumns = false;
            this.dataGridView1.AllowUserToAddRows = false;
            this.dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;

        }

    }
}

 

_____________________________________
C6309D9E0751D165D0934D0621DFF27919
Message 10 of 13
ditran7577
in reply to: ConstantineS

Thanks Hallex (*Pro) for your feedback.However,you mistake my idea. I want to display that table on win form (VB.NET better) after that export to excel winh same columns and rows. I have mtext and dtext. Can you help me?

 

 2.gif

Message 11 of 13
Hallex
in reply to: ditran7577

Hey, can you read by my lips: my nickname is Hallex

without any prefixes, keep it in mind,

Well, going farter, you can try attached files with my bad explanation,

coz I'm not a teacher to make your homework

_____________________________________
C6309D9E0751D165D0934D0621DFF27919
Message 12 of 13
ditran7577
in reply to: Hallex

Great Hallex. Thank you very much. All text are OK.How about block. For example,I want to count block base on their layer or their tag (layer is MODEL) . And how to export them to excel that we choice. I hope I did not bother you. Thanks.

 

Message 13 of 13
Hallex
in reply to: ditran7577

Better yet to start a new topic with new question,

then more peoples could to help you with it

Here is just similar one on what you need

http://www.acadnetwork.com/topic-228.0.html

About Excel part serach for this question on this forum,

or on theswamp.com

_____________________________________
C6309D9E0751D165D0934D0621DFF27919

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