Reply
 
LinkBack Thread Tools Search this Thread Display Modes
  #1   Report Post  
Posted to microsoft.public.excel.programming
external usenet poster
 
Posts: 783
Default Changing For...Next index

I have seen it stated that it is undesirable, in a For...Next loop, e.g.,

For i = 1 to 10
'Do Something
Next

to change the index (i, in the above illustration) programatically.

1. Is this a commonly accepted taboo?

2. If so, why is it thought to be undesirable?

Thanks,
Alan Beban
  #2   Report Post  
Posted to microsoft.public.excel.programming
external usenet poster
 
Posts: 10,593
Default Changing For...Next index

The only danger that I can see is if the index gets set back, it could
create an infinite loop.

I have never experienced a problem just moving the index along its
step-path, even going beyond its loop limit.

It's like everything I guess, if you understand the implications, and know
the data, you can weigh up the risks.

--
---
HTH

Bob

(there's no email, no snail mail, but somewhere should be gmail in my addy)



"Alan Beban" wrote in message
...
I have seen it stated that it is undesirable, in a For...Next loop, e.g.,

For i = 1 to 10
'Do Something
Next

to change the index (i, in the above illustration) programatically.

1. Is this a commonly accepted taboo?

2. If so, why is it thought to be undesirable?

Thanks,
Alan Beban



  #3   Report Post  
Posted to microsoft.public.excel.programming
external usenet poster
 
Posts: 389
Default Changing For...Next index

Hi Alan.

I suppose that an iterative programming challenge might be OK for
programmatic index modification. But otherwise, the way I interpret this, is
that what is being changed must inherently be tightly coupled with what is
changing it. In the real world that could result in disparate code fragments
evaluating similar business logic differently, and might non-obviously have
to be maintained concurrently.

Tim

"Alan Beban" wrote in message
...
I have seen it stated that it is undesirable, in a For...Next loop, e.g.,

For i = 1 to 10
'Do Something
Next

to change the index (i, in the above illustration) programatically.

1. Is this a commonly accepted taboo?

2. If so, why is it thought to be undesirable?

Thanks,
Alan Beban



  #4   Report Post  
Posted to microsoft.public.excel.programming
external usenet poster
 
Posts: 5,939
Default Changing For...Next index

I personally avoid changing the index as I find it too difficult to debug
when things go wrong. The loops either run long (infinite loop possibly) or
end too soon and I end up patching things up in a bandaid kind of fashion.
Nothing written in stone here but I have never run into a situation that I
could not work around needing to change the index. The way I see it it is
kind of like Goto's... better to avoid them than to fix them.
--
HTH...

Jim Thomlinson


"Alan Beban" wrote:

I have seen it stated that it is undesirable, in a For...Next loop, e.g.,

For i = 1 to 10
'Do Something
Next

to change the index (i, in the above illustration) programatically.

1. Is this a commonly accepted taboo?

2. If so, why is it thought to be undesirable?

Thanks,
Alan Beban

  #5   Report Post  
Posted to microsoft.public.excel.programming
external usenet poster
 
Posts: 783
Default Changing For...Next index

Thanks to Bob Phillips, Tim Zych and Jim Thomlinson for taking the time
to respond (although I must say I wasn't able to follow Tim's response).
Just for the record, the situation that prompted my post was code to
delete all duplicate rows in a range. The following, in which RowsEqual
is a function that returns True or False depending on whether two rows
in a range or a two-dimensional array have all the same elements, was
what I coded:

Sub abtest4()
Dim rng As Range, i As Integer, j As Integer
Set rng = Range("DataRange").Rows
For i = rng.Rows.Count To 2 Step -1
For j = i - 1 To 1 Step -1
If RowsEqual(rng(i), rng(j)) Then
rng(i).Delete
i = i - 1
j = i
End If
Next j
Next i
End Sub

Alan Beban

Jim Thomlinson wrote:
I personally avoid changing the index as I find it too difficult to debug
when things go wrong. The loops either run long (infinite loop possibly) or
end too soon and I end up patching things up in a bandaid kind of fashion.
Nothing written in stone here but I have never run into a situation that I
could not work around needing to change the index. The way I see it it is
kind of like Goto's... better to avoid them than to fix them.



  #6   Report Post  
Posted to microsoft.public.excel.programming
external usenet poster
 
Posts: 5,939
Default Changing For...Next index

Your rng.Rows.Count is going to change as you delete rows and that is not a
good idea. Not onny are you changing i but you are also changing the range in
which it is moving...

This is just my preference but when I am deleteing I always create a range
object of all of the cells that want to delete within the loop structure and
then do one big delete of all of the cells I found at the end. It is more
effiecient and it avoids problems with the range changing while I am looking
through it. Just my two cents... With your code it would look like this...

Sub abtest4()
Dim rng As Range, i As Integer, j As Integer
dim rngToDelete as range

Set rng = Range("DataRange")
For i = rng.Rows.Count To 2 Step -1
For j = i - 1 To 1 Step -1
If RowsEqual(rng(i), rng(j)) Then
if rngToDelete is nothing then
Set rngtoDelete = rng(i)
else
Set rngToDelete = union(rngToDelete, rng(i))
end if
End If
Next j
Next i
if not rngToDelete is nothing then rngToDelete.Delete
End Sub
--
HTH...

Jim Thomlinson


"Alan Beban" wrote:

Thanks to Bob Phillips, Tim Zych and Jim Thomlinson for taking the time
to respond (although I must say I wasn't able to follow Tim's response).
Just for the record, the situation that prompted my post was code to
delete all duplicate rows in a range. The following, in which RowsEqual
is a function that returns True or False depending on whether two rows
in a range or a two-dimensional array have all the same elements, was
what I coded:

Sub abtest4()
Dim rng As Range, i As Integer, j As Integer
Set rng = Range("DataRange").Rows
For i = rng.Rows.Count To 2 Step -1
For j = i - 1 To 1 Step -1
If RowsEqual(rng(i), rng(j)) Then
rng(i).Delete
i = i - 1
j = i
End If
Next j
Next i
End Sub

Alan Beban

Jim Thomlinson wrote:
I personally avoid changing the index as I find it too difficult to debug
when things go wrong. The loops either run long (infinite loop possibly) or
end too soon and I end up patching things up in a bandaid kind of fashion.
Nothing written in stone here but I have never run into a situation that I
could not work around needing to change the index. The way I see it it is
kind of like Goto's... better to avoid them than to fix them.


  #7   Report Post  
Posted to microsoft.public.excel.programming
external usenet poster
 
Posts: 783
Default Changing For...Next index

Hi Jim,

My data range contained the following:

1 2 3 4
a b c d
1 2 3 4
a b c d
5 6 7 8
1 2 3 4
a b c d
1 2 3 4
a b c d
5 6 7 8

When I run my code on it the result is

1 2 3 4
a b c d
5 6 7 8

When I first attempted to run your code, I got a compiler error, Type
mismatch, at the indicated line. I then changed your code from

Set rng = Range("DataRange") to

Set rng = Range("DataRange").Rows with this result:

1 2 3 4
a b c d


5 6 7 8

Your comment did make me rethink my code and I simplified it to

Sub abtest4()
Dim rng As Range, i As Integer, j As Integer
Set rng = Range("DataRange").Rows
For i = rng.Rows.Count To 2 Step -1
For j = i - 1 To 1 Step -1
If RowsEqual(rng(i), rng(j)) Then
rng(i).Delete
End If
Next j
Next i
End Sub

Thanks for your interest. In case you wanted to check it yourself, here
is the RowsEqual function (watch for wordwrap):

Function RowsEqual(Row1, Row2)
'This function checks to see if two "rows"
'of an array or range are equal; it returns
'True if they are, False if they are not.

k = True

'Check to see that input rows are arrays or
'multicell ranges.
If (IsArray(Row1) And IsArray(Row2)) Then

'Convert input ranges to arrays.
arr1 = Row1: arr2 = Row2

'Loop to see if all elements are the same.
For i = LBound(arr1) To UBound(arr1)
For j = LBound(arr2) To UBound(arr2, 2)
If Not (arr1(i, j) = arr2(i, j)) Then RowsEqual =
False: Exit Function
Next
Next
RowsEqual = True

'If either input row is not an array or multicell
'range, give error message
Else
RowsEqual = "This function accepts only arrays and multicell
ranges"
End If

End Function


Jim Thomlinson wrote:
Your rng.Rows.Count is going to change as you delete rows and that is not a
good idea. Not onny are you changing i but you are also changing the range in
which it is moving...

This is just my preference but when I am deleteing I always create a range
object of all of the cells that want to delete within the loop structure and
then do one big delete of all of the cells I found at the end. It is more
effiecient and it avoids problems with the range changing while I am looking
through it. Just my two cents... With your code it would look like this...

Sub abtest4()
Dim rng As Range, i As Integer, j As Integer
dim rngToDelete as range

Set rng = Range("DataRange")
For i = rng.Rows.Count To 2 Step -1
For j = i - 1 To 1 Step -1
If RowsEqual(rng(i), rng(j)) Then '<------Type mismatch
if rngToDelete is nothing then
Set rngtoDelete = rng(i)
else
Set rngToDelete = union(rngToDelete, rng(i))
end if
End If
Next j
Next i
if not rngToDelete is nothing then rngToDelete.Delete
End Sub

  #8   Report Post  
Posted to microsoft.public.excel.programming
external usenet poster
 
Posts: 10,593
Default Changing For...Next index

Alan,

Notwithstanding what I said earlier, I tend to agree with Jim in that I
would avoid setting an index from within an inner loop, the debugging could
get tricky! In other words, I don't like those risks :-).

Also, by saving up the deletes until the end as Jim does, you stop the
screen flashing as the screen gets re-painted when deleting.

I amended Jim's code and this worked for me

Sub abtest4()
Dim rng As Range, i As Integer, j As Integer
Dim rngToDelete As Range

Set rng = Range("DataRange").Rows
For i = rng.Rows.Count To 2 Step -1
For j = i - 1 To 1 Step -1
If RowsEqual(rng(i), rng(j)) Then
If rngToDelete Is Nothing Then
Set rngToDelete = Rows(i)
Else
Set rngToDelete = Union(rngToDelete, Rows(i))
End If
End If
Next j
Next i
If Not rngToDelete Is Nothing Then rngToDelete.Delete
End Sub

--
---
HTH

Bob

(there's no email, no snail mail, but somewhere should be gmail in my addy)



"Alan Beban" wrote in message
...
Hi Jim,

My data range contained the following:

1 2 3 4
a b c d
1 2 3 4
a b c d
5 6 7 8
1 2 3 4
a b c d
1 2 3 4
a b c d
5 6 7 8

When I run my code on it the result is

1 2 3 4
a b c d
5 6 7 8

When I first attempted to run your code, I got a compiler error, Type
mismatch, at the indicated line. I then changed your code from

Set rng = Range("DataRange") to

Set rng = Range("DataRange").Rows with this result:

1 2 3 4
a b c d


5 6 7 8

Your comment did make me rethink my code and I simplified it to

Sub abtest4()
Dim rng As Range, i As Integer, j As Integer
Set rng = Range("DataRange").Rows
For i = rng.Rows.Count To 2 Step -1
For j = i - 1 To 1 Step -1
If RowsEqual(rng(i), rng(j)) Then
rng(i).Delete
End If
Next j
Next i
End Sub

Thanks for your interest. In case you wanted to check it yourself, here is
the RowsEqual function (watch for wordwrap):

Function RowsEqual(Row1, Row2)
'This function checks to see if two "rows"
'of an array or range are equal; it returns
'True if they are, False if they are not.

k = True

'Check to see that input rows are arrays or
'multicell ranges.
If (IsArray(Row1) And IsArray(Row2)) Then

'Convert input ranges to arrays.
arr1 = Row1: arr2 = Row2

'Loop to see if all elements are the same.
For i = LBound(arr1) To UBound(arr1)
For j = LBound(arr2) To UBound(arr2, 2)
If Not (arr1(i, j) = arr2(i, j)) Then RowsEqual = False:
Exit Function
Next
Next
RowsEqual = True

'If either input row is not an array or multicell
'range, give error message
Else
RowsEqual = "This function accepts only arrays and multicell
ranges"
End If

End Function


Jim Thomlinson wrote:
Your rng.Rows.Count is going to change as you delete rows and that is not
a good idea. Not onny are you changing i but you are also changing the
range in which it is moving...

This is just my preference but when I am deleteing I always create a
range object of all of the cells that want to delete within the loop
structure and then do one big delete of all of the cells I found at the
end. It is more effiecient and it avoids problems with the range changing
while I am looking through it. Just my two cents... With your code it
would look like this...

Sub abtest4()
Dim rng As Range, i As Integer, j As Integer
dim rngToDelete as range

Set rng = Range("DataRange")
For i = rng.Rows.Count To 2 Step -1
For j = i - 1 To 1 Step -1
If RowsEqual(rng(i), rng(j)) Then '<------Type mismatch
if rngToDelete is nothing then
Set rngtoDelete = rng(i)
else
Set rngToDelete = union(rngToDelete, rng(i))
end if
End If
Next j
Next i
if not rngToDelete is nothing then rngToDelete.Delete
End Sub



Reply
Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules

Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On


Similar Threads
Thread Thread Starter Forum Replies Last Post
Index function and changing criteria help. [email protected] Excel Worksheet Functions 5 August 22nd 06 07:37 AM
Changing a cell to the same tab index color as its value CRayF Excel Programming 2 September 24th 05 12:26 AM
Multipage Control Pages - Changing Index Value in Code misseill Excel Programming 0 July 13th 05 04:32 PM
changing an palette index value programmatically in Excel brad Excel Programming 2 April 3rd 04 04:05 AM
Linking to specific cells in a changing table. How to Index? Chong Moua Excel Programming 0 August 9th 03 07:15 AM


All times are GMT +1. The time now is 07:14 PM.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Copyright ©2004-2025 ExcelBanter.
The comments are property of their posters.
 

About Us

"It's about Microsoft Excel"