0

Greeting all! I wrote a code that allows me to compare two EXCEL worksheets for same values; here it is:

Sub compare()

  Dim i As Integer
  Dim j As Integer
  Dim oldVal1 As Variant
  Dim oldVal2 As Variant
  Dim newVal1 As Variant
  Dim newVal2 As Variant
  Dim count As Integer

  Const equal = "equal"

  Dim WKB As Workbook
  Dim OldWS As Worksheet
  Dim NewWS As Worksheet
  Dim DiffWS As Worksheet

  Const OldWSName = "Sheet1"
  Const NewWSName = "Sheet2"
  Const DiffWSName = "Sheet3"

  Set WKB = ActiveWorkbook
  Set OldWS = WKB.Worksheets(OldWSName)
  Set NewWS = WKB.Worksheets(NewWSName)
  Set DiffWS = WKB.Worksheets(DiffWSName)

  Dim OldRow As Long
  Dim NewRow As Long

  Call OptimizeCode_Begin

  oldRow = OldWS.Cells(Rows.Count, 1).End(xlUp).Row
  newRow = NewWS.Cells(Rows.Count, 1).End(xlUp).Row

count = 1

For i = 2 To oldRow
    oldVal1 = OldWS.Cells(i, 1).Value
    oldVal2 = OldWS.Cells(i, 4).Value

    For j = 2 To newRow
        newVal1 = NewWS.Cells(j, 1).Value
        newVal2 = NewWS.Cells(j, 4).Value


        If (oldVal1 = newVal1) And (oldVal2 = newVal2) Then

            count = count + 1
            DiffWS.Cells(count, 1).Value = equal 
            DiffWS.Cells(count, 2).Value = oldVal1 
            DiffWS.Cells(count, 3).Value = oldVal2 
        End If
    Next j
Next i


Call OptimizeCode_End
DiffWS.Activate


'Reset variables

Set WKB = Nothing
Set OldWS = Nothing
Set NewWS = Nothing
Set DiffWS = Nothing

Application.ScreenUpdating = True
MsgBox ("Your data has been compared!")
End Sub

This code is preceded by the variables definitions, long list that I chose not to paste in here. But basically, oldVal1 is the first value compared from OldWS worksheet and oldVal2 the second one from the same worksheet. Those values are being compared with newVal1 and newVal2 from NewWS worksheet (second worksheet). Same values are copied over to DiffWS (third worksheet) with an additional column on the left for the status equal, hence DiffWS.Cells(count + 1, 2).Value = oldVal1.

I've added the following functions to optimize the code and make it run fast when it comes to comparing 2 worksheets of at east 100000 rows:

Sub OptimizeCode_Begin()
Application.Calculation = xlCalculationManual
Application.ScreenUpdating = False

EventState = Application.EnableEvents
Application.EnableEvents = False

PageBreakState = ActiveSheet.DisplayPageBreaks
ActiveSheet.DisplayPageBreaks = False

End Sub

AND

Sub OptimizeCode_End()

ActiveSheet.DisplayPageBreaks = PageBreakState
Application.EnableEvents = EventState
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
End Sub

The execution is faster on a low number of rows I must admit, but it just doesn't work when the worksheets grow bigger. My EXCEL crashes when I run my code.

Any other optimization tips I should know of? because I am at loss as to how to do this. My code would be useless if no solution is available, and I'd better know it now and think about a way other than EXCEL to compare my data.

Thanks in advance for shedding light on this.

