How to manipulate the selected objects on screen in AUTOCAD using VBA? - vba

In autocad 2008, I want to learn how to operate the screen selected objects. There is a VBA object named ThisDrawing.SelectionSets, but it is a sets of selections, not the selected objects which are selected by user. Which VBA object represents the user selected objects?

There is also a "built-in" selection set you can use that represents the currently selected objects.
Public Sub test()
Dim ss As AcadSelectionSet
Set ss = ThisDrawing.ActiveSelectionSet
MsgBox ss.Count
End Sub

You actually need to create your own Selection Set and add it to ThisDrawing.SelectionSets.
Then when the user clicks on an entity you need to add it to the Selection Set you created.
Finally, you can then step through every entity in the Selection Set to perform some manipulation on it.
I'm sorry I can't offer VBA code as I use C# but this is the process that you need to follow. You can however get help from within AutoCAD itself by hitting F1 and then looking under:
ActiveX and VBA Developer's Guide -> Create and Edit AutoCAD Entities -> Work with Selection Sets

Related

VBA - Using .onAction on SmartArtNodes

I am new to VBA and trying to use smartArt.Nodes to dynamically generate an organizational chart based on some cell data. I am able to generate the chart with no problems. Now, I would like to be able to display more details of specific nodes of the chart by clicking on them. I am aware that we can convert smartArts into Shapes with the Drawing Tools in Excel and then use .onAction on them like:
ActiveSheet.Shapes(name1).OnAction = "detail"
However, is there a way to achieve the same thing with smartArt.nodes using VBA? Say I have a node called "nodes1" I have tried:
nodes1.Shapes.OnAction = "detail"
or
Dim objShape As Shape
Dim SmartArtNod As SmartArtNode
Set objShape = ActiveSheet.Shapes(1)
Set SmartArtNod = objShape.SmartArt.AllNodes(1)
SmartArtNod.Shapes(1).OnAction = "detail"
and other combinations, but none of them seem to work...
Thank you for your help!
Hard to prove a negative, but I believe this is not possible. Testing with Excel 2013, I can confirm the following do not work:
Trying to trap the Selection of the SmartArt using
Worksheet_SelectionChanged does not fire. If you change the
selection from a cell to the SmartArt object, you will not get an
event. You will get an event however when you lose focus on the
SmartArt and go back to the cell.
You can select a SmartArt object and then debug to check what is selected. The object is of type
Object/Shape and the watch window indicates that it exposes an
OnAction property, but attempting to set this property will throw
an error.
I take the two issues above to mean that is will be very difficult (if not impossible) to get an OnAction event to fire from the SmartArt.

AutoFill when user types into a combo box using VBA in excel

I'm currently working on a project that I need to have a combobox in an excel sheet for. I have the data needed for the combo box inside of a different sheet in the current workbook I am using.
My question is, is there a way to add autofill/autocomplete functionality to the box using VBA?
My code is as follows:
Private Sub ThirdFloorBox_Initialize()
ThirdFloorBox.Clear
ThirdFloorBox.List = Sheets(8).Range("A3:A37").Value
ThirdFloorBox.Visible = False
End Sub
Any suggestions would be helpful. FYI: I'm new to VBA as most of my coding experience comes from the front-end web world.
Thanks
Best if you define the range (Serving the list of Thirdfloorbox) in Name Manager and then in the properties window of the box you can add that range as the rowsource.

Creating an userform object hierarchy with grouping in vba

