Mourning the loss of our friend, WhitPhil.
There's no such thing as a stupid question, but they're the easiest to answer.
JoinTour
Login
Search
 
Business Applications
Tag Cloud
access audio black screen blue screen boot bsod connection crash dell desktop driver drivers dvd email error excel firefox hard drive hardware hijackthis internet keyboard laptop malware monitor motherboard network networking outlook problem ram recovery router safe mode screen slow sound spyware trojan upgrade vba video virus vista vundo windows windows 7 windows vista windows xp wireless
Search
Search for:
Tech Support Guy Forums > Software & Hardware > Business Applications >
Solved: Excel Macro - Not sure if it can be done

Tip: Click here to scan for System Errors and Optimize PC performance
[ Sponsored Link ]

Closed Thread
 
Thread Tools
cristobal03's Avatar
Distinguished Member with 2,994 posts.
 
Join Date: Aug 2005
Experience: Advanced
14-Nov-2005, 09:35 AM #16
Code:
Sub InsertRowsAtSets()
  Dim Rng As Range
  Dim lngCurRow As Long
  Dim lngCounter As Long

  Set Rng = Range("A1:A" & Cells(Rows.Count, "A").End(xlUp).Row)

  For lngCurRow = 1 To Rng.Rows.Count
    If Rng.Cells(lngCurRow, 1).Value = Rng.Cells(lngCurRow, 1).Offset(1, 0).Value Then
      lngCounter = 1
      Do While Rng.Cells(lngCurRow, 1).Value = Rng.Cells(lngCurRow, 1).Offset(lngCounter, 0).Value
        lngCounter = lngCounter + 1
      Loop
      lngCurRow = lngCurRow + lngCounter
      Rng.Cells(lngCurRow, 1).EntireRow.Insert Shift:=xlDown
    End If
  Next lngCurRow
End Sub
Kind of a mix of everybody's suggestions...I haven't tested, so I don't know if that'll work like I expect it to.

HTH, post back if it inserts a row only after a set of numbers, or if it doesn't work at all too, I guess...

chris.

[edit]
Just tested and it worked great for me. Produced output:

1
2
2
2
2
new row
3
4
4
4
4
new row
5
6
7
7
7
new row
8
8
8
new row
9
9

If that's more like what you wanted.
[/edit]

Last edited by cristobal03 : 14-Nov-2005 09:42 AM.
Glaswegian's Avatar
Computer Specs
Distinguished Member with 3,084 posts.
 
Join Date: Dec 2004
Location: Erm...Glasgow?
Experience: of what?
14-Nov-2005, 09:52 AM #17
Chris

Had a quick look. I may be wrong here, but the original row count will count the number of rows in the range - OK. However, once you start to insert rows from the top, the range becomes extended because of the extra rows. So the code will not insert rows after a certain point. So if you have 25 rows to start, and you insert five rows in, say the first twenty rows, the total number of rows now becomes 30. the last five rows will have moved beyond the original count and will therefore be missed. Does that make sense? I'm not here to criticise BTW - just my take on a first look at your code.

I don't have time just now to test or confirm this - I'll maybe get a chance later tonight. Or else Zack will pop in and tell me I'm talking rubbish!
__________________
Member of ASAP Member of UNITE

The length of a minute depends on which side of the bathroom door you are on.

SpywareBlaster::SpywareGuard::Spybot::Ad-Aware::HijackThis::HOSTS file::Get Firefox!
cristobal03's Avatar
Distinguished Member with 2,994 posts.
 
Join Date: Aug 2005
Experience: Advanced
14-Nov-2005, 10:17 AM #18
Is that why you did yours backwards? I couldn't figure out why you did that. It makes sense though.

Still, I didn't see that behavior...If that was the case, in the test sample I posted (#15), a new row wouldn't have been inserted after the eights because they would've fallen outside the adjusted range. I'll do some more testing.

Thanks for the spot.

chris.
cristobal03's Avatar
Distinguished Member with 2,994 posts.
 
Join Date: Aug 2005
Experience: Advanced
14-Nov-2005, 10:26 AM #19
[bump]

You are indeed correct, Glaswegian. Testing 1050 values, no new rows were inserted after row 1050. Let me modify my code a little.

