VBA code executing very slowly












1














I'm new to VBA so the code I've written is very sloppy. My apologies.



The essence of my problem is that I need to delete duplicate rows from a worksheet with approx. 45,000 rows. Each iteration where the row is deleted takes approximately 30 seconds to complete, and I need to do this for thousands of rows. Any suggestions for how to improve my code so that this all goes faster?



Sub delete_duplicate_rows()
For i = 1 To 85000
If ActiveCell <> ActiveCell.Offset(1, 0) Or ActiveCell.Offset(0, -1) <> ActiveCell.Offset(1, -1) Or ActiveCell.Offset(0, 1) <> ActiveCell.Offset(1, 1) Or ActiveCell.Offset(0, 2) <> ActiveCell.Offset(1, 2) Or ActiveCell.Offset(0, 3) <> ActiveCell.Offset(1, 3) Or ActiveCell.Offset(0, 4) <> ActiveCell.Offset(1, 4) Or ActiveCell.Offset(0, 5) <> ActiveCell.Offset(1, 5) Or ActiveCell.Offset(0, 6) <> ActiveCell.Offset(1, 6) Or ActiveCell.Offset(0, 7) <> ActiveCell.Offset(1, 7) Or ActiveCell.Offset(0, 8) <> ActiveCell.Offset(1, 8) Or ActiveCell.Offset(0, 9) <> ActiveCell.Offset(1, 9) Or ActiveCell.Offset(0, 10) <> ActiveCell.Offset(1, 10) Or ActiveCell.Offset(0, 11) <> ActiveCell.Offset(1, 11) Or ActiveCell.Offset(0, 12) <> ActiveCell.Offset(1, 12) Or ActiveCell.Offset(0, 13) <> ActiveCell.Offset(1, 13) Then
ActiveCell.Offset(1, 0).Select
GoTo NextIteration
Else
End If
If ActiveCell.Value = "" Then Exit Sub
ActiveCell.Offset(0, -1).Range("A1:Q1").Select
Selection.Delete Shift:=xlUp
ActiveCell.Offset(0, 1).Range("A1").Select
NextIteration:
Next i
End Sub


Many thanks.










