|
code
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
Arrays. Beginner's question!Dim K(1 to 4)
.... K=Array(45,65,23,465) What am I doing wrong please as I get "can't assign" error? "Suzy" <not@valid> wrote in message news:474b0175$1@dnews.tpgi.com.au... The Array function returns a single variant containing the array and you > Dim K(1 to 4) > > ... > > K=Array(45,65,23,465) > > What am I doing wrong please as I get "can't assign" error? can't assign that to an array of variants. Unfortunately VB doesn't have any great way of doing what you are trying to do. The simplest would be to use: Dim K As Variant K=Array(45,65,23,465) You can then use K(0) through K(3) to get the values
Show quote
"Bob Butler" <noway@nospam.ever> wrote in message Thanks Bob. So basically I have to use a variant, which people have alawys news:eyaLnJFMIHA.5160@TK2MSFTNGP05.phx.gbl... > "Suzy" <not@valid> wrote in message news:474b0175$1@dnews.tpgi.com.au... >> Dim K(1 to 4) >> >> ... >> >> K=Array(45,65,23,465) >> >> What am I doing wrong please as I get "can't assign" error? > > The Array function returns a single variant containing the array and you > can't assign that to an array of variants. Unfortunately VB doesn't have > any great way of doing what you are trying to do. The simplest would be > to use: > > Dim K As Variant > K=Array(45,65,23,465) > > You can then use K(0) through K(3) to get the values advised strongly against?
Show quote
"Suzy" <not@valid> wrote in message news:474b04a7@dnews.tpgi.com.au... You could skip the Array function:> > "Bob Butler" <noway@nospam.ever> wrote in message > news:eyaLnJFMIHA.5160@TK2MSFTNGP05.phx.gbl... >> "Suzy" <not@valid> wrote in message news:474b0175$1@dnews.tpgi.com.au... >>> Dim K(1 to 4) >>> >>> ... >>> >>> K=Array(45,65,23,465) >>> >>> What am I doing wrong please as I get "can't assign" error? >> >> The Array function returns a single variant containing the array and you >> can't assign that to an array of variants. Unfortunately VB doesn't have >> any great way of doing what you are trying to do. The simplest would be >> to use: >> >> Dim K As Variant >> K=Array(45,65,23,465) >> >> You can then use K(0) through K(3) to get the values > > Thanks Bob. So basically I have to use a variant, which people have alawys > advised strongly against? Dim K(1 to 4) as long k(1)=45 k(2)=65 k(3)=23 k(4)=465 You could copy it over to a typed array... Dim K(1 To 4) As Long Dim V As Variant Dim x As Long V=Array(45,65,23,465) For x=0 to ubound(v) k(x+1)=v(x) Next That could also be sped up using API calls but using a Variant isn't the end of the world. They have their place and there are some things, like Array, that make it hard to use anything else.
Show quote
"Bob Butler" <noway@nospam.ever> wrote in message ***Thanks Bob but the arrays are far longer. I just gave a few elements for news:OE6OZdFMIHA.820@TK2MSFTNGP06.phx.gbl... > "Suzy" <not@valid> wrote in message news:474b04a7@dnews.tpgi.com.au... >> >> "Bob Butler" <noway@nospam.ever> wrote in message >> news:eyaLnJFMIHA.5160@TK2MSFTNGP05.phx.gbl... >>> "Suzy" <not@valid> wrote in message news:474b0175$1@dnews.tpgi.com.au... >>>> Dim K(1 to 4) >>>> >>>> ... >>>> >>>> K=Array(45,65,23,465) >>>> >>>> What am I doing wrong please as I get "can't assign" error? >>> >>> The Array function returns a single variant containing the array and you >>> can't assign that to an array of variants. Unfortunately VB doesn't >>> have any great way of doing what you are trying to do. The simplest >>> would be to use: >>> >>> Dim K As Variant >>> K=Array(45,65,23,465) >>> >>> You can then use K(0) through K(3) to get the values >> >> Thanks Bob. So basically I have to use a variant, which people have >> alawys advised strongly against? > > > You could skip the Array function: > Dim K(1 to 4) as long > k(1)=45 > k(2)=65 > k(3)=23 > k(4)=465 > the example. I have followed the simple variant idea but notice that the calculations are a bit different. I now have Dim K As Variant and then K = Array(lots of stuff...) Show quote > You could copy it over to a typed array... > > Dim K(1 To 4) As Long > Dim V As Variant > Dim x As Long > V=Array(45,65,23,465) > For x=0 to ubound(v) > k(x+1)=v(x) > Next > > That could also be sped up using API calls but using a Variant isn't the > end of the world. They have their place and there are some things, like > Array, that make it hard to use anything else. > > The advice against variants centres on (a) the ability for the variable to
assume the data type needed to represent the data, even if that data type is not the one the programmer expects, and (b) variants use more memory than explicitly typed variables. The need to use variants with a subset of VB5 and VB6 functions is a result of accomodating most users in a single data type. As long as you are sure the data you assigned holds the data type you want, you should have no problems. For example: Private Sub CommandButton1_Click() Dim v() Dim x As Long v = Array(1, 2, 3, 4, 5) For x = LBound(v) To UBound(v) Debug.Print VarType(v(x)) Next End Sub .... will print out 2 for integer. But an errant string thrown into the mix will muck things up. Show quote "Suzy" <not@valid> wrote in message news:474b04a7@dnews.tpgi.com.au... > > "Bob Butler" <noway@nospam.ever> wrote in message > news:eyaLnJFMIHA.5160@TK2MSFTNGP05.phx.gbl... >> "Suzy" <not@valid> wrote in message news:474b0175$1@dnews.tpgi.com.au... >>> Dim K(1 to 4) >>> >>> ... >>> >>> K=Array(45,65,23,465) >>> >>> What am I doing wrong please as I get "can't assign" error? >> >> The Array function returns a single variant containing the array and you >> can't assign that to an array of variants. Unfortunately VB doesn't have >> any great way of doing what you are trying to do. The simplest would be >> to use: >> >> Dim K As Variant >> K=Array(45,65,23,465) >> >> You can then use K(0) through K(3) to get the values > > Thanks Bob. So basically I have to use a variant, which people have alawys > advised strongly against? > > Note that in your original post you are already using a variant:
>>> Dim K(1 to 4) What Bob (and I) suggest is that instead of using a variant array, you usea variant variable. You should avoid using variant types whenever possible. This is one of those cases when a variant type is your friend. Also note that Bob qualified the variant type by explicitly including "as variant" in the dim statement, something that I neglected to do. Definitely recommended doing it Bob's way <g>. Regards Saga -- Show quote23, 22, 21, 20, 19, 18... "Suzy" <not@valid> wrote in message news:474b04a7@dnews.tpgi.com.au... > > "Bob Butler" <noway@nospam.ever> wrote in message news:eyaLnJFMIHA.5160@TK2MSFTNGP05.phx.gbl... >> "Suzy" <not@valid> wrote in message news:474b0175$1@dnews.tpgi.com.au... >>> Dim K(1 to 4) >>> >>> ... >>> >>> K=Array(45,65,23,465) >>> >>> What am I doing wrong please as I get "can't assign" error? >> >> The Array function returns a single variant containing the array and you can't assign that to an >> array of variants. Unfortunately VB doesn't have any great way of doing what you are trying to >> do. The simplest would be to use: >> >> Dim K As Variant >> K=Array(45,65,23,465) >> >> You can then use K(0) through K(3) to get the values > > Thanks Bob. So basically I have to use a variant, which people have alawys advised strongly > against? > > "Suzy" <not@valid> wrote in message news:474b04a7@dnews.tpgi.com.au... No. You don't need to use a Variant. In fact I would strongly advise against > Thanks Bob. So basically I have to use a variant, which > people have alawys advised strongly against? doing so. Just use an Array of the appropriate variable type and fill the array with your data using one of a number of different possible techniques. Mike "Mike Williams" <mi***@whiskyandCoke.com> wrote in message Thanks Mike. I was going to post that when using a variant I am getting news:OMB8LpHMIHA.1204@TK2MSFTNGP03.phx.gbl... > "Suzy" <not@valid> wrote in message news:474b04a7@dnews.tpgi.com.au... > >> Thanks Bob. So basically I have to use a variant, which >> people have alawys advised strongly against? > > No. You don't need to use a Variant. In fact I would strongly advise > against doing so. Just use an Array of the appropriate variable type and > fill the array with your data using one of a number of different possible > techniques. > > Mike > slightly different results to when I am using Double and was wondering why. The old code was Dim K1(7) as double .... K1(1)=0.4711 K1(2)=0.462 K1(3)=0.4538 etc... which I changed (on advice) to Dim K1 As Variant .... K1 = Array(0, 0.4711, 0.462, 0.4538, 0.4491, 0.4421, 0.4385, 0.4268) Calculations using this data came out slightly differently using the two methods. Any suggestions?
Show quote
"Suzy" <not@valid> wrote in message news:474bb9bc@dnews.tpgi.com.au... Can you show an example of a calculation that comes out different?> > Thanks Mike. I was going to post that when using a variant I am getting > slightly different results to when I am using Double and was wondering why. > > The old code was > > Dim K1(7) as double > ... > K1(1)=0.4711 > K1(2)=0.462 > K1(3)=0.4538 > etc... > > which I changed (on advice) to > > Dim K1 As Variant > ... > K1 = Array(0, 0.4711, 0.462, 0.4538, 0.4491, 0.4421, 0.4385, 0.4268) > > Calculations using this data came out slightly differently using the two > methods. Any suggestions? In your new version, you have a variant, which is an array of variants, where each element is variant type double, which is not quite the same as being a double. For a really clean result, I would take Bob's suggestion, and do Dim KTemp As Variant Dim K1(7) As Double Dim N As Long KTemp = Array(0, 0.4711, 0.462, 0.4538, 0.4491, 0.4421, 0.4385, 0.4268) For N = 0 To 7 K1(N) = KTemp(N) Next N Then you have a simple array of doubles, no doubts about data type. "Suzy" <not@valid> wrote in message news:474bb9bc@dnews.tpgi.com.au... If you are using Doubles, and if you are using the same base for the array > Thanks Mike. I was going to post that when using a variant > I am getting slightly different results to when I am using > Double and was wondering why. and not accidentally failing to account for an element, then the results should be approximately the same, because the Array function uses Doubles in the Variant array, although with floating point data you always need to be prepared to accept the fact that decimal values (and calculations performed on them) are almost never held in any floating point variable with absolute accuracy because the binary number system simply cannot do so, especially with the limited number of bits which the IEEE floating point data has to work with and the vast range of values that it needs to encompass. This is all fairly commonly accepted stuff and you always need to accept a certain amount of "error" in any floating point calculation. On a more general note, personally I think you should always avoid Variants anyway unless you have a very specific need to use them, because they are generally slower and less efficient. Mike "Mike Williams" <mi***@whiskyandCoke.com> wrote in message snipnews:OjiRBtNMIHA.5860@TK2MSFTNGP04.phx.gbl... > "Suzy" <not@valid> wrote in message news:474bb9bc@dnews.tpgi.com.au... > > If I may hitchhike on this thread <g>...> On a more general note, personally I think you should always avoid > Variants anyway unless you have a very specific need to use them, because > they are generally slower and less efficient. > > Mike in that context, I had always tried to avoid variants for the previously mentioned and well advertised reasons. Then along came a thread that pointed out that iterating a collection was more efficient with For Each than With For idx = 1 to count But as the enumerator has to be a variant(unless the collection contains only objects in which case it could be an object) So I've taken to doing something like Dim vItem as Variant, sItem as string For Each vItem in collectionOfStrings sItem = Cstr(vItem) 'do something with sItem Next vItem What's the advice on that? Thanks mark "MP" <NoSpam@Thanks.com> wrote in message My advice would be to avoid Collections as well, unless you have a very news:%230OYgaOMIHA.4456@TK2MSFTNGP03.phx.gbl... > For Each vItem in collectionOfStrings > sItem = Cstr(vItem) > 'do something with sItem > Next vItem > What's the advice on that? specific need for using them. Mike
Show quote
"Mike Williams" <mi***@whiskyandCoke.com> wrote in message "avoid Collections " ... in favor of what? arrays?news:%23s%23syBPMIHA.820@TK2MSFTNGP06.phx.gbl... > "MP" <NoSpam@Thanks.com> wrote in message > news:%230OYgaOMIHA.4456@TK2MSFTNGP03.phx.gbl... > >> For Each vItem in collectionOfStrings >> sItem = Cstr(vItem) >> 'do something with sItem >> Next vItem >> What's the advice on that? > > My advice would be to avoid Collections as well, unless you have a very > specific need for using them. > > Mike > do these count as.. "> specific need(s) for using them." 1 the Redim preserve issue when building arrays...(mitigated by the If Mod 1xxx ...Redim technique) 2 avoids passing variants as return types (assuming a function that returns a "grouping of some things") 3 awful handy when adding items :-) 4 has key property if needed 5 easy avoidance of duplicate entries if using key I know collections have some memory cost and in critical time situations arrays are faster...but avoid them altogether?
Show quote
"MP" <NoSpam@Thanks.com> wrote in message I use collections frequently, so I don't agree with Mike's comment outright. news:%23svuVKPMIHA.5988@TK2MSFTNGP02.phx.gbl... > > "Mike Williams" <mi***@whiskyandCoke.com> wrote in message > news:%23s%23syBPMIHA.820@TK2MSFTNGP06.phx.gbl... >> My advice would be to avoid Collections as well, unless you have a very >> specific need for using them. >> >> Mike >> > > "avoid Collections " ... in favor of what? arrays? > I know collections have some memory cost and in critical time situations > arrays are faster...but avoid them altogether? However almost all my use of collections is for objects, not value data types. Arrays work just fine for most value data situations. "MP" <NoSpam@Thanks.com> wrote in message Well that's what I would personally do. Each to his own of course. But as news:%23svuVKPMIHA.5988@TK2MSFTNGP02.phx.gbl... > "avoid Collections " ... in favor of what? arrays? Steve has said, Collections might be better for lots of Objects. In my own case the data items I usually deal with are standard variable types, usually either Longs or Strings (or preferably Byte arrays instead of Strings whenever I can get away with usign them). For such variables I definitely prefer arrays. > the Redim preserve issue when building arrays The trick, as you've already suggested, is to Redim only when really necessary. For example, if you've got a typical polulated array of 10,000 variable length Strings and you run out of elements and you do a Redim Preserve to add a further 10,000 elements to the array it takes only about a fifth of a millisecond (on my own machine) to add the 10,000 elements. When compared to the time it takes for you to do whatever you are doing with the 20,000 variable length Strings, an extra fifth of a millisecond overall is so negligible as to be almost non existent. Also, with arrays you have a wide choice of methods when it comes to deciding how to handle them, binary searches, indexing, linked lists, all sorts of things, so they can be quite fast (as far as anything that contains Strings in VB, including Collections, can be called fast). As others have already said, it's really "horses for courses" and each to his own, but my own personal preference is for arrays rather than Collections. Mike "MP" <NoSpam@Thanks.com> wrote in <SNIP>news:#svuVKPMIHA.5988@TK2MSFTNGP02.phx.gbl: > I know collections have some memory cost and in critical time While I was always against using a collection for anything, but it seems > situations arrays are faster...but avoid them altogether? that was because I was constantly working with large amounts of data. In a personal project, I've recreated the system tray....some of the code was found online, and that used a collection. I immediately intended to change that to arrays, but didn't, because that part of the code worked already, and I wanted to get my code working with it. I never did change it to an array. There's maybe 15 or 20 members max at any one time, so speed it not an issue. I've used a collection or two since then, when dealing with a small sets of data, and it works out well.
Show quote
"MP" <NoSpam@Thanks.com> wrote I'd say why bother moving it to a string type? Unless you have a dozen or more> Then along came a thread that pointed out that iterating a collection was > more efficient with For Each than With For idx = 1 to count > But as the enumerator has to be a variant(unless the collection contains > only objects in which case it could be an object) > So I've taken to doing something like > Dim vItem as Variant, sItem as string > For Each vItem in collectionOfStrings > sItem = Cstr(vItem) > 'do something with sItem > Next vItem > What's the advice on that? accesses on that particular string, you may not see much gain for the effort. Collections are great for small lists where you don't know how many items there will be, but if you get up into the 1,000's of items, a string array may suit the need better. Of course, that's my opinion, others may have a different take on it.... LFS
Show quote
"Larry Serflaten" <serfla***@usinternet.com> wrote in message Hi Larry,news:%23bxUQoPMIHA.4584@TK2MSFTNGP03.phx.gbl... > > "MP" <NoSpam@Thanks.com> wrote > >> Then along came a thread that pointed out that iterating a collection was >> more efficient with For Each than With For idx = 1 to count >> But as the enumerator has to be a variant(unless the collection contains >> only objects in which case it could be an object) > >> So I've taken to doing something like > >> Dim vItem as Variant, sItem as string >> For Each vItem in collectionOfStrings >> sItem = Cstr(vItem) >> 'do something with sItem >> Next vItem >> What's the advice on that? > Thanks for the response. > I'd say why bother moving it to a string type? Unless you have a dozen or I only showed that because lots of times I'm passing the value to a function > more > accesses on that particular string, you may not see much gain for the > effort. that receives a string type arg Without the cast I'd get a type mismatch I do wonder, now that you mention it, am I creating an unnecessary string .... (in the context of vb's reputed inefficient string manipulation,) compare optionA and option B option A Dim sItem as String sItem = Cstr(vItem) Call FunctionEatString( sItem) Option B Call FunctionEatString( Cstr(vItem)) if that's called in a loop am I saving a few microseconds with option B??? > 99.999% of my items would be <1000> Collections are great for small lists where you don't know how many items > there > will be, but if you get up into the 1,000's of items, a string array may > suit the > need better. > as an amature making inhouse utilities as small helper apps only....I have a very limited viewpoint <g> > Of course, that's my opinion, others may have a different take on it.... naaahhhhh, not around here...:-)> > LFS Thanks as always,> oh...an apologies to op for horning in on thread...I didn't mean to side track from original post...just had similar questions Mark Dim K 'Note that K is declared as variant simpl evar, not an array
Dim i As Integer K = Array(45, 65, 23, 465) For i = LBound(K) To UBound(K) MsgBox "k(" & i & "): " & K(i) Next i Saga -- Show quote23, 22, 21, 20, 19, 18... "Suzy" <not@valid> wrote in message news:474b0175$1@dnews.tpgi.com.au... > Dim K(1 to 4) > > ... > > K=Array(45,65,23,465) > > What am I doing wrong please as I get "can't assign" error? > "Saga" <antiSpam@somewhere.com> wrote in message ?news:%237QsOJFMIHA.4584@TK2MSFTNGP03.phx.gbl... > -- > 23, 22, 21, 20, 19, 18... seconds until Michael C posts a pointless diatribe in response? Days until my annual (long awaited) vacation :-D
-- Show quote23, 22, 21, 20, 19, 18... "Bob Butler" <noway@nospam.ever> wrote in message news:uG8PgMFMIHA.4688@TK2MSFTNGP06.phx.gbl... > "Saga" <antiSpam@somewhere.com> wrote in message news:%237QsOJFMIHA.4584@TK2MSFTNGP03.phx.gbl... >> -- >> 23, 22, 21, 20, 19, 18... > > > ? > > seconds until Michael C posts a pointless diatribe in response? > > > "Bob Butler" <noway@nospam.ever> wrote in message Likely. After looking at his posts for a few months,news:uG8PgMFMIHA.4688@TK2MSFTNGP06.phx.gbl... > "Saga" <antiSpam@somewhere.com> wrote in message > news:%237QsOJFMIHA.4584@TK2MSFTNGP03.phx.gbl... > > -- > > 23, 22, 21, 20, 19, 18... > > > ? > > seconds until Michael C posts a pointless diatribe in response? I'm of the opinion that Michael C means Michael Charlie as in Michael 'Last Word' C Where is this data coming from?
Are you just entering all the data yourself. Is it numeric? Wondering if Split() might be helpful. Show quote "Suzy" wrote: > Dim K(1 to 4) > > .... > > K=Array(45,65,23,465) > > What am I doing wrong please as I get "can't assign" error? > > >
Show quote
> "Suzy" wrote: It is an old interpreter BASIC program that used the data/read format. I > >> Dim K(1 to 4) >> >> .... >> >> K=Array(45,65,23,465) >> >> What am I doing wrong please as I get "can't assign" error? >> >> >> "Lorin" <Lo***@discussions.microsoft.com> wrote in message news:D4C0F4FA-784B-4913-820B-861548E26290@microsoft.com... > Where is this data coming from? > Are you just entering all the data yourself. > Is it numeric? > Wondering if Split() might be helpful. > want to keep the two as close as possible to maintain understanding but there is no data/read function with vb so I had explicitly spelt out each data element as a separate variable. There must be a less tedious method... "Suzy" <not@valid> wrote in message news:474bbb2b@dnews.tpgi.com.au... There is. Basically you just need to write code to perform a similar task to > It is an old interpreter BASIC program that used > the data/read format. I want to keep the two as > close as possible to maintain understanding but there is no data/read > function with vb so I had > explicitly spelt out each data element as a > separate variable. There must be a less tedious > method... the old Read / Data stuff, or at least as close to that as you can get. Here is a very inefficient way (inefficient because it uses an intermediate step to create an array of strings and then transfers those to an array of Single) but it shows the basic idea. A better way would be to loop through the dta String using Instr looking for the commas and then dump each preceeding value into the array of Singles, thereby avoiding the intermediate "Split" step, but I'll leave that to you. There are lots of different methods. Basically you would write a general purpose function on the following lines and pass it a dta() String array and the array of Singles into which you want it dumped, so that in general use (once the function has been written) the main code uses just a single call to perform the conversion. Dim dta As String, b() As String, d() As Single, n As Long dta = "0.4711, 0.4620, 0.4538, 1.0234, 0.3547, 0.2890," _ & "0.3270, 1.4560, 0.4790, 0.2410, 1.5670, 0.3245," _ & "0.3245, 0.1189, 0.7650" ' write the function along the following lines b() = Split(dta, ",") ReDim d(LBound(b) To UBound(b)) For n = LBound(b) To UBound(b) d(n) = CSng(b(n)) Print d(n) Next n Mike |
|||||||||||||||||||||||