Without Option Explicit, the msoGraphic identifier in that property scope is a Variant/Empty; there's an implicit type conversion happening when you do this:
If msoGraphic = 0 Then
Sure vbEmpty will equate to 0, or even vbNullString or "", but that's after converting to a comparable type (Integer, or String). There's a better way.
If IsEmpty(msoGraphic) ...
This answer assumes that all Names in the data are unique. There is no
provision in this example to handle duplicate Names except to issue a
note in the debug output.
This answer will involve Dictionaries. Please review this website for complete information on how and why they are an efficient way to store unique data. The short answer is that you can ...
You are doing twice the work by having a function to get the starting row and a second function get the last row. Passing the starting row into the GetLastRow() function would be more efficient.
I prefer to have a single function return the range object. Using the WorkshetFunction.Match() is far more efficient then iterating over the cells.
QuickSortArrAscDesc does not work if there are repeat values. Although there are clear improvements over the original, a couple of changes are causing the partitions from combing properly.
varPivot = arrySource(Int((lngMin + lngMax) / 2), lngSortCol)
varMid = SortArray((lngMin + lngMax) \ 2, lngColumn)
75K Non-Contiguous Areas, No Problem
My FastUnion class was able to crack the 75K non-contiguous areas goal by expanding on Ahmed AU answer using Union() with multiple parameters. Although, this class excels at smaller numbers of areas, my UnionCollection class far out performs it by working with smaller groups of cells at a time.