share|improve this question


















  • 4




    Avoid using .Select/.Activate
    – BruceWayne
    Dec 17 '18 at 15:24






  • 2




    Curious why the "Remove Duplicates" built-in tool under the [Data] Ribbon tab can't be used for this?
    – Mathieu Guindon
    Dec 17 '18 at 15:35






  • 1




    @Comintern the answer below is still making way too many worksheet reads (and hints at nesting yet another loop, which wouln't improve performance). I'd work out the last row, dump the appropriate columns into a 2D array, iterate that array, and Union the rows that need to be deleted - then delete all union'd rows in a single .Delete operation. I guess MT could be useful if there are millions of rows to go through, but then the MT overhead might just outweight its benefits.. not to mention out-of-process overhead for whatever non-VBA scripting tech is used for this.
    – Mathieu Guindon
    Dec 17 '18 at 16:29










  • Also see if that rather impressive matching criteria can be worked into a Range.RemoveDuplicates call. If so, then you get Excel to do all the hard work.
    – Mathieu Guindon
    Dec 17 '18 at 16:36










  • A sample of data would be helpful. It appears you are satisfied with only looking a few rows ahead or behind for duplicates? There are many ways to speed this up but by necessity are more complex.
    – Appleoddity
    Dec 17 '18 at 20:15
















1














I'm new to VBA so the code I've written is very sloppy. My apologies.



The essence of my problem is that I need to delete duplicate rows from a worksheet with approx. 45,000 rows. Each iteration where the row is deleted takes approximately 30 seconds to complete, and I need to do this for thousands of rows. Any suggestions for how to improve my code so that this all goes faster?



Sub delete_duplicate_rows()
For i = 1 To 85000
If ActiveCell <> ActiveCell.Offset(1, 0) Or ActiveCell.Offset(0, -1) <> ActiveCell.Offset(1, -1) Or ActiveCell.Offset(0, 1) <> ActiveCell.Offset(1, 1) Or ActiveCell.Offset(0, 2) <> ActiveCell.Offset(1, 2) Or ActiveCell.Offset(0, 3) <> ActiveCell.Offset(1, 3) Or ActiveCell.Offset(0, 4) <> ActiveCell.Offset(1, 4) Or ActiveCell.Offset(0, 5) <> ActiveCell.Offset(1, 5) Or ActiveCell.Offset(0, 6) <> ActiveCell.Offset(1, 6) Or ActiveCell.Offset(0, 7) <> ActiveCell.Offset(1, 7) Or ActiveCell.Offset(0, 8) <> ActiveCell.Offset(1, 8) Or ActiveCell.Offset(0, 9) <> ActiveCell.Offset(1, 9) Or ActiveCell.Offset(0, 10) <> ActiveCell.Offset(1, 10) Or ActiveCell.Offset(0, 11) <> ActiveCell.Offset(1, 11) Or ActiveCell.Offset(0, 12) <> ActiveCell.Offset(1, 12) Or ActiveCell.Offset(0, 13) <> ActiveCell.Offset(1, 13) Then
ActiveCell.Offset(1, 0).Select
GoTo NextIteration
Else
End If
If ActiveCell.Value = "" Then Exit Sub
ActiveCell.Offset(0, -1).Range("A1:Q1").Select
Selection.Delete Shift:=xlUp
ActiveCell.Offset(0, 1).Range("A1").Select
NextIteration:
Next i
End Sub


Many thanks.










share|improve this question


















  • 4




    Avoid using .Select/.Activate
    – BruceWayne
    Dec 17 '18 at 15:24






  • 2




    Curious why the "Remove Duplicates" built-in tool under the [Data] Ribbon tab can't be used for this?
    – Mathieu Guindon
    Dec 17 '18 at 15:35






  • 1




    @Comintern the answer below is still making way too many worksheet reads (and hints at nesting yet another loop, which wouln't improve performance). I'd work out the last row, dump the appropriate columns into a 2D array, iterate that array, and Union the rows that need to be deleted - then delete all union'd rows in a single .Delete operation. I guess MT could be useful if there are millions of rows to go through, but then the MT overhead might just outweight its benefits.. not to mention out-of-process overhead for whatever non-VBA scripting tech is used for this.
    – Mathieu Guindon
    Dec 17 '18 at 16:29










  • Also see if that rather impressive matching criteria can be worked into a Range.RemoveDuplicates call. If so, then you get Excel to do all the hard work.
    – Mathieu Guindon
    Dec 17 '18 at 16:36










  • A sample of data would be helpful. It appears you are satisfied with only looking a few rows ahead or behind for duplicates? There are many ways to speed this up but by necessity are more complex.
    – Appleoddity
    Dec 17 '18 at 20:15














1












1








1


1





I'm new to VBA so the code I've written is very sloppy. My apologies.



The essence of my problem is that I need to delete duplicate rows from a worksheet with approx. 45,000 rows. Each iteration where the row is deleted takes approximately 30 seconds to complete, and I need to do this for thousands of rows. Any suggestions for how to improve my code so that this all goes faster?



Sub delete_duplicate_rows()
For i = 1 To 85000
If ActiveCell <> ActiveCell.Offset(1, 0) Or ActiveCell.Offset(0, -1) <> ActiveCell.Offset(1, -1) Or ActiveCell.Offset(0, 1) <> ActiveCell.Offset(1, 1) Or ActiveCell.Offset(0, 2) <> ActiveCell.Offset(1, 2) Or ActiveCell.Offset(0, 3) <> ActiveCell.Offset(1, 3) Or ActiveCell.Offset(0, 4) <> ActiveCell.Offset(1, 4) Or ActiveCell.Offset(0, 5) <> ActiveCell.Offset(1, 5) Or ActiveCell.Offset(0, 6) <> ActiveCell.Offset(1, 6) Or ActiveCell.Offset(0, 7) <> ActiveCell.Offset(1, 7) Or ActiveCell.Offset(0, 8) <> ActiveCell.Offset(1, 8) Or ActiveCell.Offset(0, 9) <> ActiveCell.Offset(1, 9) Or ActiveCell.Offset(0, 10) <> ActiveCell.Offset(1, 10) Or ActiveCell.Offset(0, 11) <> ActiveCell.Offset(1, 11) Or ActiveCell.Offset(0, 12) <> ActiveCell.Offset(1, 12) Or ActiveCell.Offset(0, 13) <> ActiveCell.Offset(1, 13) Then
ActiveCell.Offset(1, 0).Select
GoTo NextIteration
Else
End If
If ActiveCell.Value = "" Then Exit Sub
ActiveCell.Offset(0, -1).Range("A1:Q1").Select
Selection.Delete Shift:=xlUp
ActiveCell.Offset(0, 1).Range("A1").Select
NextIteration:
Next i
End Sub


Many thanks.










share|improve this question













I'm new to VBA so the code I've written is very sloppy. My apologies.



The essence of my problem is that I need to delete duplicate rows from a worksheet with approx. 45,000 rows. Each iteration where the row is deleted takes approximately 30 seconds to complete, and I need to do this for thousands of rows. Any suggestions for how to improve my code so that this all goes faster?



Sub delete_duplicate_rows()
For i = 1 To 85000
If ActiveCell <> ActiveCell.Offset(1, 0) Or ActiveCell.Offset(0, -1) <> ActiveCell.Offset(1, -1) Or ActiveCell.Offset(0, 1) <> ActiveCell.Offset(1, 1) Or ActiveCell.Offset(0, 2) <> ActiveCell.Offset(1, 2) Or ActiveCell.Offset(0, 3) <> ActiveCell.Offset(1, 3) Or ActiveCell.Offset(0, 4) <> ActiveCell.Offset(1, 4) Or ActiveCell.Offset(0, 5) <> ActiveCell.Offset(1, 5) Or ActiveCell.Offset(0, 6) <> ActiveCell.Offset(1, 6) Or ActiveCell.Offset(0, 7) <> ActiveCell.Offset(1, 7) Or ActiveCell.Offset(0, 8) <> ActiveCell.Offset(1, 8) Or ActiveCell.Offset(0, 9) <> ActiveCell.Offset(1, 9) Or ActiveCell.Offset(0, 10) <> ActiveCell.Offset(1, 10) Or ActiveCell.Offset(0, 11) <> ActiveCell.Offset(1, 11) Or ActiveCell.Offset(0, 12) <> ActiveCell.Offset(1, 12) Or ActiveCell.Offset(0, 13) <> ActiveCell.Offset(1, 13) Then
ActiveCell.Offset(1, 0).Select
GoTo NextIteration
Else
End If
If ActiveCell.Value = "" Then Exit Sub
ActiveCell.Offset(0, -1).Range("A1:Q1").Select
Selection.Delete Shift:=xlUp
ActiveCell.Offset(0, 1).Range("A1").Select
NextIteration:
Next i
End Sub


Many thanks.







microsoft-excel vba microsoft-excel-2016






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Dec 17 '18 at 15:19









plshelpmewithexcel

132




132








  • 4




    Avoid using .Select/.Activate
    – BruceWayne
    Dec 17 '18 at 15:24






  • 2




    Curious why the "Remove Duplicates" built-in tool under the [Data] Ribbon tab can't be used for this?
    – Mathieu Guindon
    Dec 17 '18 at 15:35






  • 1




    @Comintern the answer below is still making way too many worksheet reads (and hints at nesting yet another loop, which wouln't improve performance). I'd work out the last row, dump the appropriate columns into a 2D array, iterate that array, and Union the rows that need to be deleted - then delete all union'd rows in a single .Delete operation. I guess MT could be useful if there are millions of rows to go through, but then the MT overhead might just outweight its benefits.. not to mention out-of-process overhead for whatever non-VBA scripting tech is used for this.
    – Mathieu Guindon
    Dec 17 '18 at 16:29










  • Also see if that rather impressive matching criteria can be worked into a Range.RemoveDuplicates call. If so, then you get Excel to do all the hard work.
    – Mathieu Guindon
    Dec 17 '18 at 16:36










  • A sample of data would be helpful. It appears you are satisfied with only looking a few rows ahead or behind for duplicates? There are many ways to speed this up but by necessity are more complex.
    – Appleoddity
    Dec 17 '18 at 20:15














  • 4




    Avoid using .Select/.Activate
    – BruceWayne
    Dec 17 '18 at 15:24






  • 2




    Curious why the "Remove Duplicates" built-in tool under the [Data] Ribbon tab can't be used for this?
    – Mathieu Guindon
    Dec 17 '18 at 15:35






  • 1




    @Comintern the answer below is still making way too many worksheet reads (and hints at nesting yet another loop, which wouln't improve performance). I'd work out the last row, dump the appropriate columns into a 2D array, iterate that array, and Union the rows that need to be deleted - then delete all union'd rows in a single .Delete operation. I guess MT could be useful if there are millions of rows to go through, but then the MT overhead might just outweight its benefits.. not to mention out-of-process overhead for whatever non-VBA scripting tech is used for this.
    – Mathieu Guindon
    Dec 17 '18 at 16:29










  • Also see if that rather impressive matching criteria can be worked into a Range.RemoveDuplicates call. If so, then you get Excel to do all the hard work.
    – Mathieu Guindon
    Dec 17 '18 at 16:36










  • A sample of data would be helpful. It appears you are satisfied with only looking a few rows ahead or behind for duplicates? There are many ways to speed this up but by necessity are more complex.
    – Appleoddity
    Dec 17 '18 at 20:15








4




4




Avoid using .Select/.Activate
– BruceWayne
Dec 17 '18 at 15:24




Avoid using .Select/.Activate
– BruceWayne
Dec 17 '18 at 15:24




2




2




Curious why the "Remove Duplicates" built-in tool under the [Data] Ribbon tab can't be used for this?
– Mathieu Guindon
Dec 17 '18 at 15:35




Curious why the "Remove Duplicates" built-in tool under the [Data] Ribbon tab can't be used for this?
– Mathieu Guindon
Dec 17 '18 at 15:35




1




1




@Comintern the answer below is still making way too many worksheet reads (and hints at nesting yet another loop, which wouln't improve performance). I'd work out the last row, dump the appropriate columns into a 2D array, iterate that array, and Union the rows that need to be deleted - then delete all union'd rows in a single .Delete operation. I guess MT could be useful if there are millions of rows to go through, but then the MT overhead might just outweight its benefits.. not to mention out-of-process overhead for whatever non-VBA scripting tech is used for this.
– Mathieu Guindon
Dec 17 '18 at 16:29




@Comintern the answer below is still making way too many worksheet reads (and hints at nesting yet another loop, which wouln't improve performance). I'd work out the last row, dump the appropriate columns into a 2D array, iterate that array, and Union the rows that need to be deleted - then delete all union'd rows in a single .Delete operation. I guess MT could be useful if there are millions of rows to go through, but then the MT overhead might just outweight its benefits.. not to mention out-of-process overhead for whatever non-VBA scripting tech is used for this.
– Mathieu Guindon
Dec 17 '18 at 16:29












Also see if that rather impressive matching criteria can be worked into a Range.RemoveDuplicates call. If so, then you get Excel to do all the hard work.
– Mathieu Guindon
Dec 17 '18 at 16:36




Also see if that rather impressive matching criteria can be worked into a Range.RemoveDuplicates call. If so, then you get Excel to do all the hard work.
– Mathieu Guindon
Dec 17 '18 at 16:36












A sample of data would be helpful. It appears you are satisfied with only looking a few rows ahead or behind for duplicates? There are many ways to speed this up but by necessity are more complex.
– Appleoddity
Dec 17 '18 at 20:15




A sample of data would be helpful. It appears you are satisfied with only looking a few rows ahead or behind for duplicates? There are many ways to speed this up but by necessity are more complex.
– Appleoddity
Dec 17 '18 at 20:15










1 Answer
1






active

oldest

votes


















0














As others said, your code is slow do to a couple of things like using select, activate and goto



I believe the culprit of the slow performance is the multiple condition check at once, as you could check for changes on cells.



sub delete_duplicate_rows(byref ws as worksheet)

' Dim tbl_width as long, tbl_height as long
' Dim row_n, col_n as long
'
' This would be the correct form of one line var declarations, as it was stated in the comments
' I prefer this style, so I can group things like iters, table sizes, variants for `For each`
' and save some lines and see more code(I've a small screen)

dim tbl_width as long
dim tbl_height as long
dim row_n as long
dim col_n as long
with ws
for row_n=tbl_height to 2 step -1
for col_n=1 to tbl_width
if .range(.cells(row_n, col_n)) <> .range(.cells(row_n - 1, col_n)) then
.range(.cells(row_n , 1), .cells(row_n, tbl_width)).delete shift:=xlShiftUp
col_n = tbl_width
next col_n
next row_n
end with

end sub


This doesn't deppends on a fixed set of rows, don't activate or select anything, and the inner loop could be exited before when one of the conditions is not met. This way you will only check enough to make a decision on wheter to delete.



You could nest another loop, so it will check al the rows not just the one below to it.






share|improve this answer



















  • 1




    note that dim tbl_width, tbl_height as long is declaring tbl_height as a long integer, and tbl_weight remains an implicit Variant. Ditto with row_n. ws has no reason to be passed ByRef, too. Lastly, this is still accessing the sheet directly in a tight, nested loop - that'll be faster than OP, but not half as efficient as it could be.
    – Mathieu Guindon
    Dec 17 '18 at 15:53












  • @MathieuGuindon is this true? Never had a problem with this style of declaration while using option explicit you just poked my curiossity and I'm gonna check on that.
    – dmb
    Dec 17 '18 at 15:55










  • Yup. We even built an inspection for it in Rubberduck =)
    – Mathieu Guindon
    Dec 17 '18 at 15:58










  • @Comintern Given, forgot about this.
    – dmb
    Dec 17 '18 at 15:58












  • @MathieuGuindon You were right! I've been coding this whole time ignoring this implicit DIM thing I think I've been trapped in the c mentality. Thanks man, I love when stuff like this happens It makes improve your basics.
    – dmb
    Dec 21 '18 at 12:10











Your Answer








StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "3"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fsuperuser.com%2fquestions%2f1385274%2fvba-code-executing-very-slowly%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









0














As others said, your code is slow do to a couple of things like using select, activate and goto



I believe the culprit of the slow performance is the multiple condition check at once, as you could check for changes on cells.



sub delete_duplicate_rows(byref ws as worksheet)

' Dim tbl_width as long, tbl_height as long
' Dim row_n, col_n as long
'
' This would be the correct form of one line var declarations, as it was stated in the comments
' I prefer this style, so I can group things like iters, table sizes, variants for `For each`
' and save some lines and see more code(I've a small screen)

dim tbl_width as long
dim tbl_height as long
dim row_n as long
dim col_n as long
with ws
for row_n=tbl_height to 2 step -1
for col_n=1 to tbl_width
if .range(.cells(row_n, col_n)) <> .range(.cells(row_n - 1, col_n)) then
.range(.cells(row_n , 1), .cells(row_n, tbl_width)).delete shift:=xlShiftUp
col_n = tbl_width
next col_n
next row_n
end with

end sub


This doesn't deppends on a fixed set of rows, don't activate or select anything, and the inner loop could be exited before when one of the conditions is not met. This way you will only check enough to make a decision on wheter to delete.



You could nest another loop, so it will check al the rows not just the one below to it.






share|improve this answer



















  • 1




    note that dim tbl_width, tbl_height as long is declaring tbl_height as a long integer, and tbl_weight remains an implicit Variant. Ditto with row_n. ws has no reason to be passed ByRef, too. Lastly, this is still accessing the sheet directly in a tight, nested loop - that'll be faster than OP, but not half as efficient as it could be.
    – Mathieu Guindon
    Dec 17 '18 at 15:53












  • @MathieuGuindon is this true? Never had a problem with this style of declaration while using option explicit you just poked my curiossity and I'm gonna check on that.
    – dmb
    Dec 17 '18 at 15:55










  • Yup. We even built an inspection for it in Rubberduck =)
    – Mathieu Guindon
    Dec 17 '18 at 15:58










  • @Comintern Given, forgot about this.
    – dmb
    Dec 17 '18 at 15:58












  • @MathieuGuindon You were right! I've been coding this whole time ignoring this implicit DIM thing I think I've been trapped in the c mentality. Thanks man, I love when stuff like this happens It makes improve your basics.
    – dmb
    Dec 21 '18 at 12:10
















0














As others said, your code is slow do to a couple of things like using select, activate and goto



I believe the culprit of the slow performance is the multiple condition check at once, as you could check for changes on cells.



sub delete_duplicate_rows(byref ws as worksheet)

' Dim tbl_width as long, tbl_height as long
' Dim row_n, col_n as long
'
' This would be the correct form of one line var declarations, as it was stated in the comments
' I prefer this style, so I can group things like iters, table sizes, variants for `For each`
' and save some lines and see more code(I've a small screen)

dim tbl_width as long
dim tbl_height as long
dim row_n as long
dim col_n as long
with ws
for row_n=tbl_height to 2 step -1
for col_n=1 to tbl_width
if .range(.cells(row_n, col_n)) <> .range(.cells(row_n - 1, col_n)) then
.range(.cells(row_n , 1), .cells(row_n, tbl_width)).delete shift:=xlShiftUp
col_n = tbl_width
next col_n
next row_n
end with

end sub


This doesn't deppends on a fixed set of rows, don't activate or select anything, and the inner loop could be exited before when one of the conditions is not met. This way you will only check enough to make a decision on wheter to delete.



You could nest another loop, so it will check al the rows not just the one below to it.






share|improve this answer



















  • 1




    note that dim tbl_width, tbl_height as long is declaring tbl_height as a long integer, and tbl_weight remains an implicit Variant. Ditto with row_n. ws has no reason to be passed ByRef, too. Lastly, this is still accessing the sheet directly in a tight, nested loop - that'll be faster than OP, but not half as efficient as it could be.
    – Mathieu Guindon
    Dec 17 '18 at 15:53












  • @MathieuGuindon is this true? Never had a problem with this style of declaration while using option explicit you just poked my curiossity and I'm gonna check on that.
    – dmb
    Dec 17 '18 at 15:55










  • Yup. We even built an inspection for it in Rubberduck =)
    – Mathieu Guindon
    Dec 17 '18 at 15:58










  • @Comintern Given, forgot about this.
    – dmb
    Dec 17 '18 at 15:58












  • @MathieuGuindon You were right! I've been coding this whole time ignoring this implicit DIM thing I think I've been trapped in the c mentality. Thanks man, I love when stuff like this happens It makes improve your basics.
    – dmb
    Dec 21 '18 at 12:10