chris.
cristobal03's Avatar
Distinguished Member with 2,994 posts.
 
Join Date: Aug 2005
Experience: Advanced
14-Nov-2005, 10:49 AM #20
Well, I know this isn't a great way to do it, but I'm too tired to figure out the logic to do it in reverse, so I just opened up the range entirely and added a conditional for empty cells. Running 1050 values took a couple seconds. Here's the code:

Code:
Public Sub InsertRowAtSet()

' Written for TSG user Dreambringer; inserts a blank row
' after a set of numbers in column A (skips rows that
' have distinct/unique values in column A).

  Dim Rng As Range
  Dim lngCurRow As Long
  Dim lngCounter As Long

  Application.ScreenUpdating = False

  Set Rng = Range("A1:A" & Cells(Rows.Count, "A").Row)

  For lngCurRow = 1 To Rng.Rows.Count
    If Rng.Cells(lngCurRow, 1).Value <> "" Then
      If Rng.Cells(lngCurRow, 1).Value = Rng.Cells(lngCurRow, 1).Offset(1, 0).Value Then
        lngCounter = 1
        Do While Rng.Cells(lngCurRow, 1).Value = Rng.Cells(lngCurRow, 1).Offset(lngCounter, 0).Value
          lngCounter = lngCounter + 1
        Loop
        lngCurRow = lngCurRow + lngCounter
        Rng.Cells(lngCurRow, 1).EntireRow.Insert Shift:=xlDown
      End If
    End If
  Next lngCurRow

  Application.ScreenUpdating = True

End Sub
If someone wants to figure out the logic to do it in reverse, feel free. I have a feeling it might be as simple as swapping these two lines (in the algorithm, I mean; of course code would have to be changed to decrement):

Code:
lngCurRow = lngCurRow + lngCounter
Rng.Cells(lngCurRow, 1).EntireRow.Insert Shift:=xlDown
chris.
Dreambringer's Avatar
Computer Specs
Senior Member with 1,354 posts.
 
Join Date: Jan 2005
Location: Austin, Texas
Experience: If its broken, Reformat..
14-Nov-2005, 10:54 AM #21
This is why I love this place, so many options, and I learn so much.. I am going to be running through all of these, and see which one helps the most, thanx again guys for all your suggestions...
cristobal03's Avatar
Distinguished Member with 2,994 posts.
 
Join Date: Aug 2005
Experience: Advanced
14-Nov-2005, 01:25 PM #22
Just for giggles. I got the decrement method to work. I was missing a + 1 in my code. I hate little things like that.

Code:
Public Sub InsertRowAtSet()

' Written for TSG user Dreambringer; inserts a blank row
' after a set of numbers in column A (skips rows that
' have distinct/unique values in column A).

  Dim Rng As Range
  Dim lngCurRow As Long
  Dim lngCounter As Long

  Application.ScreenUpdating = False

  Set Rng = Range("A1:A" & Cells(Rows.Count, "A").End(xlUp).Row)

  For lngCurRow = Rng.Rows.Count To 2 Step -1
    If Rng.Cells(lngCurRow, 1).Value = Rng.Cells(lngCurRow, 1).Offset(-1, 0).Value Then
      Rng.Cells(lngCurRow, 1).Offset(1, 0).EntireRow.Insert Shift:=xlDown
      lngCounter = -1
      Do While Rng.Cells(lngCurRow, 1).Value = Rng.Cells(lngCurRow, 1).Offset(lngCounter, 0).Value
        lngCounter = lngCounter - 1
      Loop
      ' I have no idea why I had to add the + 1 to get this to work.
      lngCurRow = lngCurRow + lngCounter + 1
    End If
  Next lngCurRow

  Application.ScreenUpdating = True

End Sub
As you can see, I can't quite figure out why I needed the + 1, but I tossed it in instinctively after using some Debug.Prints to list the row numbers, so I guess it had something to do with that.

Anyway, just so's you have another option.

chris.
Zack Barresse's Avatar
Computer Specs
Distinguished Member with 4,511 posts.
 