dil
  • 1
  • 2
  • think of how long it takes to loop through every row on the second worksheet then think of how long it takes for an application.match on the same second worksheet. –  Jan 28 '18 at 09:46
  • [I'm rounding some figures here...] You have two (nested) loops where, each cycle of the outer, you are looping the inner 100,000 times, so you have 10,000,000,000 loops altogether... How long do you expect this to last? – FDavidov Jan 28 '18 at 10:14
  • Your code sample doesn't indicate how you're opening each of the workbooks. In my experience, almost any time Excel crashes, it's because of a memory issue, and often that's because instances of Excel are being opened in the background, and not `.close`'d properly or perhaps the excel objects not being set to `Nothing` (perhaps from repeated execution of the code due to errors). ***Have you tried rebooting your computer?*** – ashleedawg Jan 28 '18 at 10:14
  • I updated the code so that you can see how worksheets are accessed, and how they're reset at the end. The time it takes doesn't bother me at all, but it bothers me that evrytime I run the code on more than 100 rows the EXCEL crashes. – dil Jan 28 '18 at 10:38
  • 1
    there are a number of issues with your code. For example, you're setting `Set WK = Nothing` but there is no variable `WK` -- so the `WKS` variable is not being cleared, and is being recreated on each attempt. I found that ***easily*** by adding a line to the top of the module: **`Option Explicit`**. ***Put that at the top of every module, always, especially while learning or troubleshooting***. Also, did you *reboot* after the crashes? As others stated, your "100 rows" isn't necessarily only looking at 100 rows. How did you limit it? (Did you set `OldRow` and `NewRow` both to 100?) – ashleedawg Jan 28 '18 at 10:49
  • Thanks for your help @ashleedawg, the rows are not limited, they are very dynamic. The goal is to run the code on any worksheet. Of course, the format of both worsheets is the same, but the number of rows varies, hence: `oldRow = OldWS.Cells(Rows.Count, 1).End(xlUp).Row` AND `newRow = NewWS.Cells(Rows.Count, 1).End(xlUp).Row`. The goal is really to have a third worksheet with the delta between sheet1 and sheet2 and a status (same rows or not same rows), so that I can draw reports and graphs over it. – dil Jan 28 '18 at 11:03
  • By the way, good spot for the "WS" – dil Jan 28 '18 at 11:20
  • read the worksheet into a VBA variant array (one step: `arr = range`, then compare the two arrays. **MUCH** faster than repeated accesses of a worksheet. – Ron Rosenfeld Jan 28 '18 at 12:08
  • Use variant array. Refer [this](https://stackoverflow.com/questions/48236872/why-is-my-excel-with-vba-very-slow/48241024#48241024) – Dy.Lee Jan 28 '18 at 12:22
  • The other method is using sql base on adodb. – Dy.Lee Jan 28 '18 at 13:43
  • Thanks @Dy.Lee for following up. Happy that I brought up an interesting subject. I'll test your propositions and report back. Thanks – dil Jan 28 '18 at 14:04

1 Answers1

1

Your code sample doesn't indicate how you're opening each of the workbooks. In my experience, almost any time Excel crashes, it's because of a memory issue, and often that's because instances of Excel are being opened in the background, and then not .Close'd properly, or perhaps the excel objects not being Set to Nothing (perhaps from repeated execution of the code due to errors).

If this is the case, then Ctrl+Alt+DelTask ManagerProcesses will show multiple instances of Excel, and the easiest fix is to reboot, and then, of course, fix the handling of the Excel object in your code.


If the goal is to compare two worksheets, then perhaps a better question is why you are attempting to re-create functionality that already exists existing solutions available, most likely even built-in to your copy of Office.

Depending on your version, you may already have a utility installed.

compare

For example, if you're running Office Pro Plus 2013, you can use Microsoft Spreadsheet Compare to run a report on the differences.

compare example

More information:


I'm running Excel 2016 from an Office 365 Subscription. I've never had a need to compare spreadsheets, but out of curiosity, I just:

  1. Hit the Windows Key Windows Key

  2. Start typing: spreadsheet compare

start menu

  1. Sit back and let the professionally built analysis/merge tool do it's job.

spreadsheet compare


If all else fails, there are a number of other (3rd-Party) free and paid utilities available as well (such as xlCompare).

xlCompare

ashleedawg
  • 20,365
  • 9
  • 72
  • 105
  • Tks @ashleedawg for the proposition, I know about the features (even though I didn't entirely explore them I must admit so maybe what I am looking for is there after all) but I am really looking for a proper way to move same data over to new sheet so that I can perform tasks on the latter. Plus, the comparison is made on rows, not on cells values. If there is one value that changes from one row to another, then the entire row is considered as different, and not only the value. status must be mentioned also ( same , new or old row). So for me, vba would be better than any compartison feature. – dil Jan 28 '18 at 11:11
  • Excel's **Merge** and **Consolidate** functions may also be helpful; try Googling those. Also see [this page](https://msdn.microsoft.com/en-us/library/cc837974(v=office.12).aspx) and [this post](https://www.mrexcel.com/forum/excel-questions/557784-macro-compare-move-data-one-worksheet-another.html). Also, I can almost guarantee that your crashes are caused by memory issues which are caused by mishandling Excel objects. Did you correct the typo I pointed out, add `Option Explicit`, and **reboot**, and try your code again? – ashleedawg Jan 28 '18 at 11:36
  • 1
    @ashleedawg, instructive and helpful guidepost + – T.M. Jan 28 '18 at 12:08
  • 1
    @ashleedawg, even though it serves another cause, I still thank you for your help :-) I'll do with the elements you provided me with, and post the solution once I find it. Thank you, and hope you'll get your 3K reputation score ;-) I'd give you a "+" if I could (one of my first posts in here so maybe I can, not aware of all the rules). – dil Jan 28 '18 at 13:09
  • @dil thanks! The "+" is slang for an *up-vote*, aka: the "up-arrow" to the left of my answer. You can (and should!) up-vote any questions *and* answers that you find helpful. There are a number of way to gain rep, and a few ways to lose (including down-voting). Details about reputation at this [link](https://stackoverflow.com/help/whats-reputation). As you earn more rep, you get more privileges on this site like [this](https://stackoverflow.com/help/privileges) list. If you locate a better answer, please add it to this question, to benefit others. Oh, and ***Welcome to Stack Overflow!*** :-) – ashleedawg Jan 28 '18 at 14:29