0












0








0






As others said, your code is slow do to a couple of things like using select, activate and goto



I believe the culprit of the slow performance is the multiple condition check at once, as you could check for changes on cells.



sub delete_duplicate_rows(byref ws as worksheet)

' Dim tbl_width as long, tbl_height as long
' Dim row_n, col_n as long
'
' This would be the correct form of one line var declarations, as it was stated in the comments
' I prefer this style, so I can group things like iters, table sizes, variants for `For each`
' and save some lines and see more code(I've a small screen)

dim tbl_width as long
dim tbl_height as long
dim row_n as long
dim col_n as long
with ws
for row_n=tbl_height to 2 step -1
for col_n=1 to tbl_width
if .range(.cells(row_n, col_n)) <> .range(.cells(row_n - 1, col_n)) then
.range(.cells(row_n , 1), .cells(row_n, tbl_width)).delete shift:=xlShiftUp
col_n = tbl_width
next col_n
next row_n
end with

end sub


This doesn't deppends on a fixed set of rows, don't activate or select anything, and the inner loop could be exited before when one of the conditions is not met. This way you will only check enough to make a decision on wheter to delete.



You could nest another loop, so it will check al the rows not just the one below to it.






share|improve this answer














As others said, your code is slow do to a couple of things like using select, activate and goto



