push to array vb.net 2008 - vb.net

the message was variable j is used before it have been assigned value.If in php language, it's not a problem at all.
Dim j() As String
Dim i As Integer
If (i = 1) Then
j(0) = "x"
Else
j(0) = "d"
End If

in php language,it's not a problem at all.
php doesn't use real arrays. A real array is a contiguous block of memory. Php uses a collection type with array-like semantics. They call it an array, but it's not really. Collections seldom make the same kind of guarantees about continuity because of performance problems caused when the collection grows at runtime.
If you want php-style "arrays" in .Net, you need to do the same thing php does and use a collection. The System.Collections.Generics.List<T> type works pretty well. Then you can append to the List by using its .Add() method or using the collection initializer syntax demonstrated below (requires Visual Studio 2010):
Dim i As Integer = 1
Dim j As New List(Of String) From { If(i = 1, "x","d") }
We can forgive php it's naming lapse, though, as real arrays should be used sparingly. A collection is almost always more appropriate.

Related

Mid() usage and for loops - Is this good practice?

Ok so I was in college and I was talking to my teacher and he said my code isn't good practice. I'm a bit confused as to why so here's the situation. We basically created a for loop however he declared his for loop counter outside of the loop because it's considered good practice (to him) even though we never used the variable later on in the code so to me it looks like a waste of memory. We did more to the code then just use a message box but the idea was to get each character from a string and do something with it. He also used the Mid() function to retrieve the character in the string while I called the variable with the index. Here's an example of how he would write his code:
Dim i As Integer = 0
Dim justastring As String = "test"
For i = 1 To justastring.Length Then
MsgBox( Mid( justastring, i, 1 ) )
End For
And here's an example of how I would write my code:
Dim justastring As String = "test"
For i = 0 To justastring.Length - 1 Then
MsgBox( justastring(i) )
End For
Would anyone be able to provide the advantages and disadvantages of each method and why and whether or not I should continue how I am?
Another approach would be, to just use a For Each on the string.
Like this no index variable is needed.
Dim justastring As String = "test"
For Each c As Char In justastring
MsgBox(c)
Next
I would suggest doing it your way, because you could have variables hanging around consuming(albeit a small amount) of memory, but more importantly, It is better practice to define objects with as little scope as possible. In your teacher's code, the variable i is still accessible when the loop is finished. There are occasions when this is desirable, but normally, if you're only using a variable in a limited amount of code, then you should only declare it within the smallest block that it is needed.
As for your question about the Mid function, individual characters as you know can be access simply by treating the string as an array of characters. After some basic benchmarking, using the Mid function takes a lot longer to process than just accessing the character by the index value. In relatively simple bits of code, this doesn't make much difference, but if you're doing it millions of times in a loop, it makes a huge difference.
There are other factors to consider. Such as code readability and modification of the code, but there are plenty of websites dealing with that sort of thing.
Finally I would suggest changing some compiler options in your visual studio
Option Strict to On
Option Infer to Off
Option Explicit to On
It means writing more code, but the code is safer and you'll make less mistakes. Have a look here for an explanation
In your code, it would mean that you have to write
Dim justastring As String = "test"
For i As Integer = 0 To justastring.Length - 1 Then
MsgBox( justastring(i) )
End For
This way, you know that i is definitely an integer. Consider the following ..
Dim i
Have you any idea what type it is? Me neither.
The compiler doesn't know what so it defines it as an object type which could hold anything. a string, an integer, a list..
Consider this code.
Dim i
Dim x
x = "ab"
For i = x To endcount - 1
t = Mid(s, 999)
Next
The compiler will compile it, but when it is executed you'll get an SystemArgumenException. In this case it's easy to see what is wrong, but often it isn't. And numbers in strings can be a whole new can of worms.
Hope this helps.

A null reference could result in runtime

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)

Why should I use the DIM statement in VBA or Excel?

So there is a question on what DIM is, but I can't find why I want to use it.
As far as I can tell, I see no difference between these three sets of code:
'Example 1
myVal = 2
'Example 2
DIM myVal as Integer
myVal = 2
'Example 3
DIM myVal = 2
If I omit DIM the code still runs, and after 2 or 3 nested loops I see no difference in the output when they are omitted. Having come from Python, I like to keep my code clean*.
So why should I need to declare variables with DIM? Apart from stylistic concerns, is there a technical reason to use DIM?
* also I'm lazy and out of the habit of declaring variables.
Any variable used without declaration is of type Variant. While variants can be useful in some circumstances, they should be avoided when not required, because they:
Are slower
Use more memory
Are more error prone, either through miss spelling or through assigning a value of the wrong data type
Using Dim makes the intentions of your code explicit and prevents common mistakes like a typo actually declaring a new variable. If you use Option Explicit On with your code (which I thoroughly recommend) Dim becomes mandatory.
Here's an example of failing to use Dim causing a (potentially bad) problem:
myVar = 100
' later on...
myVal = 10 'accidentally declare new variable instead of assign to myVar
Debug.Print myVar 'prints 100 when you were expecting 10
Whereas this code will save you from that mistake:
Option Explicit
Dim myVar as Integer
myVar = 100
' later on...
myVal = 10 ' error: Option Explicit means you *must* use Dim
More about Dim and Option Explicit here: http://msdn.microsoft.com/en-us/library/y9341s4f.aspx
Moderators, I'm making an effort, assuming you'll treat me with due respect in thefuture.
All local variables are stored on the stack as with all languages (and most parameters to functions). When a sub exits the stack is returned to how it was before the sub executed. So all memory is freed. Strings and objects are stored elsewhere in a object manager or string manager and the stack contains a pointer but vb looks after freeing it. Seting a vbstring (a bstr) to zero length frees all but two bytes. That's why we try to avoid global variables.
In scripting type programs, typeless programming has many advantages. Programs are short and use few variables so memory and speed don't matter - it will be fast enough. As programs get more complex it does matter. VB was designed for typeless programming as well as typed programming. For most excel macros, typeless programming is fine and is more readable. Vbscript only supports typeless programming (and you can paste it into vba/vb6).

