I'm trying to loop through all the controls on an Access form but for some reason the controls object is not giving me the correct properties.
When I select and right click on "Control" (in 'As Control') it says "identifier under cursor is not recognized".
I'm thinking it's a reference issue but I can't figure what's missing or incorrect. I don't get any syntax error so Control is a valid object.
I tried decompiling, repair and compacting just to be sure.
The generic control object doesn't have too many useful properties or methods.
It covers also things like lines or subform containers or tab cards, which don't have much in common.
The specific controls like Textboxes have all the properties you are probably looking for.
You still can loop over all controls, and set the usual properties that most controls have, like .Visible or .Locked. Even if Intellisense doesn't provide them.
ctl.Locked = bLocked will work.
But you should handle (On Error Goto) or ignore (On Error Resume Next) runtime errors that will occur, if one control doesn't have the property you want to set.
Bonus question to everyone: why does the generic control object have the .Dropdown method that applies only to combo boxes? Very strange.
Related
To illustrate what I'm asking, let's say I have a custom TextBox that has 2 modes. Mode 1 only allows numbers, and mode 2 only allows dates in a particular format.
Using a class module I can create this custom TextBox, and I can use a loop when the userform initialises to set which TextBoxes are custom.
What I'd like to happen is have the custom TextBox, or what ever custom control I want, show up in the toolbox. And I also want its custom properties, if they exist, to show up in the property window.
So far, I've been unable to find a way to do this. In fact, I've been unable to find out if it's even possible. It seems, to me anyway, that it's something that should be possible, but maybe I'm barking up the wrong tree. If it's possible I'd really appreciate being pointed to a resource.
An MSForms.Control has a property defined as Property RowSourceType As Integer, but any attempt to read or write the property seems to fail with error:
Run-time error '-2147352573 (80020003)':
Member not found.
Are there (or were there once) any built-in MSForms controls or ActiveX controls for which this property doesn't throw an error?
A quick web search for VBA RowSourceType turns up a bunch of results for VBA Access. I've only dipped my toe into VBA for Access, and that was many years ago, so I can't say how it's used in Access. But I'm guessing that you're using VBA with something else (Excel, Word, etc.). I suspect the generic Control object is used across all application hosts.
I am writing my first VBA Add-In under Microsoft Office Word 2007 with Windows 7 Pro/64. Part of this Add-In is a UserForm. Using the Visual Basic editor that runs from Word, I find there are two ways of viewing, and two ways of modifying a UserForm's properties:
View all properties from Object Browser (F2)
View some properties and edit them from Properties Window (F4)
Manually enter and edit any property from the Code window (F7)
Here is a screenshot of my Properties and Code windows:
A problem I find is that the Properties Window contains only a subset of the UserForm's properties (notice that CanPaste, CanRedo, and CanUndo don't appear in Properties), and changes made in the Properties Window are overridden by changes made in the Code window (e.g., at runtime, Me.Caption from the Code window above overrides the Caption field in Properties).
I suppose I should avoid using Properties at all then, and enter all settings via UserForm_Initialize as shown above. But (a) for some settings, Properties makes several settings at once. For example, selecting Verdana Bold from Properties equals Font = Verdana and Font.Bold = True in Code. And (b) it seems Properties sets the subset of properties it controls to defaults of its choosing, and if I change them I can't see what they started out as.
I therefore desire unified and comprehensive access to all my UserForm's properties at once, including the aforementioned default settings. Does anyone know how to reveal a UserForm's default settings as code, or to automatically open all its current settings in the Code window? Is there an umbrella mechanism I'm not aware of?
I'm not a veteran VBA programmer, but I can't believe my experience is unique. I've searched the 'net in vain for a solution. How do you with more experience manage this dilemma?
You use the Properties window to set appearance-related properties at design time. Those property values will then always apply unless you explicitly change them at run-time with VBA code.
Properties that don't relate to appearance, such as CanPaste and CanRedo relate to the state of the form at run-time, so it doesn't make sense to have them configurable at design-time.
You can change nearly all of the properties at run-time, whether it is in the Initialize event or elsewhere. You can even add controls at run-time, but your changes won't be persisted once the instance of the form terminates.
So I feel a little foolish asking this question. I have spent plenty of time searching and only found a crude work-around. I have given this due diligence before posting.
For controls placed within a worksheet I cannot pull up the properties or even view the name to reference in code. The work-around I came across is if you right-click on the control (listbox in this case) and choose assign macro. It will suggest a macro name with the control name (e.g. ListBox13_change). In the code I refer to this listbox as Sheet2.ListBox13, but getting an error message for missing object.
With ActiveX controls or controls within a userform I can view the properties. I don't know why I am having trouble with this case.
Any guidance is much appreciated.
You can get the real name of the form control from the Immediate Window in the VBE by executing this line:
?Sheet2.Shapes(1).Name
Form controls are actually shapes in the object model.
The above assumes you have no other shapes on the worksheet.
Of course you can also see the name (and edit it) from the Name Box if the control is selected.
Once you have the name you can use it in code like so:
MsgBox Sheet2.Shapes("List Box 1").Top
I was wondering if there is a way to take an object in Visual Basic 2010 (Express, FWIW) and browse through its structure to visualize how the data inside is laid out.
For example, I have an object called "model" that is populated by a function that is a black box to me. Model is set by a "read" function that loads a DXF file from disk. The read function isn't very well-documented.
What I've discovered is that model.Entities ends up containing a list of different objects, all with different properties. I'd like to be able to simply browse this list of objects and view their associated properties and values at run-time, similar to how you can use Intellisense to view a list simply by typing "blah." and waiting for the pop-up to appear.
A tree view that you can pop open and closed would be excellent. Obviously this has to work during run-time rather than in the editor because the file hasn't been loaded if the program isn't running.
Is this something that's possible in Visual Basic 2010? Is it a built-in feature I can't find?
Thanks!
If a function returns an object, then that object has a class definition somewhere. Right-click the reference in VS and select "View in Object Browser" and you'll see the class layout with all properties and methods. You don't need to do this at run-time, either.
If you want to dig even deeper then you should check out Reflector.
EDIT
After reading your comments more, I usually do one of three things when I'm trying to do this:
Use the Autos and Locals window
Use the Immediate Window
Use "break-point and hover"
Use the Autos and Locals window
Set a breakpoint and check out the Autos and Locals windows. If you don't see them they're under the main menu at Debug, Windows. This allows you to walk a tree-view of your variables. Sometimes there can be a lot of stuff in here which I why I generally use one of the other two methods below.
Use the Immediate Window
The Immediate Window (IW) allows you to type in expressions and print out values. Its not a tree-view like you want but it allows you to hunt and peck at least. If you imagine the following short and simple code and you put a breakpoint on the second line:
Dim Names As New List(Of String)({"Alice", "Bob", "Chuck"})
Console.WriteLine(Names)
In the IW you could type:
?Names
And it would output:
Count = 3
(0): "Alice"
(1): "Bob"
(2): "Chuck"
The question mark symbol means "print". You can type almost any valid expression for print:
?Names(0)
"Alice"
?Names(0).Substring(0,1)
"A"
?Names(0).Contains("ice")
True
And as you're doing all of this you're getting IntelliSense about whatever is going on.
Use "break-point and hover"
I don't think this has a name beyond IntelliSense but once you've hit a breakpoint you can hover over any variable and inspect its current values. You'll get the occasionally warning that inspection will cause some processing but since you're debugging only this should be fine. Sometimes when I'm debugging a collection I'll create a variable specific to one item in the collection just to make this technique easier. I'll get rid of it once I'm done debugging but it really helps this process.
Is there another