I believe the culprit of the slow performance is the multiple condition check at once, as you could check for changes on cells.



sub delete_duplicate_rows(byref ws as worksheet)

' Dim tbl_width as long, tbl_height as long
' Dim row_n, col_n as long
'
' This would be the correct form of one line var declarations, as it was stated in the comments
' I prefer this style, so I can group things like iters, table sizes, variants for `For each`
' and save some lines and see more code(I've a small screen)

dim tbl_width as long
dim tbl_height as long
dim row_n as long
dim col_n as long
with ws
for row_n=tbl_height to 2 step -1
for col_n=1 to tbl_width
if .range(.cells(row_n, col_n)) <> .range(.cells(row_n - 1, col_n)) then
.range(.cells(row_n , 1), .cells(row_n, tbl_width)).delete shift:=xlShiftUp
col_n = tbl_width
next col_n
next row_n
end with

end sub


This doesn't deppends on a fixed set of rows, don't activate or select anything, and the inner loop could be exited before when one of the conditions is not met. This way you will only check enough to make a decision on wheter to delete.



You could nest another loop, so it will check al the rows not just the one below to it.







share|improve this answer














share|improve this answer



share|improve this answer








edited Dec 21 '18 at 13:26

























answered Dec 17 '18 at 15:51









dmb

