I know this is ultra basic in VBA but i have searched on 6 books (VBA for dummies 2010, Excel Bible, Proffesional Excel Development: The deffinitive guide, VBA and Macros Excel Microsoft 2010, Excel programming with VBA, Microsoft Excel VBA Proffesional Projects) and noone gives a deffinition about the 3 types of properties read-only, write-only and read/write.
They probably think is way to basic to even mention in their books but hey if you believed as i that computers were electricity purification filters 11 months ago and know you wanna code now someone has to tell ya a clean cut explanation
thanks for watching my question
As the names suggest
Read Only Property is a property from which you can read but not write to it. For example, For a range .Text is a Read Only Property
Msgbox Range("A1").Text
If you try to write to it, for example
ActiveSheet.Range("A1").Text = "Blah Blah"
then you will get the message showing an error Runtime Error 1004 - Unable to set the Text property of the Range Class
Write-only Property are moderately rare. Write Properties are simply properties that have Property Let or Set method but no Get Method.
Private MyName As String
Property Let sName(Value As String)
MyName = Value
End Property
Read/Write Property is pretty self explanatory. You can read and write to it. For example, for a Range .Value is a Read/Write Property
Range("A1").Value = "Blah Blah"
Extra Note: Courtesy #Mehow
When you press F2 in the Visual Basic Editor, the Object Browser pops up. If you click on any of the classes and then members of that class you can see in the left bottom corner which properties are read/write.
Related
Base Reference: Ten Code Conversions for VBA, Visual Basic .NET, and C#
Note: I have already created and imported a *.dll, this question is about aliases.
Let's say the programmatic name of a Test class is TestNameSpace.Test
[ProgId("TestNamespace.Test")]
public class Test ...
Now, say a C# solution has been sealed and compiled into a *.dll and I'm referencing it in a Excel's VBE. Note: at this point I cannot modify the programmatic name as if the *.dll wasn't written by me.
This is in VBA : Instead of declaring a variable like this:
Dim myTest As TestNameSpace.Test
Set myTest = new TestNameSpace.Test
I'd prefer to call it (still in VBE)
Dim myTest As Test
Set myText = new Test
In C# you would normally say
using newNameForTest = TestNamespace.Test;
newNameForTest myTest = new NewNameForTest;
Note: Assume there are no namespace conflicts in the VBA project
Question: is there an equivalent call in VBA to C# using or VB.NET imports aliases?
Interesting question (constantly using them but never thought about their exact meaning). The definition of the Imports statement (same for using) is pretty clear: its only function is shortening the references by removing the corresponding namespaces. Thus, the first question to ask is: has VBA such a thing (namespaces) at all? And the answer is no, as you can read from multiple sources; examples: Link 1 Link 2
In summary, after not having found a single reference to any VBA statement doing something similar to Imports/using and having confirmed that VBA does not consider the "structure" justifying their use (namespaces), I think that I am in a position to say: no, there is not such a thing in VBA.
Additionally you should bear in mind that it wouldn't have any real applicability. For example: when converting a VB.NET code where Imports might be used, like:
Imports Microsoft.Office.Interop.Word
...
Dim wdApp As Application
the code would be changed completely, such that the resulting string will not be so long:
Dim wdApp As Word.Application ' Prefacing the library's display name.
I think that this is a good graphical reason explaining why VBA does not need to have this kind of things: VB.NET accounts for a wide variety of realities which have to be properly classified (namespaces); VBA accounts for a much smaller number of situations and thus can afford to not perform a so systematic, long-named classification.
-------------------------- CLARIFICATION
Imports/using is a mere name shortening, that is, instead of writing whatever.whatever2.whatever3 every time you use an object of the given namespace in a Module/ Class, you add an Imports/using statement at the start which, basically, means: "for all the members of the namespace X, just forget about all the heading bla, bla".
I am not saying that you cannot emulate this kind of behaviour; just highlighting that having an in-built functionality to short names makes sense in VB.NET, where the names can become really long, but not so much in VBA.
The answer is no: there is a built-in VBE feature that recognizes the references added to a project and creates aliases at run-time(VBE's runtime) if there are no name collisions
In case of name conflicts in your registry all . dots will be replaces with _ underscores.
» ProgId's (Programmatic Identifiers)
In COM, it is only used in late-binding. It's how you make a call to create a new object
Dim myObj = CreateObject("TestNamespace.Test")
» EarlyBinding and LateBinding
In early binding you specify the type of object you are creating by using the new keyword. The name of you object should pop up with the VBA's intellisense. It has nothing to do with the ProgId. To retrieve the actual namespace used for your object type - open Object Explorer F2 and locate it there
This article explain where the names come from in Early Binding Section
use the same link for When to use late binding
for MSDN Programmatic Identifiers section please see this
I am trying to use this json converter https://github.com/VBA-tools/VBA-JSON in microsoft word.
It works excelent in excel with ms-scripting runtime.
however it fails in microsoft word.
the problem I think is object type declaration.
In microsoft word this line gives error.
Set json_ParseObject = New Dictionary
after reading https://msdn.microsoft.com/en-us/library/office/gg251782.aspx
I tried converting it to
dim json_ParseObject As Dictionary.
It give error of duplicative declaration so i removed it.
it then gave error at:
Set json_ParseObject.Item(json_Key) = json_ParseValue(json_String, json_Index)
Does anybody have ever used this project for word-vba successfully?
I earlier asked this question while I was not aware of problem. after some research I am asking it again. Please try to understand the problem as it is real. Please guide if you thing this question is off-topic
In microsoft word this line gives error.
This is because in Word there already exists a class Dictionary but this Word class can't be created with New. So it is a collision of Scripting Runtime Dictionary and Word Dictionary.
In Word fully qualify the name of the Dictionaty type with the name of the library:
Dim d As Scripting.Dictionary
Set d = New Scripting.Dictionary
We have a very complex Excel 2010 spreadsheet template. Each new copy of the template needs to pass through several people during its lifetime.
Unfortunately, one of the first people to utilize the template has Office 365 installed. After he has touched it, the spreadsheet appears to bind to the Microsoft Word 15.0 Object library, which is not available on the Excel 2010 PCs. While an individual broken file can be fixed by unchecking the missing Word object library in the VBA Code Tools > References, I need to find a way to prevent this from happening in the first place.
I have reviewed the code in detail and I cannot find any reference to the MS Word Object library, so what is causing Excel to bind to it in the first place? Is there anything I can do to prevent it?
Untested, but putting something like this in your Workbook_BeforeSave event would probably work:
With ThisWorkbook.VBProject.References
For i = .Count To 1 Step -1
If InStr(.Item(i).Name, "Word") <> 0 Then .Remove .Item(i)
Next
End With
Disclaimer: I don't have Office 365 and don't know why it would automatically add a reference to Word 15.0; anyhow, the above assumes that it does.
To Remove, place inside module: I know this dosen't prevent it from happening in the first place but this might help to at least remove it before the next person.
Private Sub RemoveRef()
Dim Reference As Object
For Each Reference In ThisWorkbook.VBProject.References
If Reference.Description = "Microsoft Word 15.0 Object library" Then
ThisWorkbook.VBProject.References.Remove Reference
End If
Next
End Sub
This seems like a simple question but I after chasing forums for several hours I think it might be impossible.
I often want to convert a program from early binding to late binding. Usually, it is a vba, visual basic for applications, program that runs under Excel 2010 and windows 7 pro.
For discussion purposes, let’s pretend it is the following.
Sub EarlyBind()
' use IDE > Tools > references > and select “Microsoft Internet Controls”
Dim shellWins1 as shdocvw.shellwindows
Line1: Set shellWins1 = New SHDocVw.ShellWindows
MsgBox TypeName(shellWins1) ' this will display “IShellWindows”
' other code that expects to be working with an IshellWindows object …..
End Sub
In my experience, converting such a program to late binding is sometimes hard.
For instance, I found some forums that suggest I change it to
Set shellwins1 = createobject("Shell.applicaton")
But that creates a IShellDispatch5 object, not an IshellWindows object. That means I have to change other code to accommodate the new object type. And, of course I have to test that other code for subtle differences.
So, my goal is to find a general solution that will allow me to rewrite “Line1” to create the CORRECT object type with late binding. I also wish to avoid the need setting a reference to "Microsof Internet Controls. In other words, I want the code to look like this:
Sub LateBind()
Dim shellWins1 as object
Line1: Set shellWins1 = createobject(“xxxxxx.yyyyyy”).zzzzzz
MsgBox TypeName(shellWins1) ‘ this should display “IShellWindows”
….. other code that expects to be working with an IshellWindows object …..
End Sub
I know how to use the vba IDE to find the dll associated with the object. In this case the dll is Library SHDocVw C:\Windows\SysWOW64\ieframe.dll.
I have installed OleView and can find the associated IshellWindows “magic numbers” for the clsId, TypeLib, and Inteface (for instance the interface is 85CB6900-4D95-11CF-960C-0080C7F4EE85).
But, I don’t know how to convert them into a program id that can be used in line1 in the sample code posted above.
I hope someone here can help.
------ With MeHow's help, I now have the answer! ------
To switch 'set myObj = new xxxx.yyyyy' to late binding for arbitrary object types
Change set myObj = new xxxx.yyyyy
into set myObj = CreateObject("xxxx.yyyyy")
Very often that will work.
But, in the some cases, (e.g. "shDocVw.ShellWindows.") it gives error 429 ActiveX component cannot be created.
When that occurs I AM COMPLETELY OUT OF LUCK. It is impossible to use late binding with that EXACT object class. Instead I must find a substitute class that does approximately the same thing. (e.g. "Shell.Application").
Your short answer is
IShellWindows is an interface.
It
Provides access to the collection of open Shell windows.
Therefore
Take a look at the CreateObject() method.
Note:
Creates and returns a reference to a COM object. CreateObject cannot
be used to create instances of classes in Visual Basic unless those
classes are explicitly exposed as COM components.
IShellWindows is not exposed as a COM component so that's why there is no way to say CreateObject("SHDocVw.IShellWindows")
When you open your registry (regedit) and search for a key type in IShellWindows. If you find anything that means you've found your Prog ID and if you don't find anything it means that nothing like IShellWindows is registered as a prog Id therefore it would make sense to assume that you can't late bind IShellWindows
I bumped into your question trying to find something for myself. But I don't know if you have tried the following -
Set shellwins1 = createobject("Shell.Application")
MsgBox TypeName(shellWins1.Windows)
This answers your question for datatype. It prints IShellWindows for me. I'm not sure though if it could actually solve your purpose for latebinding meaning if this would be the object required though the datatype is what you need.
So, I would advise you to give it a try.
There is a slightly better approach outlined at https://www.experts-exchange.com/questions/28961564/How-to-find-the-class-id-of-an-arbitrary-object-Example-Set-x-CreateObject-New-1C3B4210-F441-11CE-B9EA-00AA006B1A69.html#a41743468.
I'd like to run a user form with status bar.
I show my form with code bolow.
How should I declare variables and assigning new values to those variables?
Very important: I have to use late binding in my project.
Sub RunMyUserForm()
With MyUserForm
.LabelProgress.Width = 0
.TextBox1 = 1
'to make the progress bar color match the workbook's current theme:
.LabelProgress.BackColor = ActiveWorkbook.Theme.ThemeColorScheme.Colors(msoThemeAccent1)
.Show vbModeless
End With
End Sub
Thank you in advance for your help!
Updated information:
When I try to run my macro with "Option Explicit", it doesn't work (Compile error: Variable not defined - part of code msoThemeAccent1 is marked as yellow color). That's why I asked for help in defining the variables.
When I try to run my macro without "Option Explicit", it dosen't work (Err.Description: "Value is out of range", Err.Number: -2147024809)
When I try to run my macro with early binding (reference to "MS Office Object Library" via Tools/References in VBE) everything works perfect with (and without) "Option Explicit".
Your compiler is seeing msoThemeAccent1 as a variable, and it is undeclared. This is why your code won't run with Option Explicit and also why your code raises an error when you disable Option Explicit. .Colors is a 1-based collection (?) so when you call:
ActiveWorkbook.Theme.ThemeColorScheme.Colors(msoThemeAccent1)
It is compiling to:
ActiveWorkbook.Theme.ThemeColorScheme.Colors(0)
Which raises an expected, albeit cryptic error.
I used some code to check the value of this constant, but in hindsight I should have just referred to the documentation:
http://office.microsoft.com/en-us/excel-help/HV080559557.aspx
This should fix it for you
ActiveWorkbook.Theme.ThemeColorScheme.Colors(5)
Alternatively, if you need to rely on this value in several places in your code, you could declare a variable (public or private, scope depends on what you need it for).
Public Const myAccentColor1 as Long = 5
And then, in your code you could:
ActiveWorkbook.Theme.ThemeColorScheme.Colors(myAccentColor1)
Revised
I understand now, without reference to MS Office Object Library this makes sense. This is one of the few libraries that I maintain a reference to in my XLSB file, so my confusion was a result of the fact that I thought I was using an appropriate late-binding, but I was really using early-binding.