Block Insertion Routine

#1
I had some trouble figuring this out so I'm posting here to aid anyone else with a similar problem. Context: converting AutoCAD VBA to IntelliCAD VBA.


Our office uses VBA to run a topography routine on points collected by land surveyors in the field. The topo routine looks through all the points in a textfile, inserting them into the modelspace, and can color code points based on their descriptions. The routine also looks at the descriptions, and inserts block symbols where necessary (for trees, manholes, power, etc). To avoid large file sizes, the blocks are stored locally on our machines and attached as external references when needed.

There was a big difference between AutoCAD's VBA and the VBA I had to write to implement this correctly in IntelliCAD. Again, as I've found with other routines, IntelliCAD requires slightly more proper code with error checking. The specific difference is that, when adding an item to the drawing database (a layer, a block, a selection set), IntelliCAD WILL crash if the item already exists. AutoCAD gracefully uses the existing item. So...error checking is your friend in IntelliCAD.

Also, it seems necessary to attach the external reference before inserting a block of that name. The code I've converted from AutoCAD doesn't seem to need that pre-requisite. It simply inserts the block from file, everytime, since it handles the error check gracefully.

The below code shows the error checking routine, which looks to see if the block has already been inserted into the drawing's collection of blocks. If not, then it attaches the external reference (which by the required arguments, also inserts it into modelspace). If another block of the same type is to be inserted, the check will see that the external reference is already attached, and use that block instead.

Code: Select all

'checks to see that the layer the block is to be inserted on already
'exists. If the layer exists, it sets the layerObj to the layer specified.
'If not, it creates the layer and sets the layerObj.
'The layerObj can then be used to set the layer of the block object.
Call LAYER_Exists(LayerName, layerObj)

'This creates the path of the block to be inserted. 
'txtString is the descriptor that is pulled out of the point file.
blkName = BlkPath + txtString + ".dwg"
            