654212




654212








  • 1




    note that dim tbl_width, tbl_height as long is declaring tbl_height as a long integer, and tbl_weight remains an implicit Variant. Ditto with row_n. ws has no reason to be passed ByRef, too. Lastly, this is still accessing the sheet directly in a tight, nested loop - that'll be faster than OP, but not half as efficient as it could be.
    – Mathieu Guindon
    Dec 17 '18 at 15:53












  • @MathieuGuindon is this true? Never had a problem with this style of declaration while using option explicit you just poked my curiossity and I'm gonna check on that.
    – dmb
    Dec 17 '18 at 15:55










  • Yup. We even built an inspection for it in Rubberduck =)
    – Mathieu Guindon
    Dec 17 '18 at 15:58










  • @Comintern Given, forgot about this.
    – dmb
    Dec 17 '18 at 15:58












  • @MathieuGuindon You were right! I've been coding this whole time ignoring this implicit DIM thing I think I've been trapped in the c mentality. Thanks man, I love when stuff like this happens It makes improve your basics.
    – dmb
    Dec 21 '18 at 12:10














  • 1




    note that dim tbl_width, tbl_height as long is declaring tbl_height as a long integer, and tbl_weight remains an implicit Variant. Ditto with row_n. ws has no reason to be passed ByRef, too. Lastly, this is still accessing the sheet directly in a tight, nested loop - that'll be faster than OP, but not half as efficient as it could be.
    – Mathieu Guindon
    Dec 17 '18 at 15:53












  • @MathieuGuindon is this true? Never had a problem with this style of declaration while using option explicit you just poked my curiossity and I'm gonna check on that.
    – dmb
    Dec 17 '18 at 15:55










  • Yup. We even built an inspection for it in Rubberduck =)
    – Mathieu Guindon
    Dec 17 '18 at 15:58










  • @Comintern Given, forgot about this.
    – dmb
    Dec 17 '18 at 15:58












  • @MathieuGuindon You were right! I've been coding this whole time ignoring this implicit DIM thing I think I've been trapped in the c mentality. Thanks man, I love when stuff like this happens It makes improve your basics.
    – dmb
    Dec 21 '18 at 12:10








