I am creating what I believe is the way to create dynamic dims e.g.
Dim browser(DataGridView1.Rows(e.RowIndex).Cells(0).Value)
which basically is creating a something like Dim browser(1)
However I am trying to write a test button to call this browser by using:
browser1.load("http://google.com")
and I have even tried
browser(1).load("http://google.com"
I get the browser part underlined.
What is the correct way to reference them?
I'm not sure what the end goal is, but this construct:
Dim browser(1)
Is effectively the same as:
Dim browser(1) as Object
i.e. it's creating an array of Object of length 2, which is fine in that it can hold anything but makes your life pointlessly hard because you then have to cast the contents every time you want to do something with them; it's bad enough storing a single thing (such as a web browser widget) as an Object:
'this is bad
Dim browser as Object = New WebBrowserWidget
Because you have to cast it every time you use it (when Option Strict is On, which is really the only way you should ever program)
DirectCast(browser, webBrowserWidget).Load("http://google.com)
But to then add the indirection of storing it in an array:
'this is worse
Dim browser(1) as Object
browser(0) = New WebBrowserWidget
browser(1) = New WebBrowserWidget
And casting them to use them:
DirectCast(browser(0), webBrowserWidget).Load("http://google.com)
Just give these things a proper type when you declare them, or use type inference by providing something on the right hand side of an = that is a particular type:
'infer the type from the right hand side
Dim browser = New WebBrowserWidget
'or declare, give a type and create a new instance to assign to it
Dim browser as New WebBrowserWidget
Then it's a lot easier to use it, because Intellisense will know it's a browser and offer you help with the methods and properties, such as Load:
browser.Load("http://google.com")
If you code with Option Strict Off then you can store things in an object and just cross your fingers and hope you get everything right when youre coding, but it's like writing javascript - fumbling round eyes closed not knowing whether you got it right til it blows up at runtime:
Dim x as Object = New WebBrowserWidget
x.Load(...) 'don't get any intelllisense for this, but it'll work at runtime
x.Laod(...) 'dont get any compiler error even though this is a typo - it'll just explode at runtime
Related
I'm trying to run my code which was originally created using Visual Studio through another application where late bindings are disallowed and this option cannot be altered unfortunately. I am very new to programming in general and struggling to get my head around the issue. Here is the code im using in the invoke code stage:
Dim objIEShell As Object = CreateObject("Shell.Application")
Dim objIEShellWindows As Object = objIEShell.Windows
Dim objIEWin As Object
For Each objIEWin In objIEShellWindows
If InStr(objIEWin.LocationURL,"google")>0 Then
objIEWin.Quit
objIEWin = Nothing
End If
Next
The code simply closes all instances of Internet Explorer with "google" in the URL. This is the error message I get when trying to compile it:
Message: Error compiling code
error BC30574: Option Strict On disallows late binding. At line 2
error BC32023: Expression is of type 'Object', which is not a collection type. At line 4
From the research I've done so far I realise the first error message on line 2 is to do with the type difference between objIEShell and the Windows method. I think I have to convert objIEShell like this, CType(objIEShell,?), but I don't know the type of the .Windows method or how to find this out. Also any insight on how the fix the second error would be greatly appreciated as I'm not sure where to start with that one either.
This dates back to the wonky days when Microsoft still had plans to make Explorer behave like a web browser. Makes it pretty hard to arrive at the correct code, it is a combination of two separate COM components that don't have much to do with each other.
You need to first add two references to those components so the compiler understands the names. Use Project > Add Reference > COM tab and tick "Microsoft Internet Controls" and "Microsoft Shell Controls and Automation". That adds the Shell32 and SHDocVw namespaces.
Now you can write the code early-bound like this:
Dim objIEShell = New Shell32.Shell
Dim objIEShellWindows = CType(objIEShell.Windows, SHDocVw.IShellWindows)
Dim objIEWin As SHDocVw.WebBrowser
For Each objIEWin In objIEShellWindows
If InStr(objIEWin.LocationURL, "google") > 0 Then
objIEWin.Quit()
End If
Next
The CType() expression is probably the most unintuitive one, the Shell.Windows property is of type Object to break the dependency between those two components. The cast is the necessary voodoo to keep the compiler happy.
Dim policy_key() As RenewalClaim.PolicyKeyType
policy_key(0).policyEffectiveDt = date_format_string(ld_EffectiveDate)
Getting error at Line2.
An Error occured - Object reference not set to an instance of an object.
Each element of object arrays also needs to be declared as a new object too.
Dim policy_key() As RenewalClaim.PolicyKeyType
Redim policy_key(0)
policy_Key(0) = new RenewalClaim.PolicyKeyType
policy_key(0).policyEffectiveDt = date_format_string(ld_EffectiveDate)
QUICK TIP: When declaring classes structures etc, it is useful to name them so you can see what type they are....
e.g.
cls_Policy_Key for a class
str_Policy_Key for a structure etc.
When you come back to your code after a year.. you will thank yourself for doing so.
Dim policy_key() As RenewalClaim.PolicyKeyType
is part of your problem. When you are declaring policy_key() you are actually declaring it as an array with no elements. If you don't particularly need to use an array, for example, if you don't need to add objects to a particular element number, you might be better using a list and declaring it like this
Dim policy_key As New List(Of RenewalClaim.PolicyKeyType)
This way, you can add items easily without having to resize your array each time - The code is a little longer than Trevor's answer, but less prone to errors when you extend your code -
dim newPolicy_Key as RenewalClaim.PolicyKeyType
newPolicy_Key.policyEffectiveDt = date_format_string(ld_EffectiveDate)
policy_Key.add(newPolicyKey)
Looking through some old VB.Net code, I noticed a strange pattern that is making me scratch my head.
Dim objMyObject As Namespace.Child.ChildType = Nothing
objMyObject = New Namespace.Child.ChildType
(There is no additional code between the dimension and the assignment.)
It seems like the preferred style would be to do both on one line, or else skip the = Nothing. As follows:
Dim objMyObject As Namespace.Child.ChildType = New Namespace.Child.ChildType
OR
Dim objMyObject As Namespace.Child.ChildType
objMyObject = New Namespace.Child.ChildType
OR, as suggested by #helrich
Dim objMyObject As New Namespace.Child.ChildType
Is there any particular value to doing it this way, or is this an instance of the original programmer being used to the VB6 way of doing things?
In VB6, dimensioning and instantiating a variable on one line was considered problematic because it would rerun the instantiation (if necessary) when the variable was accessed - effectively, a variable dimensioned in this way could never be tested for Nothing, because a new instance would be created on demand. However, VB.Net does not preserve this convention.
No, this is pointless. The CLR already provides a hard guarantee that variables are initialized to Nothing.
It is otherwise completely harmless, the jitter optimizer will completely remove the code for the assignment. So if the original author preferred that style then that's okay. Maybe he was a former C# programmer that didn't understand the definite assignment rules in that language. VB.NET does some checking too but it isn't nearly as strict. Do check if this is a team standard that you are supposed to follow as well, hopefully not.
In the first example, there's no need to separate the declaration and assignment.
But I was wondering here (a hypothesis): Since you should split this way when you want to persist the variable in the stack when it is assigned in a code block (e.g: If statement), maybe once upon a time this block existed and it was removed keeping a constant association to it.
Its association, though, was not merged with its declaration.
About associating Nothing to an empty variable: I personally like this pattern. :)
It tells myself (in future maintainances) that the variable was declared with an empty (null) value on purpose. It eliminates the doubt that I, maybe, forgot to write the New keyword behind the type.
Ahh, and it will also eliminate a vb.net warning during build.
I'm brand new to Python, I'm using 3.3. I began to explore COM, and what you can do with it is incredible for an engineer. I'm an engineering undergrad student, so I've got enough programming skills to get by, but I don't actually understand what I'm really doing.
The project I'm starting with has an excellent API help if I were writing in VBA, VB.NET, C# or C++ but I'm doing this project in Python and I'm two lines of code away from being done. I'm struggling with the second last "Method" of the program.
the API help offers this VBA description of the Method I'm trying to access.
For VBA:
Dim instance As (a handle?? to the class??? of this method, I know I've got a proper object)
Dim NElementNumber As Integer
Dim NStepNum As Integer
Dim DispPlane As Object (API says if you don't have a value to use, use Nothing, they literally type Nothing in in the provided examples)
Dim NUnits As Integer
Dim value As Object
value = instance.Method(NElementNumber, NStepNum, DispPlane, NUnits, ErrorCode)
and my python shell spits back to me
"Results = instance.Method(i,1,nothing,3,0)
File "<COMObject <unknown>>", line2, in Method
TypeError: Objects of type 'object' can not be converted to a COM VARIANT"
so I'm confused because, I have an idea what the problem is, obviously somehow i need to make the other program see that 'Nothing' entry as an object like it's expecting. But how do I go about doing that? what kind of Object are there many kinds of Objects?
Running into problems creating objects through reflection and then running them on multiple threads.
I just cannot seem to figure out what I need to here:
For Each WorkerNode As XmlNode In oRunSettings.GetWorkerValues
Dim sWorkerName = WorkerNode.Attributes(SETTING_NAME_ID).Value
Dim oWorkerType As Type = Type.GetType(String.Format("Worker.{0}", sWorkerName))
Dim oWorker As Object = Activator.CreateInstance(oWorkerType)
Dim tWorker As Thread = New Thread(AddressOf oWorker.Process)
tWorker.Start()
Next
It is causing errors at the "AddressOf" because Object does not have a method called that. Do I need to do something with an interface?
First of all I want to say that I've never wrote code in VB so I can be completely wrong here but I'll try anyway.
It seems that you hold the created instance as Object instead of it's correct type.
Object does not contain method named Process, hence the error.
try casting the object to the correct type.
I hate when people answer their own question, but while waiting for an answer, I realized that I could just cast the object as its base object, and set the reflection from there. That is working now.