foundBLK = False
'Looks through blocks collection to see if external reference has been added
For Each Blk In ThisWorkspace.ActiveDocument.Blocks
     If Blk.Name = txtString Then
          Set BlkInsObj = ThisWorkspace.ActiveDocument.ModelSpace.InsertBlock(startPoint, txtString, CDbl(Dscale.text) / 10, CDbl(Dscale.text) / 10, 1#, rotang)
          'Sets the layer for the block in modelspace
          BlkInsObj.Layer = layerObj.Name
          BlkInsObj.Update
          foundBLK = True
     End If
Next Blk
'If external reference hasn't been added, add the block to the drawing
If foundBLK = False Then
     Set ExtRef = ThisWorkspace.ActiveDocument.ModelSpace.AttachExternalReference(blkName, txtString, startPoint, CDbl(Dscale.text) / 10, CDbl(Dscale.text) / 10, 1#, rotang, False)
     'Sets the layer for the block in modelspace
     ExtRef.Layer = layerObj.Name
     ExtRef.Update
End If
I hope this helps out anyone who's working on code that automatically inserts blocks into the modelspace. The LAYER_Exists function works much in the same way...check to see if it exists; if it does, set a pointer to that existing layer; if not, create the layer and set a pointer to it. Use the pointer to set the layer of what you're inserting into modelspace (block, text, etc.)

#2
It might seem obvious to a seasoned user of AutoCAD, but for beginners to the CAD environment like me not so....

An External Reference is of course much different from a block with the drawing's block collection.

This method does accomplish the insertion of blocks...however each block insertion is dependent on the external reference. The reference is not bound to a block in the drawing's collection...

I'm continuing to search for and implement the correct method for block insertion, and I'll post my revelations here.

#3
Hi Accuright,

To begin with I know nothing about VBA! :shock:

However I feel I need to learn.
I have a problem whereby Intellicad no longer supports imagemenus, & I have a large selection that I can no longer use & this is causing me lost income as things are now taking longer.

I plan to attemp to re-create my menus in VBA dialogues.
I tried to look at some old posts by John Findlay ? as he prepared a number of introductions to VBA, but the links are broken :cry:

So I have a number of questions, maybe you can help me? I'll only ask a couple at a time :lol:

1/ Could your code above be used to insert a DWG from a known path into the current file?

2/ How/where could I insert the DWG name in your code?
(eg c:\data\customcad\symbols\bolthd.dwg)

SteveN

#4
Hi sln8458,

I saw your thread inquiring about the imagemenus.

In developing the above code, I started out inserting DWGs into the drawing from file. I found, however, that the only library object that even takes a file location for insertion into the drawing, is a function that inserts the dwg as an external reference. The object is "AttachExternalRefence()". This is a lot different from a block, and why I progressed to using different code from the above to accomplish my routine

So, to quickly answer your question, yes. This is the syntax:

Code: Select all

AttachExternalReference(PathName As String, Name As String, InsertionPoint As Point, [XScale As Double = 1], [YScale As Double = 1], [ZScale As Double = 1], [Rotation As Double], [bOverlay As Boolean = False]) 
So, the big question is, what are in the DWGs that you're inserting? Are they block elements like lamp posts, centerline symbols, things you'll use over and over again? I ask because, using this method, they are not inserted as blocks.

Actually, it's pretty convoluted. If the block exists, then it's attached from the existing list of blocks. If it doesn't, then it's attached from the file as an external reference, but it isn't added to the drawing's block collection. I'm at a loss, as to how to simply add to the block collection from a file; There is no library object to accomplish such a task.

So, this is really the tip of the iceberg for this...
Dell Optiplex 745
Windows XP Professional SP3
Intel Core2 6400 @ 2.13Ghz
4GB RAM
Nvidia GeForce GT 610
[I'd rather be on my home computer]

(I do not represent CMS or it's affiliates)

#5
Hi Accuright, Thaks for the reply.

See if this works??

Here is a simple example of one of my imagemenu tiles.
Image


I have a number of these for electrical symbols, hydraulics (above), standard rolled steel angles, (other structural steels), welding symbols (BSEN22553) ....
I was in the middle of a rather lage addition, a 2D piping library(flanges/elbows/Tees....) when my PC fellover :evil: ... so here I am.

The BIG question:
Each image is a single drawing in it's own right. Some have attribute, others are just a simple symbol. Each is stored in their own directory, with their path mapped. When the symbol is selected for insertion into the current drawing a macro is initiated to prompt for input data.. layer/ insertion point/scale/rotation attribute values (if appropriate) etc

Yes there are often multiple copies of these blocks in each drawing.

SteveN

#6
Hi Accuright,

Well after much searching of the internet, and finding some useful info, it appears that there is no way for the end user to accomplish what was available via the imagemenus. Very dissapointing.

Attaching the blocks via external reference is not a viable option for me. Creating code to attached via Xref/bind/create a new block from those new entities to then use as a symbol would be convoluted :shock:

I could, & have, create toolbars but the limitations of the bitmap icon size means that this route is not practical for me.

I can attach a custom library to the hatching dialogue & see the images, but I have no way (or the skills) to copy & customise that dialogue for my ends.

Dropping the imagemenu functionality was a BIG backward step from my perspective, & since its been over a year since I asked with no reply I guess it's not coming back.

I guess I need to look for an alternative :cry: I've been with Intellicad since 98 when I started my company & it was a Visio product.

SteveN

#7
Hi sln8458,

I believe you're correct, that you won't be able to use imagemenus to accomplish your block insertion.

Here's what I can recommend:

Since I also didn't want to attache external references every time I inserted a block, I decided to take advantage of Intellicad's shortcomings and work around the procedure implemented with Autocad here. So...instead of attaching the blocks to a drawing, I simply put all relevant ones into the block collection for my template drawing. So now, when my code looks for the block, it will be found in the existing blocks collection. It puts the block in from the collection, and no external reference is added.

So, in your case, you'll want to modify your TEMPLATE (found in "C:\Program Files\CMS\IntelliCAD 7.2 Professional\Templates\icad.dwt"). The best way to do so is create a new drawing (this ensures you'll have the templates settings), make your changes, and then save the drawing as a *.dwt file. You don't have to overwrite the default template. You can change the path to your new template in the options when finished. Now on to what to do to your template...

It was a little painstaking at first, and might be more so for you if you have a very large collection, but I manually added each of my blocks to the collection in the template drawing. I made sure they were named uniformly the way I would be searching for them later on. Some forewarning: If you have some blocks that contain a lot of information, then you may run into a problem crashing your iCad when loading the blocks collection. I resolved this by NOT adding the big text blocks we have for your survey notes. I'm suspicious that this probably has more to do with my computer's power (specifically RAM) than intelliCad, though.

So now, whenever I insert a block from code or the dialogue window, all the blocks I would normally access are available to the me and the VBA.

If you have lots of small block (symbols, and this looks to be the case for you), this could work fairly well. Yes, keeping the blocks within the drawing template does increase the overall size of the file. But, for an idea of the size difference, the default template is 55KB, while mine is 322KB. It's a big difference, but the size is still negligible.

As far as inserting your blocks automatically with VBA...well, it doesn't seem like that's what you did before. You used the imagemenus to insert the block where you needed, correct? Sort of like a wysiwyg (what you see is what you get) editor? You click the imagemenu button and it loads a block that is placed where you click in modelspace? If so, you don't need to really worry about the VBA inserting the block, and more just getting the blocks into the collection. From there, you could create shortcuts to the block collection manager. It's probably still not as elegant as the imagemenus, however you could probably create some kind of grand VBA form that would have the images on buttons, that insert blocks from collection when clicked....but this is pretty much the same as the blocks collection manager and would be a waste of coding time, in my opinion.


Also, you mention your Intellicad 98 was a Visio product. I don't think Visio publishes a version of Intellicad anymore, but, understand that there are a couple different versions of Intellicad, offered by several different publishers who are all part of the Intellicad consortium. It is entirely possible that another publisher may have support for imagemenus in their version...or perhaps at least a forum that is more active and could recommend a better solution for you. You can see the members list here:
https://members.intellicad.org/members/products.php[/url]
Dell Optiplex 745
Windows XP Professional SP3
Intel Core2 6400 @ 2.13Ghz
4GB RAM
Nvidia GeForce GT 610
[I'd rather be on my home computer]

(I do not represent CMS or it's affiliates)

#8
Hi Accuright,

I appreciate your response & time.

I use(d) imagemenus primarily because it was easy for me to create & manage when I worked with AutoCad. (I go all the way back to 2.?).
As I have moved employers I developed differing menus for each of them, & kept a copy for me :wink:

When I started my own business Autocad was/is way too expensive hence Intellicad, my reference to Visio was simply to indicate how long I have used the program. Visio launched the first version of Intellicad, before the ITC was around (from memory), in fact I think it was once owned by Autocad before that!

Back to my problem,

Your assumptions are mostly true.

Yes I could create individual template files pre-loaded with the appropriate blocks. That way I could use a VBA form with images of each block & code to insert the block. That would work fine if I had total supply control, but I don’t. I have the issue of drawings that come to me for modification that I did not create & hence would not ‘pre-loaded’. One of my clients stipulates that ALL drawings are ‘purged’ of redundant data prior to final submission. Sorry I do not mean to be negative :). I could insert the pre-loaded template into each drawing as required, that would get around these issues, but that just creates more work. However, if all else fails, I may be forced down this route.

Wysiwyg, in part yes.
Imagemenus allowed for complex icons (some are very complex) to be easily displayed, & for similar icons to distinguishable. I was able to write macros behind each icon that led the user thro’ a series of commands to achieve a specific goal. Something I don’t think the Block Collection Manager offers?
They allowed me to do so much that I cannot anymore :cry: . (This is my real issue, why I feel so frustrated!)
It’s not helped by the absence of CMS input to the forum & which possibly may be why this forum is so inactive!!

I have already emailed a couple of the suppliers in your link, just waiting for replies.

SteveN
edit
PS
Just received the first response, positive :)

#9
I can imagine your frustration. Just from looking at your sample image again, it looks like your collection of symbols is vast and complex...electrical work and the like...and that's why imagemenus were such an elegant and effective solution.

The Block collection manager, has two views, detail and icon views. Perhaps the icon view is what you're looking for? You can also adjust the preview size of the blocks under the View file menu in the blocks collection window. I set the size to "Extra Large Icons" and it gives me about a 100x100 pixel preview of the block. Double clicking an icon prompts for insertion, and blocks with attributes will then prompt intelliCad to get the input from the user. When I insert blocks with attributes tied to them, I'm prompted for the input at the Intellicad Prompt. This sounds like what you used imagemenus to accomplish, but I'm almost certain you probably had more acute control over how it worked.

Let me say this, as well: tread lightly when sending iCAD drawings to users of another cad platform. I'm working with iCAD in an office where everyone else uses AutoCAD 2004....so I hear about the inconsistencies first. The biggest of them so far is the inability to copyclip entities from modelspace to paperspace if they open my drawings on their platform. iCAD puts several proxies into the document that have to be purged with AutoCAD 2013 before it can be done in '04.

Anyway, I wish you luck, and hopefully the developers may decide to implement imagemenu support again.
Dell Optiplex 745
Windows XP Professional SP3
Intel Core2 6400 @ 2.13Ghz
4GB RAM
Nvidia GeForce GT 610
[I'd rather be on my home computer]

(I do not represent CMS or it's affiliates)

#10
The icon view in Block Manager set to 100x100 pixels would probably be ok, as would the double click to insert the block, but I need more :D :D

Selecting the block begins a process that sets the layer on which the block will reside. If that layer does not exist it is defined, colour/line style/... the block is inserted & then prompted for attribute value(s) (setvar dimscale is used to qualify txt size). Then there can be a leader (all welding symbols have these) so we have a start & end point to select. All of this is defined via the imagemenu so one click initiates the complete string of commands. Each menu has differing parameters. Not all clients use the same layering stucture so I have variations of some menus specific to the clients requirements. Once the menu is constructed I don't have to think so hard about the layers etc.

I accept that all of what is done by my menus can be acheived individually, in different ways, by the core functionality of the programme.

eg, I have created a small sample toolbar with just a few symbols from one menu, it performs identically as the menu except no image. Now that's ok if the image is a simple hex nut/bolt but not for a 3 way solenoid valve with spring return & latching manual overide :shock:

Imagemenus were/are simple (that's why I use them :lol: ) but they are functional, you don't need to understand complicated syntax to acheive an 'elegant' result.

I appreciate your input :wink: . I too hope the developers re-instate this functionality, it would have been helpful to understand why it's gone :idea:

Thanks for the heads-up on the proxy issues you've had. So far no one has complained ........... yet!!

I have downloaded a trial copy from one of the competitors & will have a play. I 'll post back for info.

SteveN

#11
Ohhh ok, I now see just how customized the imagemenus can get :shock:

Best of luck! Interested to see if you find another solution.
Dell Optiplex 745
Windows XP Professional SP3
Intel Core2 6400 @ 2.13Ghz
4GB RAM
Nvidia GeForce GT 610
[I'd rather be on my home computer]

(I do not represent CMS or it's affiliates)