1




1




note that dim tbl_width, tbl_height as long is declaring tbl_height as a long integer, and tbl_weight remains an implicit Variant. Ditto with row_n. ws has no reason to be passed ByRef, too. Lastly, this is still accessing the sheet directly in a tight, nested loop - that'll be faster than OP, but not half as efficient as it could be.
– Mathieu Guindon
Dec 17 '18 at 15:53






note that dim tbl_width, tbl_height as long is declaring tbl_height as a long integer, and tbl_weight remains an implicit Variant. Ditto with row_n. ws has no reason to be passed ByRef, too. Lastly, this is still accessing the sheet directly in a tight, nested loop - that'll be faster than OP, but not half as efficient as it could be.
– Mathieu Guindon
Dec 17 '18 at 15:53














@MathieuGuindon is this true? Never had a problem with this style of declaration while using option explicit you just poked my curiossity and I'm gonna check on that.
– dmb
Dec 17 '18 at 15:55




@MathieuGuindon is this true? Never had a problem with this style of declaration while using option explicit you just poked my curiossity and I'm gonna check on that.
– dmb
Dec 17 '18 at 15:55












Yup. We even built an inspection for it in Rubberduck =)
– Mathieu Guindon
Dec 17 '18 at 15:58




Yup. We even built an inspection for it in Rubberduck =)
– Mathieu Guindon
Dec 17 '18 at 15:58