Join Date: Jul 2004
Location: Oregon, United States
Experience: I'ma learnin'!
14-Nov-2005, 01:54 PM #23
Wow, miss a day, miss everything.

So if I weren't late, I'd say, "Yup, you need to iterate through the range backwards. You do this when Inserting/Deleting/Cutting any range associated with your [parent] range." But I'm too late. LOL!

Hope I didn't come across wrong to anybody here. Glas, I've always been a fan of your work.
Glaswegian's Avatar
Computer Specs
Distinguished Member with 3,084 posts.
 
Join Date: Dec 2004
Location: Erm...Glasgow?
Experience: of what?
14-Nov-2005, 01:56 PM #24
Quote:
Originally Posted by cristobal03
Is that why you did yours backwards? I couldn't figure out why you did that. It makes sense though.

Still, I didn't see that behavior...If that was the case, in the test sample I posted (#15), a new row wouldn't have been inserted after the eights because they would've fallen outside the adjusted range. I'll do some more testing.

Thanks for the spot.

chris.
Hi Chris

Sorry I didn't get a chance to get back to you sooner. However, I see you've solved it . And you were right, working from the bottom of the range up for adding/deleting rows is always safer. I normally do the same as you did - count the rows with data to give a starting point and work from there. I don't know if my quickly garbled explanation was clear, but the same idea works for deleting rows.

Regards
__________________
Member of ASAP Member of UNITE

The length of a minute depends on which side of the bathroom door you are on.

SpywareBlaster::SpywareGuard::Spybot::Ad-Aware::HijackThis::HOSTS file::Get Firefox!
Glaswegian's Avatar
Computer Specs
Distinguished Member with 3,084 posts.
 
Join Date: Dec 2004
Location: Erm...Glasgow?
Experience: of what?
14-Nov-2005, 01:58 PM #25
Quote:
Originally Posted by firefytr
Wow, miss a day, miss everything.

So if I weren't late, I'd say, "Yup, you need to iterate through the range backwards. You do this when Inserting/Deleting/Cutting any range associated with your [parent] range." But I'm too late. LOL!

Hope I didn't come across wrong to anybody here. Glas, I've always been a fan of your work.
Zack, I was leaving this fight to you and Andy (Bomb) but Chris has beaten us all.
Dreambringer's Avatar
Computer Specs
Senior Member with 1,354 posts.
 
Join Date: Jan 2005
Location: Austin, Texas
Experience: If its broken, Reformat..
14-Nov-2005, 01:59 PM #26
Works like a champ cris!

Now for grins, would you mind breaking down the code just so I know what im looking at? if its too much trouble dont worry about it, but thats exacly what I was looking for!
cristobal03's Avatar
Distinguished Member with 2,994 posts.
 
Join Date: Aug 2005
Experience: Advanced
14-Nov-2005, 02:19 PM #27
No problems, glad I could help

I've commented the code I posted. Just to be clear, when I speak of a preceding row in my comments, I mean the row above the active row, not the row that came before. I hope that makes sense. If anyone else wants to add to my comments, please feel free. I don't have a great understanding of Excel and its objects.

Code:
Public Sub InsertRowAtSet()

