Why does every class in VBA have an Application property? - excel

I would like a bit of clarification about why each class (or nearly each class) in VBA (when you scroll through Object Browser) has an Application property.
MSDN says
When used without an object qualifier, this property returns an
Application object that represents the Microsoft Excel application.
When used with an object qualifier, this property returns an
Application object that represents the creator of the specified object
(you can use this property with an OLE Automation object to return the
application of that object). Read-only.
The first sentence is pretty clear. Your hosting application used without a qualifier can be one of the MS Office products supporting VBA.
In Excel Debug.Print Application = Microsoft Excel
In Word Debug.Print Application = Microsoft Word
etc...
but...the second sentence is totally unclear to me... So I am thinking like no matter where you call .Application from it will always return the host of an object...
So, what is the point of each class in VBA to have an Application property?
PS. you can always call .Parent => .Parent to go up the hierarchy... can't you? You can just call the Application wit no qualifier to get that...
I can't even think of one SSCCE OLE scenario for this so I am sorry I am not providing an example. The Application property (not to be confused with Application class) is poorly documented this is why I am asking for someone with more experience to clarify this for me.
One (well, sort of) scenario, but not sure it even applies here could be using Interop for Office. Like, when you have an external application that opens two files ( one Excel, and one Word ) then by getting references to Ranges in both, you may be able to return Microsoft Excel and Microsoft Word.. but would this be even useful to anyone? hmm..Am I not understanding this entire concept?