Copy byte array in VB.NET

I am retrieving a byte blob from an SQLite database/record set. I am not experienced with garbage collection yet.
When I say:
Dim bt() As Byte
bt = r.fields("mybyteblob").value
... is that okay or unsafe?
I would like to make a copy of the byte array in the record set field, and I am not sure if I am simply referencing the byte array here instead of copying it.
In your code you are only referencing the byte array.
If you want to copy it you need
Dim bt() As Byte
if r.fields("mybyteblob").Value Is not Nothing then
dim lenArray = r.fields("mybyteblob").Length
bt = new Byte(lenArray)
Array.Copy(r.fields("mybyteblob").value, bt, lenArray)
end if
There is another alternative.
The Buffer class is faster than Array and more appropriate because you are using a byte array
Dim bt() As Byte
if r.fields("mybyteblob").Value Is not Nothing then
dim lenArray = r.fields("mybyteblob").Length
bt = new Byte(lenArray)
Buffer.BlockCopy(r.fields("mybyteblob").value, 0, bt, 0, lenArray)
end if
Here a good question on the two methods
It is very unusual to run into garbage collection problems if you only write managed code (i.e. no P/Invoke).
Many smart people has put a lot of effort into making garbage collection work without you having to worry about it, so do just that: don't worry about it. Just write your code, and if you run into a specific behavior you don't understand, then ask about that particular behavior (and I can assure you that in 99.9967% [1] of the cases it will not be the garbage collector).
[1] This is not a random number. I've ran into a garbage collection gotcha once in ~10 years of programming. Assuming 10 bugs a day and 300 days of work per year, that makes 29999/30000 bugs which are not garbage-collection related = 99.9967%.

What is the C# equivalent of this Excel VBA code for Shapes?

This is the VBA code for an Excel template, which I'm trying to convert to C# in a VSTO project I'm working on. By the way, it's a VSTO add-in:
Dim addedShapes() As Variant
ReDim addedShapes(1)
addedShapes(1) = aBracket.Name
ReDim Preserve addedShapes(UBound(addedShapes) + 1)
addedShapes(UBound(addedShapes)) = "unique2"
Set tmpShape = Me.Shapes.Range(addedShapes).Group
At this point, I'm stumped by the addedShapes(), not sure what this is all about.
Update: Matti mentioned that addedShapes() represents a variant array in VBA. So now I'm wondering what the contents of addedShapes() should be. Would this be the correct way to call the Shapes.Range() call in C#?
List<string> addedShapes = new List<string>();
...
Shape tmpShape = worksheet.Shapes.get_Range
(addedShapes.Cast<object>().ToArray()).Group();
I'd appreciate anyone who's worked with VBA and C# willing to make a comment on my question & problem!
I'm not sure what your actual question is supposed to be, but addedShapes is an array. In VB and its variants, arrays are declared and accessed using () instead of [].
Also, your code looks like it's just a really long-winded way of doing:
object[] addedShapes = new object[] { aBracket.Name, "unique2" };
Shape tmpShape = worksheet.Shapes.get_Range(addedShapes).Group();
The last part might alternatively be
Shape tmpShape = worksheet.Shapes[addedShapes].Group();
See which ever works. I can't really figure out which one MSDN suggests.
Excuse the c style comments, the vb style doesnt syntax hilight nicely.
//This declares an array of variants but does not initialize it.
Dim addedshapes() As Variant
//Initializes the array with a max index of 1. (insert vb index rant here)
ReDim addedShapes(1)
//assigns the contents of aBracket.Name to element 1 of the array.
addedShapes(1) = aBracket.Name
//increases the size of addedShapes by 1, retaining any values.
ReDim Preserve addedShapes(UBound(addedShapes) + 1)
//sets the last element to the string literal
addedShapes(UBOund(addedShapes)) = "unique2"
//Not sure here because I havent done any VBA in a loooong time,
//but anyway it's passing the array.
set tmpShape = Me.Shapes.Range(addedShapes).Group
in VB, Variant is just a lazy struct that can hold any datatype, int, floats, objects, etc. so in .Net the most direct comparison would be some collection/array of objects. However if you know what is going in there then it's far better to limit the collection to that. So rather than List<object> you'd use List<Class> or List<BaseClass> or List<ISomeInterface>