@Comintern Given, forgot about this.
– dmb
Dec 17 '18 at 15:58






@Comintern Given, forgot about this.
– dmb
Dec 17 '18 at 15:58














@MathieuGuindon You were right! I've been coding this whole time ignoring this implicit DIM thing I think I've been trapped in the c mentality. Thanks man, I love when stuff like this happens It makes improve your basics.
– dmb
Dec 21 '18 at 12:10




@MathieuGuindon You were right! I've been coding this whole time ignoring this implicit DIM thing I think I've been trapped in the c mentality. Thanks man, I love when stuff like this happens It makes improve your basics.
– dmb
Dec 21 '18 at 12:10


















draft saved

draft discarded




















































Thanks for contributing an answer to Super User!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.





Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


Please pay close attention to the following guidance:


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fsuperuser.com%2fquestions%2f1385274%2fvba-code-executing-very-slowly%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

flock() on closed filehandle LOCK_FILE at /usr/bin/apt-mirror

Mangá

 ⁒  ․,‪⁊‑⁙ ⁖, ⁇‒※‌, †,⁖‗‌⁝    ‾‸⁘,‖⁔⁣,⁂‾
”‑,‥–,‬ ,⁀‹⁋‴⁑ ‒ ,‴⁋”‼ ⁨,‷⁔„ ‰′,‐‚ ‥‡‎“‷⁃⁨⁅⁣,⁔
⁇‘⁔⁡⁏⁌⁡‿‶‏⁨ ⁣⁕⁖⁨⁩⁥‽⁀  ‴‬⁜‟ ⁃‣‧⁕‮ …‍⁨‴ ⁩,⁚⁖‫ ,‵ ⁀,‮⁝‣‣ ⁑  ⁂– ․, ‾‽ ‏⁁“⁗‸ ‾… ‹‡⁌⁎‸‘ ‡⁏⁌‪ ‵⁛ ‎⁨ ―⁦⁤⁄⁕