First things first. There's a good chance what I want to do should really be done with VB and not VBA. But as long as it is possible I would rather use VBA.
I have a userform of essentially a big diagram made of hundreds of labels. I want to separate these labels into groups. And then separate these groups into subsystems. The idea being I have some form of heirarchy to work with. The label groups need to change color based on what I have selected in a combo box, and if I click on one of these labels I want to bring up a user form showing details of the subsystem using click events.
I'm pretty sure I need to use multiple classes to do what I want but am fairly new to using class modules. Though I get the concept.
Basically I want some functionality that goes subsystem -> label group( or part) -> color with click events for the whole subsystem and combo box events for changing label group colors.
I saw a thread online about grouping labels or text boxes but it only works to trigger the even for a group, not change the properties of the whole group once the event is triggered. I would like to set this up in classes as well so I can export the system for use in other future userforms.
I was able to create groups of labels and change them together like I wanted:
CPart (Class Module 1):
*This is meant to handle the event triggering of the labels and includes some color code that I used to test functionality of the groups changing together and functionality of changing colors.
Public WithEvents trigger As MSForms.Label
Dim pLabels As Collection
Property Set triggers(c As Collection)
Set pLabels = c
End Property
Private Sub trigger_Click()
For Each obj In pLabels
obj.BackColor = RGB(255, 0, 0)
Next obj
End Sub
CTrigger (Class Module 2):
*This took a collection of labels which were passed in through a collection variable in the userform and then stored each label as a trigger in a separate class variable, along with the whole collection of labels in that group. This way when any trigger fires the event, all of the labels change.
Dim CTrigger() As New CPart
Dim pLabels As Collection
Dim i As Integer
Property Set Labels(c As Collection)
Set pLabels = c
For i = 1 To pLabels.Count
ReDim Preserve CTrigger(1 To i)
Set CTrigger(i).trigger = pLabels.Item(i)
Set CTrigger(i).triggers = pLabels
Next i
End Property
Property Get Labels() As Collection
Labels = pLabels
End Property
I really don't like the way it works, partly because I am losing myself in the logic of it constantly, and partly because it means that in order to use this I have to make collections of labels in the userform module anyway just to run it. It is very inefficient code, but I am putting it up so you get an idea of what I am trying to accomplish.
What I would much rather do instead is have one class variable to hold my custom collection of labels (a "LabelGroup"). Another class variable is likely required to hold the labels themselves (I think). And then all I would have to do is go through and write methods for the LabelGroup class such as changecolor, and it could handle that. But I can handle that part, for now what I really need help with is setting up the class framework in a neat way, so that the module I will eventually run could just say things like:
LabelGroup1.Add Label1
LabelGroup2.Add Label2
or
Private Sub button_click()
LabelGroup1.ChangeColor(RGB(...))
End Sub
These two articles have been helping me along:
http://www.databaseadvisors.com/newsletters/newsletter200503/0503usingcustomcollections/using%20custom%20collections%20in%20microsoft%20access.asp
http://j-walk.com/ss/excel/tips/tip44.htm
I was just looking at something similar but not quite so detailed. I'm trying to improve the look of a complex userform by making it look more modern and was going to try to fake mouseOver highlighting or at least active/inactive shading for labels placed overtop of graphical buttons.
Anyway, have you considered just changing the names of the label objects so that they are prefixed/suffixed with some kind of group or subsystem ID?
That way when you pass them to a sub to change their colour, you can check the prefix or suffix.

MS-Word VBA reference identification

I have a custom content control in Microsoft Word from a third party I am trying to resize the width and height of. Normal content control selection via VBA is not working because this control has no Title or Tag. However, if I manually select the object and resize it programmatically using "Selection.ShapeRange.Height = x" or ShapeRange.Width it does work. So to do it all programmatically I need to determine the name of the "selection" without having to manually select it.
Is there a way to "inspect" the complete reference to the currently selected object in word, so we can then get a starting point to work with it in VBA?
It's hard to know what type of object your dealing with. I tested this by inserting a blank ActiveX image control, selecting it and then running the macro. The code has two methods but one is commented out.
Sub FindName()
MsgBox (Selection.Fields.Item(1).OLEFormat.ClassType)
'MsgBox (Selection.InlineShapes.Item(1).OLEFormat.ClassType)
MsgBox (Selection.InlineShapes.Item(1).Field.Index)
MsgBox (Selection.InlineShapes.Item(1).AlternativeText)
'Show current name
MsgBox (Selection.Fields.Item(1).OLEFormat.Object.Name)
'Set new name
Selection.Fields.Item(1).OLEFormat.Object.Name = "Image5"
'Re-display name to show that it changed
MsgBox (Selection.Fields.Item(1).OLEFormat.Object.Name)
End Sub
The result was this:

Open multiple copies of word form?

I'm fair at Access vba but Word is a new dialect for me.
I work for a hospital that has an Electronic Medical Record (EMR). We need a specific format and structure for the Nurse’s Clinical Progress Notes that can’t be created and enforced in the EMR. I created a Word vba UserForm, "frmProgNote" attached to a document "ProgNote.doc". FrmProgNote" has textboxes that create the structure we need for documentation and there is a command button that when clicked sends the info from the form to bookmarks in ProgNote.doc and copies all text from the document, including the newly inserted text onto the clipboard. The user then pastes it into the EMR. This all works great (believe it or not) but now they want to have multiple copies of frmProgNote open at the same time so they can move between several patients at once.
I’ve worked on this for 2 days and just can’t get it. I found I could not open multiple instances of Word and have the same form open in more than one. I copied the document and form so now have ProgNote1.doc with frmProgNote1 and ProgNote2.doc with frmProgNote2. I can get both to open BUT if I open frmProgNote1 then open frmProgNote2 the only data I can copy comes from frmProgNote2; the copy button doesn’t copy anything from the first form. I can click on frm1 and get it to take new data but the copy button doesn’t work anymore. Any suggestions? Thanks so much.
The following code gives the basis for creating a new instance of a UserForm.
Private frmNewInstance As Object
Private Sub CommandButton1_Click()
Set frmNewInstance = UserForms.Add(Me.Name)
frmNewInstance.Show
End Sub
Private Sub UserForm_Terminate()
Set frmNewInstance = Nothing
End Sub
It is necessary to control the object-reference, setting it to Nothing when the form instance is closed.
Note that this process is not as robust or reliable as it would be in, for example, VB.NET or C#. In particular, it is more difficult to distinguish between the different instances of the form.
One approach to consider is to use the Tag property of the form:
frmNewInstance.Tag = "OtherOne"
frmNewInstance.Show