If I am writing an argument in Excel-hosted VBA, for example
ActiveSheet.UsedRange.Select
Halfway through writing the first part -- ActiveSheet -- CTRL+SPACE will autocomplete that part, or I can select the available options from a dropdown list.
However- the Intellisense dropdown box and autocompletion won't work /appear for anything after the first full stop. For example I can't autocomplete the UsedRange property.
Is it possible to make the suggestions appear etc. past writing the first part?
If you look at ActiveSheet in the Object Browser (press F2), you'll see that ActiveSheet is typed as Object. Therefore, Intellisense can't display any further properties specific to the Worksheet. The typing of Object makes sense, because the active sheet might be something other than a standard Excel worksheet -- e.g. a chart sheet or a dialog sheet.
Many global properties are strongly typed, e.g. ActiveWorkbook as Workbook; Intellisense will present the properties and methods just fine.
If you are certain that ActiveSheet when used in this code will always refer to a Worksheet, you could assign it to a Worksheet variable:
Dim wks As Worksheet
Set wks = ActiveSheet
Intellisense would then give you the appropriate properties and methods of the Worksheet object for the strongly-typed variable:
(Theoretically, the Excel object model could have typed ActiveSheet as something like Sheet, which would have all the common members of Worksheet, Chart and DialogSheet. I'm not sure why this wasn't done.)
Related
Normally when using the VBA editor, code autosuggests from available methods.properties for whatever object being referenced.
I'm trying to pull data from an Excel sheet into a Word document using a macro on the Word document. Whenever I try to use worksheets.activate, no autosuggestion for activate comes up, leading me to think it's not activating. Neither can I use it from a VBA script in Excel.
My script is still in it's beginning stages:
Sub Populate()
Dim doc As Document
Set doc = ActiveDocument
Dim appXL As excel.Application
Set appXL = CreateObject("excel.Application")
Dim partnerNames As excel.Workbook
Dim ihmNames As excel.Workbook
Set partnerNames = appXL.Workbooks.Open("D:/Database/Imports and Exports/Funder Credit Lists/2022-01 Partners.csv")
Set ihmNames = appXL.Workbooks.Open("D:\Database\Imports and Exports\Funder Credit Lists\2022-01 IHM.csv")
appXL.Worksheets(Left(partnerNames.Name, Len(partnerNames.Name) - 4)).Activate
Dim lastRow As Long
lastRow = appXL.Cells.Find(What:="*", After:=Range("C1"), SearchOrder:=xlByRows, searchDirection:=xlPrevios).Row
appXL.Range("A1").Resize(lastRow, 3).Select
'Insert Hero Names
Dim hero As Range
Set hero = doc.Range(Start:=doc.Bookmarks("Hero").Start, End:=doc.Bookmarks("Hero").End)
hero.InsertAfter ("IT WORKS!!!")
End Sub
The lastRow = appXL.Cells..... is causing a type mismatch, which I believe is being caused by the fact that appXL.Cells refers to the active sheet, and the ActiveDocument is a Word document.
That leads me to activating the sheet, but trying to do so causes the error "Subscript out of range," even if I explicitly type the sheet name.
appXL is an excel.Application object. Worksheets property belongs to Workbook class. You can use just Worksheets.(...) to refer the active workbook sheets. Same to property .Cells
Or you can define a new Workbook variable and handle it:
Dim wbXL as Workbook
set wbXL = ActiveWorkbook
wbXL.Worksheets(...).Activate
It seems you just need to add an Excel COM reference in Word VBA to be able to get auto-suggestions. From the Tools menu, choose References to display the References dialog box. The References dialog box shows all object libraries registered with the operating system. Scroll through the list for the application whose object library you want to reference. References whose check boxes are selected are used by your project; those that aren't selected are not used, but can be added. Select the object library reference in the Available References box in the References dialog box and choose OK. Your Visual Basic project now has a reference to the application's object library. If you open the Object Browser (press F2) and select the application's library, it displays the objects provided by the selected object library, as well as each object's methods and properties. In the Object Browser, you can select a class in the Classes box and select a method or property in the Members box.
So the problem was specifically the "After:=Range" portion in the appXL.Cells.Find function. I forgot that, since I'm working from a word doc and not an excel, I needed to specify appXL.Range instead of just Range. Oh the joy of finding out my weeklong problem was just a simple missed class specification.
That said, thanks to #Eugene for informing me of the Object Browser window. That was useful.
Microsoft Docs do not list all the properties of Object Application.ActiveSheet:
https://learn.microsoft.com/en-us/office/vba/api/excel.application.activesheet
It has only included some of the properties like: ActiveSheet.Name. But from VBA scripts I found on the internet, I know that there are more properties such as: ActiveSheet.Type
So I thought maybe I can list them all with this VBA code: from: VBA collection: list of keys
Sub AktivSheet()
Dim key As Variant
For Each key In Application.ActiveSheet
Debug.Print "Key: " & key, "Value: " & Application.ActiveSheet.Item(key)
Next
End Sub
But it didn't work, and Microsoft Docs suggests to use Object Browser. But Object Browser does not list the properties for Application.ActiveSheet:
I'm out of ideas! I just want a list of all ActiveSheet properties. Because I simply need to know the Text Direction of the Active Sheet, as in if it's Left to Right OR Right to Left.
I just want a list of all ActiveSheet properties
You cannot easily get that programmatically with 100% VBA code, VBA has pretty much zero reflection capabilities.
Now, assuming we're not looking for a programmatic way to retrieve object properties, here's how to use the object browser to get what you're looking for.
First, right-click anywhere in the object browser and select the "Show hidden members" option to reveal the full breadth of the libraries you're looking at. This affects the names list dropdown when editing code: you'll be shown hidden members now.
One of the hidden modules in the Excel type library, is a module named Global, with a hidden _Global interface:
That hidden global module is how you can type MsgBox ActiveSheet.Name and it "just works" (assuming there is an ActiveSheet - it could always blow up with error 91 when there's no active workbook open in the Application instance you're working with) even though you haven't specified what Workbook you're working with: implicitly, ActiveSheet is just working off whatever the ActiveWorkbook is.
So ActiveSheet is a property, not an object. It's a property that returns an object, but its declared type is Object.
This means any member call you make directly against ActiveSheet, is implicitly late-bound: you can type MsgBox ActiveSheet.Naem and VBA will happily compile the typo (Option Explicit can't save you here), and only blow up at run-time with error 438 "I can't find that property!".
In order to know what properties the ActiveSheet has, we need to know what run-time type we're looking at. And since a sheet in a Workbook object can be a Worksheet, a Chart, or several other types of legacy "sheet" objects, there is indeed no member accessible at compile-time, because at compile-time the ActiveSheet is just a pointer to an Object, and what type of object that is will only be known at run-time.
So instead of coding against ActiveSheet, we code against Worksheet, because we know the particular sheet we're expecting to work with is a Worksheet object.
Dim Sheet As Worksheet
Set Sheet = ActiveSheet
Now when we type Sheet., we're early-bound (types involved are known and resolved at compile-time) and helpfully provided with a list of all available members:
Every time you access a member (function, property) that returns an Object or a Variant, any member call made against it will be late-bound.
Strive to stay in the early-bound realm: declare local variables as needed, such that the compiler gets to "see" and validate everything! Try typing the below code to feel the difference - whenever you type a . dot and nothing comes up, it's a sign the compiler is losing sight of what's going on and you're possibly moving compile-time errors to run-time:
MsgBox ActiveSheet.DisplayRightToLeft '<~ late bound
Dim Sheet As Worksheet
Set Sheet = ActiveSheet
MsgBox Sheet.DisplayRightToLeft '<~ early bound
So there are a few ways to set a worksheet in Excel.
set WS = Sheets("Name Here!")
set WS = WB.Sheets("Name Here!")
set WS = shNameOfTheSheetObject
However, there doesn't seem to be a way to do:
set WS = WB.shNameOfTheSheetObject
I'd like to know how, if it's possible, I can get this type of reference to work. I like being very, very explicit with my code (Perhaps too much so), and it'd be useful to know if I have multiple workbooks open that I'm handling.
I think there is a slight confusion on how the access via the code name works. When you get a worksheet via ThisWorkbook.Worksheets("SheetName") you query a collection on the workbook; when you use the code name, you get the corresponding component of the VBA project containing your project, which implements the Worksheet interface.
Both are the same object, but the resolution of the identifier takes a different path: a workbook does not know about the VBA components. Consequently, as #Comintern mentioned in the comments, you can only use the project name of the containing VBA project as further qualifier. That name is whatever you set it to via the project properties dialog. If you do not change it, it will always be VBAProject in Excel, which is not very helpful.
I have a dataset with is quite simple. When I add data at the end of it, I want to automatically get that in my chartsheet.
For example:
At this moment, the chartsheet exists with a Datasource "A1:Q10". After I enter some values within the sheet where the Datascource is, it should change to A1:R10.
But it doens't work. Here the code which ends up in
"Application or object-defined error"
Sheets("_Chartsheet-sheet").Select
Activesheet.Chartobjects(1).Activate
ActiveChart.SetSourceDate Source:=Range("A10:" & ActualLetter & "10")
As ashleedawg noted, SetSourceDate isn't a member of the Chart class - using Option Explicit and the VBE's IntelliSense & auto-complete will help prevent these. Writing it off as a typo, there's another problem with the code...
Source:=Range("A10:" & ActualLetter & "10")
Range being unqualified, if that code is written in a standard code module, it implicitly refers to whatever the ActiveSheet is - in this case...
Sheets("_Chartsheet-sheet").Select
...a chart sheet, which isn't a Worksheet and, as such, doesn't have a Range property.
An unqualified Range call, made explicit, reads as follows:
[_Global].Range("address")
The solution is to properly qualify that Range call with the Worksheet object instance you mean to work with - assuming Sheet1:
Source:=Sheet1.Range("address")
That Sheet1 is a global-scope Worksheet object that you get for free, given that your worksheet exists at compile-time. Select the worksheet under "Microsoft Excel Objects" in the VBE's Project Explorer, then look at its properties (F4): you'll notice it has a Name property with a value that corresponds to its "tab name" (the name you'd use to fetch the worksheet by name), but it also has a (Name) property, with a value that corresponds to its "code name" - that's the identifier VBA uses to generate the free global-scope object variable you can (and should) use anywhere in your code whenever you need to refer to that worksheet.
Fetching that object from the Sheets or Worksheets collection by name, puts your code at risk: unless workbook structure is protected, the user can change that "tab name" at any time, and that will break every Worksheets("name") call in your code.
If the code is written in a worksheet's code-behind, then the unqualified Range call is implicitly referring to that worksheet. In that case, explicitly qualifying Range with Me would make the code more... explicit about its intent.
Lastly, .Select and .Activate aren't needed here. Avoid Select and Activate, it's macro-recorder code that's as frail as code gets. Instead, work the object references - here I'm assuming that the code is written in the source sheet's code-behind, hence the Me qualifier in front of Range:
Dim chartSheet As Chart
Set chartSheet = ThisWorkbook.Sheets("_Chartsheet-sheet")
chartSheet.SetSourceData Source:=Me.Range("A10:" & ActualLetter & "10")
I want the VBA Editor to use the Autocomplete feature to display the properties of the Worksheet object.
Out of this question on SuperUser, I've learned that the Worksheets object Item() property returns the Variant type. That type is not strongly typed to the Worksheet object.
But, even if I use the ActiveSheet object or the following code, the IDE still does not display the properties of the Worksheet object.
My question is, how to make the VBA Editor in Excel to display the properties of the Worksheet object through the Autocomplete feature?
Kindly declare mySheet variable as worksheet to get autocompletion.Please refer to the below image.