There are two levels to this. First, the reason every class has an Application property is because somebody thought it would be a good idea and they made a base class from which every other class inherits. Kind of like the decision to have a Value property or an Item property consistently applied through classes.
The real question is why somebody thought it was a good idea. I don't know, but it was probably Spolsky's idea, so he should answer. I can tell you how I use it.
If I'm automating Outlook from Excel, I'll generally create an olApp variable to hold the Outlook Application. But I don't have to. I could just create, say, a MailItem and reference Application via that. Where I do use the Application property is debugging. I have a MailItem object instantiated and I'm getting an error. I could, for instance, see how many items are in the inbox even though I don't have an application object variable in scope. In the immediate window:
?olMailItem.Application.GetDefaultFolder(1).Items.Count
I could string a bunch of .Parent calls together, but I don't necessarily know how many I would need. Here's where the second part of the MSDN description comes into play. If I use Application with not qualifier (I'm in Excel), it defaults to Excel.Application. But the Application property of olMailItem returns Outlook.Application because that's what's at the top of the object hierarchy that includes the MailItem class.
I think it's just a handy shortcut that somebody thought was so handy they coded it into the base class for all objects.

Related

Does 'Excel' in 'Excel.Application' refer to an Object? If not, what does it refer to?

I am trying to understand the hierarchy of object classes in VBA, and I can't understand why one has to write Excel.Application rather than just Excel, eg why do we have to write Excel.Application.ActiveWorkbook rather than just Excel.ActiveWorkbook?
It would make sense to me if 'Excel' denoted an object in a class called something like 'Office App' whose other members were Word, Access etc, and objects of that class had a number of methods and properties, of which Application was only one. But I can't find any such class in Microsoft's online reference and, as far as I can tell, Application is the only property or method name that can go after the dot after the word Excel.
Is it just an idiosyncrasy of how VBA was set up, or is there some internal logic as to why VBA requires us to write Excel.Application.ActiveWorkbook rather than just Excel.ActiveWorkbook?
The same question applies to all the other MS Office apps, eg why we have to write Word.Application.ActiveDocument rather than just Word.ActiveDocument.
Thank you

How does Microsoft implement automated properties without "set"? (c#)

As I understand, when using automated properties, one must write both set and get methods.
However, when I look at Microsoft's System.Exception, there are some properties that clearly does not follow this demand, for instance: http://msdn.microsoft.com/en-us/library/system.exception.innerexception.aspx.
Can someone please explain me how can this be?
When using an automatic property, one never writes set and get methods. The compiler provides both for you.
If you see a property without a set, or without a get, it was defined the long way, and not an automatic property.
The fact that the backing property is a legal C# name, and not a compiler-reserved name, is another clue that you're looking at a manual property. So is the fact that this property has been around since long before automatic properties were implemented.
Sorry?
What about "no public set"?
Can be.... protected or private and thus be filtered in the documentation.

Dynamically adding the same UserControl multiple times

I have a simple UserControl that I've created that simply allows a user to enter the date. For the time being, it has a single Textbox with ID="tbDate". I am trying to dynamically add this control multiple times via (for example) placeholder.Controls.Add(LoadControl()) but am receiving the error "An entry with the same key already exists". I could, perhaps, change the ID of the elements but then it would be difficult to grab the value entered by the user.
Does anyone have an idea on this?
Thanks!
I generate a unique identifier as part of a Component class that I created and then use that value as the Control.ID. You can generate this unique value in any way you'd like but I am storing it as part of a database table. In the end it isn't that important since when the class is instantiated the values are initialized and consistent throughout the run of the application.
The class has a private instance variable:
private Control _control;
When adding the control to the form (and, specifically, the placeholder) I do something similiar to this. Note that c references my created class.
c.Control.ID = c.ComponentName + c.UniqueIdentifier;
phHere.Controls.Add(c.Control);
Then when I need to reference the control at a later point I essentially reverse the steps above:
string component = c.ComponentName + c.UniqueIdentifier;
UserControl uc = (UserControl)ph.FindControl(component);
Hopefully this helps. If you have any questions please feel free to ask. The root of the problem, though, is that the Control.ID must be set in order to avoid the error.
Thanks

bind subsonic object collection to Microsoft report (rdlc)

Has anyone been able to use a SubSonic generated collection as a "business object datasource" with Microsoft report (rdlc)? I have generated the SubSonic class code but for some reason the report datasource window is not seeing the class as a potential object collection datasource.
Is there something I need to do for this to work?
Thanks in advance...vsdotnetguy
I have loaded Reporting Service reports from business objects before (loaded via NHibernate -- which isn't exact but close enough for argument sake).
Couple of key points:
1. return your objects in List, even if you are only returning one object.
2. You want FLAT business objects. You might have to go thru a DTO transformation to get that. By flat, I mean the most complex property you can have in a business object is a string and a number (int, decimal, double). If you are expecting to grab a value like this:
myObject.Customer.Name, forget it. Create a CustomerName property.
3. If you need data from multiple places try to break up your reports into subreports. You key off of the datasource key to figure out what data to return to the report.
I'll add more as I remember, it has been a few months since I've done this.
Yes I've done it, you should only need to make sure the project containing your reports references your SubSonic project (obviously :).
Sometimes I've also found that Visual Studio can get a little borked and require a restart before repopulating the datasource window with SubSonic generated objects.
Thx Chris and Adam,
Here is the answer I found.
In my case I wanted to dynamically set the main and subreport datasources at run time using the SubSonic object collections. However, I also wanted to design the report layout using drag and drop of the datasource columns.
But I was unable to design the report using drag&drop because none of my SubSonic collections were showing up in the Website Data Sources.
However, later while I was doing some control binding using the ObjectDataSource control, I noticed that NOW my SubSonic collections were showing up in the Website DataSources window and I could drag and drop the report layout.
So if you are dynamically setting the report datasources at run time and ARE NOT using the ObjectDataSource control already in your project, you MUST add a dummy ObjectDataSource control to one of your aspx pages. This will then make the business object datasources show up in the report designer.

Regarding MOSS or WSS 3.0, What parts of the API might have been implemented better?

Such as:
Sealed Methods you might have liked to extend
Exceptions thrown are more vague than is helpful
Elimination of Connected Content which was a major feature in MCMS 2002
HTML is stripped from fields when stored and returned. No easy option to work around this problem
Creating an SPWeb takes an eternity.
Nonexistant migration path from MCMC 2002
I wish that the Sharepoint object model was purely managed code. Although having .NET wrappers is convenient, having to worry about disposing the many objects that implement IDisposable is a pain. It's so easy to run into memory issues when dispose does not get called in a WSS app. And I thought the reason for moving to .NET was to free developers from having to deal with memory management...
How about refactoring Properties that result in additional database calls to methods instead, for example the Items property on SPList.
Any of the SPList API could use a complete rewrite. Trying to deal with libraries with nested folders is a complete nightmare with the list being completely flattened with no obvious hierarchical structure.
Another wonderful addition would be adding interfaces to SPWeb, SPList and other Sharepoint classes to aid testing.
Has anyone seen this method:
http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.spsecurity.runwithelevatedprivileges.aspx This method shows the unbelievable nonsense that Sharepoint exposes to developers.
My personal favourite is the SPField.GetFieldValue Method. I have no idea why they designed it the way they did, but to me it does hardly make sense. To get a object out of a ListItem you have to do somethine like:
SPField field = ((SPList)list).Fields.GetField("FieldName");
object fieldValue = field.GetFieldValue(((SPListItem)item)[field.Title].ToString());
Getting an object out of a ListItem is IMO a basic operation, so this should not be that complicated.
Inconsistencies when passing field names to methods or arrays. For example:
SPFieldCollection.ContainsField(): Internal name or display name
SPFieldCollection.GetField(): Internal name or display name
SPFieldCollection.GetFieldByInternalName(): Internal name
SPFieldCollection.Item: Display name
SPListItem.Item: Internal name or display name
SPListItem.GetFormattedValue(): Internal name or display name
SPViewFieldCollection.Exists: Internal name
To put the icing on the cake, there is usually no documentation about whether a method takes internal and/or display name.

Resources