' Written for TSG user Dreambringer; inserts a blank row
' after a set of numbers in column A (skips rows that
' have distinct/unique values in column A).

  ' I'll take for granted the variable declarations are
  ' pretty self-explanatory.  I use lngCurRow to keep
  ' track of the row I'm on, and lngCounter to increment
  ' (or, in this case, decrement) through sets of identical
  ' numbers.
  Dim Rng As Range
  Dim lngCurRow As Long
  Dim lngCounter As Long

  ' This isn't necessary but saves a lot of processor.
  Application.ScreenUpdating = False

  ' Based on Zack's (firefytr) forward-compatibility model; sets
  ' the working range to the used cells in column A by grabbing
  ' the whole column (A1:A65536) and moving up once, which moves
  ' to the first populated cell from the bottom of the sheet.
  Set Rng = Range("A1:A" & Cells(Rows.Count, "A").End(xlUp).Row)

  ' We set the current row lngCurRow to the last row in the range,
  ' which has the same row number as the count of all rows in the range.
  ' We're decrementing by 1 (or incrementing by -1) until row 2.  If
  ' we went to row 1, it would throw an error at row 1, because there's
  ' no row 0.
  For lngCurRow = Rng.Rows.Count To 2 Step -1
    ' If the Value of the Cell in column 1 of the current row =
    ' the Value of the Cell in column 1 of the current row offset -1
    ' (think: the cell immediately above), then we know we've hit a set of
    ' identical numbers.
    If Rng.Cells(lngCurRow, 1).Value = Rng.Cells(lngCurRow, 1).Offset(-1, 0).Value Then
      ' First, insert a row below the current row.  It has to be below
      ' the current row because the current row represents the last row
      ' of the set of identical numbers.  This is because the current row's
      ' value is equal to the value of the row above it.
      Rng.Cells(lngCurRow, 1).Offset(1, 0).EntireRow.Insert Shift:=xlDown
      lngCounter = -1
      ' lngCounter, our decrement counter, manages the offsets.  This
      ' Do While...Loop compares the current row's value to preceding rows
      ' without changing the current row.  As soon as the loop hits a
      ' preceding row that is not equal to the current row, it stops.
      ' That way, our counter lngCounter tells us how many rows are in the
      ' set of identical numbers.
      Do While Rng.Cells(lngCurRow, 1).Value = Rng.Cells(lngCurRow, 1).Offset(lngCounter, 0).Value
        lngCounter = lngCounter - 1
      Loop
      ' I have no idea why I had to add the + 1 to get this to work.
      ' And I still don't, though I imagine it has something to do with the
      ' fact that we inserted a row.  It may seem odd that we're adding
      ' lngCurRow and lngCounter since we're decrementing, but remember
      ' lngCounter is a negative number, so we're actually subtracting.
      ' The point is, we're changing the current row to the current row
      ' minus the number of rows in the set of identical numbers.
      lngCurRow = lngCurRow + lngCounter + 1
    End If
    ' If the current row's value does not match the preceding row's value,
    ' the For...Next loop iterates to the preceding row (remember, Step -1).
  Next lngCurRow

  ' Now we get to see the results.
  Application.ScreenUpdating = True
End Sub
It'd probably help to copy/paste into a code editor so the comments appear green. Anyway, glad I could help.

chris.
Dreambringer's Avatar
Computer Specs
Senior Member with 1,354 posts.
 
Join Date: Jan 2005
Location: Austin, Texas
Experience: If its broken, Reformat..
14-Nov-2005, 02:50 PM #28
Thanx, pretty easy once I see what it all means!

Is there some place that I can look at hat tells me a list of the commands/defs ie.

Rng
lngCurRow
LngCounter

I know you broke it down for me, but was looking for a list somewhere

Last edited by Dreambringer : 14-Nov-2005 02:45 PM. Reason: Another question.
cristobal03's Avatar
Distinguished Member with 2,994 posts.
 
Join Date: Aug 2005
Experience: Advanced
14-Nov-2005, 02:52 PM #29


You can mark this thread Solved using the Thread Tools at the top of the page, if you're satisfied.

chris.
Dreambringer's Avatar
Computer Specs
Senior Member with 1,354 posts.
 
Join Date: Jan 2005
Location: Austin, Texas
Experience: If its broken, Reformat..
14-Nov-2005, 03:00 PM #30
Did allready
Closed Thread Bookmark and Share

THIS THREAD HAS EXPIRED.
Are you having the same problem? We have volunteers ready to answer your question, but first you'll have to join for free. Need help getting started? Check out our Welcome Guide.

Smart Search

Find your solution!



Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
WELCOME TO TECH SUPPORT GUY! Are you looking for the solution to your computer problem? Join our site today to ask your question -- for free! Our site is run completely by volunteers who want to help you solve your computer problems. See our Welcome Guide to get started.

Thread Tools


You Are Using:
Server ID
Advertisements do not imply our endorsement of that product or service.
All times are GMT -5. The time now is 02:28 PM.
Copyright © 1996 - 2009 TechGuy, Inc. All rights reserved.
Powered by vBulletin, Copyright © 2000 - 2009, Jelsoft Enterprises Ltd.
Powered by Cermak Technologies, Inc.