'Explanations Here : Post # 10 http://www.mrexcel.com/forum/excel-questions/832103-using-microsoft-scripting-runtime-dictionary-store-then-retrieve-range-objects.html?&&
Sub ScriptingRuntimeDictionaryToStoreRangesAndReOrderItemsKyle2G() ' http://www.mrexcel.com/forum/excel-questions/832103-using-microsoft-scripting-runtime-dictionary-store-then-retrieve-range-objects.html?#post4062236
On Error GoTo TheEnd '**I added this after problems in particular with the Big German Lists to try and be sure that things were turned off
Dim wksLkUp As Worksheet: Set wksLkUp = ThisWorkbook.Worksheets("LeftSpeedsDeutsch") 'Give Abbreviation the Under objects, Methods and Properties of Object Worksheets (Intellisense then gives suggestions through use of . Dot
wksLkUp.Activate: wksLkUp.Cells(1).Select 'See and select first cell in the sheet for reorganising item order. This line was mostly not always necessary, but occasionally was needed, at least the first time around. (Convention for one cell() argument is L to R first row, then next row down etc.. This one argument convention is not taken as (1 , 1))
Dim rcell As Range: Set rcell = wksLkUp.Range("E21") 'Any cell in required Range. Note the perimeter of this range should be free, that is to say cells touching this range should be empty###, or the CurrentRegion will catch it. Note also a s useful mod here for empty cells: Post #12 #13 http://www.mrexcel.com/forum/excel-questions/213591-pipe-delimited-files-2.html
'##### Change Sheet Reference and reference Cell above to suit your Range
'1a) Part 1a. The initial "Creating" One Range Object to include all cells of interest mainly to get grid size info
Dim ObjectCapturedRange As Range 'This will be set to One Range Object. Only a Range object is seen so item types can be defined as Range Objects
Set ObjectCapturedRange = rcell.CurrentRegion 'Typical way to capture the Range in one go. Captured Range will be a grid which Inlcudes any cells "connected" to rcell. SO IMPORTANT: Keep periphery of required range free###. Alternative UsedRange would make a grid catching / Capturing any cell EVER used. Note also
Dim OutputTableRow As Long, OutputTableColumn As Long 'Bound Loop Count Variables for Output Table.. ...... http://www.mrexcel.com/forum/excel-questions/803662-byte-backward-loop-4.html
Dim StartRowTableOutput As Long: Let StartRowTableOutput = rcell.Row 'We wish to loop below through items in the Range Capture. For conveniebce use the Row and Column property of our user given
Dim StartColumnTableOutput As Long: Let StartColumnTableOutput = rcell.Column 'Reference cell to obtain Start Rows and start Columns.
Dim LastRowTableOutput As Long: Let LastRowTableOutput = StartRowTableOutput + ObjectCapturedRange.Rows.Count - 1 'Simaly the last cell in looping can for convenience be obtained once we have the grid size (Row..
Dim LastColumnTableOutput As Long: Let LastColumnTableOutput = StartColumnTableOutput + ObjectCapturedRange.Columns.Count - 1 '...and column Couct) obtained from those Properties of a single "Capture" Range Object
'End part 1a. Info obtained for Spreadsheet range sizes--------------------------------------------------------
' 1b) 'Part 1b: Setting up Scriptimg Runtime Stuff-----------------------------
' Attempting Using the Microsooft Scripting Runtime Dictionary to store Range Objects
'We put the unique values now into a Dictionary for later look up purposes:
'--requires library reference to MS Scripting Runtime (Early Binding)-
' Tools>>References>>scrolldown and check the box next to Microsoft Scripting Runtime
' ..Or crashes at next line.....
Dim dicLookupTable As Scripting.Dictionary 'Data held with a unique "Key"or Part Number.
Set dicLookupTable = New Scripting.Dictionary
' The next two lines are an alternative called Late binding. (But note some Dictionary methods and properties( Such as at the end ####) will not work with it - in those cases Early Binging must be used.
' Dim dicLookupTable As Object
' Set dicLookupTable = CreateObject("Scripting.Dictionary")
' Late Binding is better when sharing files as I am here. Early Binding has the advantage that Excel intellisense
' will then work for the Microsoft Scripüting Runtime stuff and give you suggestions after you type the .dot thing
dicLookupTable.CompareMode = vbTextCompare 'Not quite sure wot this does yet
'. A Dictionary in VBA is a collection of objects :you can store all kinds of things in it.
'. Every item in a Dictionary gets its own unique key, a very important characteristic. A Dictionary can only contain unique keys. That's why you can use the property .keys to create a list of unique strings, numbers or dates.
'. (Although the Dictionary has not been designed for that purpose it's a nice side effect.)
'End of Part 1b initial set up Of Scripting Runtime------------------------
Dim i As Long, j As Long 'LoopBoundVariableCounts used in looping here and at end-----Long is a Big whole Number limit (-2,147,483,648 to 2,147,483,647) If you need some sort of validation the value should only be within the range of a Byte/Integer otherwise there's no point using anything but Long.--upon/after 32-bit, Integers (Short) need converted internally anyways, so a Long is actually faster.
Dim TempColumn As Long: Let TempColumn = Columns.Count: Let TempColumn = 6 'Usually when not debugging comment out last let so Temp Column is last in sheet given by Columns.count....
Dim TempCell As Range: Set TempCell = wksLkUp.Cells(1, TempColumn): Dim TempCellOffset As Long: Let TempCellOffset = 0 '....We choose a cell (or through the later use of the offset step down a column) to use for Duplicate or Empty cells. We often use the last column in the sheet. (This is genarally a good practice as it will not effect finding last column with .End(XltoLeft). Note there were sometimes strange resource problems with deleting columns on large files using the last column rather than one "just off screen" instead )
'2a) Part2a) Looping to put Range Objects in MRSD
For i = StartColumnTableOutput To LastColumnTableOutput Step 1
For j = StartRowTableOutput To LastRowTableOutput Step 1
If wksLkUp.Cells(j, i).Value <> "" Then 'If cell is not empty then...
If Not dicLookupTable.Exists(wksLkUp.Cells(j, i).Value) Then 'check that the unique value does not already exist. ##NOTE
dicLookupTable.Add wksLkUp.Cells(j, i).Value, wksLkUp.Cells(j, i) 'it is easier to understand as well as kind of explicit the first argument does a CStr and the Second Takes anything
Else 'If the key exists, that is to say we have a Range with a Duplicate value, we give the key a slightly modified (unique value) , still give the Range Object as an item, but make an indication, here by highlighting the cell in Pink
Let TempCellOffset = TempCellOffset + 1
Let TempCell.Offset(TempCellOffset, 0).Value = "Duplicate at " & j & " | " & i & ""
wksLkUp.Cells(j, i).Interior.Color = 10987519
dicLookupTable.Add TempCell.Offset(TempCellOffset, 0).Value, wksLkUp.Cells(j, i) 'In case of duplicate we need a unique key, but we stillinclude the Duplicate Range
End If
Else 'Case fo an empty cell - inform of empty cell by writing message in that cell via the Tempory cell
Let TempCellOffset = TempCellOffset + 1 'Go to next free tempory cell in tempory column
Let TempCell.Offset(TempCellOffset, 0).Value = "Empty Cell at " & j & " | " & i & ""
dicLookupTable.Add TempCell.Offset(TempCellOffset, 0).Value, TempCell.Offset(TempCellOffset, 0)
End If
Next j
Next i
'End Part 2
'3) Part 3)--transfer range objects from dictionary to array of ranges in one go!!
Dim rResults() As Variant ' See Question 2) Post #3 and then Further Question 2) Posts #4 and #5 and ? http://www.mrexcel.com/forum/excel-questions/832103-using-microsoft-scripting-runtime-dictionary-store-then-retrieve-range-objects.html?#post4059199
Let rResults() = dicLookupTable.Items() 'Note this gives automatically the 0 to .. convention in rResults Array!
'End part 3)
'--confirm range objects were transfered to array of ranges with various methods
Dim MSRDindex As Long: Let MSRDindex = 0 'LoopBoundVariableCounts for Item number of MSRD
For i = StartColumnTableOutput To LastColumnTableOutput Step 1
For j = StartRowTableOutput To LastRowTableOutput Step 1
Let MSRDindex = MSRDindex + 1 'Next item numbe from MSRD
' With rResults(MSRDindex - 1) 'Jerry Sullivan Demo for example entire range full with Hyperlinks
' wksLkUp.Cells(j, i).Offset(0, 4).Value = .Address & ">" & .Row & ">" & .Value & ">" & .Hyperlinks(1).Address
' End With
' rResults(MSRDindex - 1).Copy Destination:=wksLkUp.Cells(j, i).Offset(0, 4) '
'
rResults(MSRDindex - 1).Copy
wksLkUp.Cells(j, i).Offset(0, -4).PasteSpecial Paste:=xlPasteAllUsingSourceTheme 'These 2 lines may be better Preferably to ensure that VBA...'.....guesses or here rather chooses the correct version from the Clipboard which includes all the full Range Info. Post #6 here - http://www.mrexcel.com/forum/excel-questions/828241-visual-basic-applications-autofilter-specialcells-xlcelltypevisible-copy-only-values-not-formulas.html
wksLkUp.Cells(j, i).ClearContents 'if you do this then you are able to make full use of about 65530 hyperlink sheet number limit ' (.. from speed measurements on Acer Aspire 4810TZGfor a Row of 33928 Hyperlinks took to reorder 657s with the extra ClearContents and 500s with just Copy and Paste (If you do the ClearContents at the end of the program you will ofcourse not be able to use the full 65530 )
Next j
Next i
Set dicLookupTable = Nothing 'Genarally good practice to turn these thimgs off. 'May not be needed but to keep program flexible should alterations need it.
Exit Sub 'End assuming no errors occurred
TheEnd: 'End here if errors occurred**. This ensures importent closing things are done even in the case of an err0r
Application.ScreenUpdating = True
Set dicLookupTable = Nothing
MsgBox Err.Description 'Last action before stoping when error occurs:- Give error description in a Message Box.
End Sub 'ScriptingRuntimeDictionaryToStoreRangesAndReorderItemsKyle2
'
'
Bookmarks