VBA Evaluate Range and VLOOKUP

DocAElstein

Banned user
Joined
May 24, 2014
Messages
1,336
Hi,
As a beginner I may be going a bit above my head!!

After studying and participating at some considerable length in Threads and links to do with using the Evaluate function to speed things up, I thought I understood it. Here are some of those links and Threads. (www.excelfox.com/forum/f22/concatenating-balls-1891/ VBA Trick of the Week :: Avoid Loop for Range Calculations – Evaluate | Useful Gyaan )

. So … the following simplified example File (XL2007 .xlsm)
https://app.box.com/s/pr78mhna00advvhsrmvi
has a Spreadsheet LEFT Function and a Spreadsheet VLOOKUP Function

The results look good! (That is to say wot I expect!) :-



Book1
ABCD
1Produnt
2Name
3Chocolate-europe aroma4Choc
4Chocolate-Cookies0Choc
5Banana-Chocolate-Split10Bana
6Limette-Ksekuchen16Lime
7Erdbeere-Quark8Erdb
8Erdbeere-Mix0Erdb
9Jamaica Sun6Jama
10Waldbeeren0Wald
11
12
13
14LOOKUP Table
15Product Name
16Haselnu-Walnu-aromatisiert
17Tiramisu2
18Chocolate-colonial blend
19Chocolate-europe aroma4
20Chocolate-Cookies
21Jamaica Sun6
22Himbeere-Joghurt
23Erdbeere-Quark8
24Erdbeere-Mix
25Banana-Chocolate-Split10
26Waldbeeren
27Kirsche12
28Kirsche-grner Apfel
29Kirsche-Ananas14
30Stracciatella
31Limette-Ksekuchen16
32grner Apfel-Quark
33Blutorange-Quark
Sheet1
Cell Formulas
RangeFormula
B3=VLOOKUP(A3,$A$16:$C$33,3,FALSE)
B4=VLOOKUP(A4,$A$16:$C$33,3,FALSE)
B5=VLOOKUP(A5,$A$16:$C$33,3,FALSE)
B6=VLOOKUP(A6,$A$16:$C$33,3,FALSE)
B7=VLOOKUP(A7,$A$16:$C$33,3,FALSE)
B8=VLOOKUP(A8,$A$16:$C$33,3,FALSE)
B9=VLOOKUP(A9,$A$16:$C$33,3,FALSE)
B10=VLOOKUP(A10,$A$16:$C$33,3,FALSE)
D3=LEFT(A3,4)
D4=LEFT(A4,4)
D5=LEFT(A5,4)
D6=LEFT(A6,4)
D7=LEFT(A7,4)
D8=LEFT(A8,4)
D9=LEFT(A9,4)
D10=LEFT(A10,4)




I apply this code

Code:
[color=darkblue]Sub[/color] Evaluate_Left()[color=darkblue]Dim[/color] rngName [color=darkblue]As[/color] Range
[color=darkblue]Set[/color] rngName = ThisWorkbook.Worksheets("Sheet1").Range("A3:A10")
[color=darkblue]Dim[/color] rngEE [color=darkblue]As[/color] Range
[color=darkblue]Set[/color] rngEE = ThisWorkbook.Worksheets("sheet1").Range("E3:E10")
[color=darkblue]Let[/color] rngEE = Evaluate("if(row(3:10),LEFT(" & rngName.Address & ",4))")
[color=darkblue]End[/color] [color=darkblue]Sub[/color] [color=green]'Evaluate_Left()[/color]


And get the following:-


Book1
ABCDE
1Produnt
2Name
3Chocolate-europe aroma4ChocChoc
4Chocolate-Cookies0ChocChoc
5Banana-Chocolate-Split10BanaBana
6Limette-Ksekuchen16LimeLime
7Erdbeere-Quark8ErdbErdb
8Erdbeere-Mix0ErdbErdb
9Jamaica Sun6JamaJama
10Waldbeeren0WaldWald
11
12
Sheet1


Which again is wot I expect.


Now I apply this code

Code:
[color=darkblue]Sub[/color] Evaluate_VLOOKUP()[color=darkblue]Dim[/color] rngName [color=darkblue]As[/color] Range
[color=darkblue]Set[/color] rngName = ThisWorkbook.Worksheets("Sheet1").Range("A3:A10")
[color=darkblue]Dim[/color] rngCC [color=darkblue]As[/color] Range
[color=darkblue]Set[/color] rngCC = ThisWorkbook.Worksheets("sheet1").Range("C3:C10")
[color=darkblue]Let[/color] rngCC = Evaluate("if(row(3:10),VLOOKUP(" & rngName.Address & ",$A$16:$C$33,3,FALSE))")
[color=darkblue]End[/color] [color=darkblue]Sub[/color] [color=green]'Evaluate_VLOOKUP()[/color]


…but get the following:-



Book1
ABCDE
1Produnt
2Name
3Chocolate-europe aroma44ChocChoc
4Chocolate-Cookies04ChocChoc
5Banana-Chocolate-Split104BanaBana
6Limette-Ksekuchen164LimeLime
7Erdbeere-Quark84ErdbErdb
8Erdbeere-Mix04ErdbErdb
9Jamaica Sun64JamaJama
10Waldbeeren04WaldWald
11
12
Sheet1


. I would have expected that result without The extra If Row() stuff, which I thought overcame this problem.
. can anyone suggest wot is going wrong, or how I obtain the correct results (Using the Evaluate Function for a range)
Thanks
Alan.

P.s. I will also post this Thread Here: Multiple Columns Into Single Column Using Data Text To Column - Page 2
 
Sadly, I am no genius - merely a persistent hack. :biggrin:
 
Upvote 0

Excel Facts

What is the fastest way to copy a formula?
If A2:A50000 contain data. Enter a formula in B2. Select B2. Double-click the Fill Handle and Excel will shoot the formula down to B50000.
. Hi
. I’m “back” in this thread again, sorry about that. But I Thought this next problem I have might be relevant as a follow up question, at least along the Theme of Evaluate Range, (which in the meantime might be a better title for this Thread!??)….
. I promise not to come back here again, at least with questions, if I sort this last bit out.. I know I ‘ave over done it a bit. But this is the last bit of Evaluate Range stuff I need to get on with my main project…..

So my Current problem/ Question…
. For my project I will frequently be getting lists of Hyperlinks which could frequently run into several 100’s of thousands. So something looking like this:


Book1
AB
1HyperLinkUrlLinkString
2Apfel
3"Cordon bleu" vom Schwein, bofrost
4"Peperonata" Paprikazubereitung Vogeley GV
5"Pomona" Tomtenpree-Konzentrat Vogeley GV
FoodsLookUpTable


. I knocked up a simple code which works (based amongst others on MrExcel threads such as
http://www.mrexcel.com/forum/excel-...ess-excel-2003-visual-basic-applications.html
)

Code:
[color=darkblue]Sub[/color] GetCellAddressravi4everLoop() [color=green]'http://www.mrexcel.com/forum/excel-questions/616749-getting-hyperlink-address-excel-2003-visual-basic-applications.html[/color]
    [color=darkblue]Dim[/color] wksLookUpTable [color=darkblue]As[/color] Worksheet: [color=darkblue]Set[/color] wksLookUpTable = ThisWorkbook.Worksheets("FoodsLookUpTable") [color=green]'Give Abbreviation methods and properties of Object Worksheets[/color]
    [color=darkblue]Dim[/color] CellAddress [color=darkblue]As[/color] [color=darkblue]String[/color] [color=green]'Link in String form required to input in Browser Search[/color]
    [color=darkblue]Dim[/color] Hyp_LinkRow [color=darkblue]As[/color] [color=darkblue]Long[/color], LastRowHyp_Link [color=darkblue]As[/color] Long: [color=darkblue]Let[/color] LastRowHyp_Link = wksLookUpTable.Cells(Rows.Count, 1).End(xlUp).Row [color=green]'BoundLoopVariable and Last entry in column 1 found by going to end of Spreadsheet, then coming back up until an entry is found, then get the row property from that Range (Cell)  object[/color]
     
      [color=darkblue]For[/color] Hyp_LinkRow = 2 [color=darkblue]To[/color] LastRowHyp_Link [color=darkblue]Step[/color] 1 [color=green]'Go through each Row starting at Row 2[/color]
      Application.StatusBar = "At Row " & Hyp_LinkRow & " of " & LastRowHyp_Link
      [color=darkblue]Let[/color] CellAddress = Range("A" & Hyp_LinkRow & "").Hyperlinks(1).Address
      [color=green]'Let CellAddress = Replace(Range("A" & Hyp_LinkRow & "").Hyperlinks(1).Address, "mailto:", "")[/color]
      [color=darkblue]Let[/color] Range("B" & Hyp_LinkRow & "").Value = CellAddress
      [color=darkblue]Next[/color] Hyp_LinkRow
    
    Application.StatusBar = [color=darkblue]False[/color] [color=green]'Reset to default[/color]
[color=darkblue]End[/color] [color=darkblue]Sub[/color] [color=green]'GetCellAddressravi4everLoop()[/color]

. Partly For practical reasons (because the above code can be a bit slow) and partly as a learning excessive I tried a few other methods, Most of which I got working. Maybe you guessed the problem: To complete the set I would like to get an Evaluate Range One liner solution… and my attempts so far have failed..
. The approach I expected to work would be to make a UDF and stick that in an Evaluate Range One liner, as many spreadsheet functions (such as the very first Left Function discussed at the outset of this Thread) work easily in such an Range Evaluate One liner.
. To that end I knocked up the following UDFs which all work fine themselves when written in a spreadsheet cell

Code:
    [color=darkblue]Public[/color] [color=darkblue]Function[/color] GetURL(cell [color=darkblue]As[/color] Range, [color=darkblue]Optional[/color] default_value [color=darkblue]As[/color] [color=darkblue]Variant[/color])
                        [color=green]'     'Lists the Hyperlink Address for a Given Cell[/color]
                        [color=green]'     'If cell does not contain a hyperlink, return default_value[/color]
                        [color=green]'          If (cell.Range("A1").Hyperlinks.Count <> 1) Then[/color]
                        [color=green]'              GetURL = default_value[/color]
                        [color=green]'          Else[/color]
              GetURL = cell.Range("A1").Hyperlinks(1).Address
                        [color=green]'          End If[/color]
    [color=darkblue]End[/color] [color=darkblue]Function[/color]
 
 
    [color=darkblue]Public[/color] [color=darkblue]Function[/color] GetURLstr(Hyplinkcell [color=darkblue]As[/color] Range)
     [color=green]'Lists the Hyperlink Address for a Given Cell[/color]
              GetURLstr = Hyplinkcell.Hyperlinks(1).Address
    [color=darkblue]End[/color] [color=darkblue]Function[/color]
 
 
 
    [color=darkblue]Public[/color] [color=darkblue]Function[/color] GetURLstrS(Hyplinkcells [color=darkblue]As[/color] [color=darkblue]Variant[/color])
     [color=green]'Lists the Hyperlink Address for a Given Cell[/color]
        [color=darkblue]With[/color] Hyplinkcells
              GetURLstrS = Hyplinkcells.Hyperlinks(1).Address
        [color=darkblue]End[/color] [color=darkblue]With[/color]
    End [color=darkblue]Function[/color]

. I have made many attempts at hacking out a solution as shown below, many of which seem from the Syntax OK as well as being along the lines of ideas discussed in this Thread but none seem to work.
. Can anyone help me in somehow to get this to work?
. I have learnt a lot from this thread: I note that I see no array in the formula bar, no matter wot I have tried. So it may not be the usual thing of trying to “coerce” it to work”. Also, right at the beginning of this thread I gave the spreadsheet function LEFT as an example which even I managed to co-coerce into working in Evaluate with Range. It also worked for me here:

Code:
[color=darkblue]Sub[/color] EvaluateRangeLeftSpreadsheetFunction()
 
[color=darkblue]Dim[/color] wksLookUpTable [color=darkblue]As[/color] Worksheet: [color=darkblue]Set[/color] wksLookUpTable = ThisWorkbook.Worksheets("FoodsLookUpTable")
[color=darkblue]Dim[/color] Hyp_LinkRow [color=darkblue]As[/color] [color=darkblue]Long[/color], LastRowHyp_Link [color=darkblue]As[/color] Long: [color=darkblue]Let[/color] LastRowHyp_Link = wksLookUpTable.Cells(Rows.Count, 1).End(xlUp).Row
[color=darkblue]Dim[/color] rngHypLink [color=darkblue]As[/color] Range: [color=darkblue]Set[/color] rngHypLink = wksLookUpTable.Range("A2:A" & LastRowHyp_Link)
[color=darkblue]Dim[/color] RngEE [color=darkblue]As[/color] Range: [color=darkblue]Set[/color] RngEE = wksLookUpTable.Range("E2:E" & LastRowHyp_Link & "")
 
[color=darkblue]Let[/color] RngEE = evaluate("if(row(),LEFT(" & rngHypLink.Address & ",4))") [color=green]'Works[/color]
 
[color=darkblue]End[/color] [color=darkblue]Sub[/color] 'EvaluateRangeLeftSpreadsheetFunction()

As part of my experimenting here I re-wrote the spreadsheet function LEFT as a UDF which worked in the spreadsheet exactly the same as spreadsheet LEFT Function……

Code:
    [color=darkblue]Public[/color] [color=darkblue]Function[/color] LeftBit(cell [color=darkblue]As[/color] Range, TheLength [color=darkblue]As[/color] [color=darkblue]Long[/color])
       [color=darkblue]Let[/color] LeftBit = Left(cell.Value, TheLength)
    [color=darkblue]End[/color] [color=darkblue]Function[/color]

….But….. I could not get that to work in Evaluate with range.

Code:
[color=darkblue]Sub[/color] EvaluateRangeLeftUDFFunction()
 
[color=darkblue]Dim[/color] wksLookUpTable [color=darkblue]As[/color] Worksheet: [color=darkblue]Set[/color] wksLookUpTable = ThisWorkbook.Worksheets("FoodsLookUpTable")
[color=darkblue]Dim[/color] Hyp_LinkRow [color=darkblue]As[/color] [color=darkblue]Long[/color], LastRowHyp_Link [color=darkblue]As[/color] Long: [color=darkblue]Let[/color] LastRowHyp_Link = wksLookUpTable.Cells(Rows.Count, 1).End(xlUp).Row
[color=darkblue]Dim[/color] rngHypLink [color=darkblue]As[/color] Range: [color=darkblue]Set[/color] rngHypLink = wksLookUpTable.Range("A2:A" & LastRowHyp_Link)
[color=darkblue]Dim[/color] RngEE [color=darkblue]As[/color] Range: [color=darkblue]Set[/color] RngEE = wksLookUpTable.Range("E2:E" & LastRowHyp_Link & "")
 
[color=darkblue]Let[/color] RngEE = evaluate("if(row(),LeftBit(" & rngHypLink.Address & ",4))") [color=green]'Doesn't Work[/color]
 
[color=darkblue]End[/color] [color=darkblue]Sub[/color] [color=green]'EvaluateRangeLeftUDFFunction()[/color]

- So maybe I have hit on a more fundamental problem to do with how I am using UDFs that I do not understand.



Thanks
Alan.

Code Attempts so far:

Code:
[color=darkblue]Sub[/color] GetCellAddressrEvaluate() [color=green]'[/color]
    [color=darkblue]Dim[/color] wksLookUpTable [color=darkblue]As[/color] Worksheet: [color=darkblue]Set[/color] wksLookUpTable = ThisWorkbook.Worksheets("FoodsLookUpTable") 'Give Abbreviation methods and properties of Object Worksheets
    [color=darkblue]Dim[/color] Hyp_LinkRow [color=darkblue]As[/color] [color=darkblue]Long[/color], LastRowHyp_Link [color=darkblue]As[/color] Long: [color=darkblue]Let[/color] LastRowHyp_Link = wksLookUpTable.Cells(Rows.Count, 1).End(xlUp).Row [color=green]'BoundLoopVariable and Last entry in column 1 found by going to end of Spreadsheet, then coming back up until an entry is found, then get the row property from that Range (Cell)  object[/color]
    [color=darkblue]Dim[/color] rngHypLink [color=darkblue]As[/color] Range, rngUrlstr [color=darkblue]As[/color] Range
    [color=darkblue]Set[/color] rngHypLink = wksLookUpTable.Range("A2:A" & LastRowHyp_Link): [color=darkblue]Set[/color] rngUrlstr = wksLookUpTable.Range("B2:B" & LastRowHyp_Link)
           
                [color=green]'Let rngUrlstr.Value = Evaluate("" & rngHypLink.Address & "").Hyperlinks(1).Address   'Evaluate for an Address is a special case and returns a Range Object (See here: http://usefulgyaan.wordpress.com/2013/06/19/avoid-loop-for-range-calculations-evaluate/comment-page-1/#comment-358 ). So we can further apply the . to give further range properties and methods. But we need a trick to coerce all array values or we just get the first row[/color]
                [color=green]'Let rngUrlstr.Value = Evaluate("IF(Row()," & "" & rngHypLink.Address & "" & ")").Hyperlinks(1).Address 'Unfortunately a Row() trick ( see here: http://www.excelfox.com/forum/f2/multiple-columns-into-single-column-using-data-text-to-column-1891/index2.html) can not here be used here as we then no longer have a range object to further apply the . to[/color]
                [color=green]'To get this idea to work, first make a public Spreadsheet function called getUrl, then use it in the VBA Evaluate Function[/color]
                [color=green]'Let rngUrlstr.Value = Evaluate("getURL(" & "" & rngHypLink.Address & "" & ")")'Again this just return the first value, so "coerce it":...[/color]
    [color=darkblue]Let[/color] rngUrlstr.Value = Evaluate("IF(Row()," & "getURL(" & "" & rngHypLink.Address & "" & ")" & ")")
    [color=darkblue]Let[/color] rngUrlstr.Value = Evaluate("IF(1," & "getURL(" & "" & rngHypLink.Address & "" & ")" & ")")
 
    [color=darkblue]Let[/color] rngUrlstr.Value = Evaluate("getURLstr(" & "" & rngHypLink.Address & "" & ")")
    [color=darkblue]Let[/color] rngUrlstr.Value = Evaluate("IF(Row()," & "getURLstr(" & "" & rngHypLink.Address & "" & ")" & ")")
 
                        [color=green]'Evaluate("INDEX(VLOOKUP(T(IF(1,{""B"",""A""})),A1:B2,2,0),)")[/color]
                        [color=green]'Evaluate("transpose(INDEX(VLOOKUP(T(IF(1,TRANSPOSE(" & rngName.Address & "))),A16:C33,3,FALSE),))")[/color]
                        [color=green]'                                           Evaluate("INDEX(INDEX($C$16:$C$33,N(IF(1,MATCH($A$3:$A$10,$A$16:$A$33,0)))),)")[/color]
 
 
    [color=darkblue]Let[/color] rngUrlstr.Value = Evaluate("IF(Row()," & "getURLstrS(" & "" & rngHypLink.Address & "" & ")" & ")")
    [color=darkblue]Let[/color] rngUrlstr.Value = GetURLstrS(rngHypLink)
 
                        [color=green]'=GetURL(INDEX(A2:A5;VERGLEICH(WAHR;INDEX(A2:A5=A2;0);0)))[/color]
                        [color=green]'                                                 =GetURL(INDEX(A2:A5;VERGLEICH(WAHR;INDEX(A2:A5=A2:A5;0);0)))  =getURL(INDEX(A$3:A$6;VERGLEICH(WAHR;INDEX(A$3:A$6=A3;0);0)))[/color]
 
    [color=darkblue]Let[/color] rngUrlstr.Value = Evaluate("GetURL(Index(" & rngHypLink.Address & ",match(True,Index(" & rngHypLink.Address & "=" & rngHypLink.Address & ",0),0)))")
    [color=darkblue]Let[/color] rngUrlstr.Value = Evaluate("GetURL(Index(" & rngHypLink.Address & ",N(IF(1,match(True,Index(" & rngHypLink.Address & "=" & rngHypLink.Address & ",0,0)))),)")
 
 
 
 
[color=darkblue]End[/color] [color=darkblue]Sub[/color] [color=green]'GetCellAddressrEvaluate()[/color]


…………………………………………………………………..














P.s. In the meantime for anyone interested, I have got several other methods working with formulas, range Arrays etc. Here are a few codes. If I can get the Evaluate Method working I’ll do some extensive speed tests on the different methods and post the results here…



Code:
[color=darkblue]Sub[/color] GetCellAddressFormulaWithRange()
 
    [color=darkblue]Dim[/color] wksLookUpTable [color=darkblue]As[/color] Worksheet: [color=darkblue]Set[/color] wksLookUpTable = ThisWorkbook.Worksheets("FoodsLookUpTable") [color=green]'Give Abbreviation methods and properties of Object Worksheets[/color]
    [color=darkblue]Dim[/color] Hyp_LinkRow [color=darkblue]As[/color] [color=darkblue]Long[/color], LastRowHyp_Link [color=darkblue]As[/color] Long: [color=darkblue]Let[/color] LastRowHyp_Link = wksLookUpTable.Cells(Rows.Count, 1).End(xlUp).Row [color=green]'BoundLoopVariable and Last entry in column 1 found by going to end of Spreadsheet, then coming back up until an entry is found, then get the row property from that Range (Cell)  object[/color]
    [color=darkblue]Dim[/color] rngHypLink [color=darkblue]As[/color] Range, rngUrlstr [color=darkblue]As[/color] Range
    [color=darkblue]Set[/color] rngHypLink = wksLookUpTable.Range("A2:A" & LastRowHyp_Link): [color=darkblue]Set[/color] rngUrlstr = wksLookUpTable.Range("B2:B" & LastRowHyp_Link)
   
      [color=darkblue]With[/color] rngUrlstr
        .Formula = "=getURLstr(" & rngHypLink(1, 1).Address(0, 0) & ")" [color=green]'Note:- Anything other than 0,0 in Address(0, 0) gives fixed $Address based on Cell in range given by ...rngHypLink(Row, Column). So (Row,Column) here is relative referencing from rngUrlstr in our case 1,1 nooffset[/color]
     
        .FormulaR1C1 = "=getURLstr(R[0]C[-1])" [color=green]'. Syntax: FormulaR1C1="here the formula ". The [] makes it relative referrencing.[/color]
  
                        
   [color=green]'.Value = .Value 'Removes Formula(Putsvalue in)[/color]
   [color=green]'.Replace What:=0,Replacement:="", LookAt:=xlWhole, SearchFormat:=False 'Get rid of zeros[/color]
    [color=darkblue]End[/color] [color=darkblue]With[/color]
[color=darkblue]End[/color] [color=darkblue]Sub[/color] [color=green]'GetCellAddressFormulaWithRange()[/color]
 
 
 
 
 
[color=darkblue]Sub[/color] GetCellAddressFormulaWithLoop()
 
    [color=darkblue]Dim[/color] wksLookUpTable [color=darkblue]As[/color] Worksheet: [color=darkblue]Set[/color] wksLookUpTable = ThisWorkbook.Worksheets("FoodsLookUpTable") [color=green]'Give Abbreviation methods and properties of Object Worksheets[/color]
    [color=darkblue]Dim[/color] Hyp_LinkRow [color=darkblue]As[/color] [color=darkblue]Long[/color], LastRowHyp_Link [color=darkblue]As[/color] Long: [color=darkblue]Let[/color] LastRowHyp_Link = wksLookUpTable.Cells(Rows.Count, 1).End(xlUp).Row [color=green]'BoundLoopVariable and Last entry in column 1 found by going to end of Spreadsheet, then coming back up until an entry is found, then get the row property from that Range (Cell)  object[/color]
    [color=darkblue]Dim[/color] rngHypLink [color=darkblue]As[/color] Range, rngUrlstr [color=darkblue]As[/color] Range
    [color=darkblue]Set[/color] rngHypLink = wksLookUpTable.Range("A2:A" & LastRowHyp_Link): [color=darkblue]Set[/color] rngUrlstr = wksLookUpTable.Range("B2:B" & LastRowHyp_Link)
 
  
      [color=darkblue]For[/color] Hyp_LinkRow = 2 [color=darkblue]To[/color] LastRowHyp_Link [color=darkblue]Step[/color] 1 [color=green]'Go through each Row starting at Row 2[/color]
      Application.StatusBar = "At Row " & Hyp_LinkRow & " of " & LastRowHyp_Link
      [color=darkblue]Let[/color] wksLookUpTable.Cells(Hyp_LinkRow, 2).Formula = "=getURLstr(" & rngHypLink(Hyp_LinkRow - 1, 1).Address(0, 0) & ")"
      [color=darkblue]Let[/color] wksLookUpTable.Cells(Hyp_LinkRow, 2).Formula = "=getURLstr(R[0]C[-1])"
      [color=darkblue]Next[/color] Hyp_LinkRow
  
  
   [color=green]'.Value = .Value 'Removes Formula(Putsvalue in)[/color]
   [color=green]'.Replace What:=0,Replacement:="", LookAt:=xlWhole, SearchFormat:=False 'Get rid of zeros[/color]
 
[color=darkblue]End[/color] [color=darkblue]Sub[/color] [color=green]'GetCellAddressFormulaWithLoop()[/color]
 
 
 
 
 
[color=darkblue]Sub[/color] UrlFromHyperlinkArrayOfRangesMethod() [color=green]' stores results  in array then transfers array values to cells in onewrite[/color]
 
[color=darkblue]Dim[/color] wksLookUpTable [color=darkblue]As[/color] Worksheet: [color=darkblue]Set[/color] wksLookUpTable = ThisWorkbook.Worksheets("FoodsLookUpTable") [color=green]'Give Abbreviation methods and properties of Object Worksheets[/color]
[color=darkblue]Dim[/color] Hyp_LinkRow [color=darkblue]As[/color] [color=darkblue]Long[/color], LastRowHyp_Link [color=darkblue]As[/color] Long: [color=darkblue]Let[/color] LastRowHyp_Link = wksLookUpTable.Cells(Rows.Count, 1).End(xlUp).Row [color=green]'BoundLoopVariable and Last entry in column 1 found by going to end of Spreadsheet, then coming back up until an entry is found, then get the row property from that Range (Cell)  object[/color]
[color=darkblue]Dim[/color] ScreenCapturerngHypLink() [color=darkblue]As[/color] [color=darkblue]Variant[/color], ScreenThingsrngHypLink() [color=darkblue]As[/color] [color=darkblue]Variant[/color]
[color=green]'  "ScreenCapture" - Alan idea for getting close to "everything" wot is really there - Range has lots of info in[/color]
[color=darkblue]Let[/color] ScreenThingsrngHypLink() = wksLookUpTable.Range("A2:A" & LastRowHyp_Link).Value
 
[color=darkblue]Dim[/color] LastRowTable [color=darkblue]As[/color] [color=darkblue]Long[/color]
[color=darkblue]Let[/color] LastRowTable = [color=darkblue]UBound[/color](ScreenThingsrngHypLink, 1)
 
[color=darkblue]Dim[/color] TableClm [color=darkblue]As[/color] [color=darkblue]Long[/color], TableRow [color=darkblue]As[/color] [color=darkblue]Long[/color]
[color=darkblue]ReDim[/color] ScreenCapturerngHypLink(2 [color=darkblue]To[/color] LastRowTable + 1, 1 [color=darkblue]To[/color] 3) [color=green]'We have the info now to dimension our Array of ranges[/color]
 
    [color=darkblue]For[/color] TableRow = 2 [color=darkblue]To[/color] LastRowTable + 1 [color=green]'...go down each row[/color]
    [color=darkblue]Set[/color] ScreenCapturerngHypLink(TableRow, 1) = Cells(TableRow, 1) [color=green]'Puts a Range NOT a value in each Array Element[/color]
    [color=darkblue]Let[/color] ScreenCapturerngHypLink(TableRow, 2) = ScreenCapturerngHypLink(TableRow, 1).Hyperlinks(1).Address
    [color=darkblue]Let[/color] ScreenCapturerngHypLink(TableRow, 3) = ScreenCapturerngHypLink(TableRow, 1).Value
    [color=darkblue]Next[/color] TableRow
[color=darkblue]Let[/color] wksLookUpTable.Range("B2").Resize(LastRowTable, 3).Value = ScreenCapturerngHypLink()
 
 
[color=darkblue]End[/color] [color=darkblue]Sub[/color] [color=green]'UrlFromHyperlinkArrayOfRangesMethod()[/color]

. If it helps, here is the current File I am working on. My Macro Sub() attempts so far are in Module “ForMrExcelFredEvaluateRange”. And my Macro Public Function attempts are in Module “PublicImageLtd”. The Files should open in the relevant sheet “FoodsLookUpTable”.
.
Xl 2007 .xlsm File named “ForMrExcelDebiNetGet.xlsm”
https://app.box.com/s/g30i7nu29nd7dquuyb9t
 
Upvote 0
The problem is that your UDF is not written to return an array under any circumstances. You can change it to:
Code:
Public Function GetURL(cell As Range, Optional default_value As Variant)
'     'Lists the Hyperlink Addresses for a given range
'     'If cell does not contain a hyperlink, return default_value
    Dim rCell                 As Range
    Dim vOut()
    Dim x                     As Long
    Dim y                     As Long
    
    If IsMissing(default_value) Then default_value = vbNullString

    If cell.Count = 1 Then
        If cell.Hyperlinks.Count > 0 Then
            GetURL = cell.Hyperlinks(1).Address
        Else
            GetURL = default_value
        End If
    Else
        ReDim vOut(1 To cell.Rows.Count, 1 To cell.Columns.Count)
        For x = 1 To cell.Rows.Count
            For y = 1 To cell.Columns.Count
                If cell(x, y).Hyperlinks.Count > 0 Then
                    vOut(x, y) = cell(x, y).Hyperlinks(1).Address
                Else
                    vOut(x, y) = default_value
                End If
            Next y
        Next x
        GetURL = vOut
    End If
End Function
for example and then you can use it with evaluate.
 
Upvote 0
Hi Rory.
. Sorry I did not reply sooner. I just cannot pull myself away from ripping that Function apart, (trying to) figure out exactly how it works and doing endless variations of it. Here just one simple version of wot I am doing just now (The classic left Function Again!!)

Code:
[color=darkblue]Sub[/color] EvaluateRangeLeftUDFFunction()
 
[color=darkblue]Dim[/color] wksLookUpTable [color=darkblue]As[/color] Worksheet: [color=darkblue]Set[/color] wksLookUpTable = ThisWorkbook.Worksheets("FoodsLookUpTable")
[color=darkblue]Dim[/color] Hyp_LinkRow [color=darkblue]As[/color] [color=darkblue]Long[/color], LastRowHyp_Link [color=darkblue]As[/color] Long: [color=darkblue]Let[/color] LastRowHyp_Link = wksLookUpTable.Cells(Rows.Count, 1).End(xlUp).Row
[color=darkblue]Dim[/color] rngHypLink [color=darkblue]As[/color] Range: [color=darkblue]Set[/color] rngHypLink = wksLookUpTable.Range("A2:A" & LastRowHyp_Link)
[color=darkblue]Dim[/color] RngEE [color=darkblue]As[/color] Range: [color=darkblue]Set[/color] RngEE = wksLookUpTable.Range("E2:E" & LastRowHyp_Link & "")
 
[color=green]'Let RngEE = evaluate("if(row(),GetLeftBitRoaryA(" & rngHypLink.Address & ",4))") 'Works[/color]
[color=darkblue]Let[/color] RngEE = evaluate("GetLeftBitRoaryA(" & rngHypLink.Address & ",4)") [color=green]'Works also!! - no coerciing[/color]
[color=darkblue]End[/color] [color=darkblue]Sub[/color] [color=green]'EvaluateRangeLeftUDFFunction()[/color]
[color=green]'[/color]
'
'
 
 
[color=darkblue]Function[/color] GetLeftBitRoaryA(cell [color=darkblue]As[/color] Range, TheLength [color=darkblue]As[/color] [color=darkblue]Long[/color])
[color=green]'     'Lists the Hyperlink Addresses for a given range[/color]
[color=green]'     'If cell does not contain a hyperlink, return default_value[/color]
    [color=green]'Dim [color=red]rCell[/color]                 As Range’ Think this don't do anything[/color]
    [color=darkblue]Dim[/color] vOut()
    [color=darkblue]Dim[/color] x                     [color=darkblue]As[/color] [color=darkblue]Long[/color]
    [color=darkblue]Dim[/color] y                     [color=darkblue]As[/color] [color=darkblue]Long[/color]
   
[color=green]'    If IsMissing(default_value) Then default_value = vbNullString[/color]
 
    [color=green]'If cell.Count = 1 Then[/color]
[color=green]'        If cell.Hyperlinks.Count > 0 Then[/color]
[color=green]'            GetLeftBitRoaryA = cell.Hyperlinks(1).Address[/color]
[color=green]'        Else[/color]
'            GetLeftBitRoaryA = default_value
[color=green]'        End If[/color]
    [color=green]'Else[/color]
        [color=darkblue]ReDim[/color] vOut(1 [color=darkblue]To[/color] cell.Rows.Count, 1 [color=darkblue]To[/color] cell.Columns.Count)
        [color=darkblue]For[/color] x = 1 [color=darkblue]To[/color] cell.Rows.Count
            [color=darkblue]For[/color] y = 1 [color=darkblue]To[/color] cell.Columns.Count
[color=green]'                If cell(x, y).Hyperlinks.Count > 0 Then[/color]
                    vOut(x, y) = Left(cell(x, y).Value, TheLength)
[color=green]'                Else[/color]
[color=green]'                    vOut(x, y) = default_value[/color]
[color=green]'                End If[/color]
            [color=darkblue]Next[/color] y
        [color=darkblue]Next[/color] x
        GetLeftBitRoaryA = vOut
    [color=green]'End If[/color]
End [color=darkblue]Function[/color] 'GetGetLeftBitRoaryA



. Up to now everything I try is working hyperlink Functions , other Functions etc. (and Looking at the moment for example at about 40,000 Hyperlinks in one go!!.) …. And that WITHOUT the usually required “coercing stuff” - So you ‘ave invented maybe an alternative to that (God that sets off sad ideas in my head – Don’t worry I won’t Bug you here with them when they don’t work!!)***

…..
The problem is that your UDF is not written to return an array under any circumstances. You can change it to:..........
for example and then you can use it with evaluate.

……. I note that I see no array in the formula bar, no matter wot I have tried. So it may not be the usual thing of trying to “coerce” it to work”. …..
- So maybe I have hit on a more fundamental problem to do with how I am using UDFs that I do not understan......

.. You might of caught some of my ramblings in the Test Area last week with Trying to get an Array to come up in the formula bar etc..
..so.. .. I might even `ave got it.. in a week or two or twenty-five!!

. *** This was the last thing really bugging me to get on with my main project. I am extremely grateful. I will never be good enough to help you in return. (Maybe a very small help is when I continue to pick up and answer some long boring, but technically easy Threads to keep you Mega Hackers free to do the clever stuff!)

Thanks Again.

Alan


P.s. Think your “r Cell” is doing nothing, if you pardon the expression ….:LOL:!!?
 
Upvote 0
P.s. Think your “r Cell” is doing nothing, if you pardon the expression ….:LOL:!!?

Correct. I started out with a simpler version and then decided to redo it to handle ranges with more than one row/column but forgot to remove the variable declaration.
 
Upvote 0
Hi,
. Just a follow up, just sharing some results…or rather correcting small error in a Post 84
. (***any comments as always welcome!)

.......
. I will not come back here again, at least with questions***,........
. .......
......If I can get the Evaluate Method working I’ll do some extensive speed tests on the different methods and post the results here….........

.
. I hope to be doing some extensive speed tests and comparisons of some of the large formulas and Codes here with very large data. (May then out of interest post the results?
. As it may be a bit big, may just post a file link rather than a big post..)
.
. Here I am just doing some preliminary tidying up really my post #84 where the actual code I gave was not clear and as given would not actually Work!!.. The “RoaryLeftFunction” needed to be in a Public Function to make it available to all codes including those using Evaluate..!!.
. Also I am reminding myself how to do speed tests as in
http://www.mrexcel.com/forum/excel-...ria-code-alternative-looping.html#post3937559
. which was already linked to tests with the various formulas created in this Thread..
…………………………..

. Anyways a preliminary bit of work on a simple limited set of codes on reduced size data

. So taking that simplest Function first used as example right at the beginning of this Thread, The Left Function…

. Data is approx 1654 rows initially, but then up to around 100,000 eventually..

. Just a few different basic codes I will work with to get something like this in Column D from Column A




A
B
C
D
21
Apple fresh​
Appl​
22
'Bierwurst' (coarse heat-treated sausage in bladder and smo​
'Bie​
23
'Breslauer' Lyonaise​
'Bre​
24
'Gaisburger Marsch' (potatoes with beef) (1)​
'Gai​
25
'Göttinger Blasenwurst'/Krakauer​
'Göt​


Some typical codes Would be


Code:
[color=blue]Option[/color] [color=blue]Explicit[/color]
[color=blue]Sub[/color] SimpleLoop() [color=lightgreen]'Simplist Loop[/color]
 
 [color=blue]Dim[/color] wksLE [color=blue]As[/color] Worksheet: [color=blue]Set[/color] wksLE = ThisWorkbook.Worksheets("LeftSpeedsEnglish") [color=lightgreen]'Give abbreviations the  Methods, properties, sub-Objects through dot of Worksheets Object[/color]
 [color=blue]Dim[/color] lr [color=blue]As[/color] [color=blue]Long[/color], rws [color=blue]As[/color] [color=blue]Long[/color] [color=lightgreen]'last row and rows in sheet( Long is a Big whole Number limit (-2,147,483,648 to 2,147,483,647) -Most smaller numbers, Byte, Integer, Single are converted in computer to long so no advantage of Dim to smaller Type here)[/color]
 [color=blue]Let[/color] lr = wksLE.Cells.Find(What:="*", after:=wksLE.Cells(1, 1), Lookat:=xlPart, LookIn:=xlFormulas, SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row [color=lightgreen]'Get last Row with entry anywhere for Sheet1. Method: You start at first cell then go backwards (which effectively starts at end of sheet), sercching for anything ( = * ) by rows, then get the row number. This allows for different excel versions with different available Row numbers) Just a different method here for fun- finds last row in sheet rather than row for last entry in particular cell[/color]
 [color=blue]Let[/color] lr = wksLE.Cells(Rows.Count, 1).End(xlUp).Row [color=lightgreen]'Better alternative for single column work. - Starting at last Spreadsheet Row in column1, quasi "go back up" / return the last cell with entry in it as a Range object using .End Property and obtain rows from the .Rows Property of that returned Range Object[/color]
 [color=blue]Dim[/color] sr [color=blue]As[/color] Long: [color=blue]Let[/color] sr = 21 [color=lightgreen]'Start row of data[/color]
 
   [color=blue]For[/color] rws = sr [color=blue]To[/color] lr [color=blue]Step[/color] 1
   wksLE.Range("D" & rws & "").Value = Left((wksLE.Range("A" & rws & "").Value), 4)
   [color=blue]Next[/color] rws
 
[color=blue]End[/color] [color=blue]Sub[/color] [color=lightgreen]'SimpleLoop[/color]
'
'
[color=blue]Sub[/color] TypicalEvaluateAlternativeToLoop()
 [color=blue]Dim[/color] wksLE [color=blue]As[/color] Worksheet: [color=blue]Set[/color] wksLE = ThisWorkbook.Worksheets("LeftSpeedsEnglish") [color=lightgreen]'Give abbreviations the  Methods, properties, sub-Objects through dot of Worksheets Object[/color]
 [color=blue]Dim[/color] RngName [color=blue]As[/color] Range, RngD [color=blue]As[/color] Range [color=lightgreen]'Data Column range and an offset Column for results.. Give abbreviations >>>[/color]
 [color=blue]Dim[/color] lr [color=blue]As[/color] [color=blue]Long[/color], rws [color=blue]As[/color] [color=blue]Long[/color] [color=lightgreen]'last row and rows in sheet( Long is a Big whole Number limit (-2,147,483,648 to 2,147,483,647) -Most smaller numbers, Byte, Integer, Single are converted in computer to long so no advantage of Dim to smaller Type here)[/color]
 [color=blue]Let[/color] lr = wksLE.Cells(Rows.Count, 1).End(xlUp).Row [color=lightgreen]'Better alternative for single column work. - Starting at last Spreadsheet Row in column1, quasi "go back up" / return the last cell with entry in it as a Range object using .End Property and obtain rows from the .Rows Property of that returned Range Object[/color]
 [color=blue]Dim[/color] sr [color=blue]As[/color] Long: [color=blue]Let[/color] sr = 21 [color=lightgreen]'Start row of data[/color]
 [color=blue]Set[/color] RngName = Range("A" & sr & ":A" & lr & ""): [color=blue]Set[/color] RngD = Range("D" & sr & ":D" & lr & "") [color=lightgreen]'...>>>>..the  Methods, properties, sub-Objects through dot of Range Object[/color]
 
 [color=lightgreen]'Let RngD.Value = Evaluate("if(Row(21:1674),LEFT(" & RngName.Address & ",4))")[/color]
 [color=blue]Let[/color] RngD.Value = Evaluate("if(Row(" & sr & ":" & lr & "),LEFT(" & RngName.Address & ",4))")
 
[color=blue]End[/color] [color=blue]Sub[/color] [color=lightgreen]'TypicalEvaluateAlternativeToLoop[/color]
[color=lightgreen]'[/color]
'
[color=blue]Sub[/color] VBAWithFormula()
 [color=blue]Dim[/color] wksLE [color=blue]As[/color] Worksheet: [color=blue]Set[/color] wksLE = ThisWorkbook.Worksheets("LeftSpeedsEnglish")
 [color=blue]Dim[/color] RngName [color=blue]As[/color] Range, RngD [color=blue]As[/color] Range
 [color=blue]Dim[/color] lr [color=blue]As[/color] [color=blue]Long[/color], rws [color=blue]As[/color] [color=blue]Long[/color]
 [color=blue]Let[/color] lr = wksLE.Cells(Rows.Count, 1).End(xlUp).Row
 [color=blue]Dim[/color] sr [color=blue]As[/color] Long: [color=blue]Let[/color] sr = 21
 [color=blue]Set[/color] RngName = Range("A" & sr & ":A" & lr & ""): [color=blue]Set[/color] RngD = Range("D" & sr & ":D" & lr & "")
 
    [color=blue]With[/color] RngD
        .Formula = "=Left(" & RngName.Address & ",4)"
    [color=blue]End[/color] [color=blue]With[/color]
 
[color=blue]End[/color] [color=blue]Sub[/color] [color=lightgreen]'VBAWithFormula()[/color]

.. -___________

. To correct my post and in preparation for some more detailed results …The “Roary” type function needs to be in a module as a Public Function. Here are Two versions, the first where I have attempted to ruin it with explaining ‘Green Comments for anyone learning still like me.



Code:
[color=blue]Option[/color] [color=blue]Explicit[/color]
[color=blue]Public[/color] [color=blue]Function[/color] RoaryLeftPubic(cell [color=blue]As[/color] Range, TheLength [color=blue]As[/color] [color=blue]Long[/color]) [color=blue]As[/color] [color=blue]Variant[/color] [color=lightgreen]'When an Array is assigned through Let to this function, it returns an Array which then through effectively A "Let One Liner" becomes a modified Range based on the Supplied range and any Additional Arguments. It can be thought as a normal Function working on a input Range. A Particular characteristic here is that the Output is created in a loop which specifically assigns each cell within the range. This probably ensures that VBA in any further workings "Know" or "allows" for an Array and so for example ensures that this Function can be used in Evaluate Function "One liners" without the usual "coercing stuff"[/color]
 
    [color=blue]Dim[/color] x [color=blue]As[/color] [color=blue]Long[/color], y [color=blue]As[/color] Long [color=lightgreen]'We build a collection of output by looping into an Array. So these variables will be used for both Row,Column indicies for the cell Range coming into the Function, as well as the Array Indicies. 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.[/color]
    [color=blue]Dim[/color] vOut() [color=blue]As[/color] [color=blue]Variant[/color] [color=lightgreen]'Typically in such a line the type requied may need suit a Function or Object that is used to return the actual values. So usually it will need to be Variant rather than the type of the final items in the Array[/color]
    [color=blue]ReDim[/color] vOut(1 [color=blue]To[/color] cell.Rows.Count, 1 [color=blue]To[/color] cell.Columns.Count) [color=lightgreen]'As we are filling in an array with a loop below it is necerssary to have the Array "There" as it were, so Sized. Also Needs to be at least big enough. Here it is made exactly the correct size by setting it to the size of the in coming array. Te "1 To" bit is important as otherwise Arrays tend to have an annoying tendancy to start otherwise (by default) at zero rather than 1![/color]
       
        [color=blue]For[/color] x = 1 [color=blue]To[/color] cell.Rows.Count [color=lightgreen]'We take each row in turn and fo that row we go along....[/color]
            [color=blue]For[/color] y = 1 [color=blue]To[/color] cell.Columns.Count [color=lightgreen]'...each cloumn. (This convention is good to choose, as this is a typical sequence in which VBA tends to store things "internally" in one long "item" list.)[/color]
                    [color=lightgreen]'The Main part of Thje Function: Each Array element is set to something which is obtained by a formula similar to what one would use in a VBA code to put something in a cell.[/color]
                    [color=lightgreen]'Important Note here: Often at this point in a function we work with the one Input. Indeed we are here as well, that is to say one cell from the Range. A typical mistake therefore in any formulas below would be to forget the extra (x, y).Value required as we are working with an Inputed Array[/color]
                    [color=blue]Let[/color] vOut(x, y) = Left(cell(x, y).Value, TheLength) [color=lightgreen]'First Argument is often a  type of "LookUp ValuE-see note above".[/color]
                        [color=lightgreen]'Debug.Print vOut(x, y)'I found in practice that in a Code calling a [color=blue]Function[/color] strange things sometimes happen when attempting Step through with F8. So A Debug.Print was found to be prefferable to assist in degugging. Possibly a Bug![/color]
            [color=blue]Next[/color] y
        [color=blue]Next[/color] x
       
        [color=blue]Let[/color] RoaryLeftPubic = vOut() [color=lightgreen]' At This point RoaryLeftPubic becomes an Array or Rather an Object with collections. By Virtue of a typical =RoaryLeftPubic(Rng ,   ____) a Range Object will be returned. (Somehow!?)[/color]
 
[color=blue]End[/color] Function [color=lightgreen]'RoaryLeftPubic[/color]



Again code without comments.

Code:
[color=blue]Public[/color] [color=blue]Function[/color] RoaryLeftPubic(cell [color=blue]As[/color] Range, TheLength [color=blue]As[/color] [color=blue]Long[/color])
 
    [color=blue]Dim[/color] vOut() [color=blue]As[/color] [color=blue]Variant[/color]
    [color=blue]Dim[/color] x [color=blue]As[/color] [color=blue]Long[/color], y [color=blue]As[/color] Long
 
    [color=blue]ReDim[/color] vOut(1 [color=blue]To[/color] cell.Rows.Count, 1 [color=blue]To[/color] cell.Columns.Count)
        [color=blue]For[/color] x = 1 [color=blue]To[/color] cell.Rows.Count
            [color=blue]For[/color] y = 1 [color=blue]To[/color] cell.Columns.Count
                    vOut(x, y) = Left(cell(x, y).Value, TheLength) [color=lightgreen]'First Argument is LookUp VALUE[/color]
            [color=blue]Next[/color] y
        [color=blue]Next[/color] x
        RoaryLeftPubic = vOut
 
[color=blue]End[/color] [color=blue]Function[/color] [color=lightgreen]'RoaryLeftPubic[/color]

. To check this is working typing
=R
In any cell will then lead Spreadsheet intellisense to give an additional Spreadsheet suggestion in the drop down list of
=RoaryLeftPubic(

. My original reasoning behind requesting such a function was that it could be used within an Evaluate function as an “Evaluate Range” type solution alternative, which was, (or has certainly become in the meantime the Theme of this Thread.. Indeed as discussed in Post #84 it can be used to that end.. and without the usual “coercing stuff”. For Completeness the code Variation again for that here: -



Code:
[color=lightgreen]'[/color]
'
[color=blue]Sub[/color] EvaluateRoaryALeftFunction()
 [color=blue]Dim[/color] wksLE [color=blue]As[/color] Worksheet: [color=blue]Set[/color] wksLE = ThisWorkbook.Worksheets("LeftSpeedsEnglish")
 [color=blue]Dim[/color] RngName [color=blue]As[/color] Range, RngD [color=blue]As[/color] Range
 [color=blue]Dim[/color] lr [color=blue]As[/color] [color=blue]Long[/color], rws [color=blue]As[/color] [color=blue]Long[/color]
 [color=blue]Let[/color] lr = wksLE.Cells(Rows.Count, 1).End(xlUp).Row
 [color=blue]Dim[/color] sr [color=blue]As[/color] Long: [color=blue]Let[/color] sr = 21
 [color=blue]Set[/color] RngName = Range("A" & sr & ":A" & lr & ""): [color=blue]Set[/color] RngD = Range("D" & sr & ":D" & lr & "")
 
  RngD.Value = Evaluate("RoaryLeftPubic(" & RngName.Address & ",4)")
 
[color=blue]End[/color] [color=blue]Sub[/color] [color=lightgreen]'EvaluateRoaryALeftFunction()[/color]




. But An interesting outcome of the “Roary” type function is that we have another possible Code variation. This could possibly be regarded as a type of new quasi pseudo
Application.WorksheetFunction.

. I say this as although the usual VBA Left Function takes the first argument as a string… The RoaryLeftPubic takes a Range as Second Argument, which could be considered as a parallel to the
Application.WorksheetFunction.VLookup
. as offered by MrExcel MVP pgc01 way back in Post #2 as an alternative for my original Post #1 request for the VBA Evaluate Range and VLOOKUP

. In other words we have a neat “one liner” alternative code for comparison purposes……..This is virtue of the fact that this new spreadsheet function is also available to VBA


Code:
[color=lightgreen]'[/color]
[color=blue]Sub[/color] ApplicationWorksheetRoaryFunctionLeft()
 
 [color=blue]Dim[/color] wksLE [color=blue]As[/color] Worksheet: [color=blue]Set[/color] wksLE = ThisWorkbook.Worksheets("LeftSpeedsEnglish")
 [color=blue]Dim[/color] RngName [color=blue]As[/color] Range, RngD [color=blue]As[/color] Range
 [color=blue]Dim[/color] lr [color=blue]As[/color] [color=blue]Long[/color], rws [color=blue]As[/color] [color=blue]Long[/color]
 [color=blue]Let[/color] lr = wksLE.Cells(Rows.Count, 1).End(xlUp).Row
 [color=blue]Dim[/color] sr [color=blue]As[/color] Long: [color=blue]Let[/color] sr = 21
 [color=blue]Set[/color] RngName = Range("A" & sr & ":A" & lr & ""): [color=blue]Set[/color] RngD = Range("D" & sr & ":D" & lr & "")
 
 [color=blue]Let[/color] RngD.Value = RoaryLeftPubic(RngName, 4)
 
[color=blue]End[/color] [color=blue]Sub[/color] [color=lightgreen]'ApplicationWorksheetRoaryFunctionLeft()[/color]





. I will probably come back here with some extensive speed test in a day or so.. I didn’t want to clutter it up too much again in one go…

Alan
 
Upvote 0
Hi….


. Just a follow up to last few Posts for anyone following an interested…..


. I have seen the Left function quite often given as an example in comparing an “Evaluate Range One Liner”, the main Theme in the meantime of this Thread. (For example: . . …………
https://usefulgyaan.wordpress.com/2...ulations-evaluate/comment-page-1/#comment-358
. ), so I use it often as a sort of “base” calculation to check before somewhat more complicated things like the Hyperlink stuff….

.. here again A few different and extra methods. If anyone has any others and can give the equivalent code for it I will try them out and compare: The relative speed I guess is all that is important from my measurements as the actual is dependent on too many things that will be different for anyone else trying on their system.
. I only give a very brief Results and description of the different methods/Codes. Anyone further interested can reply to this Thread. I am subscribed to it, and will help if I can…

. here are some preliminary results just for approximately 1654 Rows.



F
G
H
1
Brief Description of Code​
Average Run Time in Seconds​
2
(Micro Timer + VBA Timer ) / 2​
3
L1​
Simplist Loop​
0.4​
4
L2​
Typical Evaluate Alternative​
0.02​
5
L3​
Typical .Formula in a With EndWith​
0.008​
6
L4​
Typical .FormulaR1C1 in a With EndWith​
0.007​
7
L5​
.Formula in a Loop​
0.7​
8
L6​
FormulaR1C1 in a Loop​
0.6​
9
L7​
Evalute using Range Object Left UDF​
0.1​
10
L8​
Range Object Left UDF - Direct​
0.06​
11
L9​
VBA Array Of Ranges (1a)​
.07​
12
L9​
VBA Array Of Ranges () (1a)​
0.22​
13
L10​
VBA Array Of Ranges (1aa)​
0.13 - .07​
14
L10​
VBA Array Of Ranges () (1aa)​
0.29 - .07​
15
L11​
VBA Array Of Ranges (1b) First use of intermediateArray​
.08​
16
L11​
VBA Array Of Ranges () (1b) First use of intermediateArray​
0.22​
17
L12​
VBA Array Of Ranges (2)​
.07​
18
L12​
VBA Array Of Ranges () (2)​
0.18​
19
L13​
RangeObjectCapture value2 (___)​
3.8​
20
L13​
RangeObjectCapture value2 () (___)​
3.8​
21
L14​
MSRDKeysItems item (___)​
.65​
22
L14​
MSRDKeysItems item () (___)​
.66​
23
L14​
MSRDKeysItems intermediteArray (___).​
.16​
24
L14​
MSRDKeysItems intermediteArray () (___).​
.65​
25
L14​
MSRDKeysItems Keys (As values)​
2.1​
26
L14​
MSRDKeysItems Keys () (As values)​
2.1​
27
L15​
MSRDKeys (As Full Range Objects)​
.56​
28
L15​
MSRDKeys () (As Full Range Objects)​
.56​
29
L15​
MSRDKeys intermediateArray (As Full Range Objects)​
.08​
30
L15​
MSRDKeys intermediateArray () (As Full Range Objects)​
.56​

L.1 ) Simplest Loop

L.2) Classical Evaluate (with coercing) “One liner equivalent”

L.3 - L.4) Typical .Formulas within With End With

L.5 – L.6) Formulas used within Loop

L.7) Classical Evaluate (without coercing) “One liner equivalent” using Guru Given UDF Range Object returning “Left” Function.

L.8) Direct use of UDF Left Function As mentioned in previous Post this gives a sort of extra “Application.Worksheet-Type” Function as an alternative to the existing Left which is only applicable to a string as first argument rather than a range here. In simplest form the UDF returns a collection in an Array based on the standard Left Function, which effectively allows a direct
Let RngA = RngB “type” assignment where RngB is UDFLeftFunction(RngA,_____,____etc. )

L.9a) Loop in a VBA Array Of Ranges. Use . Dot on range in second loop to produce output array. Use the typical allowed one liner to give values of a Range the values in a VBA Array

( L.10aa) Similar to L.9a). This has an extra step that re-dimensions the Output array and shortens looping in output array making to allow for any conditions of empty final output arrays. This has speed advantages in the case of large Ranges that might have many empty cells which would in this code not be considered are “ignored” in the output calculations and placing of output values in an array in looping. Effectively just reducing the output array size and looping count. A simple but possibly sometimes overlooked novel idea. )

L.11b) As in L.9a) But just demonstrating for the first time in these tests a “one liner” IntermediateArray indicia assigner, mostly often used often for a collection of values. But equally as here shown applicable to a collection of Ranges. –(Post Kyle #4_3 rResults=_____
http://www.mrexcel.com/forum/excel-...onary-store-then-retrieve-range-objects.html?

L.12c) Similar again to L.-8a) just a more untypical requirement where any workings can be done within one loop and Input and Output arrays may be similarly sized. So only one loop is required. (But note it is the “slower” one used to input / Populate an array of ranges).

L.13) RangeObjectCapture The entire range is captured as One Range Object and its Value2 and used then in a Loop for making an output Array as before. Output as usual in a "Output Value One Liner"

L.14) Microsoft Scripting Runtime Dictionary Range Of Ranges Keys & Items1. Similar to the L.) – L.11 Array of Ranges, but a full Microsoft Scripting Runtime Dictionary of keys (Reference name) and items (The Ranges as Object of type Range in this case) is used in place of the VBA Array.. (Additionally full use is used (or rather allowance and correction is made!1for ) of the unique Key requirement / characteristic. ) Also allowance for referencing empty ranges. (3 Versions tested using
. – items()(___).
. – IntermediateArray()(___).
. - (. - keys()(___). Which coincidentally can also be used for simple Left applied to . value in these examples ).

L.15) Microsoft Scripting Runtime Dictionary Range Of Ranges Keys. Simplified version of L.14 taking advantage of the peculiar characteristic that the reference name (Key) of a Microsoft Scripting Runtime Dictionary ( MSRD ) can be of a form of just about everything (except arrays) - the same as the items themselves!!!!??!! ( Kyle #9
http://www.mrexcel.com/forum/excel-...onary-store-then-retrieve-range-objects.html?
So just the keys are used and the It has to be simplified, that is to say not including the allowance for the Unique Key characteristic.

L.16 – L.17 etc.
. These are not worth to much discussion yet. I have the basic idea of capturing a Large array of multiple cells initially as one Large Range Object similar to L.13, but then within VBA creating a MSRD of Range objects identical to that produced from looping individual cells as Ranges in as in L.9a). This remains an open question just now from post #11 _2)
http://www.mrexcel.com/forum/excel-...nary-store-then-retrieve-range-objects-2.html
and newly here Post #8 - ___
Range Dimensioning, Range and Value Referencing and Referring to Arrays [SOLVED]
. … --- As a somewhat unsatisfactory bodge I replaced what I hope will be individual Range objects with the complete Range Object Itself... A very peculiar and unnecessary step... .. But some interesting things were learnt along the way form answers starting from around Post #12 to #13. – because of this bodge It was necessary then to access through value2 again as in L13 leading to some interesting “levels of increased direction” necessary. Just for fun and justice to the discussion there I include a couple of working versions of those “Bodge” codes. But more out of my sad curiosity rather than anything else!! (If I say so myself!!)
. ( The only difference in L.18 – L.19 is the introduction in L.19 alternative to the required new .(to me!) extra (). Parenthesis in writing an array because of otherwise going “A Level of Indirection to far” (for VBA to “guess correctly…”…)… )
.. The speeds will hopefully be improved if I get my idea working , or maybe not… the point of my experimenting to find out… …………….( I just did not do another sad L.16 and L.17 using a VBA Array rather than MSRD corresponding to L.9a) - may wait or not until I get the other idea sorted )

……………………………….


. . In my next chapter of War and Peace I shall repeat the work for much bigger Lists and for obtaining the URL Address for a Hyperlink.


Alan…

……………..

.P.s. :-

. Despite my best efforts I could not get the Forum Software to crash by sticking all my codes with comments in one Code Window….
. So Sorry here they are.. ( The only other code needed is the “Public Function RoaryLeftPubic” discussed and given in last Post # 86… but as I understand it fully now I include it with explaining ‘green comments for completeness again right at the end in my Endeavour to crash the Forum Software…


…..


Code:
[color=blue]Option[/color] [color=blue]Explicit[/color]
[color=blue]Sub[/color] L1_SimpleLoop() [color=lightgreen]'Simplist Loop[/color]
 
 [color=blue]Dim[/color] wksLE [color=blue]As[/color] Worksheet: [color=blue]Set[/color] wksLE = ThisWorkbook.Worksheets("LeftSpeedsEnglish") [color=lightgreen]'Give abbreviations the  Methods, properties, sub-Objects through dot of Worksheets Object[/color]
 [color=blue]Dim[/color] lr [color=blue]As[/color] [color=blue]Long[/color], rws [color=blue]As[/color] [color=blue]Long[/color] [color=lightgreen]'last row and rows in sheet( Long is a Big whole Number limit (-2,147,483,648 to 2,147,483,647) -Most smaller numbers, Byte, Integer, Single are converted in computer to long so no advantage of Dim to smaller Type here) >>> 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. http://www.mrexcel.com/forum/excel-questions/803662-byte-backward-loop-3.html[/color]
 [color=blue]Let[/color] lr = wksLE.Cells.Find(What:="*", after:=wksLE.Cells(1, 1), Lookat:=xlPart, LookIn:=xlFormulas, SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row [color=lightgreen]'Get last Row with entry anywhere for Sheet1. Method: You start at first cell then go backwards (which effectively starts at end of sheet), sercching for anything ( = * ) by rows, then get the row number. This allows for different excel versions with different available Row numbers) Just a different method here for fun- finds last row in sheet rather than row for last entry in particular cell[/color]
 [color=blue]Let[/color] lr = wksLE.Cells(Rows.Count, 1).End(xlUp).Row [color=lightgreen]'Better alternative for single column work. - Starting at last Spreadsheet Row in column1, quasi "go back up" / return the last cell with entry in it as a Range object using .End Property and obtain rows from the .Rows Property of that returned Range Object[/color]
 [color=blue]Dim[/color] sr [color=blue]As[/color] Long: [color=blue]Let[/color] sr = 21 [color=lightgreen]'Start row of data[/color]
 
    [color=blue]For[/color] rws = sr [color=blue]To[/color] lr [color=blue]Step[/color] 1
    wksLE.Range("D" & rws & "").Value = Left((wksLE.Range("A" & rws & "").Value), 4)
    [color=lightgreen]'wksLE.Range("D" & rws & "").Value = Left$((wksLE.Range("A" & rws & "").Value), 4)[/color]
    [color=blue]Next[/color] rws
 
[color=blue]End[/color] [color=blue]Sub[/color] [color=lightgreen]'SimpleLoop[/color]
'
'
[color=blue]Sub[/color] L2_TypicalEvaluateAlternativeToLoop()
 [color=blue]Dim[/color] wksLE [color=blue]As[/color] Worksheet: [color=blue]Set[/color] wksLE = ThisWorkbook.Worksheets("LeftSpeedsEnglish") [color=lightgreen]'Give abbreviations the  Methods, properties, sub-Objects through dot of Worksheets Object[/color]
 [color=blue]Dim[/color] RngName [color=blue]As[/color] Range, RngD [color=blue]As[/color] Range [color=lightgreen]'Data Column range and an offset Column for results.. Give abbreviations >>>[/color]
 [color=blue]Dim[/color] lr [color=blue]As[/color] [color=blue]Long[/color] [color=lightgreen]'last row ( Long is a Big whole Number limit (-2,147,483,648 to 2,147,483,647) -Most smaller numbers, Byte, Integer, Single are converted in computer to long so no advantage of Dim to smaller Type here)[/color]
 [color=blue]Let[/color] lr = wksLE.Cells(Rows.Count, 1).End(xlUp).Row [color=lightgreen]'Better alternative for single column work. - Starting at last Spreadsheet Row in column1, quasi "go back up" / return the last cell with entry in it as a Range object using .End Property and obtain rows from the .Rows Property of that returned Range Object[/color]
 [color=blue]Dim[/color] sr [color=blue]As[/color] Long: [color=blue]Let[/color] sr = 21 [color=lightgreen]'Start row of data[/color]
 [color=blue]Set[/color] RngName = Range("A" & sr & ":A" & lr & ""): [color=blue]Set[/color] RngD = Range("D" & sr & ":D" & lr & "") [color=lightgreen]'...>>>>..the  Methods, properties, sub-Objects through dot of Worksheets Object[/color]
 
  [color=lightgreen]'Let RngD.Value = Evaluate("if(Row(21:1674),LEFT(" & RngName.Address & ",4))")[/color]
  [color=blue]Let[/color] RngD.Value = Evaluate("if(Row(" & sr & ":" & lr & "),LEFT(" & RngName.Address & ",4))")
 
[color=blue]End[/color] [color=blue]Sub[/color] [color=lightgreen]'TypicalEvaluateAlternativeToLoop[/color]
[color=lightgreen]'[/color]
'
[color=blue]Sub[/color] L3_4_VBAWithFormula()
 [color=blue]Dim[/color] wksLE [color=blue]As[/color] Worksheet: [color=blue]Set[/color] wksLE = ThisWorkbook.Worksheets("LeftSpeedsEnglish")
 [color=blue]Dim[/color] RngD [color=blue]As[/color] Range, RngName [color=blue]As[/color] Range
 [color=blue]Dim[/color] lr [color=blue]As[/color] [color=blue]Long[/color], rws [color=blue]As[/color] [color=blue]Long[/color]
 [color=blue]Let[/color] lr = wksLE.Cells(Rows.Count, 1).End(xlUp).Row
 [color=blue]Dim[/color] sr [color=blue]As[/color] Long: [color=blue]Let[/color] sr = 21
 [color=blue]Set[/color] RngD = Range("D" & sr & ":D" & lr & ""):  [color=blue]Set[/color] RngName = Range("A" & sr & ":A" & lr & "")
 
    [color=blue]With[/color] RngD
        [color=lightgreen]'.Formula = "=Left(" & RngName.Address & ",4)"[/color]
        .FormulaR1C1 = "=left(R[0]C[-3],4)"
    [color=blue]End[/color] [color=blue]With[/color]
 
[color=blue]End[/color] [color=blue]Sub[/color] [color=lightgreen]'VBAWithFormula()[/color]
[color=lightgreen]'[/color]
[color=blue]Sub[/color] L5_6_VBAFormulaLoop() 'Looping the [color=blue]For[/color]mulas in
 
 [color=blue]Dim[/color] wksLE [color=blue]As[/color] Worksheet: [color=blue]Set[/color] wksLE = ThisWorkbook.Worksheets("LeftSpeedsEnglish") [color=lightgreen]'Give abbreviations the  Methods, properties, sub-Objects through dot of Worksheets Object[/color]
 [color=blue]Dim[/color] lr [color=blue]As[/color] [color=blue]Long[/color], rws [color=blue]As[/color] [color=blue]Long[/color]
 [color=blue]Let[/color] lr = wksLE.Cells(Rows.Count, 1).End(xlUp).Row [color=lightgreen]'Better alternative for single column work. - Starting at last Spreadsheet Row in column1, quasi "go back up" / return the last cell with entry in it as a Range object using .End Property and obtain rows from the .Rows Property of that returned Range Object[/color]
 [color=blue]Dim[/color] sr [color=blue]As[/color] Long: [color=blue]Let[/color] sr = 21 [color=lightgreen]'Start row of data[/color]
 [color=blue]Dim[/color] RngD [color=blue]As[/color] Range, RngName [color=blue]As[/color] Range
 [color=blue]Set[/color] RngD = Range("D" & sr & ":D" & lr & ""):  [color=blue]Set[/color] RngName = Range("A" & sr & ":A" & lr & "")
   
    For rws = sr [color=blue]To[/color] lr [color=blue]Step[/color] 1
    [color=lightgreen]'wksLE.Range("D" & rws & "").Formula = "=Left(" & RngName.Address & ",4)"[/color]
    wksLE.Range("D" & rws & "").FormulaR1C1 = "=left(R[0]C[-3],4)"
    [color=blue]Next[/color] rws
 
[color=blue]End[/color] [color=blue]Sub[/color] [color=lightgreen]'VBA[color=blue]For[/color]mulaLoop[/color]
[color=lightgreen]'[/color]
'
[color=blue]Sub[/color] VBALeft()
 [color=blue]Dim[/color] wksLE [color=blue]As[/color] Worksheet: [color=blue]Set[/color] wksLE = ThisWorkbook.Worksheets("LeftSpeedsEnglish")
 [color=blue]Dim[/color] RngD [color=blue]As[/color] Range, RngName [color=blue]As[/color] Range
 [color=blue]Dim[/color] lr [color=blue]As[/color] [color=blue]Long[/color], rws [color=blue]As[/color] [color=blue]Long[/color]
 [color=blue]Let[/color] lr = wksLE.Cells(Rows.Count, 1).End(xlUp).Row
 [color=blue]Dim[/color] sr [color=blue]As[/color] Long: [color=blue]Let[/color] sr = 21
 [color=blue]Set[/color] RngD = Range("D" & sr & ":D" & lr & ""): [color=blue]Set[/color] RngName = Range("A" & sr & ":A" & lr & "")
 
    [color=lightgreen]'Let RngD.Value = Left(RngName, 4) Wont work..RngName is nat a string as required in first argument![/color]
 
[color=blue]End[/color] [color=blue]Sub[/color]
[color=lightgreen]'[/color]
'
[color=blue]Sub[/color] L7_EvaluateRoaryALeftFunction()
 [color=blue]Dim[/color] wksLE [color=blue]As[/color] Worksheet: [color=blue]Set[/color] wksLE = ThisWorkbook.Worksheets("LeftSpeedsEnglish")
 [color=blue]Dim[/color] RngName [color=blue]As[/color] Range, RngD [color=blue]As[/color] Range
 [color=blue]Dim[/color] lr [color=blue]As[/color] [color=blue]Long[/color], rws [color=blue]As[/color] [color=blue]Long[/color]
 [color=blue]Let[/color] lr = wksLE.Cells(Rows.Count, 1).End(xlUp).Row
 [color=blue]Dim[/color] sr [color=blue]As[/color] Long: [color=blue]Let[/color] sr = 21
 [color=blue]Set[/color] RngName = Range("A" & sr & ":A" & lr & ""): [color=blue]Set[/color] RngD = Range("D" & sr & ":D" & lr & "")
 
  [color=blue]Let[/color] RngD.Value = Evaluate("RoaryLeftPubic(" & RngName.Address & ",4)")
 
[color=blue]End[/color] [color=blue]Sub[/color] [color=lightgreen]'EvaluateRoaryALeftFunction()[/color]
[color=lightgreen]'[/color]
'
 
 
 
 
 
'
[color=blue]Sub[/color] L8_ApplicationWorksheetRoaryFunctionLeft()
 
 [color=blue]Dim[/color] wksLE [color=blue]As[/color] Worksheet: [color=blue]Set[/color] wksLE = ThisWorkbook.Worksheets("LeftSpeedsEnglish")
 [color=blue]Dim[/color] RngName [color=blue]As[/color] Range, RngD [color=blue]As[/color] Range
 [color=blue]Dim[/color] lr [color=blue]As[/color] [color=blue]Long[/color], rws [color=blue]As[/color] [color=blue]Long[/color]
 [color=blue]Let[/color] lr = wksLE.Cells(Rows.Count, 1).End(xlUp).Row
 [color=blue]Dim[/color] sr [color=blue]As[/color] Long: [color=blue]Let[/color] sr = 21
 [color=blue]Set[/color] RngName = Range("A" & sr & ":A" & lr & ""): [color=blue]Set[/color] RngD = Range("D" & sr & ":D" & lr & "")
 
 [color=blue]Let[/color] RngD.Value = RoaryLeftPubic(RngName, 4)
 
[color=blue]End[/color] [color=blue]Sub[/color] [color=lightgreen]'ApplicationWorksheetRoaryFunctionLeft()[/color]
[color=lightgreen]'[/color]
'
 
 
'
''
[color=blue]Sub[/color] L9_VBAArrayOfRanges1a()
[color=lightgreen]'Loop Range of Ranges. VBA Make Array for Output. Output in a "Output Value One Liner"[/color]
[color=lightgreen]'Typical application requiring seperate loops for the (often differnt sized) input and output arrays[/color]
 [color=blue]Dim[/color] wksLE [color=blue]As[/color] Worksheet: [color=blue]Set[/color] wksLE = ThisWorkbook.Worksheets("LeftSpeedsEnglish")
 [color=blue]Dim[/color] RngName [color=blue]As[/color] Range, RngD [color=blue]As[/color] Range
 [color=blue]Dim[/color] lr [color=blue]As[/color] [color=blue]Long[/color], rws [color=blue]As[/color] [color=blue]Long[/color]
 [color=blue]Let[/color] lr = wksLE.Cells(Rows.Count, 1).End(xlUp).Row
 [color=blue]Dim[/color] sr [color=blue]As[/color] Long: [color=blue]Let[/color] sr = 21
 [color=blue]Set[/color] RngName = Range("A" & sr & ":A" & lr & ""): [color=blue]Set[/color] RngD = Range("D" & sr & ":D" & lr & "")
 
 [color=blue]Dim[/color] arrIn() [color=blue]As[/color] Range [color=lightgreen]'Variant 'In the looping, the Set would appear to be responsible for bringing **Ranges into the Array The variable type remains as defined here: Either a range for As Range or a Variant Object for [color=blue]As[/color] Variant[/color]
 [color=blue]ReDim[/color] arrIn(sr [color=blue]To[/color] lr, 1 [color=blue]To[/color] 1) [color=lightgreen]'We must give array a size as we give specific value in a loop. ReDim Must be used rather than Dim as [color=blue]Dim[/color] only takes Numbers not variables[/color]
 
    For rws = sr [color=blue]To[/color] lr [color=blue]Step[/color] 1 [color=lightgreen]'Input Array of Ranges[/color]
        [color=blue]Set[/color] arrIn(rws, 1) = Range("A" & rws & "")
        [color=lightgreen]'Set arrIn(rws, 1) = wksLE.Range("A" & rws & "") 'This would be tolerate**[/color]
    [color=blue]Next[/color] rws
 
 Dim arrOut() As [color=blue]String[/color] [color=lightgreen]'We can use string as in the looping below as we are not relying on (/seeing) a range object to rturn us an array of values.[/color]
 [color=blue]ReDim[/color] arrOut(sr [color=blue]To[/color] lr, 1 To 1) [color=lightgreen]'Antoher way to look at it is to say we have a fixed, rather than dynamiy array, and as VBA does not allow a direct assigning one liner in this case it is also not necerssarily expecting to see an object. [color=blue]For[/color] Let it is likely to expect to see some value, and for Set an object (Would expect an Range Object if indicies of arrOut were so defined by arrOut() As String initially[/color]
 
    [color=blue]For[/color] rws = sr [color=blue]To[/color] lr [color=blue]Step[/color] 1 [color=lightgreen]'Input Array of Ranges[/color]
 
    [color=lightgreen]'Let arrOut(rws, 1) = arrIn(rws, 1).Value 'Works 'VBA would appear to recognise this array element as A range as it gives me the Method, Object and property selkection to choose from via intellisense brought in by typing . Dot after the Array elemant[/color]
    [color=lightgreen]'Let arrOut(rws, 1) = arrIn()(rws, 1).Value 'Works'.. because of how VBA “works”, This extra () will ensure that indices are always returned to the resulting array (and not occasionally, for example, arguments ) by any following method or property.[/color]
       [color=lightgreen]'Let arrOut()(rws, 1) = arrIn()(rws, 1).Value 'Works but Rory said it aint ever needed on the LHS,  so it aint[/color]
    [color=lightgreen]'Let arrOut(rws, 1) = Left(arrIn(rws, 1).Value, 4) 'Even A function on the RHS of the = is accepted Here. So again for a non dynamic Array it is not relying on what the function to "define" the type[/color]
    [color=blue]Let[/color] arrOut(rws, 1) = Left(arrIn()(rws, 1).Value, 4) [color=lightgreen]'Works[/color]
      'Let arrOut()(rws, 1) = Left(arrIn()(rws, 1).Value, 4) 'Works
    [color=blue]Next[/color] rws
[color=lightgreen]'         Possibility to Note here:          Dim IntermediateArray() [color=blue]As[/color] Range 'Variant  'Note RoryA Post #2You can only assign one array to another directly (i.e. without looping) if the destination array is dynamic AND THE TWO ARRAYS ARE THE SAME TYPE.[/color]
[color=lightgreen]'                                          '  Re[color=blue]Dim[/color] IntermediateArray(sr [color=blue]To[/color] lr, 1 [color=blue]To[/color] 1)'THIS Line Will NOT Work: RoryA Post #2 http://www.excelforum.com/excel-new-users-basics/1058406-range-dimensioning-range-and-value-referencing-and-referring-to-arrays.html    - You can only assign one array to another directly (i.e. without looping) if the destination array is dynamic[/color]
[color=lightgreen]'                                            Let IntermediateArray() = arrIn()[/color]
 [color=blue]Let[/color] RngD.Value = arrOut() [color=lightgreen]'This is the typical allowed one liner to give values of a Range the values in an  Array (VBA does not allow this one liner in any way for assigning the ranges. There is no way of getting over having to paste each Range Object in a loop.[/color]
 
 [color=blue]End[/color] [color=blue]Sub[/color] [color=lightgreen]'VBAArrayOfRanges1a[/color]
[color=blue]Sub[/color] L10_VBAArrayOfRanges1aa()
[color=lightgreen]'Loop Range of Ranges. VBA Make Array for Output. Output in a "Output Value One Liner"[/color]
[color=lightgreen]'Typical application requiring seperate loops for the (often differnt sized) input and output arrays[/color]
 [color=blue]Dim[/color] wksLE [color=blue]As[/color] Worksheet: [color=blue]Set[/color] wksLE = ThisWorkbook.Worksheets("LeftSpeedsEnglish")
 [color=blue]Dim[/color] RngName [color=blue]As[/color] Range, RngD [color=blue]As[/color] Range
 [color=blue]Dim[/color] lr [color=blue]As[/color] [color=blue]Long[/color], rws [color=blue]As[/color] [color=blue]Long[/color]
 [color=blue]Let[/color] lr = wksLE.Cells(Rows.Count, 1).End(xlUp).Row
 [color=blue]Dim[/color] sr [color=blue]As[/color] Long: [color=blue]Let[/color] sr = 21
 [color=blue]Set[/color] RngName = Range("A" & sr & ":A" & lr & ""): [color=blue]Set[/color] RngD = Range("D" & sr & ":D" & lr & "")
 
 Dim arrIn() As Range [color=lightgreen]'Variant 'In the looping, the Set would appear to be responsible for bringing **Ranges into the Array The variable type remains as defined here: Either a range for [color=blue]As[/color] Range or a Variant Object for [color=blue]As[/color] Variant[/color]
 [color=blue]ReDim[/color] arrIn(sr [color=blue]To[/color] lr, 1 [color=blue]To[/color] 1) [color=lightgreen]'We must give array a size as we give specific value in a loop. ReDim Must be used rather than [color=blue]Dim[/color] as [color=blue]Dim[/color] only takes Numbers not variables[/color]
 
 Dim EmtpyInArrIndiciesCount As Long: [color=blue]Let[/color] EmtpyInArrIndiciesCount = 0 [color=lightgreen]'Here possibility to Redim ArrIn if any extra conitions, such as MSRD etc unique entries being ommited, leading to unused indicies.. then###[/color]
 
 
    For rws = sr To lr [color=blue]Step[/color] 1 [color=lightgreen]'Input Array of Ranges[/color]
        [color=blue]If[/color] Range("A" & rws & "").Value <> "" [color=blue]Then[/color]
        [color=blue]Set[/color] arrIn(rws - EmtpyInArrIndiciesCount, 1) = Range("A" & rws & "")  [color=lightgreen]'The extra "  - Emtp...." will take inidie niumber back accordingly to fill just after next free indicie[/color]
        [color=lightgreen]'Set arrIn((rws - EmtpyInArrIndiciesCount, 1) = wksLE.Range("A" & rws & "") 'This would be tolerate**[/color]
        [color=blue]Else[/color]
        [color=blue]Let[/color] EmtpyInArrIndiciesCount = EmtpyInArrIndiciesCount + 1
        [color=blue]End[/color] [color=blue]If[/color]
    [color=blue]Next[/color] rws
 
 Dim arrOut() As [color=blue]String[/color] [color=lightgreen]'We can use string as in the looping below as we are not relying on (/seeing) a range object to rturn us an array of values.[/color]
 [color=blue]ReDim[/color] arrOut(sr To lr - EmtpyInArrIndiciesCount, 1 To 1) [color=lightgreen]'Antoher way to look at it is to say we have a fixed, rather than dynamiy array, and as VBA does not allow a direct assigning one liner in this case it is also not necerssarily expecting to see an object. [color=blue]For[/color] Let it is likely to expect to see some value, and for Set an object (Would expect an Range Object if indicies of arrOut were so defined by arrOut() As String initially[/color]
   
    [color=blue]For[/color] rws = sr To lr - EmtpyInArrIndiciesCount [color=blue]Step[/color] 1 [color=lightgreen]'Input Array of Ranges'The extra   - Emtp.... prevents looping to far[/color]
 
    [color=lightgreen]'Let arrOut(rws, 1) = arrIn(rws, 1).Value 'Works 'VBA would appear to recognise this array element as A range as it gives me the Method, Object and property selkection to choose from via intellisense brought in by typing . Dot after the Array elemant[/color]
    [color=lightgreen]'Let arrOut(rws, 1) = arrIn()(rws, 1).Value 'Works'.. because of how VBA “works”, This extra () will ensure that indices are always returned to the resulting array (and not occasionally, for example, arguments ) by any following method or property.[/color]
       [color=lightgreen]'Let arrOut()(rws, 1) = arrIn()(rws, 1).Value 'Works but Rory said it aint ever needed on the LHS,  so it aint[/color]
    [color=lightgreen]'Let arrOut(rws, 1) = Left(arrIn(rws, 1).Value, 4) 'Even A function on the RHS of the = is accepted Here. So again for a non dynamic Array it is not relying on what the function to "define" the type[/color]
    [color=blue]Let[/color] arrOut(rws, 1) = Left(arrIn()(rws, 1).Value, 4) [color=lightgreen]'Works[/color]
      'Let arrOut()(rws, 1) = Left(arrIn()(rws, 1).Value, 4) 'Works
    [color=blue]Next[/color] rws
[color=lightgreen]'         Possibility to Note here:          Dim IntermediateArray() [color=blue]As[/color] Range 'Variant  'Note RoryA Post #2You can only assign one array to another directly (i.e. without looping) if the destination array is dynamic AND THE TWO ARRAYS ARE THE SAME TYPE.[/color]
[color=lightgreen]'                                          '  ReDim IntermediateArray(sr To lr, 1 To 1)'THIS Line Will NOT Work: RoryA Post #2 http://www.excelforum.com/excel-new-users-basics/1058406-range-dimensioning-range-and-value-referencing-and-referring-to-arrays.html    - You can only assign one array to another directly (i.e. without looping) if the destination array is dynamic[/color]
[color=lightgreen]'                                            Let IntermediateArray() = arrIn()[/color]
 [color=blue]Let[/color] RngD.Resize(lr - sr - EmtpyInArrIndiciesCount + 1, 1).Value = arrOut() [color=lightgreen]'This is the typical allowed one liner to give values of a Range the values in an  Array (VBA does not allow this one liner in any way for assigning the ranges. There is no way of getting over having to paste each Range Object in a loop. 'The extra size corrections prevents a NoValue error placed in last cell if trying to assign to indicies that are not there[/color]
 
[color=lightgreen]''        'Long winded alternative to give an empty indicie rather than no indicie to prevent6 output error[/color]
[color=lightgreen]''        ' 1)Because we assign the Array using the Value property of a range, the returned array has lower bounds[/color]
[color=lightgreen]''        ' of 1 for each dimension. When we redim it without providing lower bounds explicitly,[/color]
[color=lightgreen]''        ' the redim tries to assign each dimension the default lower bound, which is 0 giving an error.[/color]
[color=lightgreen]''        ' So we need to explicitly provide the lower bounds[/color]
[color=lightgreen]''        ' 2) Only the size of the last dimension can be changed for a non dynamic arrange. We want to change the first.[/color]
[color=lightgreen]''        ' So we do a transpose trick for that problem[/color]
[color=lightgreen]''        ' 3) Preseve ensures we do not loose the info already there.   (Post #11   http://www.mrexcel.com/forum/excel-questions/830139-proper-redim-preserve-syntax-best-practice-2.html#post4049584)[/color]
[color=lightgreen]''        ' 4) Would only be needed if arrOut has only 1 column as the Transpose does some thing wiered .. does not give 1 to 1 back.. gives normal array...just 1 indicie in ()[/color]
[color=lightgreen]'        Dim TempTranspose() [color=blue]As[/color] Variant 'Must be variant as seeing a Function below in a "one Liner" which returns a collection which VBA will always guess as an Array because Rory-a-Romping Archibald said so to me... a few times now!!![/color]
[color=lightgreen]'        Let TempTranspose = Application.WorksheetFunction.Transpose(arrOut) 'This woulöd annoyingly take for example 21 to 23 , 1 to 1   and give back ... 1 to 3   ONLY!![/color]
[color=lightgreen]'        ReDim Preserve arrOut(sr [color=blue]To[/color] lr - EmtpyInArrIndiciesCount, 1 [color=blue]To[/color] 2) 'This  extra bodge 4  '- Seems to be necerssary to make at least bigger than 1 column - goes from for example 21-23, 1 to 1   > Redim Preserve > 21-23, 1 to 2[/color]
[color=lightgreen]'        Let TempTranspose = Application.WorksheetFunction.Transpose(arrOut) 'Important.. transposes, but > is 1 to 2, ... 1 to 3 ... so would appoear always to start at 1[/color]
[color=lightgreen]'        ReDim Preserve TempTranspose(1 To 2, 1 [color=blue]To[/color] lr - sr + EmtpyInArrIndiciesCount) 'This increase from 3 to 4 columns[/color]
[color=lightgreen]'          'ReDim Preserve TempTranspose(1 [color=blue]To[/color] 2, sr To lr)' This will NOT work!![/color]
[color=lightgreen]'        Let TempTranspose = Application.WorksheetFunction.Transpose(TempTranspose) 'We have the increased row size bot are stuck with the convention of rows starting at 1[/color]
[color=lightgreen]'        Re[color=blue]Dim[/color] Preserve TempTranspose(1 To lr - sr + EmtpyInArrIndiciesCount, 1 To 1) 'This is extra bodge 4 Part 2[/color]
[color=lightgreen]'[/color]
'        Let RngD.Value = TempTranspose
 
 [color=blue]End[/color] [color=blue]Sub[/color] [color=lightgreen]'VBAArrayOfRanges1aa[/color]
[color=lightgreen]'[/color]
'
''
[color=blue]Sub[/color] L11_VBAArrayOfRanges1b()
[color=lightgreen]'Loop Range of Ranges. VBA Make Array for Output. Output in a "Output Value One Liner"[/color]
[color=lightgreen]'Typical application requiring seperate loops for the (often differnt sized) input and output arrays[/color]
[color=lightgreen]'Just an extra direct assigniong bit to demonstrate possibillity of assigning a non dynamic array to a dynamic array in one go, noting [color=blue]Dim[/color] characteristics[/color]
 [color=blue]Dim[/color] wksLE [color=blue]As[/color] Worksheet: [color=blue]Set[/color] wksLE = ThisWorkbook.Worksheets("LeftSpeedsEnglish")
 [color=blue]Dim[/color] RngName [color=blue]As[/color] Range, RngD [color=blue]As[/color] Range
 Dim lr [color=blue]As[/color] [color=blue]Long[/color], rws [color=blue]As[/color] [color=blue]Long[/color]
 [color=blue]Let[/color] lr = wksLE.Cells(Rows.Count, 1).End(xlUp).Row
 Dim sr As Long: [color=blue]Let[/color] sr = 21
 [color=blue]Set[/color] RngName = Range("A" & sr & ":A" & lr & ""): [color=blue]Set[/color] RngD = Range("D" & sr & ":D" & lr & "")
 
 Dim arrIn() [color=blue]As[/color] Range [color=lightgreen]'Variant 'In the looping, the Set would appear to be responsible for bringing **Ranges into the Array The variable type remains as defined here: Either a range for [color=blue]As[/color] Range or a Variant Object for As Variant[/color]
 [color=blue]Re[color=blue]Dim[/color][/color] arrIn(sr To lr, 1 To 1) [color=lightgreen]'We must give array a size as we give specific value in a loop. ReDim Must be used rather than Dim as [color=blue]Dim[/color] only takes Numbers not variables[/color]
 
    For rws = sr To lr [color=blue]Step[/color] 1 [color=lightgreen]'Input Array of Ranges[/color]
    [color=lightgreen]'Set arrIn()(rws, 1) = Range("A" & rws & "") 'Does not work, that is to say produces error later####!!!![/color]
    [color=blue]Set[/color] arrIn(rws, 1) = Range("A" & rws & "") [color=lightgreen]'no error later - we are setting, that is to say "making an object, or rather putting? one in an[/color]
    [color=lightgreen]'Set arrIn(rws, 1) = wksLE.Range("A" & rws & "") 'This would be tolerate**[/color]
    [color=blue]Next[/color] rws
   
   
Dim IntermediateArray() As Range [color=lightgreen]'Variant  'Note RoryA Post #2You can only assign one array to another directly (i.e. without looping) if the destination array is dynamic AND THE TWO ARRAYS ARE THE SAME TYPE.[/color]
[color=lightgreen]'                                          '  ReDim IntermediateArray(sr To lr, 1 To 1)'THIS Line Will NOT Work: RoryA Post #2 http://www.excelforum.com/excel-new-users-basics/1058406-range-dimensioning-range-and-value-referencing-and-referring-to-arrays.html    - You can only assign one array to another directly (i.e. without looping) if the destination array is dynamic[/color]
[color=blue]Let[/color] IntermediateArray() = arrIn() [color=lightgreen]'  ......and the output held in the Array is Variant type and is an OBJECT of the sort like a Range. (This compares with a similar code utilising An Array of Ranges rather than the MicrosoftScriptimeRuntimeDictionary. (In the Array of Ranges case we could Dim as Range or Variant here. - Important however in that case is that the Dynamic IntermediateArray() Array and the (in that Array of Ranges case non dynamic) arrIn() Array are of the same type. - Either both Range to return an Array of element Type Range or both Variant to Return an Array of element Type Of Objects of the Range Sort : - RoryA . You can only assign one array to another directly (i.e. without looping....... and the two arrays are the same type. http://www.excelforum.com/excel-new-users-basics/1058406-range-dimensioning-range-and-value-referencing-and-referring-to-arrays.html[/color]
 
 
 Dim arrOut() As [color=blue]String[/color] [color=lightgreen]'We can use string as in the looping below as we are not relying on (/seeing) a range object to rturn us an array of values.[/color]
 [color=blue]ReDim[/color] arrOut(sr To lr, 1 To 1) [color=lightgreen]'Antoher way to look at it is to say we have a fixed, rather than dynamiy array, and as VBA does not allow a direct assigning one liner in this case it is also not necerssarily expecting to see an object. [color=blue]For[/color] Let it is likely to expect to see some value, and for Set an object (Would expect an Range Object if indicies of arrOut were so defined by arrOut() As String initially[/color]
 
    For rws = sr To lr [color=blue]Step[/color] 1 [color=lightgreen]'Input Array of Ranges[/color]
    [color=lightgreen]'Let arrOut(rws, 1) = IntermediateArray(rws, 1).Value 'VBA would appear to recognise this array element as A range as it gives me the Method, Object and property selkection to choose from via intellisense brought in by typing . Dot after the Array elemant[/color]
[color=lightgreen]'    Let arrOut(rws, 1) = IntermediateArray(rws, 1).Value'####here comes the error by replaceing Set arrIn(rws, 1) with Set arrIn()(rws, 1) or in the following similar lines[/color]
[color=lightgreen]'    Let arrOut(rws, 1) = IntermediateArray()(rws, 1).Value.. because of how VBA “works”, This extra () will ensure that indices are always returned to the resulting array (and not occasionally, for example, arguments ) by any following method or property.[/color]
[color=lightgreen]'    Let arrOut()(rws, 1) = IntermediateArray(rws, 1).Value'Works but Rory said it aint ever needed on the LHS,  so it aint[/color]
[color=lightgreen]'    Let arrOut()(rws, 1) = IntermediateArray()(rws, 1).Value'Works but Rory said it aint ever needed on the LHS,  so it aint[/color]
[color=lightgreen]'    Let arrOut(rws, 1) = Left(IntermediateArray(rws, 1).Value, 4) 'Even A function on the RHS of the = is accepted Here. So again for a non dynamic Array it is not relying on what the function to "define" the type[/color]
[color=lightgreen]'    Let arrOut()(rws, 1) = Left(IntermediateArray(rws, 1).Value, 4)[/color]
    [color=lightgreen]'Let arrOut()(rws, 1) = Left(IntermediateArray()(rws, 1).Value, 4)[/color]
    [color=blue]Let[/color] arrOut(rws, 1) = Left(IntermediateArray()(rws, 1).Value, 4)
    [color=blue]Next[/color] rws
   
 [color=blue]Let[/color] RngD.Value = arrOut() [color=lightgreen]'This is the typical allowed one liner to give values of a Range the valiues in an  Array (VBA does not allow this one liner in any way for assigning the ranges. There is no wy of getting over having to paste each Range Object in in a loop.[/color]
 
 [color=blue]End[/color] [color=blue]Sub[/color] [color=lightgreen]'VBAArrayOfRanges1b[/color]
 
 
[color=lightgreen]'[/color]
 '
'
[color=blue]Sub[/color] L12_VBAArrayOfRanges2()
[color=lightgreen]'Loop Range of Ranges. VBA Make Array for Output. Output in a "Output Value One Liner"[/color]
[color=lightgreen]'less typical application where any workings can be done within one loop and Input and Output arrays may be similarly sized[/color]
 [color=blue]Dim[/color] wksLE [color=blue]As[/color] Worksheet: [color=blue]Set[/color] wksLE = ThisWorkbook.Worksheets("LeftSpeedsEnglish")
 [color=blue]Dim[/color] RngName [color=blue]As[/color] Range, RngD [color=blue]As[/color] Range
 [color=blue]Dim[/color] lr [color=blue]As[/color] [color=blue]Long[/color], rws [color=blue]As[/color] [color=blue]Long[/color]
 [color=blue]Let[/color] lr = wksLE.Cells(Rows.Count, 1).End(xlUp).Row
 [color=blue]Dim[/color] sr [color=blue]As[/color] Long: [color=blue]Let[/color] sr = 21
 [color=blue]Set[/color] RngName = Range("A" & sr & ":A" & lr & ""): [color=blue]Set[/color] RngD = Range("D" & sr & ":D" & lr & "")
 
 [color=blue]Dim[/color] arrIn()  [color=blue]As[/color] Range, arrOut() [color=blue]As[/color] [color=blue]String[/color] [color=lightgreen]'[/color]
 [color=blue]ReDim[/color] arrIn(sr [color=blue]To[/color] lr, 1 [color=blue]To[/color] 1): [color=blue]ReDim[/color] arrOut(sr [color=blue]To[/color] lr, 1 [color=blue]To[/color] 1)
    [color=blue]For[/color] rws = sr [color=blue]To[/color] lr [color=blue]Step[/color] 1 [color=lightgreen]'Input Array of Ranges[/color]
    [color=blue]Set[/color] arrIn(rws, 1) = Range("A" & rws & "")
    [color=blue]Let[/color] arrOut(rws, 1) = Left(arrIn()(rws, 1).Value, 4) [color=lightgreen]'.. because of how VBA “works”, This extra () will ensure that indices are always returned to the resulting array (and not occasionally, for example, arguments ) by any following method or property. It "works" for Let on LHS also (but not for Set in the case of similar line involving Ranges..)..But Rory thinks it would never be needed there.[/color]
    [color=blue]Next[/color] rws
 
 [color=blue]Let[/color] RngD.Value = arrOut()
 
[color=blue]End[/color] [color=blue]Sub[/color] [color=lightgreen]'VBAArrayOfRanges2[/color]
 
 
[color=blue]Sub[/color] L13_RangeObjectCapture()
[color=lightgreen]'The entire range is captured as One Range Object and its Value2 values accesed and used[/color]
[color=lightgreen]'then as before VBA Make Array for Output. Output in a "Output Value One Liner"[/color]
 [color=blue]Dim[/color] wksLE [color=blue]As[/color] Worksheet: [color=blue]Set[/color] wksLE = ThisWorkbook.Worksheets("LeftSpeedsEnglish")
 [color=blue]Dim[/color] RngName [color=blue]As[/color] Range, RngD [color=blue]As[/color] Range
 [color=blue]Dim[/color] lr [color=blue]As[/color] [color=blue]Long[/color], rws [color=blue]As[/color] [color=blue]Long[/color]
 [color=blue]Let[/color] lr = wksLE.Cells(Rows.Count, 1).End(xlUp).Row
 [color=blue]Dim[/color] sr [color=blue]As[/color] Long: [color=blue]Let[/color] sr = 21
 [color=blue]Set[/color] RngName = Range("A" & sr & ":A" & lr & ""): [color=blue]Set[/color] RngD = Range("D" & sr & ":D" & lr & "")
 
 [color=blue]Dim[/color] CapturedRangeObject [color=blue]As[/color] Range [color=lightgreen]'One Range Object for entire range[/color]
 [color=blue]Set[/color] CapturedRangeObject = RngName [color=lightgreen]'Direct assignmet to existing Dimensioned Array[/color]
 
 Dim arrOut() [color=blue]As[/color] [color=blue]String[/color] [color=lightgreen]'We can use string as in the looping below as we are not relying on (/seeing) a range object to return us an array of values.[/color]
 [color=blue]Re[color=blue]Dim[/color][/color] arrOut(sr To lr, 1 To 1) [color=lightgreen]'Antoher way to look at it is to say we have a fixed, rather than dynamiy array, and as VBA does not allow a direct assigning one liner in this case it is also not necerssarily expecting to see an object. For Let it is likely to expect to see some value, and for Set an object (Would expect an Range Object if indicies of arrOut were so defined by arrOut() As String initially[/color]
 
    [color=blue]For[/color] rws = sr [color=blue]To[/color] lr [color=blue]Step[/color] 1 [color=lightgreen]'Input Array of Ranges[/color]
    [color=lightgreen]'Let arrOut(rws, 1) = CapturedRangeObject.Value2(rws - sr + 1, 1) 'Conventionally the Value2 values are in an Array starting at ( 1, 1) and extending over the two (in this case 1) dimensional array. So a bit of adjusting with the indicies is necerssary[/color]
    [color=lightgreen]'Let arrOut(rws, 1) = Left(CapturedRangeObject.Value2()(rws - sr + 1, 1), 4) ' because of how VBA “works”, This extra () will ensure that indices are always returned to the resulting array (and not occasionally, for example, arguments ) by any following method or property, or passed to any method or property, (In the "bodge subs it is assigned each time to the full object[/color]
    [color=blue]Let[/color] arrOut(rws, 1) = Left(CapturedRangeObject.Value2(rws - sr + 1, 1), 4)
    [color=blue]Next[/color] rws
   
 [color=blue]Let[/color] RngD.Value = arrOut()
 
[color=blue]End[/color] [color=blue]Sub[/color] [color=lightgreen]'RangeObjectCapture()[/color]
 
[color=lightgreen]'[/color]
'
'
[color=blue]Sub[/color] L14_MicrosoftScriptingRuntimeDictionaryRangeOfRangesKeysItems1()
[color=lightgreen]'Similar to the Array of Range ranges, except that the Ranges are held in a full MSRD[/color]
[color=lightgreen]'Lots of interaction with the spreadsheet, including the use of a temporary cell for use of unique key characteristic.[/color]
 [color=blue]Dim[/color] wksLE [color=blue]As[/color] Worksheet: [color=blue]Set[/color] wksLE = ThisWorkbook.Worksheets("LeftSpeedsEnglish")
 [color=blue]Dim[/color] RngName [color=blue]As[/color] Range, RngD [color=blue]As[/color] Range
 [color=blue]Dim[/color] lr [color=blue]As[/color] [color=blue]Long[/color], rws [color=blue]As[/color] [color=blue]Long[/color]
 [color=blue]Let[/color] lr = wksLE.Cells(Rows.Count, 1).End(xlUp).Row
 [color=blue]Dim[/color] sr [color=blue]As[/color] Long: [color=blue]Let[/color] sr = 21
 [color=blue]Set[/color] RngName = Range("A" & sr & ":A" & lr & ""): [color=blue]Set[/color] RngD = Range("D" & sr & ":D" & lr & "")
 
[color=lightgreen]' 1)  'Part 1b: Setting up Scriptimg Runtime Stuff-----------------------------[/color]
[color=lightgreen]' Attempting Using the Microsooft Scripting Runtime Dictionary to store Range Objects[/color]
 
[color=lightgreen]'We put the unique values now into a Dictionary for later look up purposes:[/color]
[color=lightgreen]'--requires library reference to MS Scripting Runtime (Early Binding)-[/color]
[color=lightgreen]'        [color=blue]To[/color]ols>>References>>scrolldown and check the box next to Microsoft Scripting Runtime[/color]
[color=lightgreen]'  ..Or crashes at next line.....[/color]
 Dim dicLookupTable [color=blue]As[/color] Scripting.Dictionary [color=lightgreen]'Data held with a unique "Key"or Part Number.[/color]
 [color=blue]Set[/color] dicLookupTable = [color=blue]New[/color] Scripting.Dictionary
[color=lightgreen]' 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.[/color]
[color=lightgreen]'        Dim dicLookupTable As Object[/color]
[color=lightgreen]'        Set dicLookupTable = CreateObject("Scripting.Dictionary")[/color]
[color=lightgreen]' Late Binding is better when sharing files as I am here. Early Binding has the advantage that Excel intellisense[/color]
[color=lightgreen]' will then work for the Microsoft Scripüting Runtime stuff and give you suggestions after you type the .dot thing[/color]
 
     dicLookupTable.CompareMode = vbTextCompare [color=lightgreen]'Not quite sure wot this does yet[/color]
 
[color=lightgreen]'.  A Dictionary in VBA is a collection of objects :you can store all kinds of things in it.[/color]
[color=lightgreen]'.  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.[/color]
[color=lightgreen]'.  (Although the Dictionary has not been designed for that purpose it's a nice side effect.)[/color]
 
[color=lightgreen]'End of Part 1b initial set up Of Scripting Runtime------------------------[/color]
 
 [color=lightgreen]'[color=blue]Dim[/color] j As Long ', i [color=blue]As[/color] Long  'LoopBoundVariableCounts used in looping here and at end-----[/color]
 [color=blue]Dim[/color] TempCell [color=blue]As[/color] Range: [color=blue]Set[/color] TempCell = wksLE.Cells(1, Columns.Count): [color=blue]Dim[/color] TempCellOffset [color=blue]As[/color] [color=blue]Long[/color]: [color=blue]Let[/color] TempCellOffset = 0 [color=lightgreen]'We choose a cell (or through the later use of the offset a column) to use for Duplicate or Empty cells. We use the last column in the sheet. (This is genarally a good practice as it will not effect attempts with .End(XltoLeft) to find last column[/color]
 [color=lightgreen]'2a) Part2a) Looping to put Range Objects in MRSD[/color]
    [color=lightgreen]'For i = StartColumnTableOutput [color=blue]To[/color] LastColumnTableOutput Step 1[/color]
        [color=blue]For[/color] rws = sr To lr [color=blue]Step[/color] 1
          [color=blue]If[/color] wksLE.Cells(rws, 1).Value <> "" [color=blue]Then[/color] [color=lightgreen]'If cell is not empty then...[/color]
               [color=blue]If[/color] [color=blue]Not[/color] dicLookupTable.Exists(wksLE.Cells(rws, 1).Value) [color=blue]Then[/color] [color=lightgreen]'check that the unique value does not already exist. ##NOTE[/color]
                  dicLookupTable.Add wksLE.Cells(rws, 1).Value, wksLE.Cells(rws, 1) [color=lightgreen]'it is easier to understand as well as kind of explicit the first argument does a CStr and the Second Takes anything[/color]
               [color=blue]Else[/color] [color=lightgreen]'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[/color]
               [color=blue]Let[/color] TempCellOffset = TempCellOffset + 1
               [color=blue]Let[/color] TempCell.Offset(TempCellOffset, 0).Value = "Duplicate at   " & rws & " | " & 1 & ""
               wksLE.Cells(rws, 1).Interior.Color = 10987519
               dicLookupTable.Add TempCell.Offset(TempCellOffset, 0).Value, wksLE.Cells(rws, 1) [color=lightgreen]'In case of duplicate we need a unique key, but we stillinclude the Duplicate Range[/color]
               [color=blue]End[/color] [color=blue]If[/color]
           [color=blue]Else[/color] [color=lightgreen]'Case r an empty cell - inform of empty cell by writing message in that cell via the Tempory cell[/color]
           [color=blue]Let[/color] TempCellOffset = TempCellOffset + 1 [color=lightgreen]'Go to next free tempory cell in tempory column[/color]
           [color=blue]Let[/color] TempCell.Offset(TempCellOffset, 0).Value = "Empty Cell at   " & rws & " | " & 1 & ""
           dicLookupTable.Add TempCell.Offset(TempCellOffset, 0).Value, TempCell.Offset(TempCellOffset, 0)
           [color=blue]End[/color] [color=blue]If[/color]
        [color=blue]Next[/color] rws
    [color=lightgreen]'Next i[/color]
'End Part 2-----------------------------------------------------------
 
 [color=lightgreen]'3) Part 3)--transfer range objects from dictionary to array of ranges in one go, typical Array assignment "One Liner" - The quick way to place data into an array is to dimension a variable ( for example rResults ) ....>>[/color]
 Dim IntermediateArray() As [color=blue]Variant[/color] [color=lightgreen]'... [color=blue]As[/color] a Variant and then the "Let IntermediateArray  = " code line Using a variant allows BOTH .-1) for capturing Objects, text, numbers, blanks  errors etc. from those cells and also 2) allows rResults to be an array variable.....[/color]
 [color=blue]Let[/color] IntermediateArray() = dicLookupTable.Items() [color=lightgreen]'... In this case it will also accept us quasi pre - defining as Array with the pair of parentheses IntermediateArray()[/color]
 [color=lightgreen]'End part 3)--- NOTE: this gives automatically the 0 to _ convention in IntermediateArray Array!.        >>>.....and the output held in the Array is Variant type and is an OBJECT of the sort like a Range. (This compares with a similar code utilising An Array of Ranges rather than the MicrosoftScriptimeRuntimeDictionary. (In the Array of Ranges case we could [color=blue]Dim[/color] as Range or Variant here. - Important however in that case is that the Dynamic IntermediateArray() Array and the (in that Array of Ranges case non dynamic) arrIn() Array are of the same type. - Either both Range to return an Array of element Type Range or both Variant to Return an Array of element Type Of Objects of the Range Sort : - RoryA . You can only assign one array to another directly (i.e. without looping....... and the two arrays are the same type. http://www.excelforum.com/excel-new-users-basics/1058406-range-dimensioning-range-and-value-referencing-and-referring-to-arrays.html[/color]
 
 Dim arrOut() As [color=blue]String[/color] [color=lightgreen]'We can use string as in the looping below as we are not relying on (/seeing) a range object to rturn us an array of values.[/color]
 [color=blue]Re[color=blue]Dim[/color][/color] arrOut(sr To lr, 1 [color=blue]To[/color] 1) [color=lightgreen]'Antoher way to look at it is to say we have a fixed, rather than dynamiy array, and as VBA does not allow a direct assigning one liner in this case it is also not necerssarily expecting to see an object. For Let it is likely to expect to see some value, and for Set an object (Would expect an Range Object if indicies of arrOut were so defined by arrOut() [color=blue]As[/color] String initially[/color]
 
    [color=blue]For[/color] rws = sr [color=blue]To[/color] lr [color=blue]Step[/color] 1 [color=lightgreen]'Input Array of Ranges[/color]
        [color=lightgreen]'Let arrOut(rws, 1) = IntermediateArray(rws - sr).Value 'VBA would appear to recognise this array element as A range as it gives me the Method, Object and property selkection to choose from via intellisense brought in by typing . Dot after the Array elemant[/color]
[color=lightgreen]'    Let arrOut(rws, 1) = Left(IntermediateArray()(rws - sr).Value, 4) 'Even A function on the RHS of the = is accepted Here. So again for a non dynamic Array it is not relying on what the function to "define" the type[/color]
[color=lightgreen]'    Let arrOut(rws, 1) = Left(dicLookupTable.Items()(rws - sr).Value, 4)[/color]
[color=lightgreen]'    Let arrOut(rws, 1) = Left(dicLookupTable.Keys()(rws - sr), 4)[/color]
[color=lightgreen]'    Let arrOut(rws, 1) = Left(IntermediateArray(rws - sr).Value, 4)[/color]
    [color=blue]Let[/color] arrOut(rws, 1) = Left(dicLookupTable.Items(rws - sr).Value, 4)
[color=lightgreen]'    Let arrOut(rws, 1) = Left(dicLookupTable.Keys(rws - sr), 4)[/color]
    [color=blue]Next[/color] rws
 
 [color=blue]Let[/color] RngD.Value = arrOut()
 [color=lightgreen]'   Let RngD.Value = IntermediateArray() 'This should not do anything.. interestingly gives value from first Cell in RngName,[/color]
 
 [color=blue]Set[/color] dicLookupTable = [color=blue]Nothing[/color] [color=lightgreen]'Genarally good practice to turn these thimgs off. 'May not be needed but to keep program flexible should alterations need it.[/color]
 
[color=blue]End[/color] [color=blue]Sub[/color] [color=lightgreen]'MicrosoftScriptimeRuntimeDictionaryRangeOfRangesKeysItems1()[/color]
 
 
 
 
[color=lightgreen]'[/color]
'
[color=blue]Sub[/color] L15_MicrosoftScriptimeRuntimeDictionaryRangeOfRangesKeys()
[color=lightgreen]'Similar to the Array of Range ranges, except that the Ranges are held in the MSRD Key. Strange but it can!![/color]
[color=lightgreen]'A bit less Lots of interaction with the spreadsheet, as the temp for the unique is not there - we are using the key,[/color]
[color=lightgreen]'so all ranges are unique keys we simply include that duplicateentry, that is to say the output array may be a bit shorter.[/color]
[color=lightgreen]'Also the cell my be empty but the RANGE cannot be="" so for it's "value" VBA writes "Empty" !![/color]
 [color=blue]Dim[/color] wksLE [color=blue]As[/color] Worksheet: [color=blue]Set[/color] wksLE = ThisWorkbook.Worksheets("LeftSpeedsEnglish")
 [color=blue]Dim[/color] RngName [color=blue]As[/color] Range, RngD [color=blue]As[/color] Range
 [color=blue]Dim[/color] lr [color=blue]As[/color] [color=blue]Long[/color], rws [color=blue]As[/color] Long
 [color=blue]Let[/color] lr = wksLE.Cells(Rows.Count, 1).End(xlUp).Row
 [color=blue]Dim[/color] sr [color=blue]As[/color] Long: [color=blue]Let[/color] sr = 21
 [color=blue]Set[/color] RngName = Range("A" & sr & ":A" & lr & ""): [color=blue]Set[/color] RngD = Range("D" & sr & ":D" & lr & "")
 
[color=lightgreen]' 1)  'Part 1b: Setting up Scriptimg Runtime Stuff-----------------------------[/color]
[color=lightgreen]' Attempting Using the Microsoft Scripting Runtime Dictionary to store Range Objects[/color]
 
[color=lightgreen]'We put the unique values now into a Dictionary for later look up purposes:[/color]
[color=lightgreen]'--requires library reference to MS Scripting Runtime (Early Binding)-[/color]
[color=lightgreen]'        [color=blue]To[/color]ols>>References>>scrolldown and check the box next to Microsoft Scripting Runtime[/color]
[color=lightgreen]'  ..Or crashes at next line.....[/color]
 Dim dicLookupTable As Scripting.Dictionary [color=lightgreen]'Data held with a unique "Key"or Part Number.[/color]
 [color=blue]Set[/color] dicLookupTable = [color=blue]New[/color] Scripting.Dictionary
[color=lightgreen]' 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.[/color]
[color=lightgreen]'        Dim dicLookupTable As Object[/color]
[color=lightgreen]'        Set dicLookupTable = CreateObject("Scripting.Dictionary")[/color]
[color=lightgreen]' Late Binding is better when sharing files as I am here. Early Binding has the advantage that Excel intellisense[/color]
[color=lightgreen]' will then work for the Microsoft Scripüting Runtime stuff and give you suggestions after you type the .dot thing[/color]
 
     dicLookupTable.CompareMode = vbTextCompare [color=lightgreen]'Not quite sure wot this does yet[/color]
 
[color=lightgreen]'.  A Dictionary in VBA is a collection of objects :you can store all kinds of things in it.[/color]
[color=lightgreen]'.  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.[/color]
[color=lightgreen]'.  (Although the Dictionary has not been designed for that purpose it's a nice side effect.)[/color]
 
[color=lightgreen]'End of Part 1b initial set up Of Scripting Runtime------------------------[/color]
 
   [color=lightgreen]'Dim j As Long ', i As Long  'LoopBoundVariableCounts used in looping here and at end-----[/color]
 [color=lightgreen]'Dim TempCell [color=blue]As[/color] Range: Set TempCell = wksLE.Cells(1, Columns.Count): [color=blue]Dim[/color] TempCellOffset As Long: Let TempCellOffset = 0 'We choose a cell (or through the later use of the offset a column) to use for Duplicate or Empty cells. We use the last column in the sheet. (This is genarally a good practice as it will not effect attempts with .End(XltoLeft) to find last column[/color]
 [color=lightgreen]'2a) Part2a) Looping to put Range Objects in MRSD[/color]
    [color=lightgreen]'For i = StartColumnTableOutput [color=blue]To[/color] LastColumnTableOutput Step 1[/color]
        [color=blue]For[/color] rws = sr To lr [color=blue]Step[/color] 1
           [color=blue]If[/color] wksLE.Cells(rws, 1).Value <> "" [color=blue]Then[/color] [color=lightgreen]'If RANGE is not there...[/color]
[color=lightgreen]'               If Not dicLookupTable.Exists(wksLE.Cells(rws, 1).Value) Then 'check that the unique value does not already exist. ##NOTE[/color]
                  dicLookupTable.Add wksLE.Cells(rws, 1), [color=blue]Nothing[/color] [color=lightgreen]'it is easier to understand as well as kind of explicit the first argument does a CStr and the Second Takes anything[/color]
[color=lightgreen]'               Else 'The key is the Range which is always unique[/color]
[color=lightgreen]'               End If[/color]
           [color=blue]Else[/color] [color=lightgreen]'Case r an empty cell. We habe a choice by virtue of us using Newlr below to do nothing.. or..[/color]
           [color=blue]Let[/color] wksLE.Cells(rws, 1).Value = "Anything" [color=lightgreen]'.. we could have done nothing - for the case of the Let function it does not erro just gives nothing[/color]
           dicLookupTable.Add wksLE.Cells(rws, 1), [color=blue]Nothing[/color] [color=lightgreen]'.. chose here it to give key anyway and..[/color]
           [color=blue]End[/color] [color=blue]If[/color]
        [color=blue]Next[/color] rws
    [color=lightgreen]'Next i[/color]
'End Part 2-----------------------------------------------------------
 
 [color=lightgreen]'3) Part 3)--transfer range objects from dictionary to array of ranges in one go, typical Array assignment "One Liner" - The quick way to place data into an array is to dimension a variable ( for example rResults ) ....>>[/color]
 Dim IntermediateArray() [color=blue]As[/color] [color=blue]Variant[/color] [color=lightgreen]'... [color=blue]As[/color] a Variant and then the "Let IntermediateArray  = " code line Using a variant allows BOTH .-1) for capturing Objects, text, numbers, blanks  errors etc. from those cells and also 2) allows rResults to be an array variable.....[/color]
 [color=blue]Let[/color] IntermediateArray() = dicLookupTable.Keys() [color=lightgreen]'... In this case it will also accept us quasi pre - defining as Array with the pair of parentheses IntermediateArray()[/color]
 [color=lightgreen]'End part 3)--- NOTE: this gives automatically the 0 to _ convention in IntermediateArray Array!.        >>>.....and the output held in the Array is Variant type and is an OBJECT of the sort like a Range. (This compares with a similar code utilising An Array of Ranges rather than the MicrosoftScriptimeRuntimeDictionary. (In the Array of Ranges case we could [color=blue]Dim[/color] as Range or Variant here. - Important however in that case is that the Dynamic IntermediateArray() Array and the (in that Array of Ranges case non dynamic) arrIn() Array are of the same type. - Either both Range to return an Array of element Type Range or both Variant to Return an Array of element Type Of Objects of the Range Sort : - RoryA . You can only assign one array to another directly (i.e. without looping....... and the two arrays are the same type. http://www.excelforum.com/excel-new-users-basics/1058406-range-dimensioning-range-and-value-referencing-and-referring-to-arrays.html[/color]
 
 [color=blue]Dim[/color] Newlr As Long: [color=blue]Let[/color] Newlr = [color=blue]UBound[/color](IntermediateArray(), 1) + sr [color=lightgreen]'This is importent when looping through dicLookupTable.Keys so that for one or more empty cell not given a key we do not try to loop too far[/color]
 Dim arrOut() As [color=blue]String[/color] [color=lightgreen]'We can use string as in the looping below as we are not relying on (/seeing) a range object to rturn us an array of values.[/color]
 [color=blue]ReDim[/color] arrOut(sr To Newlr, 1 To 1) [color=lightgreen]'Antoher way to look at it is to say we have a fixed, rather than dynamiy array, and as VBA does not allow a direct assigning one liner in this case it is also not necerssarily expecting to see an object. For Let it is likely to expect to see some value, and for Set an object (Would expect an Range Object if indicies of arrOut were so defined by arrOut() As String initially. We could leave Nerlr as lr - doesn't matter if output array is bit too big[/color]
 
    [color=blue]For[/color] rws = sr To Newlr [color=blue]Step[/color] 1 [color=lightgreen]'Input Array of Ranges[/color]
    [color=lightgreen]'Let arrOut(rws, 1) = IntermediateArray(rws - sr).Value 'VBA would appear to recognise this array element as A range as it gives me the Method, Object and property selkection to choose from via intellisense brought in by typing . Dot after the Array elemant[/color]
    [color=lightgreen]'Let arrOut(rws, 1) = Left(IntermediateArray(rws - sr).Value, 4) 'Even A function on the RHS of the = is accepted Here. So again for a non dynamic Array it is not relying on what the function to "define" the type[/color]
[color=lightgreen]'    Let arrOut(rws, 1) = Left(dicLookupTable.Keys(rws - sr).Value, 4) 'Remember.. write in .Value - Do not rely on the implicit!![/color]
    [color=blue]Let[/color] arrOut(rws, 1) = Left(dicLookupTable.Keys()(rws - sr).Value, 4)
    [color=blue]Next[/color] rws
 
 [color=blue]Let[/color] RngD.Value = arrOut()
 
 [color=blue]Set[/color] dicLookupTable = [color=blue]Nothing[/color] [color=lightgreen]'Genarally good practice to turn these thimgs off. 'May not be needed but to keep program flexible should alterations need it.[/color]
 
[color=blue]End[/color] [color=blue]Sub[/color] [color=lightgreen]'MicrosoftScriptimeRuntimeDictionaryRangeOfRangesKeys()[/color]
 
[color=lightgreen]'[/color]
'
'
 
'
 
 
 
 [color=lightgreen]'[/color]
[color=blue]Sub[/color] L18_MicrosoftScriptimeRuntimeDictionaryRangeObjectKeysItemsBodge1()
[color=lightgreen]'Similar to the Array of Range ranges, except that the Ranges are held in a full MSRD[/color]
[color=lightgreen]'Less interaction with the spreadsheet, just the use of a temporary cell for use of unique key characteristic.[/color]
[color=lightgreen]'Hopefully can get all information from that one big Range..Don't know for sure yet...Post #11 http://www.mrexcel.com/forum/excel-questions/832103-using-microsoft-scripting-runtime-dictionary-store-then-retrieve-range-objects-2.html[/color]
[color=lightgreen]'So Temporárilly put entire CapturedRangeObject in each item (except for duplicates and empty cells, which for now still access the Spreadsheet[/color]
[color=lightgreen]'This requires extra Bodges in Emptys and Duplicates and explanations of new Explicits here Post #14 - post #19  http://www.mrexcel.com/forum/excel-questions/832103-using-microsoft-scripting-runtime-dictionary-store-then-retrieve-range-objects-2.html[/color]
 [color=blue]Dim[/color] wksLE [color=blue]As[/color] Worksheet: [color=blue]Set[/color] wksLE = ThisWorkbook.Worksheets("LeftSpeedsEnglish")
 [color=blue]Dim[/color] RngName [color=blue]As[/color] Range, RngD [color=blue]As[/color] Range
 [color=blue]Dim[/color] lr [color=blue]As[/color] [color=blue]Long[/color], rws [color=blue]As[/color] [color=blue]Long[/color]
 [color=blue]Let[/color] lr = wksLE.Cells(Rows.Count, 1).End(xlUp).Row
 [color=blue]Dim[/color] sr [color=blue]As[/color] Long: [color=blue]Let[/color] sr = 21
 [color=blue]Set[/color] RngName = Range("A" & sr & ":A" & lr & ""): [color=blue]Set[/color] RngD = Range("D" & sr & ":D" & lr & "")
 
[color=lightgreen]' 1)  'Part 1b: Setting up Scriptimg Runtime Stuff-----------------------------[/color]
[color=lightgreen]' Attempting Using the Microsooft Scripting Runtime Dictionary to store Range Objects[/color]
 
[color=lightgreen]'We put the unique values now into a Dictionary for later look up purposes:[/color]
[color=lightgreen]'--requires library reference to MS Scripting Runtime (Early Binding)-[/color]
[color=lightgreen]'        Tools>>References>>scrolldown and check the box next to Microsoft Scripting Runtime[/color]
[color=lightgreen]'  ..Or crashes at next line.....[/color]
 [color=blue]Dim[/color] dicLookupTable [color=blue]As[/color] Scripting.Dictionary [color=lightgreen]'Data held with a unique "Key"or Part Number.[/color]
 [color=blue]Set[/color] dicLookupTable = [color=blue]New[/color] Scripting.Dictionary
[color=lightgreen]' 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.[/color]
[color=lightgreen]'        Dim dicLookupTable As Object[/color]
[color=lightgreen]'        Set dicLookupTable = CreateObject("Scripting.Dictionary")[/color]
[color=lightgreen]' Late Binding is better when sharing files as I am here. Early Binding has the advantage that Excel intellisense[/color]
[color=lightgreen]' will then work for the Microsoft Scripüting Runtime stuff and give you suggestions after you type the .dot thing[/color]
 
     dicLookupTable.CompareMode = vbTextCompare [color=lightgreen]'Not quite sure wot this does yet[/color]
 
[color=lightgreen]'.  A Dictionary in VBA is a collection of objects :you can store all kinds of things in it.[/color]
[color=lightgreen]'.  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.[/color]
[color=lightgreen]'.  (Although the Dictionary has not been designed for that purpose it's a nice side effect.)[/color]
 
[color=lightgreen]'End of Part 1b initial set up Of Scripting Runtime------------------------[/color]
 
 [color=lightgreen]'Dim j As Long ', i [color=blue]As[/color] Long  'LoopBoundVariableCounts used in looping here and at end-----[/color]
 [color=blue]Dim[/color] TempCell [color=blue]As[/color] Range: [color=blue]Set[/color] TempCell = wksLE.Cells(1, Columns.Count): [color=blue]Dim[/color] TempCellOffset [color=blue]As[/color] [color=blue]Long[/color]: [color=blue]Let[/color] TempCellOffset = 0 [color=lightgreen]'We choose a cell (or through the later use of the offset a column) to use for Duplicate or Empty cells. We use the last column in the sheet. (This is genarally a good practice as it will not effect attempts with .End(XltoLeft) to find last column[/color]
 
 [color=lightgreen]'2a) Direct Array  Capture[/color]
 
 [color=blue]Dim[/color] CapturedRangeObject [color=blue]As[/color] Range [color=lightgreen]'One Range Object for entire range[/color]
 [color=blue]Set[/color] CapturedRangeObject = RngName [color=lightgreen]'Direct assignmet to existing Dimensioned Array[/color]
 
 
 [color=lightgreen]'2b) Part2b) Looping to put Range Objects in MRSD[/color]
    [color=lightgreen]'For i = StartColumnTableOutput To LastColumnTableOutput Step 1[/color]
        [color=blue]For[/color] rws = sr [color=blue]To[/color] lr [color=blue]Step[/color] 1
          [color=blue]If[/color] CapturedRangeObject.Value2(rws - sr + 1, 1) <> "" [color=blue]Then[/color] [color=lightgreen]'If cell is not empty then...[/color]
               [color=blue]If[/color] [color=blue]Not[/color] dicLookupTable.Exists(wksLE.Cells(rws, 1).Value) [color=blue]Then[/color] [color=lightgreen]'check that the unique value does not already exist. ##NOTE[/color]
                  dicLookupTable.Add CapturedRangeObject.Value2(rws - sr + 1, 1), CapturedRangeObject [color=lightgreen]'it is easier to understand as well as kind of explicit the first argument does a CStr and the Second Takes anything[/color]
               [color=blue]Else[/color] [color=lightgreen]'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[/color]
               [color=blue]Let[/color] TempCellOffset = TempCellOffset + 1
               [color=blue]Let[/color] TempCell.Offset(TempCellOffset, 0).Value = "Duplicate at   " & rws & " | " & 1 & ""
               wksLE.Cells(rws, 1).Interior.Color = 10987519
               [color=lightgreen]'dicLookupTable.Add TempCell.Offset(TempCellOffset, 0).Value, wksLE.Cells(rws, 1) 'In case of duplicate we need a unique key, but we stillinclude the Duplicate Range[/color]
               dicLookupTable.Add TempCell.Offset(TempCellOffset, 0).Value, CapturedRangeObject [color=lightgreen]'Must bodge also this line or problem that for my Temp Range has a Value2 of NOT an array()[/color]
               [color=blue]End[/color] [color=blue]If[/color]
           [color=blue]Else[/color] [color=lightgreen]'Case r an empty cell - inform of empty cell by writing message in that cell via the Tempory cell[/color]
           [color=blue]Let[/color] TempCellOffset = TempCellOffset + 1 [color=lightgreen]'Go to next free tempory cell in tempory column[/color]
           [color=blue]Let[/color] TempCell.Offset(TempCellOffset, 0).Value = "Empty Cell at   " & rws & " | " & 1 & ""
           [color=lightgreen]'dicLookupTable.Add TempCell.Offset(TempCellOffset, 0).Value, TempCell.Offset(TempCellOffset, 0)[/color]
           dicLookupTable.Add TempCell.Offset(TempCellOffset, 0).Value, CapturedRangeObject [color=lightgreen]'Must bodge also this line or problem that for my Temp Range has a Value2 of NOT an array()[/color]
           [color=blue]End[/color] [color=blue]If[/color]
        [color=blue]Next[/color] rws
    [color=lightgreen]'Next i[/color]
 
 
   
   
[color=lightgreen]'End Part 2-----------------------------------------------------------[/color]
 
 [color=lightgreen]'3) Part 3)--transfer range objects from dictionary to array of ranges in one go, typical Array assignment "One Liner" - The quick way to place data into an array is to dimension a variable ( for example rResults ) ....>>[/color]
 [color=blue]Dim[/color] IntermediateArray() As [color=blue]Variant[/color] [color=lightgreen]'... [color=blue]As[/color] a Variant and then the "Let rResults  = " code line Using a variant allows BOTH .-1) for capturing Objects, text, numbers, blanks  errors etc. from those cells and also 2) allows rResults to be an array variable.....[/color]
 [color=blue]Let[/color] IntermediateArray() = dicLookupTable.Items() [color=lightgreen]'... In this case it will also accept us quasi pre - defining as Array with the pair of parentheses IntermediateArray()[/color]
 [color=lightgreen]'End part 3)--- NOTE: this gives automatically the 0 to _ convention in IntermediateArray Array!.        >>>.....and the output held in the Array is Variant type and is an OBJECT of the sort like a Range. (This compares with a similar code utilising An Array of Ranges rather than the MicrosoftScriptimeRuntimeDictionary. (In the Array of Ranges case we could Dim as Range or Variant here. - Important however in that case is that the Dynamic IntermediateArray() Array and the (in that Array of Ranges case non dynamic) arrIn() Array are of the same type. - Either both Range to return an Array of element Type Range or both Variant to Return an Array of element Type Of Objects of the Range Sort : - RoryA . You can only assign one array to another directly (i.e. without looping....... and the two arrays are the same type. http://www.excelforum.com/excel-new-users-basics/1058406-range-dimensioning-range-and-value-referencing-and-referring-to-arrays.html[/color]
 
[color=lightgreen]'4) Part 4)---Produce output array by looping[/color]
 [color=blue]Dim[/color] arrOut() As [color=blue]String[/color] [color=lightgreen]'We can use string as in the looping below as we are not relying on (/seeing) a range object to rturn us an array of values.[/color]
 [color=blue]ReDim[/color] arrOut(sr [color=blue]To[/color] lr, 1 [color=blue]To[/color] 1) [color=lightgreen]'Antoher way to look at it is to say we have a fixed, rather than dynamiy array, and as VBA does not allow a direct assigning one liner in this case it is also not necerssarily expecting to see an object. For Let it is likely to expect to see some value, and for Set an object (Would expect an Range Object if indicies of arrOut were so defined by arrOut() [color=blue]As[/color] String initially[/color]
   
    [color=blue]For[/color] rws = sr To lr [color=blue]Step[/color] 1 [color=lightgreen]'Input Array of Ranges  Note ## >> ’.. because of how VBA “works”, This extra () will ensure that indices are always returned to the resulting array (and not occasionally, for example, arguments ) by any following method or property, or passed to any method or property[/color]
    [color=lightgreen]'Let arrOut(rws, 1) = CapturedRangeObject.Value2(rws - sr + 1, 1) 'Works.. but  ...[/color]
    [color=lightgreen]'Let arrOut(rws, 1) = CapturedRangeObject.Value2()(rws - sr + 1, 1) '...better ##[/color]
    [color=lightgreen]'Let arrOut(rws, 1) = dicLookupTable.Items(rws - sr).Value2(rws - sr + 1, 1) 'Wont work[/color]
    [color=lightgreen]'Let arrOut(rws, 1) = dicLookupTable.Items(rws - sr).Value2()(rws - sr + 1, 1) 'Works ##[/color]
    [color=lightgreen]'Let arrOut(rws, 1) = IntermediateArray(rws - sr).Value2(rws - sr + 1, 1) 'Won't work[/color]
    [color=lightgreen]'Let arrOut(rws, 1) = IntermediateArray(rws - sr).Value2()(rws - sr + 1, 1) 'Works ##[/color]
    [color=blue]Let[/color] arrOut(rws, 1) = Left(dicLookupTable.Items(rws - sr).Value2()(rws - sr + 1, 1), 4) [color=lightgreen]'Works ##[/color]
    'Let arrOut(rws, 1) = Left(IntermediateArray(rws - sr).Value2()(rws - sr + 1, 1), 4) 'Works ##
    [color=blue]Next[/color] rws
 
[color=lightgreen]'End Part 4-----------------------------------[/color]
 
 [color=blue]Let[/color] RngD.Value = arrOut()
 
 [color=blue]Set[/color] dicLookupTable = [color=blue]Nothing[/color] [color=lightgreen]'Genarally good practice to turn these thimgs off. 'May not be needed but to keep program flexible should alterations need it.[/color]
 
[color=blue]End[/color] [color=blue]Sub[/color] [color=lightgreen]'MicrosoftScriptimeRuntimeDictionaryRangeObjectKeysItemsBodge1()[/color]
 
[color=lightgreen]'[/color]
'
'
'
'
'
 
 
 
[color=lightgreen]'[/color]
[color=blue]Sub[/color] L19_MicrosoftScriptimeRuntimeDictionaryRangeObjectKeysItemsBodge2()
[color=lightgreen]'Similar to the Array of Range ranges, except that the Ranges are held in a full MSRD[/color]
[color=lightgreen]'Less interaction with the spreadsheet, just the use of a temporary cell for use of unique key characteristic.[/color]
[color=lightgreen]'Hopefully can get all infomation from that one big Range..Don't know for sure yet...Post #11 http://www.mrexcel.com/forum/excel-questions/832103-using-microsoft-scripting-runtime-dictionary-store-then-retrieve-range-objects-2.html[/color]
[color=lightgreen]'So Temporárilly put entire CapturedRangeObject in each item (except for duplicates and empty cells, which for now still access the Spreadsheet[/color]
[color=lightgreen]'This requires extra Bodges in Emptys and Duplicates and explanations of an alternative way to avoid the extra () from last code (MicrosoftScriptimeRuntimeDictionaryRangeObjectKeysItemsBodge2())  Post #14 - post #19  http://www.mrexcel.com/forum/excel-questions/832103-using-microsoft-scripting-runtime-dictionary-store-then-retrieve-range-objects-2.html[/color]
 [color=blue]Dim[/color] wksLE [color=blue]As[/color] Worksheet: [color=blue]Set[/color] wksLE = ThisWorkbook.Worksheets("LeftSpeedsEnglish")
 [color=blue]Dim[/color] RngName [color=blue]As[/color] Range, RngD [color=blue]As[/color] Range
 [color=blue]Dim[/color] lr [color=blue]As[/color] [color=blue]Long[/color], rws [color=blue]As[/color] Long
 [color=blue]Let[/color] lr = wksLE.Cells(Rows.Count, 1).End(xlUp).Row
 [color=blue]Dim[/color] sr [color=blue]As[/color] Long: [color=blue]Let[/color] sr = 21
 [color=blue]Set[/color] RngName = Range("A" & sr & ":A" & lr & ""): [color=blue]Set[/color] RngD = Range("D" & sr & ":D" & lr & "")
 
[color=lightgreen]' 1)  'Part 1b: Setting up Scriptimg Runtime Stuff-----------------------------[/color]
[color=lightgreen]' Attempting Using the Microsooft Scripting Runtime Dictionary to store Range Objects[/color]
 
[color=lightgreen]'We put the unique values now into a Dictionary for later look up purposes:[/color]
[color=lightgreen]'--requires library reference to MS Scripting Runtime (Early Binding)-[/color]
[color=lightgreen]'        Tools>>References>>scrolldown and check the box next to Microsoft Scripting Runtime[/color]
[color=lightgreen]'  ..Or crashes at next line.....[/color]
 [color=blue]Dim[/color] dicLookupTable As Scripting.Dictionary [color=lightgreen]'Data held with a unique "Key"or Part Number.[/color]
 [color=blue]Set[/color] dicLookupTable = [color=blue]New[/color] Scripting.Dictionary
[color=lightgreen]' 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.[/color]
[color=lightgreen]'        Dim dicLookupTable As Object[/color]
[color=lightgreen]'        Set dicLookupTable = CreateObject("Scripting.Dictionary")[/color]
[color=lightgreen]' Late Binding is better when sharing files as I am here. Early Binding has the advantage that Excel intellisense[/color]
[color=lightgreen]' will then work for the Microsoft Scripüting Runtime stuff and give you suggestions after you type the .dot thing[/color]
 
     dicLookupTable.CompareMode = vbTextCompare [color=lightgreen]'Not quite sure wot this does yet[/color]
 
[color=lightgreen]'.  A Dictionary in VBA is a collection of objects :you can store all kinds of things in it.[/color]
[color=lightgreen]'.  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.[/color]
[color=lightgreen]'.  (Although the Dictionary has not been designed for that purpose it's a nice side effect.)[/color]
 
[color=lightgreen]'End of Part 1b initial set up Of Scripting Runtime------------------------[/color]
 
 [color=lightgreen]'Dim j [color=blue]As[/color] Long ', i [color=blue]As[/color] Long  'LoopBoundVariableCounts used in looping here and at end-----[/color]
 [color=blue]Dim[/color] TempCell [color=blue]As[/color] Range: [color=blue]Set[/color] TempCell = wksLE.Cells(1, Columns.Count): [color=blue]Dim[/color] TempCellOffset [color=blue]As[/color] Long: [color=blue]Let[/color] TempCellOffset = 0 [color=lightgreen]'We choose a cell (or through the later use of the offset a column) to use for Duplicate or Empty cells. We use the last column in the sheet. (This is genarally a good practice as it will not effect attempts with .End(XltoLeft) to find last column[/color]
 
 [color=lightgreen]'2a) Direct Array  Capture[/color]
 
 [color=blue]Dim[/color] CapturedRangeObject As Range [color=lightgreen]'One Range Object for entire range[/color]
 [color=blue]Set[/color] CapturedRangeObject = RngName [color=lightgreen]'Direct assignmet to existing Dimensioned Array[/color]
 
 
 [color=lightgreen]'2b) Part2b) Looping to put Range Objects in MRSD[/color]
    [color=lightgreen]'For i = StartColumnTableOutput [color=blue]To[/color] LastColumnTableOutput Step 1[/color]
        [color=blue]For[/color] rws = sr To lr [color=blue]Step[/color] 1
          [color=blue]If[/color] CapturedRangeObject.Value2(rws - sr + 1, 1) <> "" [color=blue]Then[/color] [color=lightgreen]'If cell is not empty then...[/color]
               [color=blue]If[/color] [color=blue]Not[/color] dicLookupTable.Exists(wksLE.Cells(rws, 1).Value) [color=blue]Then[/color] [color=lightgreen]'check that the unique value does not already exist. ##NOTE[/color]
                  dicLookupTable.Add CapturedRangeObject.Value2(rws - sr + 1, 1), CapturedRangeObject [color=lightgreen]'it is easier to understand as well as kind of explicit the first argument does a CStr and the Second Takes anything[/color]
               [color=blue]Else[/color] [color=lightgreen]'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[/color]
               [color=blue]Let[/color] TempCellOffset = TempCellOffset + 1
               [color=blue]Let[/color] TempCell.Offset(TempCellOffset, 0).Value = "Duplicate at   " & rws & " | " & 1 & ""
               wksLE.Cells(rws, 1).Interior.Color = 10987519
               [color=lightgreen]'dicLookupTable.Add TempCell.Offset(TempCellOffset, 0).Value, wksLE.Cells(rws, 1) 'In case of duplicate we need a unique key, but we stillinclude the Duplicate Range[/color]
               dicLookupTable.Add TempCell.Offset(TempCellOffset, 0).Value, CapturedRangeObject [color=lightgreen]'Must bodge also this line or problem that for my Temp Range has a Value2 of NOT an array()[/color]
               [color=blue]End[/color] [color=blue]If[/color]
           [color=blue]Else[/color] [color=lightgreen]'Case r an empty cell - inform of empty cell by writing message in that cell via the Tempory cell[/color]
           [color=blue]Let[/color] TempCellOffset = TempCellOffset + 1 [color=lightgreen]'Go to next free tempory cell in tempory column[/color]
           [color=blue]Let[/color] TempCell.Offset(TempCellOffset, 0).Value = "Empty Cell at   " & rws & " | " & 1 & ""
           [color=lightgreen]'dicLookupTable.Add TempCell.Offset(TempCellOffset, 0).Value, TempCell.Offset(TempCellOffset, 0)[/color]
           dicLookupTable.Add TempCell.Offset(TempCellOffset, 0).Value, CapturedRangeObject [color=lightgreen]'Must bodge also this line or problem that for my Temp Range has a Value2 of NOT an array()[/color]
           [color=blue]End[/color] [color=blue]If[/color]
        [color=blue]Next[/color] rws
    [color=lightgreen]'Next i[/color]
 
 
   
   
[color=lightgreen]'End Part 2-----------------------------------------------------------[/color]
 
 [color=lightgreen]'3) Part 3)--transfer range objects from dictionary to array of ranges in one go, typical Array assignment "One Liner" - The quick way to place data into an array is to dimension a variable ( for example rResults ) ....>>[/color]
 [color=blue]Dim[/color] IntermediateArray() [color=blue]As[/color] [color=blue]Variant[/color] [color=lightgreen]'... [color=blue]As[/color] a Variant and then the "Let rResults  = " code line Using a variant allows BOTH .-1) for capturing Objects, text, numbers, blanks  errors etc. from those cells and also 2) allows rResults to be an array variable.....[/color]
 [color=blue]Let[/color] IntermediateArray() = dicLookupTable.Items() [color=lightgreen]'... In this case it will also accept us quasi pre - defining as Array with the pair of parentheses IntermediateArray()[/color]
 [color=lightgreen]'End part 3)--- NOTE: this gives automatically the 0 to _ convention in rResults Array!.        >>>.....and the output held in the Array is Variant type and is an OBJECT of the sort like a Range. (This compares with a similar code utilising An Array of Ranges rather than the MicrosoftScriptimeRuntimeDictionary. (In the Array of Ranges case we could Dim as Range or Variant here. - Important however in that case is that the Dynamic IntermediateArray() Array and the (in that Array of Ranges case non dynamic) arrIn() Array are of the same type. - Either both Range to return an Array of element Type Range or both Variant to Return an Array of element Type Of Objects of the Range Sort : - RoryA . You can only assign one array to another directly (i.e. without looping....... and the two arrays are the same type. http://www.excelforum.com/excel-new-users-basics/1058406-range-dimensioning-range-and-value-referencing-and-referring-to-arrays.html[/color]
 
[color=lightgreen]'4) Part 4)---Produce output array by looping[/color]
 [color=blue]Dim[/color] vTemp As [color=blue]Variant[/color] [color=lightgreen]'Post from #20   .. return the array to a variable and then reference the elements through that variable, in which case you don't need to worry about the extra () . The usual "[color=blue]To[/color] see an object which returns a field" requirement to be dimensioned as Variant[/color]
 
 [color=blue]Dim[/color] arrOut() As [color=blue]String[/color] [color=lightgreen]'We can use string as in the looping below as we are not relying on (/seeing) a range object to rturn us an array of values.[/color]
 [color=blue]ReDim[/color] arrOut(sr [color=blue]To[/color] lr, 1 To 1) [color=lightgreen]'Antoher way to look at it is to say we have a fixed, rather than dynamiy array, and as VBA does not allow a direct assigning one liner in this case it is also not necerssarily expecting to see an object. For Let it is likely to expect to see some value, and for Set an object (Would expect an Range Object if indicies of arrOut were so defined by arrOut() As String initially[/color]
   
    [color=blue]For[/color] rws = sr To lr [color=blue]Step[/color] 1 [color=lightgreen]'Input Array of Ranges  Note ## >> ’.. because of how VBA “works”, This extra () will ensure that indices are always returned to the resulting array (and not occasionally, for example, arguments ) by any following method or property, or passed to any method or property, (In the "bodge it is assigned each time to the full object[/color]
 
[color=lightgreen]'    Let arrOut(rws, 1) = CapturedRangeObject.Value2(rws - sr + 1, 1) 'Works.. but  ...[/color]
[color=lightgreen]'    Let arrOut(rws, 1) = CapturedRangeObject.Value2()(rws - sr + 1, 1) '...better ##[/color]
[color=lightgreen]'    'Let arrOut(rws, 1) = dicLookupTable.Items(rws - sr).Value2(rws - sr + 1, 1) 'Wont work[/color]
[color=lightgreen]'    Let arrOut(rws, 1) = dicLookupTable.Items(rws - sr).Value2()(rws - sr + 1, 1) 'Works ##[/color]
    [color=blue]Let[/color] vTemp = dicLookupTable.Items(rws - sr).Value2 [color=lightgreen]'Works vTemp is Array of variants values, a Data fild[/color]
    [color=lightgreen]'Let vTemp = dicLookupTable.Items(rws - sr).Value2() 'Works also!!![/color]
    [color=lightgreen]'Let vTemp = IntermediateArray(rws - sr).Value2 'Works vTemp is Array of variants values, a Data fild[/color]
    [color=lightgreen]'Let vTemp = IntermediateArray(rws - sr).Value2()'Also works!!![/color]
   
    [color=lightgreen]'Let arrOut(rws, 1) = vTemp(rws - sr + 1, 1) 'Works[/color]
[color=lightgreen]'    'Let arrOut(rws, 1) = IntermediateArray(rws - sr).Value2(rws - sr + 1, 1) 'Won't work[/color]
[color=lightgreen]'    Let arrOut(rws, 1) = IntermediateArray(rws - sr).Value2()(rws - sr + 1, 1) 'Works ##[/color]
[color=lightgreen]'    Let arrOut(rws, 1) = Left(dicLookupTable.Items(rws - sr).Value2()(rws - sr + 1, 1), 4) 'Works ##[/color]
[color=lightgreen]'    Let arrOut(rws, 1) = Left(IntermediateArray(rws - sr).Value2()(rws - sr + 1, 1), 4) 'Works ##[/color]
    [color=blue]Let[/color] arrOut(rws, 1) = Left(vTemp(rws - sr + 1, 1), 4) [color=lightgreen]'Works[/color]
    [color=blue]Next[/color] rws
 
[color=lightgreen]'End Part 4-----------------------------------[/color]
 
 [color=blue]Let[/color] RngD.Value = arrOut()
 
 [color=blue]Set[/color] dicLookupTable = [color=blue]Nothing[/color] [color=lightgreen]'Genarally good practice to turn these thimgs off. 'May not be needed but to keep program flexible should alterations need it.[/color]
 
[color=blue]End[/color] [color=blue]Sub[/color] [color=lightgreen]'MicrosoftScriptimeRuntimeDictionaryRangeObjectKeysItemsBodge2()[/color]



And Pen ultimately - just this once the Speed test Program I wrote or rather stole. – Detailed discussions in these Threads
http://www.mrexcel.com/forum/excel-...p-visual-basic-applications-code-vlookup.html
http://www.mrexcel.com/forum/excel-...atch-criteria-code-alternative-looping-2.html


Code:
[color=blue]Option[/color] [color=blue]Explicit[/color]
[color=lightgreen]' next 2 lines needed for 'Charley Williams Micro Timer Code[/color]
[color=blue]Private[/color] [color=blue]Declare[/color] [color=blue]Function[/color] getFrequency [color=blue]Lib[/color] "kernel32" Alias "QueryPerformanceFrequency" (cyFrequency [color=blue]As[/color] [color=blue]Currency[/color]) [color=blue]As[/color] [color=blue]Long[/color]
[color=blue]Private[/color] [color=blue]Declare[/color] [color=blue]Function[/color] getTickCount [color=blue]Lib[/color] "kernel32" Alias "QueryPerformanceCounter" (cyTickCount [color=blue]As[/color] [color=blue]Currency[/color]) [color=blue]As[/color] [color=blue]Long[/color]
[color=lightgreen]'[/color]
[color=blue]Sub[/color] Timers() 'SubRoutine to call Timer Functions and Subroutines under test and display results.
Application.ScreenUpdating = [color=blue]False[/color] [color=lightgreen]'Not necerssary but speeds things up a bit and is usually done so do it consistantly here in all tests. (Turns screen updating off. Good to edit out for Debuging Purposes.[/color]
[color=blue]On[/color] [color=blue]Error[/color] [color=blue]GoTo[/color] TheEnd [color=lightgreen]'If anything goes wrong go to the End instead of crashing. Useful to Edit out for Debuging[/color]
    [color=blue]Dim[/color] StartMTTime [color=blue]As[/color] [color=blue]Long[/color], StartVBATime [color=blue]As[/color] [color=blue]Long[/color] [color=lightgreen]'times in seconds at start of a run (Long is a Big whole Number limit (-2,147,483,648 to 2,147,483,647) -Most smaller numbers, Byte, Integer, Single are converted in computer to long so no advantage of Dim to smaller Type here) >>> 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. http://www.mrexcel.com/forum/excel-questions/803662-byte-backward-loop-3.html[/color]
    [color=blue]Dim[/color] MTTime [color=blue]As[/color] [color=blue]Long[/color], VBATime [color=blue]As[/color] [color=blue]Long[/color] [color=lightgreen]'Run times given from Timer Functions[/color]
    [color=blue]Let[/color] MTTime = 0 [color=lightgreen]'Could leave this out, but good[/color]
    [color=blue]Let[/color] VBATime = 0 [color=lightgreen]'Practice to put it in[/color]
    [color=blue]Dim[/color] Iteration [color=blue]As[/color] [color=blue]Long[/color], MaxIteration [color=blue]As[/color] [color=blue]Long[/color] [color=lightgreen]'Variable used in avaraging a few runs[/color]
    [color=blue]Let[/color] MaxIteration = 100 [color=lightgreen]'Set here the nimber of runs that you want.[/color]
    [color=lightgreen]'Call L1_SimpleLoop 'A first A run without timing is often said to be a good idea. For example because sometimes extra things'may be done the first time[/color]
    [color=lightgreen]'Call L2_TypicalEvaluateAlternativeToLoop[/color]
    [color=lightgreen]'Call L3_4_VBAWithFormula[/color]
    [color=lightgreen]'Call L5_6_VBAFormulaLoop[/color]
    [color=lightgreen]'Call L7_EvaluateRoaryALeftFunction[/color]
    [color=lightgreen]'Call L8_ApplicationWorksheetRoaryFunctionLeft[/color]
    [color=lightgreen]'Call L9_VBAArrayOfRanges1a[/color]
    [color=lightgreen]'Call L10_VBAArrayOfRanges1aa[/color]
    [color=lightgreen]'Call L11_VBAArrayOfRanges1b[/color]
    [color=lightgreen]'Call L12_VBAArrayOfRanges2[/color]
    [color=lightgreen]'Call L13_RangeObjectCapture[/color]
    [color=lightgreen]'Call L14_MicrosoftScriptingRuntimeDictionaryRangeOfRangesKeysItems1[/color]
    [color=lightgreen]'Call L15_MicrosoftScriptimeRuntimeDictionaryRangeOfRangesKeys[/color]
   
   
    [color=lightgreen]'Call L18_MicrosoftScriptimeRuntimeDictionaryRangeObjectKeysItemsBodge1[/color]
    [color=blue]Call[/color] L19_MicrosoftScriptimeRuntimeDictionaryRangeObjectKeysItemsBodge2
   
      [color=blue]For[/color] Iteration = 1 [color=blue]To[/color] MaxIteration [color=lightgreen]'Run as many times as specified.[/color]
      [color=blue]Let[/color] StartMTTime = MicroTimer [color=lightgreen]'Function Code from Charley Williams[/color]
      [color=blue]Let[/color] StartVBATime = VBATimer [color=lightgreen]'Typical VBA Timer() Function code[/color]
      [color=lightgreen]'Call L1_SimpleLoop[/color]
      [color=lightgreen]'Call L2_TypicalEvaluateAlternativeToLoop[/color]
      [color=lightgreen]'Call L3_4_VBAWithFormula[/color]
      [color=lightgreen]'Call L5_6_VBAFormulaLoop[/color]
      [color=lightgreen]'Call L7_EvaluateRoaryALeftFunction[/color]
      [color=lightgreen]'Call L8_ApplicationWorksheetRoaryFunctionLeft[/color]
      [color=lightgreen]'Call L9_VBAArrayOfRanges1a[/color]
      [color=lightgreen]'Call L10_VBAArrayOfRanges1aa[/color]
      [color=lightgreen]'Call L11_VBAArrayOfRanges1b[/color]
      [color=lightgreen]'Call L12_VBAArrayOfRanges2[/color]
      [color=lightgreen]'Call L13_RangeObjectCapture[/color]
      [color=lightgreen]'Call L14_MicrosoftScriptingRuntimeDictionaryRangeOfRangesKeysItems1[/color]
      [color=lightgreen]'Call L15_MicrosoftScriptimeRuntimeDictionaryRangeOfRangesKeys[/color]
     
     
      [color=lightgreen]'Call L18_MicrosoftScriptimeRuntimeDictionaryRangeObjectKeysItemsBodge1[/color]
      [color=blue]Call[/color] L19_MicrosoftScriptimeRuntimeDictionaryRangeObjectKeysItemsBodge2
 
      [color=blue]Let[/color] MTTime = (MTTime + (MicroTimer - StartMTTime)) [color=lightgreen]'Total times so[/color]
      [color=blue]Let[/color] VBATime = (VBATime + (VBATimer - StartVBATime)) [color=lightgreen]'far.[/color]
      [color=blue]Next[/color] Iteration 'Go and do another run(s)
    MsgBox "Micro Timer " & (MTTime) / MaxIteration & " Seconds" & vbCr & _
           "VBA Timer " & (VBATime) / MaxIteration & " Seconds" [color=lightgreen]'Display avarage results.[/color]
 
Application.ScreenUpdating = [color=blue]True[/color] [color=lightgreen]'Turn screen "back on" or screen is "dead"[/color]
[color=blue]Exit[/color] [color=blue]Sub[/color] [color=lightgreen]'We stop code here assuming it worked (or at least did not crash!)[/color]
TheEnd: [color=lightgreen]'We come here on erroring rather than crashing. Anything that should be done before ending the macro should be done here, to make sure it will always be dine ecen if the code crashes![/color]
Application.ScreenUpdating = [color=blue]True[/color] [color=lightgreen]'Screen need to be turned back on or your screen will be "dead"!! Important to turn screen on here, incase anything goes wrong.[/color]
MsgBox (Err.Description) [color=lightgreen]'Print out error message in Message Box[/color]
[color=blue]End[/color] [color=blue]Sub[/color] [color=lightgreen]' Timers()[/color]
[color=blue]Function[/color] VBATimer()
[color=lightgreen]'Typical VBA Timer Program[/color]
    VBATimer = Timer [color=lightgreen]'Timer is a VBA Function that gives current time in seconds[/color]
[color=blue]End[/color] [color=blue]Function[/color] [color=lightgreen]' VBATimer()[/color]
[color=blue]Function[/color] MicroTimer() [color=blue]As[/color] [color=blue]Single[/color] 'Charley Williams Micro Timer Code
[color=lightgreen]'  http://www.mrexcel.com/forum/excel-questions/805285-copy-based-match-criteria-code-alternative-looping-2.html[/color]
[color=lightgreen]'  Jerry Sullivan  Speed up VBA code with VLOOKUP.  http://www.mrexcel.com/forum/excel-questions/745455-speed-up-visual-basic-applications-code-vlookup.html[/color]
[color=lightgreen]'  https://msdn.microsoft.com/en-us/library/ff700515(v=office.14).aspx[/color]
    [color=blue]Dim[/color] cyTicks1 [color=blue]As[/color] [color=blue]Currency[/color]
    [color=blue]Static[/color] cyFrequency [color=blue]As[/color] [color=blue]Currency[/color]
    [color=blue]Let[/color] MicroTimer = 0
      [color=blue]If[/color] cyFrequency = 0 [color=blue]Then[/color] getFrequency cyFrequency [color=lightgreen]' get ticks/sec[/color]
      getTickCount cyTicks1 [color=lightgreen]' get ticks[/color]
      [color=blue]If[/color] cyFrequency [color=blue]Then[/color] MicroTimer = cyTicks1 / cyFrequency ' calc seconds
   
[color=blue]End[/color] [color=blue]Function[/color] [color=lightgreen]'MicroTimer()[/color]

.

Public Function required in the early Codes:

Code:
[color=blue]Option[/color] [color=blue]Explicit[/color]
[color=blue]Public[/color] [color=blue]Function[/color] RoaryLeftPubic(cell [color=blue]As[/color] Range, TheLength [color=blue]As[/color] [color=blue]Long[/color]) [color=blue]As[/color] [color=blue]Variant[/color] [color=lightgreen]'When an Array is assigned through Let to this function, it returns an Array which then through effectively A "Let One Liner" becomes a modified Range based on the Supplied range and any Additional Arguments. It can be thought as a normal Function working on a input Range. A Particular characteristic here is that the Output is created in a loop which specifically assigns each cell within the range. This probably ensures that VBA in any further workings "Know" or "allows" for an Array and so for example ensures that this Function can be used in Evaluate Function "One liners" without the usual "coercing stuff"[/color]
 
    [color=blue]Dim[/color] x [color=blue]As[/color] [color=blue]Long[/color], y [color=blue]As[/color] Long [color=lightgreen]'We build a collection of output by looping into an Array. So these variables will be used for both Row,Column indicies for the cell Range coming into the Function, as well as the Array Indicies. 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.[/color]
    [color=blue]Dim[/color] vOut() [color=blue]As[/color] [color=blue]Variant[/color] [color=lightgreen]'Typically in such a line the type requied may need suit a Function or Object that is used to return the actual values. So usually it will need to be Variant rather than the type of the final items in the Array[/color]
    [color=blue]ReDim[/color] vOut(1 [color=blue]To[/color] cell.Rows.Count, 1 [color=blue]To[/color] cell.Columns.Count) [color=lightgreen]'As we are filling in an array with a loop below it is necerssary to have the Array "There" as it were, so Sized. Also Needs to be at least big enough. Here it is made exactly the correct size by setting it to the size of the in coming array. Te "1 To" bit is important as otherwise Arrays tend to have an annoying tendancy to start otherwise (by default) at zero rather than 1![/color]
       
        [color=blue]For[/color] x = 1 [color=blue]To[/color] cell.Rows.Count [color=lightgreen]'We take each row in turn and fo that row we go along....[/color]
            [color=blue]For[/color] y = 1 [color=blue]To[/color] cell.Columns.Count [color=lightgreen]'...each cloumn. (This convention is good to choose, as this is a typical sequence in which VBA tends to store things "internally" in one long "item" list.)[/color]
                    [color=lightgreen]'The Main part of Thje Function: Each Array element is set to something which is obtained by a formula similar to what one would use in a VBA code to put something in a cell.[/color]
                    [color=lightgreen]'Important Note here: Often at this point in a function we work with the one Input. Indeed we are here as well, that is to say one cell from the Range. A typical mistake therefore in any formulas below would be to forget the extra (x, y).Value required as we are working with an Inputed Array[/color]
                    [color=blue]Let[/color] vOut(x, y) = Left(cell(x, y).Value, TheLength) [color=lightgreen]'First Argument is often a  type of "LookUp ValuE-see note above".[/color]
                        [color=lightgreen]'Debug.Print vOut(x, y)'I found in practice that in a Code calling a [color=blue]Function[/color] strange things sometimes happen when attempting Step through with F8. So A Debug.Print was found to be sometimes prefferable to assist in degugging. Possibly a Bug The problem does not always happen![/color]
            [color=blue]Next[/color] y
        [color=blue]Next[/color] x
       
        [color=blue]Let[/color] RoaryLeftPubic = vOut() [color=lightgreen]' At This point RoaryLeftPubic becomes an Array or Rather an Object with collections. By Virtue of a typical =RoaryLeftPubic(Rng ,   ____) a Range Object will be returned. (Somehow!?)[/color]
 
[color=blue]End[/color] Function [color=lightgreen]'RoaryLeftPubic[/color]
 
Upvote 0
Hi,
. No Problem or Questions here…..

Hi….
. Just a follow up to last few Posts for anyone following an interested…..
...........
. ... In my next chapter of War and Peace I shall repeat the work for much bigger Lists and for ...........



... Just a quick follow Up. Similar codes for 33928 Rows..
. As the MrExcel Forum Editor Code Window can "Take it".. I post the codes again as there are a few improvements resulting from discussions here (From about post #9):-
Range Dimensioning, Range and Value Referencing and Referring to Arrays
Results are not complete due to time and resource limitations.. but anyway, in the next “chapter” I want to reduce and optimize the codes for more specific and practical use and for comparisons with more complicated formulas and functions discussed in this Thread.

Alan.
(P.s. For anyone PM-in me again.. Please write request and / questions here. I am developing and learning for my project thanks to help here, mainly for Private stuff; I ‘aint a Programmer and there are thousands more talented here you should be asking before me anyway… and BTW it ‘aint allowed wot you ask as everyone works here very generously voluntarily !!!!
<b></b><table width="10" cellpadding="1px" rules="all" style=";background-color: #FFFFFF;border: 1px solid;border-collapse: collapse; border-color: #A6AAB6"><colgroup><col width="25px" style="background-color: #E0E0F0" /><col /><col /><col /><col /><col /></colgroup><thead><tr style=" background-color: #E0E0F0;text-align: center;color: #161120"><th></th><th>H</th><th>I</th><th>J</th><th>K</th><th>L</th></tr></thead><tbody><tr ><td style="color: #161120;text-align: center;">1</td><td style="text-align: right;;"></td><td style=";">Brief Description of Code</td><td style="text-align: center;;">Average Run Time in Seconds</td><td style="text-align: center;color: #BFBFBF;;"></td><td style="text-align: center;;"></td></tr><tr ><td style="color: #161120;text-align: center;">2</td><td style="text-align: right;;"></td><td style="text-align: right;;"></td><td style="text-align: center;;">Computer1 33928 Rows</td><td style="text-align: center;color: #BFBFBF;;">Computer1 1654 Rows</td><td style="text-align: center;;">Computer2 33928Rows</td></tr><tr ><td style="color: #161120;text-align: center;">3</td><td style=";">G1</td><td style=";">Simplist Loop</td><td style="text-align: center;;">6.3</td><td style="text-align: center;color: #BFBFBF;;">0.4</td><td style="text-align: center;;"></td></tr><tr ><td style="color: #161120;text-align: center;">4</td><td style=";">G2</td><td style=";">Typical Evaluate Alternative</td><td style="text-align: center;;">.5</td><td style="text-align: center;color: #BFBFBF;;">0.02</td><td style="text-align: center;;"></td></tr><tr ><td style="color: #161120;text-align: center;">5</td><td style=";">G3</td><td style=";">Typical .Formula in a With EndWith</td><td style="text-align: center;;">.085</td><td style="text-align: center;color: #BFBFBF;;">0.008</td><td style="text-align: center;;"></td></tr><tr ><td style="color: #161120;text-align: center;">6</td><td style=";">G4</td><td style=";">Typical .FormulaR1C1 in a With EndWith</td><td style="text-align: center;;">.17</td><td style="text-align: center;color: #BFBFBF;;">0.007</td><td style="text-align: center;;"></td></tr><tr ><td style="color: #161120;text-align: center;">7</td><td style=";">G5</td><td style=";">.Formula in a Loop</td><td style="text-align: center;;">94.2</td><td style="text-align: center;color: #BFBFBF;;">0.7</td><td style="text-align: center;;"></td></tr><tr ><td style="color: #161120;text-align: center;">8</td><td style=";">G6</td><td style=";"> FormulaR1C1 in a Loop</td><td style="text-align: center;;">95.5</td><td style="text-align: center;color: #BFBFBF;;">0.6</td><td style="text-align: center;;"></td></tr><tr ><td style="color: #161120;text-align: center;">9</td><td style=";">G7</td><td style=";">Evalute using Range Object Left UDF</td><td style="text-align: center;;">1.65</td><td style="text-align: center;color: #BFBFBF;;">0.1</td><td style="text-align: center;;"></td></tr><tr ><td style="color: #161120;text-align: center;">10</td><td style="color: #D8D8D8;;">L G _ -</td><td style="color: #D8D8D8;;">VBA Left - =(String___, needs Range!….</td><td style="text-align: center;color: #D8D8D8;;">Don't Work</td><td style="text-align: center;color: #BFBFBF;;">Don't Work</td><td style="text-align: center;;"></td></tr><tr ><td style="color: #161120;text-align: center;">11</td><td style="border-bottom: 1px solid black;;">G8</td><td style="border-bottom: 1px solid black;;">Range Object Left UDF - Direct  =(Range____</td><td style="text-align: center;border-bottom: 1px solid black;;">1.1</td><td style="text-align: center;border-bottom: 1px solid black;color: #BFBFBF;;">0.06</td><td style="text-align: center;border-bottom: 1px solid black;;"></td></tr><tr ><td style="color: #161120;text-align: center;">12</td><td style="border-top: 1px solid black;border-left: 1px solid black;;">G9</td><td style="border-top: 1px solid black;;">VBA Array Of Ranges  (1a)</td><td style="text-align: center;border-top: 1px solid black;;">1.5</td><td style="text-align: center;border-top: 1px solid black;color: #BFBFBF;;">.07</td><td style="text-align: center;border-top: 1px solid black;;"></td></tr><tr ><td style="color: #161120;text-align: center;">13</td><td style="border-bottom: 1px solid black;border-left: 1px solid black;;">G9</td><td style="border-bottom: 1px solid black;;">VBA Array Of Ranges  () (1a)</td><td style="text-align: center;border-bottom: 1px solid black;;">218</td><td style="text-align: center;border-bottom: 1px solid black;color: #BFBFBF;;">0.22</td><td style="text-align: center;border-bottom: 1px solid black;;"></td></tr><tr ><td style="color: #161120;text-align: center;">14</td><td style="border-top: 1px solid black;border-left: 1px solid black;;">G10</td><td style="border-top: 1px solid black;;">VBA Array Of Ranges (1aa)</td><td style="text-align: center;border-top: 1px solid black;;">2.5-0.5</td><td style="text-align: center;border-top: 1px solid black;color: #BFBFBF;;">0.13 - .07</td><td style="text-align: center;border-top: 1px solid black;;"></td></tr><tr ><td style="color: #161120;text-align: center;">15</td><td style="border-bottom: 1px solid black;border-left: 1px solid black;;">G10</td><td style="border-bottom: 1px solid black;;">VBA Array Of Ranges   ()  (1aa)</td><td style="text-align: center;border-bottom: 1px solid black;;">217-0.5</td><td style="text-align: center;border-bottom: 1px solid black;color: #BFBFBF;;">0.29 - .07</td><td style="text-align: center;border-bottom: 1px solid black;;"></td></tr><tr ><td style="color: #161120;text-align: center;">16</td><td style="border-top: 1px solid black;border-left: 1px solid black;;">G11</td><td style="border-top: 1px solid black;;">VBA Array Of Ranges (1b)  First use of intermediateArray</td><td style="text-align: center;border-top: 1px solid black;;">1.38</td><td style="text-align: center;border-top: 1px solid black;color: #BFBFBF;;">.08</td><td style="text-align: center;border-top: 1px solid black;;"></td></tr><tr ><td style="color: #161120;text-align: center;">17</td><td style="border-bottom: 1px solid black;border-left: 1px solid black;;">G11</td><td style="border-bottom: 1px solid black;;">VBA Array Of Ranges  ()   (1b)  First use of intermediateArray</td><td style="text-align: center;border-bottom: 1px solid black;;">219.5</td><td style="text-align: center;border-bottom: 1px solid black;color: #BFBFBF;;">0.22</td><td style="text-align: center;border-bottom: 1px solid black;;"></td></tr><tr ><td style="color: #161120;text-align: center;">18</td><td style="border-top: 1px solid black;border-left: 1px solid black;;">G12</td><td style="border-top: 1px solid black;;">VBA Array Of Ranges (2)</td><td style="text-align: center;border-top: 1px solid black;;">1.5</td><td style="text-align: center;border-top: 1px solid black;color: #BFBFBF;;">.07</td><td style="text-align: center;border-top: 1px solid black;;"></td></tr><tr ><td style="color: #161120;text-align: center;">19</td><td style="border-bottom: 1px solid black;border-left: 1px solid black;;">G12</td><td style="border-bottom: 1px solid black;;">VBA Array Of Ranges   ()   (2)</td><td style="text-align: center;border-bottom: 1px solid black;;">115.5</td><td style="text-align: center;border-bottom: 1px solid black;color: #BFBFBF;;">0.18</td><td style="text-align: center;border-bottom: 1px solid black;;"></td></tr><tr ><td style="color: #161120;text-align: center;">20</td><td style="border-top: 1px solid black;border-left: 1px solid black;;">G13</td><td style="border-top: 1px solid black;;">RangeObjectCapture value2  (___)</td><td style="text-align: center;border-top: 1px solid black;;">1651.5</td><td style="text-align: center;border-top: 1px solid black;color: #BFBFBF;;">3.85</td><td style="text-align: center;border-top: 1px solid black;;">1388</td></tr><tr ><td style="color: #161120;text-align: center;">21</td><td style="border-left: 1px solid black;;">G13</td><td style=";">RangeObjectCapture value2 ()  (___)</td><td style="text-align: center;;">1667</td><td style="text-align: center;color: #BFBFBF;;">3.86</td><td style="text-align: center;;">1399</td></tr><tr ><td style="color: #161120;text-align: center;">22</td><td style="border-left: 1px solid black;;">G13b</td><td style=";">RangeObjectCapture value2  (___)</td><td style="text-align: center;;">2457.5</td><td style="text-align: center;color: #BFBFBF;;">3.6</td><td style="text-align: center;;">3250</td></tr><tr ><td style="color: #161120;text-align: center;">23</td><td style="border-left: 1px solid black;;">G13b</td><td style=";">RangeObjectCapture value2 ()  (___)</td><td style="text-align: center;color: #D8D8D8;;">Don't Work</td><td style="text-align: center;color: #BFBFBF;;">Don't Work</td><td style="text-align: center;;"></td></tr><tr ><td style="color: #161120;text-align: center;">24</td><td style="border-left: 1px solid black;;">G13c</td><td style=";">RangeObjectCapture value2  (___)</td><td style="text-align: center;;">0.325</td><td style="text-align: center;color: #BFBFBF;;">0.018</td><td style="text-align: center;;">0.34</td></tr><tr ><td style="color: #161120;text-align: center;">25</td><td style="border-bottom: 1px solid black;border-left: 1px solid black;;">G13c</td><td style="border-bottom: 1px solid black;;">RangeObjectCapture value2 ()  (___)</td><td style="text-align: center;color: #D8D8D8;;">Don't Work</td><td style="text-align: center;color: #BFBFBF;;">Don't Work</td><td style="text-align: center;;"></td></tr><tr ><td style="color: #161120;text-align: center;">26</td><td style="border-top: 1px solid black;border-left: 1px solid black;;">G14</td><td style="border-top: 1px solid black;;">MSRDKeysItems  item    (___)</td><td style="text-align: center;;">380</td><td style="text-align: center;color: #BFBFBF;;">.65</td><td style="text-align: center;;"></td></tr><tr ><td style="color: #161120;text-align: center;">27</td><td style="border-left: 1px solid black;;">G14</td><td style=";">MSRDKeysItems  item ()    (___)</td><td style="text-align: center;;">379</td><td style="text-align: center;color: #BFBFBF;;">.66</td><td style="text-align: center;;"></td></tr><tr ><td style="color: #161120;text-align: center;">28</td><td style="border-left: 1px solid black;;">G14</td><td style=";">MSRDKeysItems intermediteArray  (___).</td><td style="text-align: center;;">3.35</td><td style="text-align: center;color: #BFBFBF;;">.16</td><td style="text-align: center;;">3.15</td></tr><tr ><td style="color: #161120;text-align: center;">29</td><td style="border-left: 1px solid black;;">G14</td><td style=";">MSRDKeysItems intermediteArray  ()    (___).</td><td style="text-align: center;;">377</td><td style="text-align: center;color: #BFBFBF;;">.65</td><td style="text-align: center;;"></td></tr><tr ><td style="color: #161120;text-align: center;">30</td><td style="border-left: 1px solid black;;">G14</td><td style=";">MSRDKeysItems Keys    (As values)</td><td style="text-align: center;;">897</td><td style="text-align: center;color: #BFBFBF;;">2.1</td><td style="text-align: center;;">2178</td></tr><tr ><td style="color: #161120;text-align: center;">31</td><td style="border-bottom: 1px solid black;border-left: 1px solid black;;">G14</td><td style="border-bottom: 1px solid black;;">MSRDKeysItems Keys    ()    (As values)</td><td style="text-align: center;border-bottom: 1px solid black;;">905.5</td><td style="text-align: center;border-bottom: 1px solid black;color: #BFBFBF;;">2.1 </td><td style="text-align: center;border-bottom: 1px solid black;;"></td></tr><tr ><td style="color: #161120;text-align: center;">32</td><td style="border-top: 1px solid black;border-left: 1px solid black;;">G15</td><td style="border-top: 1px solid black;;">MSRDKeys     (As Full Range Objects)</td><td style="text-align: center;border-top: 1px solid black;;">362.5      315</td><td style="text-align: center;border-top: 1px solid black;color: #BFBFBF;;">.56</td><td style="text-align: center;border-top: 1px solid black;;">975.6   861</td></tr><tr ><td style="color: #161120;text-align: center;">33</td><td style="border-bottom: 1px solid black;border-left: 1px solid black;;">G15</td><td style="border-bottom: 1px solid black;;">MSRDKeys    ()     (As Full Range Objects)</td><td style="text-align: center;border-bottom: 1px solid black;;"></td><td style="text-align: center;border-bottom: 1px solid black;color: #BFBFBF;;">.56</td><td style="text-align: center;border-bottom: 1px solid black;;">853</td></tr><tr ><td style="color: #161120;text-align: center;">34</td><td style="border-top: 1px solid black;border-left: 1px solid black;;">G15</td><td style="border-top: 1px solid black;;">MSRDKeys  intermediateArray  (As Full Range Objects)</td><td style="text-align: center;border-top: 1px solid black;;">1.88</td><td style="text-align: center;border-top: 1px solid black;color: #BFBFBF;;">.08</td><td style="text-align: center;border-top: 1px solid black;;">1.66</td></tr><tr ><td style="color: #161120;text-align: center;">35</td><td style="border-bottom: 1px solid black;border-left: 1px solid black;;">G15</td><td style="border-bottom: 1px solid black;;">MSRDKeys  intermediateArray  ()  (As Full Range Objects)</td><td style="text-align: center;border-bottom: 1px solid black;;"></td><td style="text-align: center;border-bottom: 1px solid black;color: #BFBFBF;;">.56</td><td style="text-align: center;border-bottom: 1px solid black;;">971.6</td></tr><tr ><td style="color: #161120;text-align: center;">36</td><td style="border-top: 1px solid black;;">G16</td><td style="text-align: center;border-top: 1px solid black;;"></td><td style="text-align: center;border-top: 1px solid black;;"></td><td style="text-align: center;border-top: 1px solid black;color: #BFBFBF;;"></td><td style="text-align: center;border-top: 1px solid black;;"></td></tr><tr ><td style="color: #161120;text-align: center;">37</td><td style="border-bottom: 1px solid black;;">G17</td><td style="text-align: center;border-bottom: 1px solid black;;"></td><td style="text-align: center;border-bottom: 1px solid black;;"></td><td style="text-align: center;border-bottom: 1px solid black;color: #BFBFBF;;"></td><td style="text-align: center;border-bottom: 1px solid black;;"></td></tr><tr ><td style="color: #161120;text-align: center;">38</td><td style="border-top: 1px solid black;border-left: 1px solid black;;">G18</td><td style="border-top: 1px solid black;;">Big Range Object-MSDR Array of Range Objects "Bodge 2"</td><td style="text-align: center;border-top: 1px solid black;;">5374</td><td style="text-align: center;border-top: 1px solid black;color: #BFBFBF;;">12</td><td style="text-align: center;border-top: 1px solid black;border-right: 1px solid black;;">5466.5</td></tr><tr ><td style="color: #161120;text-align: center;">39</td><td style="text-align: right;border-left: 1px solid black;;"></td><td style=";">()  (___)</td><td style="text-align: center;color: #D8D8D8;;">Don't Work</td><td style="text-align: center;color: #BFBFBF;;">Don't Work</td><td style="text-align: center;border-right: 1px solid black;;"></td></tr><tr ><td style="color: #161120;text-align: center;">40</td><td style="text-align: right;border-left: 1px solid black;;"></td><td style=";">Ditto..  IntermediateArray</td><td style="text-align: right;;"></td><td style="text-align: right;color: #BFBFBF;;"></td><td style="text-align: center;border-right: 1px solid black;;">4390</td></tr><tr ><td style="color: #161120;text-align: center;">41</td><td style="text-align: right;border-left: 1px solid black;;"></td><td style=";">()  (___)</td><td style="text-align: right;;"></td><td style="text-align: right;color: #BFBFBF;;"></td><td style="text-align: center;border-right: 1px solid black;;"></td></tr><tr ><td style="color: #161120;text-align: center;">42</td><td style="border-left: 1px solid black;;">G19</td><td style=";">Big Range Object-MSDR Array of Range Objects "Bodge 2"</td><td style="text-align: center;;"></td><td style="text-align: center;color: #BFBFBF;;">12</td><td style="text-align: center;border-right: 1px solid black;;">5203</td></tr><tr ><td style="color: #161120;text-align: center;">43</td><td style="text-align: right;border-left: 1px solid black;;"></td><td style=";">()  (___)</td><td style="text-align: center;color: #D8D8D8;;">Don't Work</td><td style="text-align: center;color: #BFBFBF;;">Don't Work</td><td style="text-align: center;border-right: 1px solid black;;"></td></tr><tr ><td style="color: #161120;text-align: center;">44</td><td style="text-align: right;border-left: 1px solid black;;"></td><td style=";">Ditto..  IntermediateArray</td><td style="text-align: right;;"></td><td style="text-align: right;color: #BFBFBF;;"></td><td style="text-align: center;border-right: 1px solid black;;">4786</td></tr><tr ><td style="color: #161120;text-align: center;">45</td><td style="text-align: right;border-left: 1px solid black;;"></td><td style=";">()  (___)</td><td style="text-align: right;;"></td><td style="text-align: right;color: #BFBFBF;;"></td><td style="text-align: center;border-right: 1px solid black;;"></td></tr><tr ><td style="color: #161120;text-align: center;">46</td><td style="border-left: 1px solid black;;">G20</td><td style=";">Big Range Object-MSDR Array of Range Objects "Bodge 3"</td><td style="text-align: center;;"></td><td style="text-align: right;color: #BFBFBF;;">7.5</td><td style="text-align: center;border-right: 1px solid black;;">3579</td></tr><tr ><td style="color: #161120;text-align: center;">47</td><td style="text-align: right;border-left: 1px solid black;;"></td><td style=";">()  (___)</td><td style="text-align: center;color: #D8D8D8;;">Don't Work</td><td style="color: #BFBFBF;;">Don't Work</td><td style="text-align: center;border-right: 1px solid black;;"></td></tr><tr ><td style="color: #161120;text-align: center;">48</td><td style="text-align: right;border-left: 1px solid black;;"></td><td style=";">Ditto..  IntermediateArray</td><td style="text-align: right;;"></td><td style="text-align: right;color: #BFBFBF;;"></td><td style="text-align: center;border-right: 1px solid black;;">4705</td></tr><tr ><td style="color: #161120;text-align: center;">49</td><td style="text-align: right;border-bottom: 1px solid black;border-left: 1px solid black;;"></td><td style=";">()  (___)</td><td style="text-align: right;border-bottom: 1px solid black;;"></td><td style="text-align: right;border-bottom: 1px solid black;color: #BFBFBF;;"></td><td style="text-align: center;border-right: 1px solid black;border-bottom: 1px solid black;;"></td></tr></tbody></table><p style="width:5,1em;font-weight:bold;margin:0;padding:0.2em 0.6em 0.2em 0.5em;border: 1px solid #A6AAB6;border-top:none;text-align: center;background-color: #E0E0F0;color: #161120">LeftSpeedsDeutsch</p><br /><br />



Code:
[color=blue]Option[/color] [color=blue]Explicit[/color]
[color=blue]Sub[/color] G1_SimpleLoop() [color=lightgreen]'Simplist Loop[/color]
 
 [color=blue]Dim[/color] wksLG [color=blue]As[/color] Worksheet: [color=blue]Set[/color] wksLG = ThisWorkbook.Worksheets("LeftSpeedsDeutsch") [color=lightgreen]'Give abbreviations the  Methods, properties, sub-Objects through dot of Worksheets Object[/color]
 [color=blue]Dim[/color] lr [color=blue]As[/color] [color=blue]Long[/color], rws [color=blue]As[/color] [color=blue]Long[/color] [color=lightgreen]'last row and rows in sheet( Long is a Big whole Number limit (-2,147,483,648 to 2,147,483,647) -Most smaller numbers, Byte, Integer, Single are converted in computer to long so no advantage of Dim to smaller Type here) >>> 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. http://www.mrexcel.com/forum/excel-questions/803662-byte-backward-loop-3.html[/color]
 [color=blue]Let[/color] lr = wksLG.Cells.Find(What:="*", after:=wksLG.Cells(1, 1), Lookat:=xlPart, LookIn:=xlFormulas, SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row [color=lightgreen]'Get last Row with entry anywhere for Sheet1. Method: You start at first cell then go backwards (which effectively starts at end of sheet), sercching for anything ( = * ) by rows, then get the row number. This allows for different excel versions with different available Row numbers) Just a different method here for fun- finds last row in sheet rather than row for last entry in particular cell[/color]
 [color=blue]Let[/color] lr = wksLG.Cells(Rows.Count, 1).End(xlUp).Row [color=lightgreen]'Better alternative for single column work. - Starting at last Spreadsheet Row in column1, quasi "go back up" / return the last cell with entry in it as a Range object using .End Property and obtain rows from the .Rows Property of that returned Range Object[/color]
 [color=blue]Dim[/color] sr [color=blue]As[/color] Long: [color=blue]Let[/color] sr = 21 [color=lightgreen]'Start row of data[/color]
 
    [color=blue]For[/color] rws = sr [color=blue]To[/color] lr [color=blue]Step[/color] 1
    wksLG.Range("D" & rws & "").Value = Left((wksLG.Range("A" & rws & "").Value), 4)
    [color=lightgreen]'wksLG.Range("D" & rws & "").Value = Left$((wksLG.Range("A" & rws & "").Value), 4)[/color]
    [color=blue]Next[/color] rws
 
[color=blue]End[/color] [color=blue]Sub[/color] [color=lightgreen]'SimpleLoop[/color]
'
'
[color=blue]Sub[/color] G2_TypicalEvaluateAlternativeToLoop()
 [color=blue]Dim[/color] wksLG [color=blue]As[/color] Worksheet: [color=blue]Set[/color] wksLG = ThisWorkbook.Worksheets("LeftSpeedsDeutsch") [color=lightgreen]'Give abbreviations the  Methods, properties, sub-Objects through dot of Worksheets Object[/color]
 
 [color=blue]Dim[/color] RngName [color=blue]As[/color] Range, RngD [color=blue]As[/color] Range [color=lightgreen]'Data Column range and an offset Column for results.. Give abbreviations >>>[/color]
 [color=blue]Dim[/color] lr [color=blue]As[/color] [color=blue]Long[/color] [color=lightgreen]'last row ( Long is a Big whole Number limit (-2,147,483,648 to 2,147,483,647) -Most smaller numbers, Byte, Integer, Single are converted in computer to long so no advantage of Dim to smaller Type here)[/color]
 [color=blue]Let[/color] lr = wksLG.Cells(Rows.Count, 1).End(xlUp).Row [color=lightgreen]'Better alternative for single column work. - Starting at last Spreadsheet Row in column1, quasi "go back up" / return the last cell with entry in it as a Range object using .End Property and obtain rows from the .Rows Property of that returned Range Object[/color]
 [color=blue]Dim[/color] sr [color=blue]As[/color] Long: [color=blue]Let[/color] sr = 21 [color=lightgreen]'Start row of data[/color]
 [color=blue]Set[/color] RngName = wksLG.Range("A" & sr & ":A" & lr & ""): [color=blue]Set[/color] RngD = wksLG.Range("D" & sr & ":D" & lr & "") [color=lightgreen]'...>>>>..the  Methods, properties, sub-Objects through dot of Worksheets Object[/color]
 
  [color=lightgreen]'Let RngD.Value = Evaluate("if(Row(21:1674),LEFT(" & RngName.Address & ",4))")[/color]
  [color=blue]Let[/color] RngD.Value = Evaluate("if(Row(" & sr & ":" & lr & "),LEFT(" & RngName.Address & ",4))")
 
[color=blue]End[/color] [color=blue]Sub[/color] [color=lightgreen]'TypicalEvaluateAlternativeToLoop[/color]
[color=lightgreen]'[/color]
'
[color=blue]Sub[/color] G3_4_VBAWithFormula()
 [color=blue]Dim[/color] wksLG [color=blue]As[/color] Worksheet: [color=blue]Set[/color] wksLG = ThisWorkbook.Worksheets("LeftSpeedsDeutsch")
 [color=blue]Dim[/color] RngD [color=blue]As[/color] Range, RngName [color=blue]As[/color] Range
 [color=blue]Dim[/color] lr [color=blue]As[/color] [color=blue]Long[/color], rws [color=blue]As[/color] [color=blue]Long[/color]
 [color=blue]Let[/color] lr = wksLG.Cells(Rows.Count, 1).End(xlUp).Row
 [color=blue]Dim[/color] sr [color=blue]As[/color] Long: [color=blue]Let[/color] sr = 21
 [color=blue]Set[/color] RngD = Range("D" & sr & ":D" & lr & ""):  [color=blue]Set[/color] RngName = Range("A" & sr & ":A" & lr & "")
 
    [color=blue]With[/color] RngD
        [color=lightgreen]'.Formula = "=Left(" & RngName.Address & ",4)"[/color]
        .FormulaR1C1 = "=left(R[0]C[-3],4)"
    [color=blue]End[/color] [color=blue]With[/color]
 
[color=blue]End[/color] [color=blue]Sub[/color] [color=lightgreen]'VBAWithFormula()[/color]
[color=lightgreen]'[/color]
[color=blue]Sub[/color] G5_6_VBAFormulaLoop() 'Looping the [color=blue]For[/color]mulas in
 
 [color=blue]Dim[/color] wksLG [color=blue]As[/color] Worksheet: [color=blue]Set[/color] wksLG = ThisWorkbook.Worksheets("LeftSpeedsDeutsch") [color=lightgreen]'Give abbreviations the  Methods, properties, sub-Objects through dot of Worksheets Object[/color]
 [color=blue]Dim[/color] lr [color=blue]As[/color] [color=blue]Long[/color], rws [color=blue]As[/color] [color=blue]Long[/color]
 [color=blue]Let[/color] lr = wksLG.Cells(Rows.Count, 1).End(xlUp).Row [color=lightgreen]'Better alternative for single column work. - Starting at last Spreadsheet Row in column1, quasi "go back up" / return the last cell with entry in it as a Range object using .End Property and obtain rows from the .Rows Property of that returned Range Object[/color]
 [color=blue]Dim[/color] sr [color=blue]As[/color] Long: [color=blue]Let[/color] sr = 21 [color=lightgreen]'Start row of data[/color]
 [color=blue]Dim[/color] RngD [color=blue]As[/color] Range, RngName [color=blue]As[/color] Range
 [color=blue]Set[/color] RngD = Range("D" & sr & ":D" & lr & ""):  [color=blue]Set[/color] RngName = Range("A" & sr & ":A" & lr & "")
   
    For rws = sr [color=blue]To[/color] lr [color=blue]Step[/color] 1
    [color=lightgreen]'wksLG.Range("D" & rws & "").Formula = "=Left(" & RngName.Address & ",4)"[/color]
    wksLG.Range("D" & rws & "").FormulaR1C1 = "=left(R[0]C[-3],4)"
    [color=blue]Next[/color] rws
 
[color=blue]End[/color] [color=blue]Sub[/color] [color=lightgreen]'VBAFormulaLoop[/color]
 
[color=lightgreen]'[/color]
'
[color=blue]Sub[/color] G7_EvaluateRoaryALeftFunction()
 [color=blue]Dim[/color] wksLG [color=blue]As[/color] Worksheet: [color=blue]Set[/color] wksLG = ThisWorkbook.Worksheets("LeftSpeedsDeutsch")
 [color=blue]Dim[/color] RngName [color=blue]As[/color] Range, RngD [color=blue]As[/color] Range
 [color=blue]Dim[/color] lr [color=blue]As[/color] [color=blue]Long[/color], rws [color=blue]As[/color] [color=blue]Long[/color]
 [color=blue]Let[/color] lr = wksLG.Cells(Rows.Count, 1).End(xlUp).Row
 [color=blue]Dim[/color] sr [color=blue]As[/color] Long: [color=blue]Let[/color] sr = 21
 [color=blue]Set[/color] RngName = wksLG.Range("A" & sr & ":A" & lr & ""): [color=blue]Set[/color] RngD = wksLG.Range("D" & sr & ":D" & lr & "")
 
  [color=blue]Let[/color] RngD.Value = Evaluate("RoaryLeftPubic(" & RngName.Address & ",4)")
 
[color=blue]End[/color] [color=blue]Sub[/color] [color=lightgreen]'EvaluateRoaryALeftFunction()[/color]
[color=lightgreen]'[/color]
'
 
'
'
[color=blue]Sub[/color] VBALeft() 'DON'T WORK
 [color=blue]Dim[/color] wksLG [color=blue]As[/color] Worksheet: [color=blue]Set[/color] wksLG = ThisWorkbook.Worksheets("LeftSpeedsDeutsch")
 [color=blue]Dim[/color] RngD [color=blue]As[/color] Range, RngName [color=blue]As[/color] Range
 [color=blue]Dim[/color] lr [color=blue]As[/color] [color=blue]Long[/color], rws [color=blue]As[/color] [color=blue]Long[/color]
 [color=blue]Let[/color] lr = wksLG.Cells(Rows.Count, 1).End(xlUp).Row
 [color=blue]Dim[/color] sr [color=blue]As[/color] Long: [color=blue]Let[/color] sr = 21
 [color=blue]Set[/color] RngD = Range("D" & sr & ":D" & lr & ""): [color=blue]Set[/color] RngName = Range("A" & sr & ":A" & lr & "")
 
    [color=lightgreen]'Let RngD.Value = Left(RngName, 4) Wont work..RngName is nat a string as required in first argument![/color]
 
[color=blue]End[/color] [color=blue]Sub[/color]
 
 
 
[color=lightgreen]'[/color]
[color=blue]Sub[/color] G8_ApplicationWorksheetRoaryFunctionLeft()
 
 [color=blue]Dim[/color] wksLG [color=blue]As[/color] Worksheet: [color=blue]Set[/color] wksLG = ThisWorkbook.Worksheets("LeftSpeedsDeutsch")
 [color=blue]Dim[/color] RngName [color=blue]As[/color] Range, RngD [color=blue]As[/color] Range
 [color=blue]Dim[/color] lr [color=blue]As[/color] [color=blue]Long[/color], rws [color=blue]As[/color] [color=blue]Long[/color]
 [color=blue]Let[/color] lr = wksLG.Cells(Rows.Count, 1).End(xlUp).Row
 [color=blue]Dim[/color] sr [color=blue]As[/color] Long: [color=blue]Let[/color] sr = 21
 [color=blue]Set[/color] RngName = wksLG.Range("A" & sr & ":A" & lr & ""): [color=blue]Set[/color] RngD = wksLG.Range("D" & sr & ":D" & lr & "")
 
 [color=blue]Let[/color] RngD.Value = RoaryLeftPubic(RngName, 4)
 
[color=blue]End[/color] [color=blue]Sub[/color] [color=lightgreen]'ApplicationWorksheetRoaryFunctionLeft()[/color]
[color=lightgreen]'[/color]
'
 
 [color=lightgreen]'[/color]
''
[color=blue]Sub[/color] G9_VBAArrayOfRanges1a()
[color=lightgreen]'Loop Range of Ranges. VBA Make Array for Output. Output in a "Output Value One Liner"[/color]
[color=lightgreen]'Typical application requiring seperate loops for the (often differnt sized) input and output arrays[/color]
 [color=blue]Dim[/color] wksLG [color=blue]As[/color] Worksheet: [color=blue]Set[/color] wksLG = ThisWorkbook.Worksheets("LeftSpeedsDeutsch")
 [color=blue]Dim[/color] RngName [color=blue]As[/color] Range, RngD [color=blue]As[/color] Range
 [color=blue]Dim[/color] lr [color=blue]As[/color] [color=blue]Long[/color], rws [color=blue]As[/color] [color=blue]Long[/color]
 [color=blue]Let[/color] lr = wksLG.Cells(Rows.Count, 1).End(xlUp).Row
 [color=blue]Dim[/color] sr [color=blue]As[/color] Long: [color=blue]Let[/color] sr = 21
 [color=blue]Set[/color] RngName = wksLG.Range("A" & sr & ":A" & lr & ""): [color=blue]Set[/color] RngD = wksLG.Range("D" & sr & ":D" & lr & "")
 
 [color=blue]Dim[/color] arrIn() [color=blue]As[/color] Range [color=lightgreen]'Variant 'In the looping, the Set would appear to be responsible for bringing **Ranges into the Array The variable type remains as defined here: Either a range for As Range or a Variant Object for [color=blue]As[/color] Variant[/color]
 [color=blue]ReDim[/color] arrIn(sr [color=blue]To[/color] lr, 1 [color=blue]To[/color] 1) [color=lightgreen]'We must give array a size as we give specific value in a loop. ReDim Must be used rather than Dim as [color=blue]Dim[/color] only takes Numbers not variables[/color]
 
    [color=blue]For[/color] rws = sr [color=blue]To[/color] lr [color=blue]Step[/color] 1 [color=lightgreen]'Input Array of Ranges[/color]
        [color=blue]Set[/color] arrIn(rws, 1) = Range("A" & rws & "")
        [color=lightgreen]'Set arrIn(rws, 1) = wksLG.Range("A" & rws & "") 'This would be tolerate**[/color]
    [color=blue]Next[/color] rws
 
 Dim arrOut() As [color=blue]String[/color] [color=lightgreen]'We can use string as in the looping below as we are not relying on (/seeing) a range object to rturn us an array of values.[/color]
 [color=blue]ReDim[/color] arrOut(sr [color=blue]To[/color] lr, 1 To 1) [color=lightgreen]'Antoher way to look at it is to say we have a fixed, rather than dynamiy array, and as VBA does not allow a direct assigning one liner in this case it is also not necerssarily expecting to see an object. For Let it is likely to expect to see some value, and for Set an object (Would expect an Range Object if indicies of arrOut were so defined by arrOut() As String initially[/color]
 
    [color=blue]For[/color] rws = sr [color=blue]To[/color] lr [color=blue]Step[/color] 1 [color=lightgreen]'Input Array of Ranges[/color]
 
            [color=lightgreen]'Let arrOut(rws, 1) = arrIn(rws, 1).Value 'Works 'VBA would appear to recognise this array element as A range as it gives me the Method, Object and property selkection to choose from via intellisense brought in by typing . Dot after the Array elemant[/color]
            [color=lightgreen]'Let arrOut(rws, 1) = arrIn()(rws, 1).Value 'Works'.. because of how VBA “works”, This extra () will ensure that indices are always returned to the resulting array (and not occasionally, for example, arguments ) by any following method or property.[/color]
               [color=lightgreen]'Let arrOut()(rws, 1) = arrIn()(rws, 1).Value 'Doesn't - Rory said it aint ever needed on the LHS,  so it aint[/color]
 [color=lightgreen]'   Let arrOut(rws, 1) = Left(arrIn(rws, 1).Value, 4) 'Even A function on the RHS of the = is accepted Here. So again for a non dynamic Array it is not relying on what the function to "define" the type[/color]
    [color=blue]Let[/color] arrOut(rws, 1) = Left(arrIn()(rws, 1).Value, 4) [color=lightgreen]'Works[/color]
              'Let arrOut()(rws, 1) = Left(arrIn()(rws, 1).Value, 4) 'Works
    [color=blue]Next[/color] rws
[color=lightgreen]'         Possibility to Note here:          Dim IntermediateArray() [color=blue]As[/color] Range 'Variant  'Note RoryA Post #2You can only assign one array to another directly (i.e. without looping) if the destination array is dynamic AND THE TWO ARRAYS ARE THE SAME TYPE.[/color]
[color=lightgreen]'                                          '  Re[color=blue]Dim[/color] IntermediateArray(sr [color=blue]To[/color] lr, 1 [color=blue]To[/color] 1)'THIS Line Will NOT Work: RoryA Post #2 http://www.excelforum.com/excel-new-users-basics/1058406-range-dimensioning-range-and-value-referencing-and-referring-to-arrays.html    - You can only assign one array to another directly (i.e. without looping) if the destination array is dynamic[/color]
[color=lightgreen]'                                            Let IntermediateArray() = arrIn()[/color]
 [color=blue]Let[/color] RngD.Value = arrOut() [color=lightgreen]'This is the typical allowed one liner to give values of a Range the values in an  Array (VBA does not allow this one liner in any way for assigning the ranges. There is no way of getting over having to paste each Range Object in a loop.[/color]
 
 [color=blue]End[/color] [color=blue]Sub[/color] [color=lightgreen]'VBAArrayOfRanges1a[/color]
[color=blue]Sub[/color] G10_VBAArrayOfRanges1aa()
[color=lightgreen]'Loop Range of Ranges. VBA Make Array for Output. Output in a "Output Value One Liner"[/color]
[color=lightgreen]'Typical application requiring seperate loops for the (often differnt sized) input and output arrays[/color]
 [color=blue]Dim[/color] wksLG [color=blue]As[/color] Worksheet: [color=blue]Set[/color] wksLG = ThisWorkbook.Worksheets("LeftSpeedsDeutsch")
 [color=blue]Dim[/color] RngName [color=blue]As[/color] Range, RngD [color=blue]As[/color] Range
 [color=blue]Dim[/color] lr [color=blue]As[/color] [color=blue]Long[/color], rws [color=blue]As[/color] [color=blue]Long[/color]
 [color=blue]Let[/color] lr = wksLG.Cells(Rows.Count, 1).End(xlUp).Row
 [color=blue]Dim[/color] sr [color=blue]As[/color] Long: [color=blue]Let[/color] sr = 21
 [color=blue]Set[/color] RngName = wksLG.Range("A" & sr & ":A" & lr & ""): [color=blue]Set[/color] RngD = wksLG.Range("D" & sr & ":D" & lr & "")
 
 Dim arrIn() As Range [color=lightgreen]'Variant 'In the looping, the Set would appear to be responsible for bringing **Ranges into the Array The variable type remains as defined here: Either a range for [color=blue]As[/color] Range or a Variant Object for [color=blue]As[/color] Variant[/color]
 [color=blue]ReDim[/color] arrIn(sr [color=blue]To[/color] lr, 1 [color=blue]To[/color] 1) [color=lightgreen]'We must give array a size as we give specific value in a loop. ReDim Must be used rather than [color=blue]Dim[/color] as [color=blue]Dim[/color] only takes Numbers not variables[/color]
 
 Dim EmtpyInArrIndiciesCount As Long: [color=blue]Let[/color] EmtpyInArrIndiciesCount = 0 [color=lightgreen]'Here possibility to Redim ArrIn if any extra conitions, such as MSRD etc unique entries being ommited, leading to unused indicies.. then###[/color]
 
 
    [color=blue]For[/color] rws = sr To lr [color=blue]Step[/color] 1 [color=lightgreen]'Input Array of Ranges[/color]
        [color=blue]If[/color] Range("A" & rws & "").Value <> "" [color=blue]Then[/color]
        [color=blue]Set[/color] arrIn(rws - EmtpyInArrIndiciesCount, 1) = Range("A" & rws & "")  [color=lightgreen]'The extra "  - Emtp...." will take inidie niumber back accordingly to fill just after next free indicie[/color]
        [color=lightgreen]'Set arrIn((rws - EmtpyInArrIndiciesCount, 1) = wksLG.Range("A" & rws & "") 'This would be tolerate**[/color]
        [color=blue]Else[/color]
        [color=blue]Let[/color] EmtpyInArrIndiciesCount = EmtpyInArrIndiciesCount + 1
        [color=blue]End[/color] [color=blue]If[/color]
    [color=blue]Next[/color] rws
 
 Dim arrOut() As [color=blue]String[/color] [color=lightgreen]'We can use string as in the looping below as we are not relying on (/seeing) a range object to rturn us an array of values.[/color]
 [color=blue]ReDim[/color] arrOut(sr To lr - EmtpyInArrIndiciesCount, 1 To 1) [color=lightgreen]'Antoher way to look at it is to say we have a fixed, rather than dynamiy array, and as VBA does not allow a direct assigning one liner in this case it is also not necerssarily expecting to see an object. For Let it is likely to expect to see some value, and for Set an object (Would expect an Range Object if indicies of arrOut were so defined by arrOut() As String initially[/color]
   
    [color=blue]For[/color] rws = sr To lr - EmtpyInArrIndiciesCount [color=blue]Step[/color] 1 [color=lightgreen]'Input Array of Ranges'The extra   - Emtp.... prevents looping to far[/color]
 
            [color=lightgreen]'Let arrOut(rws, 1) = arrIn(rws, 1).Value 'Works 'VBA would appear to recognise this array element as A range as it gives me the Method, Object and property selkection to choose from via intellisense brought in by typing . Dot after the Array elemant[/color]
            [color=lightgreen]'Let arrOut(rws, 1) = arrIn()(rws, 1).Value 'Works'.. because of how VBA “works”, This extra () will ensure that indices are always returned to the resulting array (and not occasionally, for example, arguments ) by any following method or property.[/color]
               [color=lightgreen]'Let arrOut()(rws, 1) = arrIn()(rws, 1).Value 'Dont Work gives empty but Rory said it aint ever needed on the LHS,  so it aint[/color]
    [color=blue]Let[/color] arrOut(rws, 1) = Left(arrIn(rws, 1).Value, 4) [color=lightgreen]'Even A function on the RHS of the = is accepted Here. So again for a non dynamic Array it is not relying on what the function to "define" the type[/color]
[color=lightgreen]'    Let arrOut(rws, 1) = Left(arrIn()(rws, 1).Value, 4) 'Works[/color]
              [color=lightgreen]'Let arrOut()(rws, 1) = Left(arrIn()(rws, 1).Value, 4) 'Works[/color]
    [color=blue]Next[/color] rws
[color=lightgreen]'         Possibility to Note here:          Dim IntermediateArray() [color=blue]As[/color] Range 'Variant  'Note RoryA Post #2You can only assign one array to another directly (i.e. without looping) if the destination array is dynamic AND THE TWO ARRAYS ARE THE SAME TYPE.[/color]
[color=lightgreen]'                                          '  ReDim IntermediateArray(sr To lr, 1 To 1)'THIS Line Will NOT Work: RoryA Post #2 http://www.excelforum.com/excel-new-users-basics/1058406-range-dimensioning-range-and-value-referencing-and-referring-to-arrays.html    - You can only assign one array to another directly (i.e. without looping) if the destination array is dynamic[/color]
[color=lightgreen]'                                            Let IntermediateArray() = arrIn()[/color]
 [color=blue]Let[/color] RngD.Resize(lr - sr - EmtpyInArrIndiciesCount + 1, 1).Value = arrOut() [color=lightgreen]'This is the typical allowed one liner to give values of a Range the values in an  Array (VBA does not allow this one liner in any way for assigning the ranges. There is no way of getting over having to paste each Range Object in a loop. 'The extra size corrections prevents a NoValue error placed in last cell if trying to assign to indicies that are not there[/color]
 
[color=lightgreen]''        'Long winded alternative to give an empty indicie rather than no indicie to prevent6 output error[/color]
[color=lightgreen]''        ' 1)Because we assign the Array using the Value property of a range, the returned array has lower bounds[/color]
[color=lightgreen]''        ' of 1 for each dimension. When we redim it without providing lower bounds explicitly,[/color]
[color=lightgreen]''        ' the redim tries to assign each dimension the default lower bound, which is 0 giving an error.[/color]
[color=lightgreen]''        ' So we need to explicitly provide the lower bounds[/color]
[color=lightgreen]''        ' 2) Only the size of the last dimension can be changed for a non dynamic arrange. We want to change the first.[/color]
[color=lightgreen]''        ' So we do a transpose trick for that problem[/color]
[color=lightgreen]''        ' 3) Preseve ensures we do not loose the info already there.   (Post #11   http://www.mrexcel.com/forum/excel-questions/830139-proper-redim-preserve-syntax-best-practice-2.html#post4049584)[/color]
[color=lightgreen]''        ' 4) Would only be needed if arrOut has only 1 column as the Transpose does some thing wiered .. does not give 1 to 1 back.. gives normal array...just 1 indicie in ()[/color]
[color=lightgreen]'        Dim TempTranspose() [color=blue]As[/color] Variant 'Must be variant as seeing a Function below in a "one Liner" which returns a collection which VBA will always guess as an Array because Rory-a-Romping Archibald said so to me... a few times now!!![/color]
[color=lightgreen]'        Let TempTranspose = Application.WorksheetFunction.Transpose(arrOut) 'This woulöd annoyingly take for example 21 to 23 , 1 to 1   and give back ... 1 to 3   ONLY!![/color]
[color=lightgreen]'        ReDim Preserve arrOut(sr [color=blue]To[/color] lr - EmtpyInArrIndiciesCount, 1 [color=blue]To[/color] 2) 'This  extra bodge 4  '- Seems to be necerssary to make at least bigger than 1 column - goes from for example 21-23, 1 to 1   > Redim Preserve > 21-23, 1 to 2[/color]
[color=lightgreen]'        Let TempTranspose = Application.WorksheetFunction.Transpose(arrOut) 'Important.. transposes, but > is 1 to 2, ... 1 to 3 ... so would appoear always to start at 1[/color]
[color=lightgreen]'        ReDim Preserve TempTranspose(1 To 2, 1 [color=blue]To[/color] lr - sr + EmtpyInArrIndiciesCount) 'This increase from 3 to 4 columns[/color]
[color=lightgreen]'          'ReDim Preserve TempTranspose(1 [color=blue]To[/color] 2, sr To lr)' This will NOT work!![/color]
[color=lightgreen]'        Let TempTranspose = Application.WorksheetFunction.Transpose(TempTranspose) 'We have the increased row size bot are stuck with the convention of rows starting at 1[/color]
[color=lightgreen]'        Re[color=blue]Dim[/color] Preserve TempTranspose(1 To lr - sr + EmtpyInArrIndiciesCount, 1 To 1) 'This is extra bodge 4 Part 2[/color]
[color=lightgreen]'[/color]
'        Let RngD.Value = TempTranspose
 
 [color=blue]End[/color] [color=blue]Sub[/color] [color=lightgreen]'VBAArrayOfRanges1aa[/color]
[color=lightgreen]'[/color]
'
''
[color=blue]Sub[/color] G11_VBAArrayOfRanges1b()
[color=lightgreen]'Loop Range of Ranges. VBA Make Array for Output. Output in a "Output Value One Liner"[/color]
[color=lightgreen]'Typical application requiring seperate loops for the (often differnt sized) input and output arrays[/color]
[color=lightgreen]'Just an extra direct assigniong bit to demonstrate possibillity of assigning a non dynamic array to a dynamic array in one go, noting [color=blue]Dim[/color] characteristics[/color]
 [color=blue]Dim[/color] wksLG [color=blue]As[/color] Worksheet: [color=blue]Set[/color] wksLG = ThisWorkbook.Worksheets("LeftSpeedsDeutsch")
 [color=blue]Dim[/color] RngName [color=blue]As[/color] Range, RngD [color=blue]As[/color] Range
 Dim lr [color=blue]As[/color] [color=blue]Long[/color], rws [color=blue]As[/color] [color=blue]Long[/color]
 [color=blue]Let[/color] lr = wksLG.Cells(Rows.Count, 1).End(xlUp).Row
 Dim sr As Long: [color=blue]Let[/color] sr = 21
 [color=blue]Set[/color] RngName = wksLG.Range("A" & sr & ":A" & lr & ""): [color=blue]Set[/color] RngD = wksLG.Range("D" & sr & ":D" & lr & "")
 
 Dim arrIn() [color=blue]As[/color] Range [color=lightgreen]'Variant 'In the looping, the Set would appear to be responsible for bringing **Ranges into the Array The variable type remains as defined here: Either a range for [color=blue]As[/color] Range or a Variant Object for As Variant[/color]
 [color=blue]Re[color=blue]Dim[/color][/color] arrIn(sr To lr, 1 To 1) [color=lightgreen]'We must give array a size as we give specific value in a loop. ReDim Must be used rather than Dim as [color=blue]Dim[/color] only takes Numbers not variables[/color]
 
    [color=blue]For[/color] rws = sr To lr [color=blue]Step[/color] 1 [color=lightgreen]'Input Array of Ranges[/color]
    [color=lightgreen]'Set arrIn()(rws, 1) = Range("A" & rws & "") 'Does not work, that is to say produces error later####!!!![/color]
    [color=blue]Set[/color] arrIn(rws, 1) = Range("A" & rws & "") [color=lightgreen]'no error later - we are setting, that is to say "making an object, or rather putting? one in an[/color]
    [color=lightgreen]'Set arrIn(rws, 1) = wksLG.Range("A" & rws & "") 'This would be tolerate**[/color]
    [color=blue]Next[/color] rws
   
   
Dim IntermediateArray() As Range [color=lightgreen]'Variant  'Note RoryA Post #2You can only assign one array to another directly (i.e. without looping) if the destination array is dynamic AND THE TWO ARRAYS ARE THE SAME TYPE.[/color]
[color=lightgreen]'                                          '  ReDim IntermediateArray(sr To lr, 1 To 1)'THIS Line Will NOT Work: RoryA Post #2 http://www.excelforum.com/excel-new-users-basics/1058406-range-dimensioning-range-and-value-referencing-and-referring-to-arrays.html    - You can only assign one array to another directly (i.e. without looping) if the destination array is dynamic[/color]
[color=blue]Let[/color] IntermediateArray() = arrIn() [color=lightgreen]'  ......and the output held in the Array is Variant type and is an OBJECT of the sort like a Range. (This compares with a similar code utilising An Array of Ranges rather than the MicrosoftScriptimeRuntimeDictionary. (In the Array of Ranges case we could Dim as Range or Variant here. - Important however in that case is that the Dynamic IntermediateArray() Array and the (in that Array of Ranges case non dynamic) arrIn() Array are of the same type. - Either both Range to return an Array of element Type Range or both Variant to Return an Array of element Type Of Objects of the Range Sort : - RoryA . You can only assign one array to another directly (i.e. without looping....... and the two arrays are the same type. http://www.excelforum.com/excel-new-users-basics/1058406-range-dimensioning-range-and-value-referencing-and-referring-to-arrays.html[/color]
 
 
 Dim arrOut() As [color=blue]String[/color] [color=lightgreen]'We can use string as in the looping below as we are not relying on (/seeing) a range object to rturn us an array of values.[/color]
 [color=blue]ReDim[/color] arrOut(sr To lr, 1 To 1) [color=lightgreen]'Antoher way to look at it is to say we have a fixed, rather than dynamiy array, and as VBA does not allow a direct assigning one liner in this case it is also not necerssarily expecting to see an object. For Let it is likely to expect to see some value, and for Set an object (Would expect an Range Object if indicies of arrOut were so defined by arrOut() As String initially[/color]
 
    [color=blue]For[/color] rws = sr To lr [color=blue]Step[/color] 1 [color=lightgreen]'Input Array of Ranges[/color]
                [color=lightgreen]'Let arrOut(rws, 1) = IntermediateArray(rws, 1).Value 'VBA would appear to recognise this array element as A range as it gives me the Method, Object and property selkection to choose from via intellisense brought in by typing . Dot after the Array elemant[/color]
            [color=lightgreen]'    Let arrOut(rws, 1) = IntermediateArray(rws, 1).Value'####here comes the error by replaceing Set arrIn(rws, 1) with Set arrIn()(rws, 1) or in the following similar lines[/color]
            [color=lightgreen]'    Let arrOut(rws, 1) = IntermediateArray()(rws, 1).Value.. because of how VBA “works”, This extra () will ensure that indices are always returned to the resulting array (and not occasionally, for example, arguments ) by any following method or property.[/color]
                [color=lightgreen]'    Let arrOut()(rws, 1) = IntermediateArray(rws, 1).Value'Dos not work anyway it aint ever needed on the LHS said Rory,  so it aint[/color]
                    [color=lightgreen]'Let arrOut(rws, 1) = IntermediateArray()(rws, 1).Value[/color]
 [color=lightgreen]'   Let arrOut(rws, 1) = Left(IntermediateArray(rws, 1).Value, 4) 'Even A function on the RHS of the = is accepted Here. So again for a non dynamic Array it is not relying on what the function to "define" the type[/color]
                [color=lightgreen]'Let arrOut()(rws, 1) = Left(IntermediateArray(rws, 1).Value, 4) 'Givers empty[/color]
                [color=lightgreen]'Let arrOut()(rws, 1) = Left(IntermediateArray()(rws, 1).Value, 4)'Gives empty[/color]
    [color=blue]Let[/color] arrOut(rws, 1) = Left(IntermediateArray()(rws, 1).Value, 4)
    [color=blue]Next[/color] rws
   
 [color=blue]Let[/color] RngD.Value = arrOut() [color=lightgreen]'This is the typical allowed one liner to give values of a Range the valiues in an  Array (VBA does not allow this one liner in any way for assigning the ranges. There is no wy of getting over having to paste each Range Object in in a loop.[/color]
 
 [color=blue]End[/color] [color=blue]Sub[/color] [color=lightgreen]'VBAArrayOfRanges1b[/color]
 
 [color=lightgreen]'[/color]
 '
 '
'
[color=blue]Sub[/color] G12_VBAArrayOfRanges2()
[color=lightgreen]'Loop Range of Ranges. VBA Make Array for Output. Output in a "Output Value One Liner"[/color]
[color=lightgreen]'less typical application where any workings can be done within one loop and Input and Output arrays may be similarly sized[/color]
 [color=blue]Dim[/color] wksLG [color=blue]As[/color] Worksheet: [color=blue]Set[/color] wksLG = ThisWorkbook.Worksheets("LeftSpeedsDeutsch")
 [color=blue]Dim[/color] RngName [color=blue]As[/color] Range, RngD [color=blue]As[/color] Range
 [color=blue]Dim[/color] lr [color=blue]As[/color] [color=blue]Long[/color], rws [color=blue]As[/color] [color=blue]Long[/color]
 [color=blue]Let[/color] lr = wksLG.Cells(Rows.Count, 1).End(xlUp).Row
 [color=blue]Dim[/color] sr [color=blue]As[/color] Long: [color=blue]Let[/color] sr = 21
 [color=blue]Set[/color] RngName = wksLG.Range("A" & sr & ":A" & lr & ""): [color=blue]Set[/color] RngD = wksLG.Range("D" & sr & ":D" & lr & "")
 
 [color=blue]Dim[/color] arrIn()  [color=blue]As[/color] Range, arrOut() [color=blue]As[/color] [color=blue]String[/color] [color=lightgreen]'[/color]
 [color=blue]ReDim[/color] arrIn(sr [color=blue]To[/color] lr, 1 [color=blue]To[/color] 1): [color=blue]ReDim[/color] arrOut(sr [color=blue]To[/color] lr, 1 [color=blue]To[/color] 1)
    [color=blue]For[/color] rws = sr [color=blue]To[/color] lr [color=blue]Step[/color] 1 [color=lightgreen]'Input Array of Ranges[/color]
    [color=blue]Set[/color] arrIn(rws, 1) = Range("A" & rws & "")
   
    [color=lightgreen]'        '    Let arrOut()(rws, 1) = Left(arrIn(rws, 1).Value, 4) 'Takes 30.5s and returns empties[/color]
    [color=lightgreen]'        '    Let arrOut()(rws, 1) = Left(arrIn()(rws, 1).Value, 4)'Takes 146s and returns empties[/color]
    [color=lightgreen]'Let arrOut(rws, 1) = Left(arrIn(rws, 1).Value, 4)'Takes 1.5s. "Works"[/color]
    [color=blue]Let[/color] arrOut(rws, 1) = Left(arrIn()(rws, 1).Value, 4) [color=lightgreen]'Takes 115s.  ."Works". because of how VBA “works”, This extra () will ensure that indices are always returned to the resulting array (and not occasionally, for example, arguments ) by any following method or property. It "tolerates" for Let on LHS also (returning empties) (but not for Set in the case of similar line involving Ranges..)..But Rory thinks it would never be needed there anyway, which means it most likely doesn't.[/color]
   
    [color=blue]Next[/color] rws
 
 [color=blue]Let[/color] RngD.Value = arrOut()
 
[color=blue]End[/color] [color=blue]Sub[/color] [color=lightgreen]'VBAArrayOfRanges2[/color]
 
 
[color=blue]Sub[/color] G13_RangeObjectCapture()
[color=lightgreen]'The entire range is captured as One Range Object and its Value2 values accesed and used[/color]
[color=lightgreen]'then as before VBA Make Array for Output. Output in a "Output Value One Liner"[/color]
 [color=blue]Dim[/color] wksLG [color=blue]As[/color] Worksheet: [color=blue]Set[/color] wksLG = ThisWorkbook.Worksheets("LeftSpeedsDeutsch")
 [color=blue]Dim[/color] RngName [color=blue]As[/color] Range, RngD [color=blue]As[/color] Range
 [color=blue]Dim[/color] lr [color=blue]As[/color] [color=blue]Long[/color], rws [color=blue]As[/color] [color=blue]Long[/color]
 [color=blue]Let[/color] lr = wksLG.Cells(Rows.Count, 1).End(xlUp).Row
 [color=blue]Dim[/color] sr [color=blue]As[/color] Long: [color=blue]Let[/color] sr = 21
 [color=blue]Set[/color] RngName = wksLG.Range("A" & sr & ":A" & lr & ""): [color=blue]Set[/color] RngD = wksLG.Range("D" & sr & ":D" & lr & "")
 
 [color=blue]Dim[/color] CapturedRangeObject [color=blue]As[/color] Range [color=lightgreen]'One Range Object for entire range[/color]
 [color=blue]Set[/color] CapturedRangeObject = RngName [color=lightgreen]'Direct assignmet to existing Dimensioned Array[/color]
 
 Dim arrOut() [color=blue]As[/color] [color=blue]String[/color] [color=lightgreen]'We can use string as in the looping below as we are not relying on (/seeing) a range object to return us an array of values.[/color]
 [color=blue]Re[color=blue]Dim[/color][/color] arrOut(sr [color=blue]To[/color] lr, 1 To 1) [color=lightgreen]'Antoher way to look at it is to say we have a fixed, rather than dynamiy array, and as VBA does not allow a direct assigning one liner in this case it is also not necerssarily expecting to see an object. For Let it is likely to expect to see some value, and for Set an object (Would expect an Range Object if indicies of arrOut were so defined by arrOut() As String initially[/color]
 
    [color=blue]For[/color] rws = sr [color=blue]To[/color] lr [color=blue]Step[/color] 1 [color=lightgreen]'Input Array of Ranges[/color]
                           [color=lightgreen]'Let arrOut(rws, 1) = CapturedRangeObject.Value2(rws - sr + 1, 1) 'Conventionally the Value2 values are in an Array starting at ( 1, 1) and extending over the two (in this case just a 1 dimensional array). So a bit of adjusting with the indicies is necerssary[/color]
    [color=blue]Let[/color] arrOut(rws, 1) = Left(CapturedRangeObject.Value2(rws - sr + 1, 1), 4)
    [color=lightgreen]'Let arrOut(rws, 1) = Left(CapturedRangeObject.Value2()(rws - sr + 1, 1), 4) ' because of how VBA “works”, This extra () will ensure that indices are always returned to the resulting array (and not occasionally, for example, arguments ) by any following method or property, or passed to any method or property, (In the "bodge subs it is assigned each time to the full object[/color]
    [color=blue]Next[/color] rws
   
 [color=blue]Let[/color] RngD.Value = arrOut()
 
[color=blue]End[/color] [color=blue]Sub[/color] [color=lightgreen]'RangeObjectCapture()[/color]
[color=blue]Sub[/color] G13b_RangeObjectCapture()
[color=lightgreen]'The entire range is captured as One Range Object and its Value2 values accesed and used[/color]
[color=lightgreen]'then as before VBA Make Array for Output. Output in a "Output Value One Liner"[/color]
 [color=blue]Dim[/color] wksLG [color=blue]As[/color] Worksheet: [color=blue]Set[/color] wksLG = ThisWorkbook.Worksheets("LeftSpeedsDeutsch")
 [color=blue]Dim[/color] RngName [color=blue]As[/color] Range, RngD [color=blue]As[/color] Range
 [color=blue]Dim[/color] lr [color=blue]As[/color] [color=blue]Long[/color], rws [color=blue]As[/color] [color=blue]Long[/color]
 [color=blue]Let[/color] lr = wksLG.Cells(Rows.Count, 1).End(xlUp).Row
 [color=blue]Dim[/color] sr [color=blue]As[/color] Long: [color=blue]Let[/color] sr = 21
 [color=blue]Set[/color] RngName = wksLG.Range("A" & sr & ":A" & lr & ""): [color=blue]Set[/color] RngD = wksLG.Range("D" & sr & ":D" & lr & "")
 
 Dim CapturedRangeObject [color=blue]As[/color] Range [color=lightgreen]'One Range Object for entire range[/color]
 [color=blue]Set[/color] CapturedRangeObject = RngName [color=lightgreen]'Direct assignmet to existing Dimensioned Array[/color]
 
 [color=blue]Dim[/color] arrOut() [color=blue]As[/color] [color=blue]String[/color] [color=lightgreen]'We can use string as in the looping below as we are not relying on (/seeing) a range object to return us an array of values.[/color]
 [color=blue]Re[color=blue]Dim[/color][/color] arrOut(sr [color=blue]To[/color] lr, 1 To 1) [color=lightgreen]'Antoher way to look at it is to say we have a fixed, rather than dynamiy array, and as VBA does not allow a direct assigning one liner in this case it is also not necerssarily expecting to see an object. For Let it is likely to expect to see some value, and for Set an object (Would expect an Range Object if indicies of arrOut were so defined by arrOut() As String initially[/color]
 
  [color=blue]Dim[/color] vTemp() [color=blue]As[/color] [color=blue]Variant[/color] [color=lightgreen]'Post from #20  - #24 .. return the array to a variable and then reference the elements through that variable, in which case you don't need to worry about the extra () . The usual "[color=blue]To[/color] see an object which returns a field" requirement to be dimensioned as Variant[/color]
    [color=lightgreen]'  http://www.mrexcel.com/forum/excel-questions/832103-using-microsoft-scripting-runtime-dictionary-store-then-retrieve-range-objects-3.html[/color]
   
    [color=blue]For[/color] rws = sr To lr [color=blue]Step[/color] 1 [color=lightgreen]'Input Array of Ranges[/color]
    [color=blue]Let[/color] vTemp = CapturedRangeObject.Value2 [color=lightgreen]'Works vTemp is Array of variants values, a Data field[/color]
   
    [color=blue]Let[/color] arrOut(rws, 1) = Left(vTemp(rws - sr + 1, 1), 4)
    [color=lightgreen]'Let arrOut(rws, 1) = Left(vTemp()(rws - sr + 1, 1), 4)'This will not work..[/color]
    [color=blue]Next[/color] rws
   
 [color=blue]Let[/color] RngD.Value = arrOut()
 
[color=blue]End[/color] [color=blue]Sub[/color] [color=lightgreen]'RangeObjectCapture()[/color]
[color=blue]Sub[/color] G13c_RangeObjectCapture()
[color=lightgreen]'The entire range is captured as One Range Object and its Value2 values accesed and used[/color]
[color=lightgreen]'then as before VBA Make Array for Output. Output in a "Output Value One Liner"[/color]
 [color=blue]Dim[/color] wksLG [color=blue]As[/color] Worksheet: [color=blue]Set[/color] wksLG = ThisWorkbook.Worksheets("LeftSpeedsDeutsch")
 [color=blue]Dim[/color] RngName [color=blue]As[/color] Range, RngD [color=blue]As[/color] Range
 [color=blue]Dim[/color] lr [color=blue]As[/color] [color=blue]Long[/color], rws [color=blue]As[/color] [color=blue]Long[/color]
 [color=blue]Let[/color] lr = wksLG.Cells(Rows.Count, 1).End(xlUp).Row
 Dim sr [color=blue]As[/color] Long: [color=blue]Let[/color] sr = 21
 [color=blue]Set[/color] RngName = wksLG.Range("A" & sr & ":A" & lr & ""): [color=blue]Set[/color] RngD = wksLG.Range("D" & sr & ":D" & lr & "")
 
 Dim CapturedRangeObject [color=blue]As[/color] Range [color=lightgreen]'One Range Object for entire range[/color]
 [color=blue]Set[/color] CapturedRangeObject = RngName [color=lightgreen]'Direct assignmet to existing [color=blue]Dim[/color]ensioned Array[/color]
 
 Dim arrOut() [color=blue]As[/color] [color=blue]String[/color] [color=lightgreen]'We can use string as in the looping below as we are not relying on (/seeing) a range object to return us an array of values.[/color]
 [color=blue]ReDim[/color] arrOut(sr To lr, 1 To 1) [color=lightgreen]'Antoher way to look at it is to say we have a fixed, rather than dynamiy array, and as VBA does not allow a direct assigning one liner in this case it is also not necerssarily expecting to see an object. For Let it is likely to expect to see some value, and for Set an object (Would expect an Range Object if indicies of arrOut were so defined by arrOut() As String initially[/color]
 
  Dim vTemp [color=blue]As[/color] [color=blue]Variant[/color] [color=lightgreen]'Post from #20  - #24 .. return the array to a variable and then reference the elements through that variable, in which case you don't need to worry about the extra () . (The usual "To see an (Range) object which returns a field" requirement to be dimensioned as Variant - Post #13 Post #14 http://www.excelforum.com/excel-programming-vba-macros/1058171-return-row-index-and-column-index-of-a-cell-in-a-range.html[/color]
    [color=lightgreen]'  http://www.mrexcel.com/forum/excel-questions/832103-using-microsoft-scripting-runtime-dictionary-store-then-retrieve-range-objects-3.html[/color]
 
  [color=blue]Let[/color] vTemp = CapturedRangeObject.Value2 [color=lightgreen]'Works vTemp is Array of variants values, a Data field[/color]
   
    [color=blue]For[/color] rws = sr To lr [color=blue]Step[/color] 1 [color=lightgreen]'Input Array of Ranges[/color]
               
                    [color=lightgreen]'Let arrOut()(rws, 1) = Left(vTemp(rws - sr + 1, 1), 4) 'Tolerates the Extra () on the LHS but rerurns empties and takes usually lots longer, here (for 33928 Rows) 30.5s .. compared to _-[/color]
    [color=blue]Let[/color] arrOut(rws, 1) = Left(vTemp(rws - sr + 1, 1), 4) [color=lightgreen]'  ... takes 0.325s for 33928 Rows.[/color]
      [color=lightgreen]'Let arrOut(rws, 1) = Left(vTemp()(rws - sr + 1, 1), 4) 'wont work ????? ####1 Error 9: Index out of valid Range[/color]
    [color=blue]Next[/color] rws
   
 [color=blue]Let[/color] RngD.Value = arrOut()
 
[color=blue]End[/color] [color=blue]Sub[/color] [color=lightgreen]'RangeObjectCaptureC()[/color]
 
 
 
 
 
 
 [color=blue]Sub[/color] G13_RangeObjectCaptureExcelForumDemo()
[color=lightgreen]'The entire range is captured as One Range Object and its Value2 values accesed and used[/color]
[color=lightgreen]'then in VBA Make an Array for Output. Output in a "Output Value One Liner"[/color]
[color=lightgreen]'(Demonstrating also advantage and characteristics of temporary intermediateArray)[/color]
 [color=blue]Dim[/color] wksLG [color=blue]As[/color] Worksheet: [color=blue]Set[/color] wksLG = ThisWorkbook.Worksheets("LeftSpeedsDeutsch")
 [color=blue]Dim[/color] RngName [color=blue]As[/color] Range, RngD [color=blue]As[/color] Range
 [color=blue]Dim[/color] lr [color=blue]As[/color] [color=blue]Long[/color], rws [color=blue]As[/color] [color=blue]Long[/color]
 [color=blue]Let[/color] lr = wksLG.Cells(Rows.Count, 1).End(xlUp).Row
 [color=blue]Dim[/color] sr [color=blue]As[/color] Long: [color=blue]Let[/color] sr = 21
 [color=blue]Set[/color] RngName = wksLG.Range("A" & sr & ":A" & lr & ""): [color=blue]Set[/color] RngD = wksLG.Range("D" & sr & ":D" & lr & "")
 
 [color=blue]Dim[/color] CapturedRangeObject [color=blue]As[/color] Range [color=lightgreen]'          One Range Object for entire range[/color]
 [color=blue]Set[/color] CapturedRangeObject = RngName [color=lightgreen]'         Direct assignmet to existing Dimensioned Array[/color]
 
 Dim arrOut() [color=blue]As[/color] [color=blue]String[/color] [color=lightgreen]'We can use string as in the looping below as we are not relying on (/seeing) a range object to return us an array of values.[/color]
 [color=blue]Re[color=blue]Dim[/color][/color] arrOut(sr [color=blue]To[/color] lr, 1 To 1) [color=lightgreen]'Antoher way to look at it is to say we have a fixed, rather than dynamiy array, and as VBA does not allow a direct assigning one liner in this case it is also not necerssarily expecting to see an object. For Let it is likely to expect to see some value, and for Set an object (Would expect an Range Object if indicies of arrOut were so defined by arrOut() As String initially[/color]
 
  Dim vTemp [color=blue]As[/color] [color=blue]Variant[/color] [color=lightgreen]'                                       Post from #20  - #24 .. return the array to a variable and then reference the elements through that variable, in which case you don't need to worry about the extra () . (The usual "[color=blue]To[/color] see an (Range) object which returns a field" requirement to be dimensioned as Variant - Post #13 Post #14 http://www.excelforum.com/excel-programming-vba-macros/1058171-return-row-index-and-column-index-of-a-cell-in-a-range.html[/color]
                                                                                              [color=lightgreen]'  http://www.mrexcel.com/forum/excel-questions/832103-using-microsoft-scripting-runtime-dictionary-store-then-retrieve-range-objects-3.html[/color]
  [color=blue]Let[/color] vTemp = CapturedRangeObject.Value2 [color=lightgreen]'Works vTemp is Array of variants values, a Data field[/color]
   
    [color=blue]For[/color] rws = sr To lr [color=blue]Step[/color] 1 [color=lightgreen]'Input Array of Ranges[/color]
   
    [color=blue]Let[/color] [COLOR="#FF0000"]arrOut(rws, 1) = Left(CapturedRangeObject.Value2(rws - sr + 1, 1), 4)[/COLOR] [color=lightgreen]'Works  1651.5s 33928 Rows. 3.85 1654 Rows                                           Conventionally the Value2 values are in an Array starting at ( 1, 1) and extending over the two (in this case just a 1 dimensional array). So a bit of adjusting with the indicies is necerssary[/color]
    [color=blue]Let[/color] [COLOR="#800000"]arrOut(rws, 1) = Left(CapturedRangeObject.Value2()(rws - sr + 1, 1), 4)[/COLOR] [color=lightgreen]'Works  1667s 33928 Rows.  3.85 1654 Rows                                                        because of how VBA “works”, This extra () will ensure that indices are always returned to the resulting array (and not occasionally, for example, arguments ) by any following method or property, or passed to any method or property, (In the "bodge subs it is assigned each time to the full object[/color]
    [color=blue]Let[/color] [COLOR="#FF8C00"]arrOut()(rws, 1) = Left(CapturedRangeObject.Value2(rws - sr + 1, 1), 4)[/COLOR] [color=lightgreen]'Returns Empties ????? #2) 991.5s 33928 Rows. 3.85 1654 Rows[/color]
    [color=blue]Let[/color] [COLOR="#008000"]arrOut()(rws, 1) = Left(CapturedRangeObject.Value2()(rws - sr + 1, 1), 4)[/COLOR] [color=lightgreen]'Returns Empties ????? #2) 1696s 33928 Rows. 3.85 1654 Rows[/color]
       
    [color=blue]Let[/color] [COLOR="#800080"]arrOut(rws, 1) = Left(vTemp(rws - sr + 1, 1), 4)[/COLOR] [color=lightgreen]'Works 0.325s for 33928 Rows. 0.018 1654 Rows.      This amazing speed is easilly explained as in this SIMPLIFIED examplse file the code is working similar to the "VBA Array" version of my typical answers to sorting Threads which demonstrates the advantage of working with arrays over my alternative "Spreadsheet" type Solution which I usually also give in the Sorting Threads that I answer..[/color]
      [color=blue]Let[/color] [COLOR="#696969"]arrOut(rws, 1) = Left(vTemp()(rws - sr + 1, 1), 4)[/COLOR] [color=lightgreen]'wont work ????? #1 Error 9: Index out of valid Range[/color]
    [color=blue]Let[/color] [COLOR="#40E0D0"]arrOut()(rws, 1) = Left(vTemp(rws - sr + 1, 1), 4)[/COLOR] [color=lightgreen]'Returns Empties. ????? #2) 30.5s 33928 Rows.. 0.088 1654 Rows    Tolerates the Extra () on the LHS but rerurns empties and takes usually lots longer 30.5s 33928 Rows..[/color]
      [color=blue]Let[/color] [COLOR="#0000CD"]arrOut(rws, 1) = Left(vTemp()(rws - sr + 1, 1), 4)[/COLOR] [color=lightgreen]'wont work ????? #1 Error 9: Index out of valid Range[/color]
   
    [color=blue]Next[/color] rws
   
 [color=blue]Let[/color] RngD.Value = arrOut() [color=lightgreen]'                  the Array of Values is outputted in the typical one liner exclusively allowed to values only[/color]
 
[color=blue]End[/color] [color=blue]Sub[/color] [color=lightgreen]'G13_RangeObjectCaptureExcelForumDemo()[/color]
 
 
 
[color=lightgreen]'[/color]
'
'
[color=blue]Sub[/color] G14_MicrosoftScriptingRuntimeDictionaryRangeOfRangesKeysItems1()
[color=lightgreen]'Similar to the Array of Range ranges, except that the Ranges are held in a full MSRD[/color]
[color=lightgreen]'Lots of interaction with the spreadsheet, including the use of a temporary cell for use of unique key characteristic.[/color]
 [color=blue]Dim[/color] wksLG [color=blue]As[/color] Worksheet: [color=blue]Set[/color] wksLG = ThisWorkbook.Worksheets("LeftSpeedsDeutsch")
 [color=blue]Dim[/color] RngName [color=blue]As[/color] Range, RngD [color=blue]As[/color] Range
 [color=blue]Dim[/color] lr [color=blue]As[/color] [color=blue]Long[/color], rws [color=blue]As[/color] [color=blue]Long[/color]
 [color=blue]Let[/color] lr = wksLG.Cells(Rows.Count, 1).End(xlUp).Row
 [color=blue]Dim[/color] sr [color=blue]As[/color] Long: [color=blue]Let[/color] sr = 21
 [color=blue]Set[/color] RngName = wksLG.Range("A" & sr & ":A" & lr & ""): [color=blue]Set[/color] RngD = wksLG.Range("D" & sr & ":D" & lr & "")
 
[color=lightgreen]' 1)  'Part 1: Setting up Scriptimg Runtime Stuff-----------------------------[/color]
[color=lightgreen]' Attempting Using the Microsooft Scripting Runtime Dictionary to store Range Objects[/color]
 
[color=lightgreen]'We put the unique values now into a Dictionary for later look up purposes:[/color]
[color=lightgreen]'--requires library reference to MS Scripting Runtime (Early Binding)-[/color]
[color=lightgreen]'        Tools>>References>>scrolldown and check the box next to Microsoft Scripting Runtime[/color]
[color=lightgreen]'  ..Or crashes at next line.....[/color]
 [color=blue]Dim[/color] dicLookupTable [color=blue]As[/color] Scripting.Dictionary [color=lightgreen]'Data held with a unique "Key"or Part Number.[/color]
 [color=blue]Set[/color] dicLookupTable = [color=blue]New[/color] Scripting.Dictionary
[color=lightgreen]' 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.[/color]
[color=lightgreen]'        Dim dicLookupTable As Object[/color]
[color=lightgreen]'        Set dicLookupTable = CreateObject("Scripting.Dictionary")[/color]
[color=lightgreen]' Late Binding is better when sharing files as I am here. Early Binding has the advantage that Excel intellisense[/color]
[color=lightgreen]' will then work for the Microsoft Scripüting Runtime stuff and give you suggestions after you type the .dot thing[/color]
 
     dicLookupTable.CompareMode = vbTextCompare [color=lightgreen]'Not quite sure wot this does yet[/color]
 
[color=lightgreen]'.  A Dictionary in VBA is a collection of objects :you can store all kinds of things in it.[/color]
[color=lightgreen]'.  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.[/color]
[color=lightgreen]'.  (Although the Dictionary has not been designed for that purpose it's a nice side effect.)[/color]
 
[color=lightgreen]'End of Part 1 initial set up Of Scripting Runtime------------------------[/color]
 
 [color=lightgreen]'Dim j As Long ', i [color=blue]As[/color] Long  'LoopBoundVariableCounts used in looping here and at end-----[/color]
 
 [color=blue]Dim[/color] TempColumn [color=blue]As[/color] Long: [color=blue]Let[/color] TempColumn = Columns.Count: [color=blue]Let[/color] TempColumn = 6  [color=lightgreen]'Usually when not debugging comment out last let so Temp Column is last in sheet given by Columns.count....[/color]
 [color=blue]Dim[/color] TempCell [color=blue]As[/color] Range: [color=blue]Set[/color] TempCell = wksLG.Cells(1, TempColumn): [color=blue]Dim[/color] TempCellOffset [color=blue]As[/color] [color=blue]Long[/color]: [color=blue]Let[/color] TempCellOffset = 0 [color=lightgreen]'....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 )[/color]
 [color=lightgreen]'2a) Part2a) Looping to put Range Objects in MRSD[/color]
    [color=lightgreen]'For i = StartColumnTableOutput To LastColumnTableOutput Step 1[/color]
        [color=blue]For[/color] rws = sr [color=blue]To[/color] lr [color=blue]Step[/color] 1
          [color=blue]If[/color] wksLG.Cells(rws, 1).Value <> "" [color=blue]Then[/color] [color=lightgreen]'If cell is not empty then...[/color]
               [color=blue]If[/color] [color=blue]Not[/color] dicLookupTable.Exists(wksLG.Cells(rws, 1).Value) [color=blue]Then[/color] [color=lightgreen]'check that the unique value does not already exist. ##NOTE[/color]
                  dicLookupTable.Add wksLG.Cells(rws, 1).Value, wksLG.Cells(rws, 1) [color=lightgreen]'it is easier to understand as well as kind of explicit the first argument does a CStr and the Second Takes anything[/color]
               [color=blue]Else[/color] [color=lightgreen]'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[/color]
               [color=blue]Let[/color] TempCellOffset = TempCellOffset + 1
               [color=blue]Let[/color] TempCell.Offset(TempCellOffset, 0).Value = "Duplicate at   " & rws & " | " & 1 & ""
               wksLG.Cells(rws, 1).Interior.Color = 10987519
               dicLookupTable.Add TempCell.Offset(TempCellOffset, 0).Value, wksLG.Cells(rws, 1) [color=lightgreen]'In case of duplicate we need a unique key, but we stillinclude the Duplicate Range[/color]
               [color=blue]End[/color] [color=blue]If[/color]
           [color=blue]Else[/color] [color=lightgreen]'Case r an empty cell - inform of empty cell by writing message in that cell via the Tempory cell[/color]
           [color=blue]Let[/color] TempCellOffset = TempCellOffset + 1 [color=lightgreen]'Go to next free tempory cell in tempory column[/color]
           [color=blue]Let[/color] TempCell.Offset(TempCellOffset, 0).Value = "Empty Cell at   " & rws & " | " & 1 & ""
           dicLookupTable.Add TempCell.Offset(TempCellOffset, 0).Value, TempCell.Offset(TempCellOffset, 0)
           [color=blue]End[/color] [color=blue]If[/color]
        [color=blue]Next[/color] rws
    [color=lightgreen]'Next i[/color]
'End Part 2-----------------------------------------------------------
 
 [color=lightgreen]'3) Part 3)--transfer range objects from dictionary to array of ranges in one go, typical Array assignment "One Liner" - The quick way to place data into an array is to dimension a variable ( for example rResults ) ....>>[/color]
 [color=blue]Dim[/color] IntermediateArray() As [color=blue]Variant[/color] [color=lightgreen]'... [color=blue]As[/color] a Variant and then the "Let IntermediateArray  = " code line Using a variant allows BOTH .-1) for capturing Objects, text, numbers, blanks  errors etc. from those cells and also 2) allows rResults to be an array variable.....[/color]
 [color=blue]Let[/color] IntermediateArray() = dicLookupTable.Items() [color=lightgreen]'... In this case it will also accept us quasi pre - defining as Array with the pair of parentheses IntermediateArray()[/color]
 [color=lightgreen]'End part 3)--- NOTE: this gives automatically the 0 to _ convention in IntermediateArray Array!.        >>>.....and the output held in the Array is Variant type and is an OBJECT of the sort like a Range. (This compares with a similar code utilising An Array of Ranges rather than the MicrosoftScriptimeRuntimeDictionary. (In the Array of Ranges case we could Dim as Range or Variant here. - Important however in that case is that the Dynamic IntermediateArray() Array and the (in that Array of Ranges case non dynamic) arrIn() Array are of the same type. - Either both Range to return an Array of element Type Range or both Variant to Return an Array of element Type Of Objects of the Range Sort : - RoryA . You can only assign one array to another directly (i.e. without looping....... and the two arrays are the same type. http://www.excelforum.com/excel-new-users-basics/1058406-range-dimensioning-range-and-value-referencing-and-referring-to-arrays.html[/color]
 
 [color=blue]Dim[/color] arrOut() As [color=blue]String[/color] [color=lightgreen]'We can use string as in the looping below as we are not relying on (/seeing) a range object to rturn us an array of values.[/color]
 [color=blue]ReDim[/color] arrOut(sr [color=blue]To[/color] lr, 1 [color=blue]To[/color] 1) [color=lightgreen]'Antoher way to look at it is to say we have a fixed, rather than dynamiy array, and as VBA does not allow a direct assigning one liner in this case it is also not necerssarily expecting to see an object. For Let it is likely to expect to see some value, and for Set an object (Would expect an Range Object if indicies of arrOut were so defined by arrOut() [color=blue]As[/color] String initially[/color]
 
    [color=blue]For[/color] rws = sr To lr [color=blue]Step[/color] 1 [color=lightgreen]'Input Array of Ranges[/color]
        [color=lightgreen]'Let arrOut(rws, 1) = IntermediateArray(rws - sr).Value 'VBA would appear to recognise this array element as A range as it gives me the Method, Object and property selkection to choose from via intellisense brought in by typing . Dot after the Array elemant[/color]
[color=lightgreen]'    Let arrOut(rws, 1) = Left(dicLookupTable.Items(rws - sr).Value, 4)[/color]
[color=lightgreen]'    Let arrOut(rws, 1) = Left(dicLookupTable.Items()(rws - sr).Value, 4)[/color]
   
[color=lightgreen]'    Let arrOut(rws, 1) = Left(IntermediateArray(rws - sr).Value, 4) 'Even A function on the RHS of the = is accepted Here. So again for a non dynamic Array it is not relying on what the function to "define" the type[/color]
[color=lightgreen]'    Let arrOut(rws, 1) = Left(IntermediateArray()(rws - sr).Value, 4)[/color]
 
[color=lightgreen]'    Let arrOut(rws, 1) = Left(dicLookupTable.Keys(rws - sr), 4)[/color]
    [color=blue]Let[/color] arrOut(rws, 1) = Left(dicLookupTable.Keys()(rws - sr), 4)
    [color=blue]Next[/color] rws
 
 [color=blue]Let[/color] RngD.Value = arrOut()
 [color=lightgreen]'   Let RngD.Value = IntermediateArray() 'This should not do anything.. interestingly gives value from first Cell in RngName,[/color]
 
 [color=blue]Set[/color] dicLookupTable = [color=blue]Nothing[/color] [color=lightgreen]'Genarally good practice to turn these thimgs off. 'May not be needed but to keep program flexible should alterations need it.[/color]
 
[color=blue]End[/color] [color=blue]Sub[/color] [color=lightgreen]'MicrosoftScriptimeRuntimeDictionaryRangeOfRangesKeysItems1()[/color]
 
 
 
 
[color=lightgreen]'[/color]
'
[color=blue]Sub[/color] G15_MicrosoftScriptimeRuntimeDictionaryRangeOfRangesKeys()
[color=lightgreen]'Similar to the Array of Range ranges, except that the Ranges are held in the MSRD Key. Strange but it can!![/color]
[color=lightgreen]'A bit less Lots of interaction with the spreadsheet, as the temp for the unique is not there - we are using the key,[/color]
[color=lightgreen]'so all ranges are unique keys we simply include that duplicateentry, that is to say the output array may be a bit shorter.[/color]
[color=lightgreen]'Also the cell my be empty but the RANGE cannot be="" so for it's "value" VBA writes "Empty" !![/color]
 [color=blue]Dim[/color] wksLG [color=blue]As[/color] Worksheet: [color=blue]Set[/color] wksLG = ThisWorkbook.Worksheets("LeftSpeedsDeutsch")
 [color=blue]Dim[/color] RngName [color=blue]As[/color] Range, RngD [color=blue]As[/color] Range
 [color=blue]Dim[/color] lr [color=blue]As[/color] [color=blue]Long[/color], rws [color=blue]As[/color] Long
 [color=blue]Let[/color] lr = wksLG.Cells(Rows.Count, 1).End(xlUp).Row
 [color=blue]Dim[/color] sr [color=blue]As[/color] Long: [color=blue]Let[/color] sr = 21
 [color=blue]Set[/color] RngName = wksLG.Range("A" & sr & ":A" & lr & ""): [color=blue]Set[/color] RngD = wksLG.Range("D" & sr & ":D" & lr & "")
 
[color=lightgreen]' 1)  'Part 1b: Setting up Scriptimg Runtime Stuff-----------------------------[/color]
[color=lightgreen]'Using the Microsoft Scripting Runtime Dictionary KEYS ONLY to store Range Objects... A bit like saying "....(It is certainly a crazy concept if you think about it….Like saying in a Filing Cabinet I have a piece of paper for every House in a town with all the plans and details of the house in it. The parallel idea to the Keys being able to be almost anything would be that instead of the piece of paper I could a Duplicate of every House in the filing cabinet!!! ). ...." Alan :- Post #10 http://www.mrexcel.com/forum/excel-questions/832103-using-microsoft-scripting-runtime-dictionary-store-then-retrieve-range-objects.html[/color]
 
[color=lightgreen]'We put the unique values now into a Dictionary for later look up purposes:[/color]
[color=lightgreen]'--requires library reference to MS Scripting Runtime (Early Binding)-[/color]
[color=lightgreen]'        Tools>>References>>scrolldown and check the box next to Microsoft Scripting Runtime[/color]
[color=lightgreen]'  ..Or crashes at next line.....[/color]
 [color=blue]Dim[/color] dicLookupTable As Scripting.Dictionary [color=lightgreen]'Data held with a unique "Key"or Part Number.[/color]
 [color=blue]Set[/color] dicLookupTable = [color=blue]New[/color] Scripting.Dictionary
[color=lightgreen]' 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.[/color]
[color=lightgreen]'        Dim dicLookupTable As Object[/color]
[color=lightgreen]'        Set dicLookupTable = CreateObject("Scripting.Dictionary")[/color]
[color=lightgreen]' Late Binding is better when sharing files as I am here. Early Binding has the advantage that Excel intellisense[/color]
[color=lightgreen]' will then work for the Microsoft Scripüting Runtime stuff and give you suggestions after you type the .dot thing[/color]
 
     dicLookupTable.CompareMode = vbTextCompare [color=lightgreen]'Not quite sure wot this does yet[/color]
 
[color=lightgreen]'.  A Dictionary in VBA is a collection of objects :you can store all kinds of things in it.[/color]
[color=lightgreen]'.  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.[/color]
[color=lightgreen]'.  (Although the Dictionary has not been designed for that purpose it's a nice side effect.)[/color]
 
[color=lightgreen]'End of Part 1b initial set up Of Scripting Runtime------------------------[/color]
 
   [color=lightgreen]'Dim j As Long ', i As Long  'LoopBoundVariableCounts used in looping here and at end-----[/color]
 [color=lightgreen]'Dim TempCell [color=blue]As[/color] Range: Set TempCell = wksLG.Cells(1, Columns.Count): Dim TempCellOffset As Long: Let TempCellOffset = 0 'We choose a cell (or through the later use of the offset a column) to use for Duplicate or Empty cells. We use the last column in the sheet. (This is genarally a good practice as it will not effect attempts with .End(XltoLeft) to find last column[/color]
 [color=lightgreen]'2a) Part2a) Looping to put Range Objects in MRSD[/color]
    [color=lightgreen]'For i = StartColumnTableOutput [color=blue]To[/color] LastColumnTableOutput Step 1[/color]
        [color=blue]For[/color] rws = sr [color=blue]To[/color] lr [color=blue]Step[/color] 1
           [color=blue]If[/color] wksLG.Cells(rws, 1).Value <> "" [color=blue]Then[/color] [color=lightgreen]'If RANGE is not there...[/color]
[color=lightgreen]'               If Not dicLookupTable.Exists(wksLG.Cells(rws, 1).Value) Then 'check that the unique value does not already exist. ##NOTE[/color]
                  dicLookupTable.Add wksLG.Cells(rws, 1), [color=blue]Nothing[/color] [color=lightgreen]'it is easier to understand as well as kind of explicit the first argument does a CStr and the Second Takes anything[/color]
[color=lightgreen]'               Else 'The key is the Range which is always unique[/color]
[color=lightgreen]'               End If[/color]
           [color=blue]Else[/color] [color=lightgreen]'Case r an empty cell. We habe a choice by virtue of us using Newlr below to do nothing.. or..[/color]
           [color=blue]Let[/color] wksLG.Cells(rws, 1).Value = "Anything" [color=lightgreen]'.. we could have done nothing - for the case of the Let function it does not erro just gives nothing[/color]
           dicLookupTable.Add wksLG.Cells(rws, 1), [color=blue]Nothing[/color] [color=lightgreen]'.. chose here it to give key anyway and..[/color]
           [color=blue]End[/color] [color=blue]If[/color]
        [color=blue]Next[/color] rws
    [color=lightgreen]'Next i[/color]
'End Part 2-----------------------------------------------------------
 
 [color=lightgreen]'3) Part 3)--transfer range objects from dictionary to array of ranges in one go, typical Array assignment "One Liner" - The quick way to place data into an array is to dimension a variable ( for example rResults ) ....>>[/color]
 [color=blue]Dim[/color] IntermediateArray() [color=blue]As[/color] [color=blue]Variant[/color] [color=lightgreen]'... [color=blue]As[/color] a Variant and then the "Let IntermediateArray  = " code line Using a variant allows BOTH .-1) for capturing Objects, text, numbers, blanks  errors etc. from those cells and also 2) allows rResults to be an array variable.....[/color]
 [color=blue]Let[/color] IntermediateArray() = dicLookupTable.Keys() [color=lightgreen]'... In this case it will also accept us quasi pre - defining as Array with the pair of parentheses IntermediateArray()[/color]
 [color=lightgreen]'End part 3)--- NOTE: this gives automatically the 0 to _ convention in IntermediateArray Array!.        >>>.....and the output held in the Array is Variant type and is an OBJECT of the sort like a Range. (This compares with a similar code utilising An Array of Ranges rather than the MicrosoftScriptimeRuntimeDictionary. (In the Array of Ranges case we could Dim as Range or Variant here. - Important however in that case is that the Dynamic IntermediateArray() Array and the (in that Array of Ranges case non dynamic) arrIn() Array are of the same type. - Either both Range to return an Array of element Type Range or both Variant to Return an Array of element Type Of Objects of the Range Sort : - RoryA . You can only assign one array to another directly (i.e. without looping....... and the two arrays are the same type. http://www.excelforum.com/excel-new-users-basics/1058406-range-dimensioning-range-and-value-referencing-and-referring-to-arrays.html[/color]
 
 [color=blue]Dim[/color] Newlr As Long: [color=blue]Let[/color] Newlr = [color=blue]UBound[/color](IntermediateArray(), 1) + sr [color=lightgreen]'This is importent when looping through dicLookupTable.Keys so that for one or more empty cell not given a key we do not try to loop too far[/color]
 [color=blue]Dim[/color] arrOut() As [color=blue]String[/color] [color=lightgreen]'We can use string as in the looping below as we are not relying on (/seeing) a range object to rturn us an array of values.[/color]
 [color=blue]ReDim[/color] arrOut(sr [color=blue]To[/color] Newlr, 1 [color=blue]To[/color] 1) [color=lightgreen]'Antoher way to look at it is to say we have a fixed, rather than dynamiy array, and as VBA does not allow a direct assigning one liner in this case it is also not necerssarily expecting to see an object. For Let it is likely to expect to see some value, and for Set an object (Would expect an Range Object if indicies of arrOut were so defined by arrOut() As String initially. We could leave Nerlr as lr - doesn't matter if output array is bit too big[/color]
 
    [color=blue]For[/color] rws = sr To Newlr [color=blue]Step[/color] 1 [color=lightgreen]'Input Array of Ranges[/color]
            [color=lightgreen]'Let arrOut(rws, 1) = IntermediateArray(rws - sr).Value 'VBA would appear to recognise this array element as A range as it gives me the Method, Object and property selkection to choose from via intellisense brought in by typing . Dot after the Array elemant[/color]
    [color=blue]Let[/color] arrOut(rws, 1) = Left(dicLookupTable.Keys(rws - sr).Value, 4) [color=lightgreen]'Remember.. write in .Value - Do not rely on the implicit!![/color]
    [color=lightgreen]'Let arrOut(rws, 1) = Left(dicLookupTable.Keys()(rws - sr).Value, 4)[/color]
    [color=lightgreen]'Let arrOut(rws, 1) = Left(IntermediateArray(rws - sr).Value, 4) 'Even A function on the RHS of the = is accepted Here. So again for a non dynamic Array it is not relying on what the function to "define" the type[/color]
    [color=lightgreen]'Let arrOut(rws, 1) = Left(IntermediateArray()(rws - sr).Value, 4)[/color]
 
    [color=blue]Next[/color] rws
 
 [color=blue]Let[/color] RngD.Value = arrOut()
 
 [color=blue]Set[/color] dicLookupTable = [color=blue]Nothing[/color] [color=lightgreen]'Genarally good practice to turn these thimgs off. 'May not be needed but to keep program flexible should alterations need it.[/color]
 
[color=blue]End[/color] [color=blue]Sub[/color] [color=lightgreen]'MicrosoftScriptimeRuntimeDictionaryRangeOfRangesKeys()[/color]
 
 
 [color=lightgreen]'[/color]
'
'
 
'
 
 
 
 
 
[color=lightgreen]'[/color]
[color=blue]Sub[/color] G18_MicrosoftScriptimeRuntimeDictionaryRangeObjectKeysItemsBodge1()
[color=lightgreen]'Similar to the Array of Range ranges, except that the Ranges are held in a full MSRD[/color]
[color=lightgreen]'Less interaction with the spreadsheet, just the use of a temporary cell for use of unique key characteristic.[/color]
[color=lightgreen]'Hopefully can get all infomation from that one big Range..Don't know for sure yet...Post #11 http://www.mrexcel.com/forum/excel-questions/832103-using-microsoft-scripting-runtime-dictionary-store-then-retrieve-range-objects-2.html[/color]
[color=lightgreen]'So Temporárilly put entire CapturedRangeObject in each item (except for duplicates and empty cells, which for now still access the Spreadsheet[/color]
[color=lightgreen]'This requires extra Bodges in Emptys and Duplicates and explanations of new Explicits here Post #14 - post #19  http://www.mrexcel.com/forum/excel-questions/832103-using-microsoft-scripting-runtime-dictionary-store-then-retrieve-range-objects-2.html[/color]
 [color=blue]Dim[/color] wksLG [color=blue]As[/color] Worksheet: [color=blue]Set[/color] wksLG = ThisWorkbook.Worksheets("LeftSpeedsDeutsch")
 [color=blue]Dim[/color] RngName [color=blue]As[/color] Range, RngD [color=blue]As[/color] Range
 [color=blue]Dim[/color] lr [color=blue]As[/color] [color=blue]Long[/color], rws [color=blue]As[/color] [color=blue]Long[/color]
 [color=blue]Let[/color] lr = wksLG.Cells(Rows.Count, 1).End(xlUp).Row
 [color=blue]Dim[/color] sr [color=blue]As[/color] Long: [color=blue]Let[/color] sr = 21
 [color=blue]Set[/color] RngName = wksLG.Range("A" & sr & ":A" & lr & ""): [color=blue]Set[/color] RngD = wksLG.Range("D" & sr & ":D" & lr & "")
 
[color=lightgreen]' 1)  'Part 1b: Setting up Scriptimg Runtime Stuff-----------------------------[/color]
[color=lightgreen]' Attempting Using the Microsooft Scripting Runtime Dictionary to store Range Objects[/color]
 
[color=lightgreen]'We put the unique values now into a Dictionary for later look up purposes:[/color]
[color=lightgreen]'--requires library reference to MS Scripting Runtime (Early Binding)-[/color]
[color=lightgreen]'        Tools>>References>>scrolldown and check the box next to Microsoft Scripting Runtime[/color]
[color=lightgreen]'  ..Or crashes at next line.....[/color]
 [color=blue]Dim[/color] dicLookupTable [color=blue]As[/color] Scripting.Dictionary [color=lightgreen]'Data held with a unique "Key"or Part Number.[/color]
 [color=blue]Set[/color] dicLookupTable = [color=blue]New[/color] Scripting.Dictionary
[color=lightgreen]' 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.[/color]
[color=lightgreen]'        Dim dicLookupTable As Object[/color]
[color=lightgreen]'        Set dicLookupTable = CreateObject("Scripting.Dictionary")[/color]
[color=lightgreen]' Late Binding is better when sharing files as I am here. Early Binding has the advantage that Excel intellisense[/color]
[color=lightgreen]' will then work for the Microsoft Scripüting Runtime stuff and give you suggestions after you type the .dot thing[/color]
 
     dicLookupTable.CompareMode = vbTextCompare [color=lightgreen]'Not quite sure wot this does yet[/color]
 
[color=lightgreen]'.  A Dictionary in VBA is a collection of objects :you can store all kinds of things in it.[/color]
[color=lightgreen]'.  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.[/color]
[color=lightgreen]'.  (Although the Dictionary has not been designed for that purpose it's a nice side effect.)[/color]
 
[color=lightgreen]'End of Part 1b initial set up Of Scripting Runtime------------------------[/color]
 
 [color=lightgreen]'Dim j As Long ', i [color=blue]As[/color] Long  'LoopBoundVariableCounts used in looping here and at end-----[/color]
 [color=blue]Dim[/color] TempCell [color=blue]As[/color] Range: [color=blue]Set[/color] TempCell = wksLG.Cells(1, Columns.Count): [color=blue]Dim[/color] TempCellOffset [color=blue]As[/color] Long: [color=blue]Let[/color] TempCellOffset = 0 [color=lightgreen]'We choose a cell (or through the later use of the offset a column) to use for Duplicate or Empty cells. We use the last column in the sheet. (This is genarally a good practice as it will not effect attempts with .End(XltoLeft) to find last column[/color]
 
 [color=lightgreen]'2a) Direct Array  Capture[/color]
 
 [color=blue]Dim[/color] CapturedRangeObject [color=blue]As[/color] Range [color=lightgreen]'One Range Object for entire range[/color]
 [color=blue]Set[/color] CapturedRangeObject = RngName [color=lightgreen]'Direct assignmet to existing Dimensioned Array[/color]
 
 
 [color=lightgreen]'2b) Part2b) Looping to put Range Objects in MRSD[/color]
    [color=lightgreen]'For i = StartColumnTableOutput To LastColumnTableOutput Step 1[/color]
        [color=blue]For[/color] rws = sr [color=blue]To[/color] lr [color=blue]Step[/color] 1
          [color=blue]If[/color] CapturedRangeObject.Value2(rws - sr + 1, 1) <> "" [color=blue]Then[/color] [color=lightgreen]'If cell is not empty then...[/color]
               [color=blue]If[/color] [color=blue]Not[/color] dicLookupTable.Exists(wksLG.Cells(rws, 1).Value) [color=blue]Then[/color] [color=lightgreen]'check that the unique value does not already exist. ##NOTE[/color]
                  dicLookupTable.Add CapturedRangeObject.Value2(rws - sr + 1, 1), CapturedRangeObject [color=lightgreen]'it is easier to understand as well as kind of explicit the first argument does a CStr and the Second Takes anything[/color]
               [color=blue]Else[/color] [color=lightgreen]'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[/color]
               [color=blue]Let[/color] TempCellOffset = TempCellOffset + 1
               [color=blue]Let[/color] TempCell.Offset(TempCellOffset, 0).Value = "Duplicate at   " & rws & " | " & 1 & ""
               wksLG.Cells(rws, 1).Interior.Color = 10987519
               [color=lightgreen]'dicLookupTable.Add TempCell.Offset(TempCellOffset, 0).Value, wksLG.Cells(rws, 1) 'In case of duplicate we need a unique key, but we stillinclude the Duplicate Range[/color]
               dicLookupTable.Add TempCell.Offset(TempCellOffset, 0).Value, CapturedRangeObject [color=lightgreen]'Must bodge also this line or problem that for my Temp Range has a Value2 of NOT an array()[/color]
               [color=blue]End[/color] [color=blue]If[/color]
           [color=blue]Else[/color] [color=lightgreen]'Case r an empty cell - inform of empty cell by writing message in that cell via the Tempory cell[/color]
           [color=blue]Let[/color] TempCellOffset = TempCellOffset + 1 [color=lightgreen]'Go to next free tempory cell in tempory column[/color]
           [color=blue]Let[/color] TempCell.Offset(TempCellOffset, 0).Value = "Empty Cell at   " & rws & " | " & 1 & ""
           [color=lightgreen]'dicLookupTable.Add TempCell.Offset(TempCellOffset, 0).Value, TempCell.Offset(TempCellOffset, 0)[/color]
           dicLookupTable.Add TempCell.Offset(TempCellOffset, 0).Value, CapturedRangeObject [color=lightgreen]'Must bodge also this line or problem that for my Temp Range has a Value2 of NOT an array()[/color]
           [color=blue]End[/color] [color=blue]If[/color]
        [color=blue]Next[/color] rws
    [color=lightgreen]'Next i[/color]
 
 
   
   
[color=lightgreen]'End Part 2-----------------------------------------------------------[/color]
 
 [color=lightgreen]'3) Part 3)--transfer range objects from dictionary to array of ranges in one go, typical Array assignment "One Liner" - The quick way to place data into an array is to dimension a variable ( for example rResults ) ....>>[/color]
 [color=blue]Dim[/color] IntermediateArray() As [color=blue]Variant[/color] [color=lightgreen]'... [color=blue]As[/color] a Variant and then the "Let rResults  = " code line Using a variant allows BOTH .-1) for capturing Objects, text, numbers, blanks  errors etc. from those cells and also 2) allows rResults to be an array variable.....[/color]
 [color=blue]Let[/color] IntermediateArray() = dicLookupTable.Items() [color=lightgreen]'... In this case it will also accept us quasi pre - defining as Array with the pair of parentheses IntermediateArray()[/color]
 [color=lightgreen]'End part 3)--- NOTE: this gives automatically the 0 to _ convention in IntermediateArray Array!.        >>>.....and the output held in the Array is Variant type and is an OBJECT of the sort like a Range. (This compares with a similar code utilising An Array of Ranges rather than the MicrosoftScriptimeRuntimeDictionary. (In the Array of Ranges case we could Dim as Range or Variant here. - Important however in that case is that the Dynamic IntermediateArray() Array and the (in that Array of Ranges case non dynamic) arrIn() Array are of the same type. - Either both Range to return an Array of element Type Range or both Variant to Return an Array of element Type Of Objects of the Range Sort : - RoryA . You can only assign one array to another directly (i.e. without looping....... and the two arrays are the same type. http://www.excelforum.com/excel-new-users-basics/1058406-range-dimensioning-range-and-value-referencing-and-referring-to-arrays.html[/color]
 
[color=lightgreen]'4) Part 4)---Produce output array by looping[/color]
 [color=blue]Dim[/color] arrOut() As [color=blue]String[/color] [color=lightgreen]'We can use string as in the looping below as we are not relying on (/seeing) a range object to rturn us an array of values.[/color]
 [color=blue]ReDim[/color] arrOut(sr [color=blue]To[/color] lr, 1 [color=blue]To[/color] 1) [color=lightgreen]'Antoher way to look at it is to say we have a fixed, rather than dynamiy array, and as VBA does not allow a direct assigning one liner in this case it is also not necerssarily expecting to see an object. For Let it is likely to expect to see some value, and for Set an object (Would expect an Range Object if indicies of arrOut were so defined by arrOut() As String initially[/color]
   
    [color=blue]For[/color] rws = sr To lr [color=blue]Step[/color] 1 [color=lightgreen]'Input Array of Ranges  Note ## >> ’.. because of how VBA “works”, This extra () will ensure that indices are always returned to the resulting array (and not occasionally, for example, arguments ) by any following method or property, or passed to any method or property[/color]
        [color=lightgreen]'Let arrOut(rws, 1) = CapturedRangeObject.Value2(rws - sr + 1, 1) 'Works.. but  ...[/color]
        [color=lightgreen]'Let arrOut(rws, 1) = CapturedRangeObject.Value2()(rws - sr + 1, 1) '...better ##[/color]
        [color=lightgreen]'Let arrOut(rws, 1) = dicLookupTable.Items(rws - sr).Value2(rws - sr + 1, 1) 'Wont work[/color]
        [color=lightgreen]'Let arrOut(rws, 1) = dicLookupTable.Items(rws - sr).Value2()(rws - sr + 1, 1) 'Works ##[/color]
        [color=lightgreen]'Let arrOut(rws, 1) = IntermediateArray(rws - sr).Value2(rws - sr + 1, 1) 'Won't work[/color]
        [color=lightgreen]'Let arrOut(rws, 1) = IntermediateArray(rws - sr).Value2()(rws - sr + 1, 1) 'Works ##[/color]
    [color=blue]Let[/color] arrOut(rws, 1) = Left(dicLookupTable.Items(rws - sr).Value2()(rws - sr + 1, 1), 4) [color=lightgreen]'Works ##[/color]
        'Let arrOut(rws, 1) = Left(IntermediateArray(rws - sr).Value2()(rws - sr + 1, 1), 4) 'Works ##
    [color=blue]Next[/color] rws
 
[color=lightgreen]'End Part 4-----------------------------------[/color]
 
 [color=blue]Let[/color] RngD.Value = arrOut()
 
 [color=blue]Set[/color] dicLookupTable = [color=blue]Nothing[/color] [color=lightgreen]'Genarally good practice to turn these thimgs off. 'May not be needed but to keep program flexible should alterations need it.[/color]
 
[color=blue]End[/color] [color=blue]Sub[/color] [color=lightgreen]'MicrosoftScriptimeRuntimeDictionaryRangeObjectKeysItemsBodge1()[/color]
 
 
[color=lightgreen]'[/color]
[color=blue]Sub[/color] G19_MicrosoftScriptimeRuntimeDictionaryRangeObjectKeysItemsBodge2()
[color=lightgreen]'Similar to the Array of Range ranges, except that the Ranges are held in a full MSRD[/color]
[color=lightgreen]'Less interaction with the spreadsheet, just the use of a temporary cell for use of unique key characteristic.[/color]
[color=lightgreen]'Hopefully can get all infomation from that one big Range..Don't know for sure yet...Post #11 http://www.mrexcel.com/forum/excel-questions/832103-using-microsoft-scripting-runtime-dictionary-store-then-retrieve-range-objects-2.html[/color]
[color=lightgreen]'So Temporárilly put entire CapturedRangeObject in each item (except for duplicates and empty cells, which for now still access the Spreadsheet[/color]
[color=lightgreen]'This requires extra Bodges in Emptys and Duplicates and explanations of an alternative way to avoid the extra () from last code (MicrosoftScriptimeRuntimeDictionaryRangeObjectKeysItemsBodge2())  Post #14 - post #19  http://www.mrexcel.com/forum/excel-questions/832103-using-microsoft-scripting-runtime-dictionary-store-then-retrieve-range-objects-2.html[/color]
 [color=blue]Dim[/color] wksLG [color=blue]As[/color] Worksheet: [color=blue]Set[/color] wksLG = ThisWorkbook.Worksheets("LeftSpeedsDeutsch")
 [color=blue]Dim[/color] RngName [color=blue]As[/color] Range, RngD [color=blue]As[/color] Range
 [color=blue]Dim[/color] lr [color=blue]As[/color] [color=blue]Long[/color], rws [color=blue]As[/color] [color=blue]Long[/color]
 [color=blue]Let[/color] lr = wksLG.Cells(Rows.Count, 1).End(xlUp).Row
 [color=blue]Dim[/color] sr [color=blue]As[/color] Long: [color=blue]Let[/color] sr = 21
 [color=blue]Set[/color] RngName = wksLG.Range("A" & sr & ":A" & lr & ""): [color=blue]Set[/color] RngD = wksLG.Range("D" & sr & ":D" & lr & "")
 
[color=lightgreen]' 1)  'Part 1b: Setting up Scriptimg Runtime Stuff-----------------------------[/color]
[color=lightgreen]' Attempting Using the Microsooft Scripting Runtime Dictionary to store Range Objects[/color]
 
[color=lightgreen]'We put the unique values now into a Dictionary for later look up purposes:[/color]
[color=lightgreen]'--requires library reference to MS Scripting Runtime (Early Binding)-[/color]
[color=lightgreen]'        Tools>>References>>scrolldown and check the box next to Microsoft Scripting Runtime[/color]
[color=lightgreen]'  ..Or crashes at next line.....[/color]
 [color=blue]Dim[/color] dicLookupTable [color=blue]As[/color] Scripting.Dictionary [color=lightgreen]'Data held with a unique "Key"or Part Number.[/color]
 [color=blue]Set[/color] dicLookupTable = [color=blue]New[/color] Scripting.Dictionary
[color=lightgreen]' 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.[/color]
[color=lightgreen]'        Dim dicLookupTable As Object[/color]
[color=lightgreen]'        Set dicLookupTable = CreateObject("Scripting.Dictionary")[/color]
[color=lightgreen]' Late Binding is better when sharing files as I am here. Early Binding has the advantage that Excel intellisense[/color]
[color=lightgreen]' will then work for the Microsoft Scripüting Runtime stuff and give you suggestions after you type the .dot thing[/color]
 
     dicLookupTable.CompareMode = vbTextCompare [color=lightgreen]'Not quite sure wot this does yet[/color]
 
[color=lightgreen]'.  A Dictionary in VBA is a collection of objects :you can store all kinds of things in it.[/color]
[color=lightgreen]'.  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.[/color]
[color=lightgreen]'.  (Although the Dictionary has not been designed for that purpose it's a nice side effect.)[/color]
 
[color=lightgreen]'End of Part 1b initial set up Of Scripting Runtime------------------------[/color]
 
 [color=lightgreen]'Dim j As Long ', i [color=blue]As[/color] Long  'LoopBoundVariableCounts used in looping here and at end-----[/color]
 [color=blue]Dim[/color] TempCell [color=blue]As[/color] Range: [color=blue]Set[/color] TempCell = wksLG.Cells(1, Columns.Count): [color=blue]Dim[/color] TempCellOffset [color=blue]As[/color] [color=blue]Long[/color]: [color=blue]Let[/color] TempCellOffset = 0 [color=lightgreen]'We choose a cell (or through the later use of the offset a column) to use for Duplicate or Empty cells. We use the last column in the sheet. (This is genarally a good practice as it will not effect attempts with .End(XltoLeft) to find last column[/color]
 
 [color=lightgreen]'2a) Direct Array  Capture[/color]
 
 [color=blue]Dim[/color] CapturedRangeObject [color=blue]As[/color] Range [color=lightgreen]'One Range Object for entire range[/color]
 [color=blue]Set[/color] CapturedRangeObject = RngName [color=lightgreen]'Direct assignmet to existing Dimensioned Array[/color]
 
 
 [color=lightgreen]'2b) Part2b) Looping to put Range Objects in MRSD[/color]
    [color=lightgreen]'For i = StartColumnTableOutput To LastColumnTableOutput Step 1[/color]
        [color=blue]For[/color] rws = sr [color=blue]To[/color] lr [color=blue]Step[/color] 1
          [color=blue]If[/color] CapturedRangeObject.Value2(rws - sr + 1, 1) <> "" [color=blue]Then[/color] [color=lightgreen]'If cell is not empty then...[/color]
               [color=blue]If[/color] [color=blue]Not[/color] dicLookupTable.Exists(wksLG.Cells(rws, 1).Value) [color=blue]Then[/color] [color=lightgreen]'check that the unique value does not already exist. ##NOTE[/color]
                  dicLookupTable.Add CapturedRangeObject.Value2(rws - sr + 1, 1), CapturedRangeObject [color=lightgreen]'it is easier to understand as well as kind of explicit the first argument does a CStr and the Second Takes anything[/color]
               [color=blue]Else[/color] [color=lightgreen]'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[/color]
               [color=blue]Let[/color] TempCellOffset = TempCellOffset + 1
               [color=blue]Let[/color] TempCell.Offset(TempCellOffset, 0).Value = "Duplicate at   " & rws & " | " & 1 & ""
               wksLG.Cells(rws, 1).Interior.Color = 10987519
               [color=lightgreen]'dicLookupTable.Add TempCell.Offset(TempCellOffset, 0).Value, wksLG.Cells(rws, 1) 'In case of duplicate we need a unique key, but we stillinclude the Duplicate Range[/color]
               dicLookupTable.Add TempCell.Offset(TempCellOffset, 0).Value, CapturedRangeObject [color=lightgreen]'Must bodge also this line or problem that for my Temp Range has a Value2 of NOT an array()[/color]
               [color=blue]End[/color] [color=blue]If[/color]
           [color=blue]Else[/color] [color=lightgreen]'Case r an empty cell - inform of empty cell by writing message in that cell via the Tempory cell[/color]
           [color=blue]Let[/color] TempCellOffset = TempCellOffset + 1 [color=lightgreen]'Go to next free tempory cell in tempory column[/color]
           [color=blue]Let[/color] TempCell.Offset(TempCellOffset, 0).Value = "Empty Cell at   " & rws & " | " & 1 & ""
           [color=lightgreen]'dicLookupTable.Add TempCell.Offset(TempCellOffset, 0).Value, TempCell.Offset(TempCellOffset, 0)[/color]
           dicLookupTable.Add TempCell.Offset(TempCellOffset, 0).Value, CapturedRangeObject [color=lightgreen]'Must bodge also this line or problem that for my Temp Range has a Value2 of NOT an array()[/color]
           [color=blue]End[/color] [color=blue]If[/color]
        [color=blue]Next[/color] rws
    [color=lightgreen]'Next i[/color]
 
 
   
   
[color=lightgreen]'End Part 2-----------------------------------------------------------[/color]
 
 [color=lightgreen]'3) Part 3)--transfer range objects from dictionary to array of ranges in one go, typical Array assignment "One Liner" - The quick way to place data into an array is to dimension a variable ( for example rResults ) ....>>[/color]
 [color=blue]Dim[/color] IntermediateArray() As [color=blue]Variant[/color] [color=lightgreen]'... [color=blue]As[/color] a Variant and then the "Let rResults  = " code line Using a variant allows BOTH .-1) for capturing Objects, text, numbers, blanks  errors etc. from those cells and also 2) allows rResults to be an array variable.....[/color]
 [color=blue]Let[/color] IntermediateArray() = dicLookupTable.Items() [color=lightgreen]'... In this case it will also accept us quasi pre - defining as Array with the pair of parentheses IntermediateArray()[/color]
 [color=lightgreen]'End part 3)--- NOTE: this gives automatically the 0 to _ convention in rResults Array!.        >>>.....and the output held in the Array is Variant type and is an OBJECT of the sort like a Range. (This compares with a similar code utilising An Array of Ranges rather than the MicrosoftScriptimeRuntimeDictionary. (In the Array of Ranges case we could Dim as Range or Variant here. - Important however in that case is that the Dynamic IntermediateArray() Array and the (in that Array of Ranges case non dynamic) arrIn() Array are of the same type. - Either both Range to return an Array of element Type Range or both Variant to Return an Array of element Type Of Objects of the Range Sort : - RoryA . You can only assign one array to another directly (i.e. without looping....... and the two arrays are the same type. http://www.excelforum.com/excel-new-users-basics/1058406-range-dimensioning-range-and-value-referencing-and-referring-to-arrays.html[/color]
 
[color=lightgreen]'4) Part 4)---Produce output array by looping[/color]
 [color=blue]Dim[/color] vTemp [color=blue]As[/color] [color=blue]Variant[/color] [color=lightgreen]'Post from #20  - #24 .. return the array to a variable and then reference the elements through that variable, in which case you don't need to worry about the extra () . The usual "To see an object which returns a field" requirement to be dimensioned as Variant[/color]
    [color=lightgreen]'  http://www.mrexcel.com/forum/excel-questions/832103-using-microsoft-scripting-runtime-dictionary-store-then-retrieve-range-objects-3.html[/color]
 [color=blue]Dim[/color] arrOut() As [color=blue]String[/color] [color=lightgreen]'We can use string as in the looping below as we are not relying on (/seeing) a range object to rturn us an array of values.[/color]
 [color=blue]ReDim[/color] arrOut(sr [color=blue]To[/color] lr, 1 [color=blue]To[/color] 1) [color=lightgreen]'Antoher way to look at it is to say we have a fixed, rather than dynamiy array, and as VBA does not allow a direct assigning one liner in this case it is also not necerssarily expecting to see an object. For Let it is likely to expect to see some value, and for Set an object (Would expect an Range Object if indicies of arrOut were so defined by arrOut() [color=blue]As[/color] String initially[/color]
   
    [color=blue]For[/color] rws = sr To lr [color=blue]Step[/color] 1 [color=lightgreen]'Input Array of Ranges  Note ## >> ’.. because of how VBA “works”, This extra () will ensure that indices are always returned to the resulting array (and not occasionally, for example, arguments ) by any following method or property, or passed to any method or property, (In the "bodge it is assigned each time to the full object[/color]
 
[color=lightgreen]'    '    Let arrOut(rws, 1) = CapturedRangeObject.Value2(rws - sr + 1, 1) 'Works.. but  ...[/color]
[color=lightgreen]'    '    Let arrOut(rws, 1) = CapturedRangeObject.Value2()(rws - sr + 1, 1) '...better ##[/color]
[color=lightgreen]'    '    'Let arrOut(rws, 1) = dicLookupTable.Items(rws - sr).Value2(rws - sr + 1, 1) 'Wont work[/color]
[color=lightgreen]'    '    Let arrOut(rws, 1) = dicLookupTable.Items(rws - sr).Value2()(rws - sr + 1, 1) 'Works ##[/color]
    [color=blue]Let[/color] vTemp = dicLookupTable.Items(rws - sr).Value2 [color=lightgreen]'Works vTemp is Array of variants values, a Data field[/color]
      [color=lightgreen]'Let vTemp = dicLookupTable.Items(rws - sr).Value2() 'Works also!!![/color]
    [color=lightgreen]'Let vTemp = IntermediateArray(rws - sr).Value2 'Works vTemp is Array of variants values, a Data fild[/color]
      [color=lightgreen]'Let vTemp = IntermediateArray(rws - sr).Value2()'Also works!!![/color]
   
[color=lightgreen]'                'Let arrOut(rws, 1) = vTemp(rws - sr + 1, 1) 'Works[/color]
[color=lightgreen]'            '    'Let arrOut(rws, 1) = IntermediateArray(rws - sr).Value2(rws - sr + 1, 1) 'Won't work[/color]
[color=lightgreen]'            '    Let arrOut(rws, 1) = IntermediateArray(rws - sr).Value2()(rws - sr + 1, 1) 'Works ##[/color]
[color=lightgreen]'            '    Let arrOut(rws, 1) = Left(dicLookupTable.Items(rws - sr).Value2()(rws - sr + 1, 1), 4) 'Works ##[/color]
[color=lightgreen]'            '    Let arrOut(rws, 1) = Left(IntermediateArray(rws - sr).Value2()(rws - sr + 1, 1), 4) 'Works ##[/color]
    [color=blue]Let[/color] arrOut(rws, 1) = Left(vTemp(rws - sr + 1, 1), 4) [color=lightgreen]'Works[/color]
    [color=blue]Next[/color] rws
 
[color=lightgreen]'End Part 4-----------------------------------[/color]
 
 [color=blue]Let[/color] RngD.Value = arrOut()
 
 [color=blue]Set[/color] dicLookupTable = [color=blue]Nothing[/color] [color=lightgreen]'Genarally good practice to turn these thimgs off. 'May not be needed but to keep program flexible should alterations need it.[/color]
 
[color=blue]End[/color] [color=blue]Sub[/color] [color=lightgreen]'MicrosoftScriptimeRuntimeDictionaryRangeObjectKeysItemsBodge2()[/color]
[color=lightgreen]'[/color]
 
 
 
 
 
'
[color=blue]Sub[/color] G20_MicrosoftScriptimeRuntimeDictionaryRangeObjectKeysItemsBodge3()
[color=lightgreen]'Similar to the Array of Range ranges, except that the Ranges are held in a full MSRD[/color]
[color=lightgreen]'Less interaction with the spreadsheet, just the use of a temporary cell for use of unique key characteristic.[/color]
[color=lightgreen]'Hopefully can get all infomation from that one big Range..Don't know for sure yet...Post #11 http://www.mrexcel.com/forum/excel-questions/832103-using-microsoft-scripting-runtime-dictionary-store-then-retrieve-range-objects-2.html[/color]
[color=lightgreen]'So Temporárilly put entire CapturedRangeObject in each item (except for duplicates and empty cells, which for now still access the Spreadsheet[/color]
[color=lightgreen]'This requires extra Bodges in Emptys and Duplicates and explanations of an alternative way to avoid the extra () from last code (MicrosoftScriptimeRuntimeDictionaryRangeObjectKeysItemsBodge2())  Post #14 - post #19  http://www.mrexcel.com/forum/excel-questions/832103-using-microsoft-scripting-runtime-dictionary-store-then-retrieve-range-objects-2.html[/color]
 [color=blue]Dim[/color] wksLG [color=blue]As[/color] Worksheet: [color=blue]Set[/color] wksLG = ThisWorkbook.Worksheets("LeftSpeedsDeutsch")
 [color=blue]Dim[/color] RngName [color=blue]As[/color] Range, RngD [color=blue]As[/color] Range
 [color=blue]Dim[/color] lr [color=blue]As[/color] [color=blue]Long[/color], rws [color=blue]As[/color] Long
 [color=blue]Let[/color] lr = wksLG.Cells(Rows.Count, 1).End(xlUp).Row
 [color=blue]Dim[/color] sr [color=blue]As[/color] Long: [color=blue]Let[/color] sr = 21
 [color=blue]Set[/color] RngName = wksLG.Range("A" & sr & ":A" & lr & ""): [color=blue]Set[/color] RngD = wksLG.Range("D" & sr & ":D" & lr & "")
 
[color=lightgreen]' 1)  'Part 1b: Setting up Scriptimg Runtime Stuff-----------------------------[/color]
[color=lightgreen]' Attempting Using the Microsooft Scripting Runtime Dictionary to store Range Objects[/color]
 
[color=lightgreen]'We put the unique values now into a Dictionary for later look up purposes:[/color]
[color=lightgreen]'--requires library reference to MS Scripting Runtime (Early Binding)-[/color]
[color=lightgreen]'        Tools>>References>>scrolldown and check the box next to Microsoft Scripting Runtime[/color]
[color=lightgreen]'  ..Or crashes at next line.....[/color]
 [color=blue]Dim[/color] dicLookupTable As Scripting.Dictionary [color=lightgreen]'Data held with a unique "Key"or Part Number.[/color]
 [color=blue]Set[/color] dicLookupTable = [color=blue]New[/color] Scripting.Dictionary
[color=lightgreen]' 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.[/color]
[color=lightgreen]'        Dim dicLookupTable As Object[/color]
[color=lightgreen]'        Set dicLookupTable = CreateObject("Scripting.Dictionary")[/color]
[color=lightgreen]' Late Binding is better when sharing files as I am here. Early Binding has the advantage that Excel intellisense[/color]
[color=lightgreen]' will then work for the Microsoft Scripüting Runtime stuff and give you suggestions after you type the .dot thing[/color]
 
     dicLookupTable.CompareMode = vbTextCompare [color=lightgreen]'Not quite sure wot this does yet[/color]
 
[color=lightgreen]'.  A Dictionary in VBA is a collection of objects :you can store all kinds of things in it.[/color]
[color=lightgreen]'.  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.[/color]
[color=lightgreen]'.  (Although the Dictionary has not been designed for that purpose it's a nice side effect.)[/color]
 
[color=lightgreen]'End of Part 1b initial set up Of Scripting Runtime------------------------[/color]
 
 [color=lightgreen]'Dim j [color=blue]As[/color] Long ', i [color=blue]As[/color] Long  'LoopBoundVariableCounts used in looping here and at end-----[/color]
 [color=blue]Dim[/color] TempCell [color=blue]As[/color] Range: [color=blue]Set[/color] TempCell = wksLG.Cells(1, Columns.Count): [color=blue]Dim[/color] TempCellOffset [color=blue]As[/color] Long: [color=blue]Let[/color] TempCellOffset = 0 [color=lightgreen]'We choose a cell (or through the later use of the offset a column) to use for Duplicate or Empty cells. We use the last column in the sheet. (This is genarally a good practice as it will not effect attempts with .End(XltoLeft) to find last column[/color]
 
 [color=lightgreen]'2a) Direct Array  Capture[/color]
 
 [color=blue]Dim[/color] CapturedRangeObject As Range [color=lightgreen]'One Range Object for entire range[/color]
 [color=blue]Set[/color] CapturedRangeObject = RngName [color=lightgreen]'Direct assignmet to existing Dimensioned Array[/color]
 
 
 [color=lightgreen]'2b) Part2b) Looping to put Range Objects in MRSD[/color]
    [color=lightgreen]'For i = StartColumnTableOutput [color=blue]To[/color] LastColumnTableOutput Step 1[/color]
        [color=blue]For[/color] rws = sr To lr [color=blue]Step[/color] 1
          [color=blue]If[/color] CapturedRangeObject.Value2(rws - sr + 1, 1) <> "" [color=blue]Then[/color] [color=lightgreen]'If cell is not empty then...[/color]
               [color=blue]If[/color] [color=blue]Not[/color] dicLookupTable.Exists(wksLG.Cells(rws, 1).Value) [color=blue]Then[/color] [color=lightgreen]'check that the unique value does not already exist. ##NOTE[/color]
                  dicLookupTable.Add CapturedRangeObject.Value2(rws - sr + 1, 1), CapturedRangeObject [color=lightgreen]'it is easier to understand as well as kind of explicit the first argument does a CStr and the Second Takes anything[/color]
               [color=blue]Else[/color] [color=lightgreen]'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[/color]
               [color=blue]Let[/color] TempCellOffset = TempCellOffset + 1
               [color=blue]Let[/color] TempCell.Offset(TempCellOffset, 0).Value = "Duplicate at   " & rws & " | " & 1 & ""
               wksLG.Cells(rws, 1).Interior.Color = 10987519
               [color=lightgreen]'dicLookupTable.Add TempCell.Offset(TempCellOffset, 0).Value, wksLG.Cells(rws, 1) 'In case of duplicate we need a unique key, but we stillinclude the Duplicate Range[/color]
               dicLookupTable.Add TempCell.Offset(TempCellOffset, 0).Value, CapturedRangeObject [color=lightgreen]'Must bodge also this line or problem that for my Temp Range has a Value2 of NOT an array()[/color]
               [color=blue]End[/color] [color=blue]If[/color]
           [color=blue]Else[/color] [color=lightgreen]'Case r an empty cell - inform of empty cell by writing message in that cell via the Tempory cell[/color]
           [color=blue]Let[/color] TempCellOffset = TempCellOffset + 1 [color=lightgreen]'Go to next free tempory cell in tempory column[/color]
           [color=blue]Let[/color] TempCell.Offset(TempCellOffset, 0).Value = "Empty Cell at   " & rws & " | " & 1 & ""
           [color=lightgreen]'dicLookupTable.Add TempCell.Offset(TempCellOffset, 0).Value, TempCell.Offset(TempCellOffset, 0)[/color]
           dicLookupTable.Add TempCell.Offset(TempCellOffset, 0).Value, CapturedRangeObject [color=lightgreen]'Must bodge also this line or problem that for my Temp Range has a Value2 of NOT an array()[/color]
           [color=blue]End[/color] [color=blue]If[/color]
        [color=blue]Next[/color] rws
    [color=lightgreen]'Next i[/color]
 
 
   
   
[color=lightgreen]'End Part 2-----------------------------------------------------------[/color]
 
 [color=lightgreen]'3) Part 3)--transfer range objects from dictionary to array of ranges in one go, typical Array assignment "One Liner" - The quick way to place data into an array is to dimension a variable ( for example rResults ) ....>>[/color]
 [color=blue]Dim[/color] IntermediateArray() [color=blue]As[/color] [color=blue]Variant[/color] [color=lightgreen]'... [color=blue]As[/color] a Variant and then the "Let rResults  = " code line Using a variant allows BOTH .-1) for capturing Objects, text, numbers, blanks  errors etc. from those cells and also 2) allows rResults to be an array variable.....[/color]
 [color=blue]Let[/color] IntermediateArray() = dicLookupTable.Items() [color=lightgreen]'... In this case it will also accept us quasi pre - defining as Array with the pair of parentheses IntermediateArray()[/color]
 [color=lightgreen]'End part 3)--- NOTE: this gives automatically the 0 to _ convention in rResults Array!.        >>>.....and the output held in the Array is Variant type and is an OBJECT of the sort like a Range. (This compares with a similar code utilising An Array of Ranges rather than the MicrosoftScriptimeRuntimeDictionary. (In the Array of Ranges case we could Dim as Range or Variant here. - Important however in that case is that the Dynamic IntermediateArray() Array and the (in that Array of Ranges case non dynamic) arrIn() Array are of the same type. - Either both Range to return an Array of element Type Range or both Variant to Return an Array of element Type Of Objects of the Range Sort : - RoryA . You can only assign one array to another directly (i.e. without looping....... and the two arrays are the same type. http://www.excelforum.com/excel-new-users-basics/1058406-range-dimensioning-range-and-value-referencing-and-referring-to-arrays.html[/color]
 
[color=lightgreen]'4) Part 4)---Produce output array by looping[/color]
 [color=blue]Dim[/color] vTemp As [color=blue]Variant[/color] [color=lightgreen]'Post from #20  - #24 .. return the array to a variable and then reference the elements through that variable, in which case you don't need to worry about the extra () . The usual "[color=blue]To[/color] see an object which returns a field" requirement to be dimensioned as Variant[/color]
    [color=lightgreen]'  http://www.mrexcel.com/forum/excel-questions/832103-using-microsoft-scripting-runtime-dictionary-store-then-retrieve-range-objects-3.html[/color]
 [color=blue]Let[/color] vTemp = dicLookupTable.Items(3).Value2 [color=lightgreen]'Works vTemp is Array of variants values, a Data field. In bodge 3 set to an arbritrary item number as in this stupid bodge they are all the same[/color]
 
 [color=blue]Dim[/color] arrOut() As [color=blue]String[/color] [color=lightgreen]'We can use string as in the looping below as we are not relying on (/seeing) a range object to rturn us an array of values.[/color]
 [color=blue]ReDim[/color] arrOut(sr [color=blue]To[/color] lr, 1 To 1) [color=lightgreen]'Antoher way to look at it is to say we have a fixed, rather than dynamiy array, and as VBA does not allow a direct assigning one liner in this case it is also not necerssarily expecting to see an object. For Let it is likely to expect to see some value, and for Set an object (Would expect an Range Object if indicies of arrOut were so defined by arrOut() As String initially[/color]
   
    [color=blue]For[/color] rws = sr To lr [color=blue]Step[/color] 1 [color=lightgreen]'Input Array of Ranges  Note ## >> ’.. because of how VBA “works”, This extra () will ensure that indices are always returned to the resulting array (and not occasionally, for example, arguments ) by any following method or property, or passed to any method or property, (In the "bodge it is assigned each time to the full object[/color]
 
[color=lightgreen]'    Let arrOut(rws, 1) = CapturedRangeObject.Value2(rws - sr + 1, 1) 'Works.. but  ...[/color]
[color=lightgreen]'    Let arrOut(rws, 1) = CapturedRangeObject.Value2()(rws - sr + 1, 1) '...better ##[/color]
[color=lightgreen]'    'Let arrOut(rws, 1) = dicLookupTable.Items(rws - sr).Value2(rws - sr + 1, 1) 'Wont work[/color]
[color=lightgreen]'    Let arrOut(rws, 1) = dicLookupTable.Items(rws - sr).Value2()(rws - sr + 1, 1) 'Works ##[/color]
   
    [color=lightgreen]'Let vTemp = dicLookupTable.Items(rws - sr).Value2() 'Works also!!![/color]
    [color=lightgreen]'Let vTemp = IntermediateArray(rws - sr).Value2 'Works vTemp is Array of variants values, a Data fild[/color]
    [color=lightgreen]'Let vTemp = IntermediateArray(rws - sr).Value2()'Also works!!![/color]
   
    [color=lightgreen]'Let arrOut(rws, 1) = vTemp(rws - sr + 1, 1) 'Works[/color]
[color=lightgreen]'    'Let arrOut(rws, 1) = IntermediateArray(rws - sr).Value2(rws - sr + 1, 1) 'Won't work[/color]
[color=lightgreen]'    Let arrOut(rws, 1) = IntermediateArray(rws - sr).Value2()(rws - sr + 1, 1) 'Works ##[/color]
[color=lightgreen]'    Let arrOut(rws, 1) = Left(dicLookupTable.Items(rws - sr).Value2()(rws - sr + 1, 1), 4) 'Works ##[/color]
[color=lightgreen]'    Let arrOut(rws, 1) = Left(IntermediateArray(rws - sr).Value2()(rws - sr + 1, 1), 4) 'Works ##[/color]
    [color=blue]Let[/color] arrOut(rws, 1) = Left(vTemp(rws - sr + 1, 1), 4) [color=lightgreen]'Works[/color]
   
    [color=blue]Next[/color] rws
 
[color=lightgreen]'End Part 4-----------------------------------[/color]
 
 [color=blue]Let[/color] RngD.Value = arrOut()
 
 [color=blue]Set[/color] dicLookupTable = [color=blue]Nothing[/color] [color=lightgreen]'Genarally good practice to turn these thimgs off. 'May not be needed but to keep program flexible should alterations need it.[/color]
 
[color=blue]End[/color] [color=blue]Sub[/color] [color=lightgreen]'MicrosoftScriptimeRuntimeDictionaryRangeObjectKeysItemsBodge3()[/color]
 
Upvote 0
Hi

. Just updating results from last Post for anyone following the story...I have gone in a few wild directions with the codes.. I will not give details. Codes and results are there.
. Only conclusions for now: VBA works in some strange ways that no one longer understands.. …Post #44 #45
http://www.mrexcel.com/forum/lounge-v-2-0/814398-how-important-excel-forums-5.html
. so I am just doing my bit for mankind… and trying to tame VBA a bit before I use it finally for something important….
Alan
. P.s. I AM NO LONGER GOING to read any more PM’s about this stuff.. SEE MY note about that in last Post # 88



Brief Description of Code
Typical Run -​
Time in -​
Seconds​
Computer1 XL 2007 33928 Rows​
Computer1 1654 Rows​
Computer2 XL 2010 33928Rows​
G1Simplist Loop
6.3 6.9​
0.4​
12.59 18.2 7.75​
G1 " " replace Formula with Private Function
8.1​
7.75 7.9 7.75​
G2Typical Evaluate Alternative
.515​
0.02​
0.51 o.47​
G2 " " replace Formula with Private Function
.38​
.31​
G3Typical .Formula in a With EndWith
.085 0.175​
0.008​
0.476 0.487 0.25​
G3 " " replace Formula with Private Function
0.325​
0.71​
G4Typical .FormulaR1C1 in a With EndWith
0.17 0.1​
0.007​
0.092 0.186 0.091 0.08​
G4 " " replace Formula with Private Function
1.89​
0.86​
G5.Formula in a Loop
94.2​
0.7​
426.6​
G5 " " replace Formula with Private Function
1969.2​
3513.6 2649.6​
G6 FormulaR1C1 in a Loop
95.5​
0.6​
G6 " " replace Formula with Private Function
83.8​
354.2​
G7Evalute using Range Object Left UDF
1.65​
0.1​
1.29 1.32​
G7 " " replace Formula with Private Function (Extra Function in UDF)
1.78​
1.34​
L G _ -VBA Left - =(String___, needs Range!….
Don't Work​
Don't Work​
G8Range Object Left UDF - Direct =(Range____
1.1 1.3​
0.06​
0.96 0.87​
G8 " " replace Formula with Private Function (Extra Function in UDF)
1.48​
G9VBA Array Of Ranges (1a)
1.5​
.07​
1.38​
G9VBA Array Of Ranges () (1a)
218​
0.22​
820​
G10VBA Array Of Ranges (1aa)
2.5-0.5​
0.13 - .07​
4.31 - 1.08​
G10VBA Array Of Ranges () (1aa)
217-0.5​
0.29 - .07​
761.5 - 1.5​
G11VBA Array Of Ranges (1b) First use of intermediateArray
1.38​
.08​
1.49​
G11VBA Array Of Ranges () (1b) First use of intermediateArray
219.5​
0.22​
757.6​
G12VBA Array Of Ranges (2)
1.5​
.07​
1.59​
G12VBA Array Of Ranges () (2)
115.5​
0.18​
293.7​
G13RangeObjectCapture value2 (___)
1651.5​
3.85​
1388​
G13RangeObjectCapture value2 () (___)
1667​
3.86​
1399​
G13bRangeObjectCapture value2 (___)
2457.5​
3.6​
3250​
G13bRangeObjectCapture value2 () (___)
Don't Work​
Don't Work​
G13cRangeObjectCapture value2 (___)
0.325​
0.018​
0.34​
G13cRangeObjectCapture value2 () (___)
Don't Work​
Don't Work​
G14MSRDKeysItems item (___)
380​
.65​
989.5​
G14MSRDKeysItems item () (___)
379​
.66​
932​
G14MSRDKeysItems intermediteArray (___).
3.35​
.16​
3.15​
G14MSRDKeysItems intermediteArray () (___).
377​
.65​
954.5​
G14MSRDKeysItems Keys (As values)
897​
2.1​
2178 1638​
G14MSRDKeysItems Keys () (As values)
905.5​
2.1​
1777.7​
G15MSRDKeys (As Full Range Objects)
362.5 315​
.56​
975.6 861​
G15MSRDKeys () (As Full Range Objects)
.56​
853​
G15MSRDKeys intermediateArray (As Full Range Objects)
1.88​
.08​
1.66​
G15MSRDKeys intermediateArray () (As Full Range Objects)
.56​
971.6​
G16
G17
G18Big Range Object-MSDR Array of Range Objects "Bodge 2"
5374​
12​
5466.5​
() (___)
Don't Work​
Don't Work​
Ditto.. IntermediateArray
4390​
() (___)
G19Big Range Object-MSDR Array of Range Objects "Bodge 2"
12​
5203​
() (___)
Don't Work​
Don't Work​
Ditto.. IntermediateArray
4786​
() (___)
G20Big Range Object-MSDR Array of Range Objects "Bodge 3"
7.5​
3579​
() (___)
Don't Work​
Don't Work​
Ditto.. IntermediateArray
4705​
() (___)



Codes:

Code:
[color=blue]Option[/color] [color=blue]Explicit[/color]
[color=blue]Sub[/color] G1_SimpleLoop() [color=lightgreen]'Simplist Loop[/color]
 
 [color=blue]Dim[/color] wksLG [color=blue]As[/color] Worksheet: [color=blue]Set[/color] wksLG = ThisWorkbook.Worksheets("LeftSpeedsDeutsch") [color=lightgreen]'Give abbreviations the  Methods, properties, sub-Objects through dot of Worksheets Object[/color]
 [color=blue]Dim[/color] lr [color=blue]As[/color] [color=blue]Long[/color], rws [color=blue]As[/color] [color=blue]Long[/color] [color=lightgreen]'last row and rows in sheet( Long is a Big whole Number limit (-2,147,483,648 to 2,147,483,647) -Most smaller numbers, Byte, Integer, Single are converted in computer to long so no advantage of Dim to smaller Type here) >>> 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. http://www.mrexcel.com/forum/excel-questions/803662-byte-backward-loop-3.html[/color]
 [color=blue]Let[/color] lr = wksLG.Cells.Find(What:="*", after:=wksLG.Cells(1, 1), lookat:=xlPart, LookIn:=xlFormulas, searchorder:=xlByRows, SearchDirection:=xlPrevious).Row [color=lightgreen]'Get last Row with entry anywhere for Sheet1. Method: You start at first cell then go backwards (which effectively starts at end of sheet), sercching for anything ( = * ) by rows, then get the row number. This allows for different excel versions with different available Row numbers) Just a different method here for fun- finds last row in sheet rather than row for last entry in particular cell[/color]
 [color=blue]Let[/color] lr = wksLG.Cells(Rows.Count, 1).End(xlUp).Row [color=lightgreen]'Better alternative for single column work. - Starting at last Spreadsheet Row in column1, quasi "go back up" / return the last cell with entry in it as a Range object using .End Property and obtain rows from the .Rows Property of that returned Range Object[/color]
 [color=blue]Dim[/color] sr [color=blue]As[/color] Long: [color=blue]Let[/color] sr = 21 [color=lightgreen]'Start row of data[/color]
 
    [color=blue]For[/color] rws = sr [color=blue]To[/color] lr [color=blue]Step[/color] 1
    [color=blue]Let[/color] wksLG.Range("D" & rws & "").Value = Left((wksLG.Range("A" & rws & "").Value), 4)
    [color=lightgreen]'Let wksLG.Range("D" & rws & "").Value = GetLeftstr((wksLG.Range("A" & rws & "").Value), 4)[/color]
        [color=lightgreen]'wksLG.Range("D" & rws & "").Value = Left$((wksLG.Range("A" & rws & "").Value), 4)[/color]
    [color=blue]Next[/color] rws
 
[color=blue]End[/color] [color=blue]Sub[/color] [color=lightgreen]'SimpleLoop[/color]
'
'
[color=blue]Sub[/color] G2_TypicalEvaluateAlternativeToLoop()
 [color=blue]Dim[/color] wksLG [color=blue]As[/color] Worksheet: [color=blue]Set[/color] wksLG = ThisWorkbook.Worksheets("LeftSpeedsDeutsch") [color=lightgreen]'Give abbreviations the  Methods, properties, sub-Objects through dot of Worksheets Object[/color]
 [color=blue]Dim[/color] RngName [color=blue]As[/color] Range, RngD [color=blue]As[/color] Range [color=lightgreen]'Data Column range and an offset Column for results.. Give abbreviations >>>[/color]
 [color=blue]Dim[/color] lr [color=blue]As[/color] [color=blue]Long[/color] [color=lightgreen]'last row ( Long is a Big whole Number limit (-2,147,483,648 to 2,147,483,647) -Most smaller numbers, Byte, Integer, Single are converted in computer to long so no advantage of Dim to smaller Type here)[/color]
 [color=blue]Let[/color] lr = wksLG.Cells(Rows.Count, 1).End(xlUp).Row [color=lightgreen]'Better alternative for single column work. - Starting at last Spreadsheet Row in column1, quasi "go back up" / return the last cell with entry in it as a Range object using .End Property and obtain rows from the .Rows Property of that returned Range Object[/color]
 [color=blue]Dim[/color] sr [color=blue]As[/color] Long: [color=blue]Let[/color] sr = 21 [color=lightgreen]'Start row of data[/color]
 [color=blue]Set[/color] RngName = wksLG.Range("A" & sr & ":A" & lr & ""): [color=blue]Set[/color] RngD = wksLG.Range("D" & sr & ":D" & lr & "") [color=lightgreen]'...>>>>..the  Methods, properties, sub-Objects through dot of Worksheets Object[/color]
 
    [color=lightgreen]'Let RngD.Value = Evaluate("if(Row(21:1674),LEFT(" & RngName.Address & ",4))")[/color]
  [color=blue]Let[/color] RngD.Value = Evaluate("if(Row(" & sr & ":" & lr & "),LEFT(" & RngName.Address & ",4))")
  [color=lightgreen]'Let RngD.Value = Evaluate("if(Row(" & sr & ":" & lr & "),GetLeftstr(" & RngName.Address & ",4))")[/color]
 
[color=blue]End[/color] [color=blue]Sub[/color] [color=lightgreen]'TypicalEvaluateAlternativeToLoop[/color]
[color=lightgreen]'[/color]
'
[color=blue]Sub[/color] G3_4_VBAWithFormula()
 [color=blue]Dim[/color] wksLG [color=blue]As[/color] Worksheet: [color=blue]Set[/color] wksLG = ThisWorkbook.Worksheets("LeftSpeedsDeutsch")
 [color=blue]Dim[/color] RngD [color=blue]As[/color] Range, RngName [color=blue]As[/color] Range
 [color=blue]Dim[/color] lr [color=blue]As[/color] [color=blue]Long[/color], rws [color=blue]As[/color] [color=blue]Long[/color]
 [color=blue]Let[/color] lr = wksLG.Cells(Rows.Count, 1).End(xlUp).Row
 [color=blue]Dim[/color] sr [color=blue]As[/color] Long: [color=blue]Let[/color] sr = 21
 [color=blue]Set[/color] RngD = Range("D" & sr & ":D" & lr & ""):  [color=blue]Set[/color] RngName = Range("A" & sr & ":A" & lr & "")
 
    [color=blue]With[/color] RngD
        [color=lightgreen]'.Formula = "=Left(" & RngName.Address & ",4)"[/color]
        [color=lightgreen]'.FormulaR1C1 = "=left(R[0]C[-3],4)"[/color]
        [color=lightgreen]'.Formula = "=GetLeftstr(" & RngName.Address & ",4)"[/color]
        .FormulaR1C1 = "=GetLeftstr(R[0]C[-3],4)"
   
    [color=blue]End[/color] [color=blue]With[/color]
 
[color=blue]End[/color] [color=blue]Sub[/color] [color=lightgreen]'VBAWithFormula()[/color]
[color=lightgreen]'[/color]
[color=blue]Sub[/color] G5_6_VBAFormulaLoop() 'Looping the [color=blue]For[/color]mulas in
 
 [color=blue]Dim[/color] wksLG [color=blue]As[/color] Worksheet: [color=blue]Set[/color] wksLG = ThisWorkbook.Worksheets("LeftSpeedsDeutsch") [color=lightgreen]'Give abbreviations the  Methods, properties, sub-Objects through dot of Worksheets Object[/color]
 [color=blue]Dim[/color] lr [color=blue]As[/color] [color=blue]Long[/color], rws [color=blue]As[/color] [color=blue]Long[/color]
 [color=blue]Let[/color] lr = wksLG.Cells(Rows.Count, 1).End(xlUp).Row [color=lightgreen]'Better alternative for single column work. - Starting at last Spreadsheet Row in column1, quasi "go back up" / return the last cell with entry in it as a Range object using .End Property and obtain rows from the .Rows Property of that returned Range Object[/color]
 [color=blue]Dim[/color] sr [color=blue]As[/color] Long: [color=blue]Let[/color] sr = 21 [color=lightgreen]'Start row of data[/color]
 [color=blue]Dim[/color] RngD [color=blue]As[/color] Range, RngName [color=blue]As[/color] Range
 [color=blue]Set[/color] RngD = Range("D" & sr & ":D" & lr & ""):  [color=blue]Set[/color] RngName = Range("A" & sr & ":A" & lr & "")
   
    For rws = sr [color=blue]To[/color] lr [color=blue]Step[/color] 1
    [color=lightgreen]'wksLG.Range("D" & rws & "").Formula = "=Left(" & RngName.Address & ",4)"[/color]
    [color=lightgreen]'wksLG.Range("D" & rws & "").FormulaR1C1 = "=left(R[0]C[-3],4)"[/color]
    [color=lightgreen]'wksLG.Range("D" & rws & "").Formula = "=GetLeftstr(" & RngName.Address & ",4)"[/color]
    wksLG.Range("D" & rws & "").FormulaR1C1 = "=GetLeftstr(R[0]C[-3],4)"
    [color=blue]Next[/color] rws
 
[color=blue]End[/color] [color=blue]Sub[/color] [color=lightgreen]'VBAFormulaLoop[/color]
 
[color=lightgreen]'[/color]
'
[color=blue]Sub[/color] G7_EvaluateRoaryALeftFunction()
 [color=blue]Dim[/color] wksLG [color=blue]As[/color] Worksheet: [color=blue]Set[/color] wksLG = ThisWorkbook.Worksheets("LeftSpeedsDeutsch")
 [color=blue]Dim[/color] RngName [color=blue]As[/color] Range, RngD [color=blue]As[/color] Range
 [color=blue]Dim[/color] lr [color=blue]As[/color] [color=blue]Long[/color], rws [color=blue]As[/color] [color=blue]Long[/color]
 [color=blue]Let[/color] lr = wksLG.Cells(Rows.Count, 1).End(xlUp).Row
 [color=blue]Dim[/color] sr [color=blue]As[/color] Long: [color=blue]Let[/color] sr = 21
 [color=blue]Set[/color] RngName = wksLG.Range("A" & sr & ":A" & lr & ""): [color=blue]Set[/color] RngD = wksLG.Range("D" & sr & ":D" & lr & "")
 
  [color=blue]Let[/color] RngD.Value = Evaluate("RoaryLeftPubic(" & RngName.Address & ",4)")
 
[color=blue]End[/color] [color=blue]Sub[/color] [color=lightgreen]'EvaluateRoaryALeftFunction()[/color]
[color=lightgreen]'[/color]
 
 
 
 
[color=lightgreen]'[/color]
'
[color=blue]Sub[/color] VBALeft() 'DON'T WORK
 [color=blue]Dim[/color] wksLG [color=blue]As[/color] Worksheet: [color=blue]Set[/color] wksLG = ThisWorkbook.Worksheets("LeftSpeedsDeutsch")
 [color=blue]Dim[/color] RngD [color=blue]As[/color] Range, RngName [color=blue]As[/color] Range
 [color=blue]Dim[/color] lr [color=blue]As[/color] [color=blue]Long[/color], rws [color=blue]As[/color] [color=blue]Long[/color]
 [color=blue]Let[/color] lr = wksLG.Cells(Rows.Count, 1).End(xlUp).Row
 [color=blue]Dim[/color] sr [color=blue]As[/color] Long: [color=blue]Let[/color] sr = 21
 [color=blue]Set[/color] RngD = Range("D" & sr & ":D" & lr & ""): [color=blue]Set[/color] RngName = Range("A" & sr & ":A" & lr & "")
 
    [color=lightgreen]'Let RngD.Value = Left(RngName, 4) Wont work..RngName is nat a string as required in first argument![/color]
 
[color=blue]End[/color] [color=blue]Sub[/color]
 
 
 
[color=lightgreen]'[/color]
[color=blue]Sub[/color] G8_ApplicationWorksheetRoaryFunctionLeft()
 
 [color=blue]Dim[/color] wksLG [color=blue]As[/color] Worksheet: [color=blue]Set[/color] wksLG = ThisWorkbook.Worksheets("LeftSpeedsDeutsch")
 [color=blue]Dim[/color] RngName [color=blue]As[/color] Range, RngD [color=blue]As[/color] Range
 [color=blue]Dim[/color] lr [color=blue]As[/color] [color=blue]Long[/color], rws [color=blue]As[/color] [color=blue]Long[/color]
 [color=blue]Let[/color] lr = wksLG.Cells(Rows.Count, 1).End(xlUp).Row
 [color=blue]Dim[/color] sr [color=blue]As[/color] Long: [color=blue]Let[/color] sr = 21
 [color=blue]Set[/color] RngName = wksLG.Range("A" & sr & ":A" & lr & ""): [color=blue]Set[/color] RngD = wksLG.Range("D" & sr & ":D" & lr & "")
 
 [color=blue]Let[/color] RngD.Value = RoaryLeftPubic(RngName, 4)
 
[color=blue]End[/color] [color=blue]Sub[/color] [color=lightgreen]'ApplicationWorksheetRoaryFunctionLeft()[/color]
[color=lightgreen]'[/color]
'
 
 
'
''
[color=blue]Sub[/color] G9_VBAArrayOfRanges1a()
[color=lightgreen]'Loop Range of Ranges. VBA Make Array for Output. Output in a "Output Value One Liner"[/color]
[color=lightgreen]'Typical application requiring seperate loops for the (often differnt sized) input and output arrays[/color]
 [color=blue]Dim[/color] wksLG [color=blue]As[/color] Worksheet: [color=blue]Set[/color] wksLG = ThisWorkbook.Worksheets("LeftSpeedsDeutsch")
 [color=blue]Dim[/color] RngName [color=blue]As[/color] Range, RngD [color=blue]As[/color] Range
 [color=blue]Dim[/color] lr [color=blue]As[/color] [color=blue]Long[/color], rws [color=blue]As[/color] [color=blue]Long[/color]
 [color=blue]Let[/color] lr = wksLG.Cells(Rows.Count, 1).End(xlUp).Row
 [color=blue]Dim[/color] sr [color=blue]As[/color] Long: [color=blue]Let[/color] sr = 21
 [color=blue]Set[/color] RngName = wksLG.Range("A" & sr & ":A" & lr & ""): [color=blue]Set[/color] RngD = wksLG.Range("D" & sr & ":D" & lr & "")
 
 [color=blue]Dim[/color] arrIn() [color=blue]As[/color] Range [color=lightgreen]'Variant 'In the looping, the Set would appear to be responsible for bringing **Ranges into the Array The variable type remains as defined here: Either a range for As Range or a Variant Object for [color=blue]As[/color] Variant[/color]
 [color=blue]ReDim[/color] arrIn(sr [color=blue]To[/color] lr, 1 [color=blue]To[/color] 1) [color=lightgreen]'We must give array a size as we give specific value in a loop. ReDim Must be used rather than Dim as [color=blue]Dim[/color] only takes Numbers not variables[/color]
 
    [color=blue]For[/color] rws = sr [color=blue]To[/color] lr [color=blue]Step[/color] 1 [color=lightgreen]'Input Array of Ranges[/color]
        [color=blue]Set[/color] arrIn(rws, 1) = Range("A" & rws & "")
        [color=lightgreen]'Set arrIn(rws, 1) = wksLG.Range("A" & rws & "") 'This would be tolerate**[/color]
    [color=blue]Next[/color] rws
 
 Dim arrOut() As [color=blue]String[/color] [color=lightgreen]'We can use string as in the looping below as we are not relying on (/seeing) a range object to rturn us an array of values.[/color]
 [color=blue]ReDim[/color] arrOut(sr [color=blue]To[/color] lr, 1 To 1) [color=lightgreen]'Antoher way to look at it is to say we have a fixed, rather than dynamiy array, and as VBA does not allow a direct assigning one liner in this case it is also not necerssarily expecting to see an object. For Let it is likely to expect to see some value, and for Set an object (Would expect an Range Object if indicies of arrOut were so defined by arrOut() As String initially[/color]
 
    [color=blue]For[/color] rws = sr [color=blue]To[/color] lr [color=blue]Step[/color] 1 [color=lightgreen]'Input Array of Ranges[/color]
 
            [color=lightgreen]'Let arrOut(rws, 1) = arrIn(rws, 1).Value 'Works 'VBA would appear to recognise this array element as A range as it gives me the Method, Object and property selkection to choose from via intellisense brought in by typing . Dot after the Array elemant[/color]
            [color=lightgreen]'Let arrOut(rws, 1) = arrIn()(rws, 1).Value 'Works'.. because of how VBA “works”, This extra () will ensure that indices are always returned to the resulting array (and not occasionally, for example, arguments ) by any following method or property.[/color]
               [color=lightgreen]'Let arrOut()(rws, 1) = arrIn()(rws, 1).Value 'Doesn't - Rory said it aint ever needed on the LHS,  so it aint[/color]
 [color=lightgreen]'   Let arrOut(rws, 1) = Left(arrIn(rws, 1).Value, 4) 'Even A function on the RHS of the = is accepted Here. So again for a non dynamic Array it is not relying on what the function to "define" the type[/color]
    [color=blue]Let[/color] arrOut(rws, 1) = Left(arrIn()(rws, 1).Value, 4) [color=lightgreen]'Works[/color]
              'Let arrOut()(rws, 1) = Left(arrIn()(rws, 1).Value, 4) 'Works
    [color=blue]Next[/color] rws
[color=lightgreen]'         Possibility to Note here:          Dim IntermediateArray() [color=blue]As[/color] Range 'Variant  'Note RoryA Post #2You can only assign one array to another directly (i.e. without looping) if the destination array is dynamic AND THE TWO ARRAYS ARE THE SAME TYPE.[/color]
[color=lightgreen]'                                          '  Re[color=blue]Dim[/color] IntermediateArray(sr [color=blue]To[/color] lr, 1 [color=blue]To[/color] 1)'THIS Line Will NOT Work: RoryA Post #2 http://www.excelforum.com/excel-new-users-basics/1058406-range-dimensioning-range-and-value-referencing-and-referring-to-arrays.html    - You can only assign one array to another directly (i.e. without looping) if the destination array is dynamic[/color]
[color=lightgreen]'                                            Let IntermediateArray() = arrIn()[/color]
 [color=blue]Let[/color] RngD.Value = arrOut() [color=lightgreen]'This is the typical allowed one liner to give values of a Range the values in an  Array (VBA does not allow this one liner in any way for assigning the ranges. There is no way of getting over having to paste each Range Object in a loop.[/color]
 
 [color=blue]End[/color] [color=blue]Sub[/color] [color=lightgreen]'VBAArrayOfRanges1a[/color]
[color=blue]Sub[/color] G10_VBAArrayOfRanges1aa()
[color=lightgreen]'Loop Range of Ranges. VBA Make Array for Output. Output in a "Output Value One Liner"[/color]
[color=lightgreen]'Typical application requiring seperate loops for the (often differnt sized) input and output arrays[/color]
 [color=blue]Dim[/color] wksLG [color=blue]As[/color] Worksheet: [color=blue]Set[/color] wksLG = ThisWorkbook.Worksheets("LeftSpeedsDeutsch")
 [color=blue]Dim[/color] RngName [color=blue]As[/color] Range, RngD [color=blue]As[/color] Range
 [color=blue]Dim[/color] lr [color=blue]As[/color] [color=blue]Long[/color], rws [color=blue]As[/color] [color=blue]Long[/color]
 [color=blue]Let[/color] lr = wksLG.Cells(Rows.Count, 1).End(xlUp).Row
 [color=blue]Dim[/color] sr [color=blue]As[/color] Long: [color=blue]Let[/color] sr = 21
 [color=blue]Set[/color] RngName = wksLG.Range("A" & sr & ":A" & lr & ""): [color=blue]Set[/color] RngD = wksLG.Range("D" & sr & ":D" & lr & "")
 
 Dim arrIn() As Range [color=lightgreen]'Variant 'In the looping, the Set would appear to be responsible for bringing **Ranges into the Array The variable type remains as defined here: Either a range for [color=blue]As[/color] Range or a Variant Object for [color=blue]As[/color] Variant[/color]
 [color=blue]ReDim[/color] arrIn(sr [color=blue]To[/color] lr, 1 [color=blue]To[/color] 1) [color=lightgreen]'We must give array a size as we give specific value in a loop. ReDim Must be used rather than [color=blue]Dim[/color] as [color=blue]Dim[/color] only takes Numbers not variables[/color]
 
 Dim EmtpyInArrIndiciesCount As Long: [color=blue]Let[/color] EmtpyInArrIndiciesCount = 0 [color=lightgreen]'Here possibility to Redim ArrIn if any extra conitions, such as MSRD etc unique entries being ommited, leading to unused indicies.. then###[/color]
 
 
    [color=blue]For[/color] rws = sr To lr [color=blue]Step[/color] 1 [color=lightgreen]'Input Array of Ranges[/color]
        [color=blue]If[/color] Range("A" & rws & "").Value <> "" [color=blue]Then[/color]
        [color=blue]Set[/color] arrIn(rws - EmtpyInArrIndiciesCount, 1) = Range("A" & rws & "")  [color=lightgreen]'The extra "  - Emtp...." will take inidie niumber back accordingly to fill just after next free indicie[/color]
        [color=lightgreen]'Set arrIn((rws - EmtpyInArrIndiciesCount, 1) = wksLG.Range("A" & rws & "") 'This would be tolerate**[/color]
        [color=blue]Else[/color]
        [color=blue]Let[/color] EmtpyInArrIndiciesCount = EmtpyInArrIndiciesCount + 1
        [color=blue]End[/color] [color=blue]If[/color]
    [color=blue]Next[/color] rws
 
 Dim arrOut() As [color=blue]String[/color] [color=lightgreen]'We can use string as in the looping below as we are not relying on (/seeing) a range object to rturn us an array of values.[/color]
 [color=blue]ReDim[/color] arrOut(sr To lr - EmtpyInArrIndiciesCount, 1 To 1) [color=lightgreen]'Antoher way to look at it is to say we have a fixed, rather than dynamiy array, and as VBA does not allow a direct assigning one liner in this case it is also not necerssarily expecting to see an object. For Let it is likely to expect to see some value, and for Set an object (Would expect an Range Object if indicies of arrOut were so defined by arrOut() As String initially[/color]
   
    [color=blue]For[/color] rws = sr To lr - EmtpyInArrIndiciesCount [color=blue]Step[/color] 1 [color=lightgreen]'Input Array of Ranges'The extra   - Emtp.... prevents looping to far[/color]
 
            [color=lightgreen]'Let arrOut(rws, 1) = arrIn(rws, 1).Value 'Works 'VBA would appear to recognise this array element as A range as it gives me the Method, Object and property selkection to choose from via intellisense brought in by typing . Dot after the Array elemant[/color]
            [color=lightgreen]'Let arrOut(rws, 1) = arrIn()(rws, 1).Value 'Works'.. because of how VBA “works”, This extra () will ensure that indices are always returned to the resulting array (and not occasionally, for example, arguments ) by any following method or property.[/color]
               [color=lightgreen]'Let arrOut()(rws, 1) = arrIn()(rws, 1).Value 'Dont Work gives empty but Rory said it aint ever needed on the LHS,  so it aint[/color]
    [color=blue]Let[/color] arrOut(rws, 1) = Left(arrIn(rws, 1).Value, 4) [color=lightgreen]'Even A function on the RHS of the = is accepted Here. So again for a non dynamic Array it is not relying on what the function to "define" the type[/color]
[color=lightgreen]'    Let arrOut(rws, 1) = Left(arrIn()(rws, 1).Value, 4) 'Works[/color]
              [color=lightgreen]'Let arrOut()(rws, 1) = Left(arrIn()(rws, 1).Value, 4) 'Works[/color]
    [color=blue]Next[/color] rws
[color=lightgreen]'         Possibility to Note here:          Dim IntermediateArray() As Range 'Variant  'Note RoryA Post #2You can only assign one array to another directly (i.e. without looping) if the destination array is dynamic AND THE TWO ARRAYS ARE THE SAME TYPE.[/color]
[color=lightgreen]'                                          '  ReDim IntermediateArray(sr To lr, 1 To 1)'THIS Line Will NOT Work: RoryA Post #2 http://www.excelforum.com/excel-new-users-basics/1058406-range-dimensioning-range-and-value-referencing-and-referring-to-arrays.html    - You can only assign one array to another directly (i.e. without looping) if the destination array is dynamic[/color]
[color=lightgreen]'                                            Let IntermediateArray() = arrIn()[/color]
 [color=blue]Let[/color] RngD.Resize(lr - sr - EmtpyInArrIndiciesCount + 1, 1).Value = arrOut() [color=lightgreen]'This is the typical allowed one liner to give values of a Range the values in an  Array (VBA does not allow this one liner in any way for assigning the ranges. There is no way of getting over having to paste each Range Object in a loop. 'The extra size corrections prevents a NoValue error placed in last cell if trying to assign to indicies that are not there[/color]
 
[color=lightgreen]''        'Long winded alternative to give an empty indicie rather than no indicie to prevent6 output error[/color]
[color=lightgreen]''        ' 1)Because we assign the Array using the Value property of a range, the returned array has lower bounds[/color]
[color=lightgreen]''        ' of 1 for each dimension. When we redim it without providing lower bounds explicitly,[/color]
[color=lightgreen]''        ' the redim tries to assign each dimension the default lower bound, which is 0 giving an error.[/color]
[color=lightgreen]''        ' So we need to explicitly provide the lower bounds[/color]
[color=lightgreen]''        ' 2) Only the size of the last dimension can be changed for a non dynamic arrange. We want to change the first.[/color]
[color=lightgreen]''        ' So we do a transpose trick for that problem[/color]
[color=lightgreen]''        ' 3) Preseve ensures we do not loose the info already there.   (Post #11   http://www.mrexcel.com/forum/excel-questions/830139-proper-redim-preserve-syntax-best-practice-2.html#post4049584)[/color]
[color=lightgreen]''        ' 4) Would only be needed if arrOut has only 1 column as the Transpose does some thing wiered .. does not give 1 to 1 back.. gives normal array...just 1 indicie in ()[/color]
[color=lightgreen]'        Dim TempTranspose() As Variant 'Must be variant as seeing a Function below in a "one Liner" which returns a collection which VBA will always guess as an Array because Rory-a-Romping Archibald said so to me... a few times now!!![/color]
[color=lightgreen]'        Let TempTranspose = Application.WorksheetFunction.Transpose(arrOut) 'This woulöd annoyingly take for example 21 to 23 , 1 to 1   and give back ... 1 to 3   ONLY!![/color]
[color=lightgreen]'        ReDim Preserve arrOut(sr To lr - EmtpyInArrIndiciesCount, 1 To 2) 'This  extra bodge 4  '- Seems to be necerssary to make at least bigger than 1 column - goes from for example 21-23, 1 to 1   > Redim Preserve > 21-23, 1 to 2[/color]
[color=lightgreen]'        Let TempTranspose = Application.WorksheetFunction.Transpose(arrOut) 'Important.. transposes, but > is 1 to 2, ... 1 to 3 ... so would appoear always to start at 1[/color]
[color=lightgreen]'        ReDim Preserve TempTranspose(1 To 2, 1 To lr - sr + EmtpyInArrIndiciesCount) 'This increase from 3 to 4 columns[/color]
[color=lightgreen]'          'ReDim Preserve TempTranspose(1 To 2, sr To lr)' This will NOT work!![/color]
[color=lightgreen]'        Let TempTranspose = Application.WorksheetFunction.Transpose(TempTranspose) 'We have the increased row size bot are stuck with the convention of rows starting at 1[/color]
[color=lightgreen]'        ReDim Preserve TempTranspose(1 To lr - sr + EmtpyInArrIndiciesCount, 1 To 1) 'This is extra bodge 4 Part 2[/color]
[color=lightgreen]'[/color]
'        Let RngD.Value = TempTranspose
 
 [color=blue]End[/color] [color=blue]Sub[/color] [color=lightgreen]'VBAArrayOfRanges1aa[/color]
 
 
 
[color=lightgreen]'[/color]
'
''
[color=blue]Sub[/color] G11_VBAArrayOfRanges1b()
[color=lightgreen]'Loop Range of Ranges. VBA Make Array for Output. Output in a "Output Value One Liner"[/color]
[color=lightgreen]'Typical application requiring seperate loops for the (often differnt sized) input and output arrays[/color]
[color=lightgreen]'Just an extra direct assigniong bit to demonstrate possibillity of assigning a non dynamic array to a dynamic array in one go, noting Dim characteristics[/color]
 [color=blue]Dim[/color] wksLG [color=blue]As[/color] Worksheet: [color=blue]Set[/color] wksLG = ThisWorkbook.Worksheets("LeftSpeedsDeutsch")
 [color=blue]Dim[/color] RngName [color=blue]As[/color] Range, RngD [color=blue]As[/color] Range
 [color=blue]Dim[/color] lr [color=blue]As[/color] [color=blue]Long[/color], rws [color=blue]As[/color] [color=blue]Long[/color]
 [color=blue]Let[/color] lr = wksLG.Cells(Rows.Count, 1).End(xlUp).Row
 [color=blue]Dim[/color] sr [color=blue]As[/color] Long: [color=blue]Let[/color] sr = 21
 [color=blue]Set[/color] RngName = wksLG.Range("A" & sr & ":A" & lr & ""): [color=blue]Set[/color] RngD = wksLG.Range("D" & sr & ":D" & lr & "")
 
 Dim arrIn() [color=blue]As[/color] Range [color=lightgreen]'Variant 'In the looping, the Set would appear to be responsible for bringing **Ranges into the Array The variable type remains as defined here: Either a range for As Range or a Variant Object for [color=blue]As[/color] Variant[/color]
 [color=blue]ReDim[/color] arrIn(sr [color=blue]To[/color] lr, 1 [color=blue]To[/color] 1) [color=lightgreen]'We must give array a size as we give specific value in a loop. ReDim Must be used rather than [color=blue]Dim[/color] as Dim only takes Numbers not variables[/color]
 
    [color=blue]For[/color] rws = sr To lr [color=blue]Step[/color] 1 [color=lightgreen]'Input Array of Ranges[/color]
    [color=lightgreen]'Set arrIn()(rws, 1) = Range("A" & rws & "") 'Does not work, that is to say produces error later####!!!![/color]
    [color=blue]Set[/color] arrIn(rws, 1) = Range("A" & rws & "") [color=lightgreen]'no error later - we are setting, that is to say "making an object, or rather putting? one in an[/color]
    [color=lightgreen]'Set arrIn(rws, 1) = wksLG.Range("A" & rws & "") 'This would be tolerate**[/color]
    [color=blue]Next[/color] rws
   
   
Dim IntermediateArray() [color=blue]As[/color] Range [color=lightgreen]'Variant  'Note RoryA Post #2You can only assign one array to another directly (i.e. without looping) if the destination array is dynamic AND THE TWO ARRAYS ARE THE SAME TYPE.[/color]
[color=lightgreen]'                                          '  Re[color=blue]Dim[/color] IntermediateArray(sr [color=blue]To[/color] lr, 1 [color=blue]To[/color] 1)'THIS Line Will NOT Work: RoryA Post #2 http://www.excelforum.com/excel-new-users-basics/1058406-range-dimensioning-range-and-value-referencing-and-referring-to-arrays.html    - You can only assign one array to another directly (i.e. without looping) if the destination array is dynamic[/color]
[color=blue]Let[/color] IntermediateArray() = arrIn() [color=lightgreen]'  ......and the output held in the Array is Variant type and is an OBJECT of the sort like a Range. (This compares with a similar code utilising An Array of Ranges rather than the MicrosoftScriptimeRuntimeDictionary. (In the Array of Ranges case we could Dim as Range or Variant here. - Important however in that case is that the Dynamic IntermediateArray() Array and the (in that Array of Ranges case non dynamic) arrIn() Array are of the same type. - Either both Range to return an Array of element Type Range or both [color=blue]Variant[/color] to Return an Array of element Type Of Objects of the Range Sort : - RoryA . You can only assign one array to another directly (i.e. without looping....... and the two arrays are the same type. http://www.excelforum.com/excel-new-users-basics/1058406-range-dimensioning-range-and-value-referencing-and-referring-to-arrays.html[/color]
 
 
 [color=blue]Dim[/color] arrOut() As [color=blue]String[/color] [color=lightgreen]'We can use string as in the looping below as we are not relying on (/seeing) a range object to rturn us an array of values.[/color]
 [color=blue]Re[color=blue]Dim[/color][/color] arrOut(sr [color=blue]To[/color] lr, 1 [color=blue]To[/color] 1) [color=lightgreen]'Antoher way to look at it is to say we have a fixed, rather than dynamiy array, and as VBA does not allow a direct assigning one liner in this case it is also not necerssarily expecting to see an object. For Let it is likely to expect to see some value, and for Set an object (Would expect an Range Object if indicies of arrOut were so defined by arrOut() [color=blue]As[/color] String initially[/color]
 
    [color=blue]For[/color] rws = sr [color=blue]To[/color] lr [color=blue]Step[/color] 1 [color=lightgreen]'Input Array of Ranges[/color]
                [color=lightgreen]'Let arrOut(rws, 1) = IntermediateArray(rws, 1).Value 'VBA would appear to recognise this array element as A range as it gives me the Method, Object and property selkection to choose from via intellisense brought in by typing . Dot after the Array elemant[/color]
            [color=lightgreen]'    Let arrOut(rws, 1) = IntermediateArray(rws, 1).Value'####here comes the error by replaceing Set arrIn(rws, 1) with [color=blue]Set[/color] arrIn()(rws, 1) or in the following similar lines[/color]
            [color=lightgreen]'    Let arrOut(rws, 1) = IntermediateArray()(rws, 1).Value.. because of how VBA “works”, This extra () will ensure that indices are always returned to the resulting array (and not occasionally, for example, arguments ) by any following method or property.[/color]
                [color=lightgreen]'    Let arrOut()(rws, 1) = IntermediateArray(rws, 1).Value'Dos not work anyway it aint ever needed on the LHS said Rory,  so it aint[/color]
                    [color=lightgreen]'Let arrOut(rws, 1) = IntermediateArray()(rws, 1).Value[/color]
 [color=lightgreen]'   Let arrOut(rws, 1) = Left(IntermediateArray(rws, 1).Value, 4) 'Even A function on the RHS of the = is accepted Here. So again for a non dynamic Array it is not relying on what the function to "define" the type[/color]
                [color=lightgreen]'Let arrOut()(rws, 1) = Left(IntermediateArray(rws, 1).Value, 4) 'Givers empty[/color]
                [color=lightgreen]'Let arrOut()(rws, 1) = Left(IntermediateArray()(rws, 1).Value, 4)'Gives empty[/color]
    [color=blue]Let[/color] arrOut(rws, 1) = Left(IntermediateArray()(rws, 1).Value, 4)
    [color=blue]Next[/color] rws
   
 [color=blue]Let[/color] RngD.Value = arrOut() [color=lightgreen]'This is the typical allowed one liner to give values of a Range the valiues in an  Array (VBA does not allow this one liner in any way for assigning the ranges. There is no wy of getting over having to paste each Range Object in in a loop.[/color]
 
 [color=blue]End[/color] [color=blue]Sub[/color] [color=lightgreen]'VBAArrayOfRanges1b[/color]
 [color=lightgreen]'[/color]
 '
 '
'
[color=blue]Sub[/color] G12_VBAArrayOfRanges2()
[color=lightgreen]'Loop Range of Ranges. VBA Make Array for Output. Output in a "Output Value One Liner"[/color]
[color=lightgreen]'less typical application where any workings can be done within one loop and Input and Output arrays may be similarly sized[/color]
 [color=blue]Dim[/color] wksLG [color=blue]As[/color] Worksheet: [color=blue]Set[/color] wksLG = ThisWorkbook.Worksheets("LeftSpeedsDeutsch")
 [color=blue]Dim[/color] RngName [color=blue]As[/color] Range, RngD [color=blue]As[/color] Range
 [color=blue]Dim[/color] lr [color=blue]As[/color] [color=blue]Long[/color], rws [color=blue]As[/color] [color=blue]Long[/color]
 [color=blue]Let[/color] lr = wksLG.Cells(Rows.Count, 1).End(xlUp).Row
 Dim sr [color=blue]As[/color] Long: [color=blue]Let[/color] sr = 21
 [color=blue]Set[/color] RngName = wksLG.Range("A" & sr & ":A" & lr & ""): [color=blue]Set[/color] RngD = wksLG.Range("D" & sr & ":D" & lr & "")
 
 Dim arrIn()  [color=blue]As[/color] Range, arrOut() [color=blue]As[/color] [color=blue]String[/color] [color=lightgreen]'[/color]
 [color=blue]Re[color=blue]Dim[/color][/color] arrIn(sr [color=blue]To[/color] lr, 1 [color=blue]To[/color] 1): [color=blue]Re[color=blue]Dim[/color][/color] arrOut(sr [color=blue]To[/color] lr, 1 To 1)
    [color=blue]For[/color] rws = sr [color=blue]To[/color] lr [color=blue]Step[/color] 1 [color=lightgreen]'Input Array of Ranges[/color]
    Set arrIn(rws, 1) = Range("A" & rws & "")
   
    [color=lightgreen]'        '    Let arrOut()(rws, 1) = Left(arrIn(rws, 1).Value, 4) 'Takes 30.5s and returns empties[/color]
    [color=lightgreen]'        '    Let arrOut()(rws, 1) = Left(arrIn()(rws, 1).Value, 4)'Takes 146s and returns empties[/color]
    [color=lightgreen]'Let arrOut(rws, 1) = Left(arrIn(rws, 1).Value, 4)'Takes 1.5s. "Works"[/color]
    [color=blue]Let[/color] arrOut(rws, 1) = Left(arrIn()(rws, 1).Value, 4) [color=lightgreen]'Takes 115s.  ."Works". because of how VBA “works”, This extra () will ensure that indices are always returned to the resulting array (and not occasionally, for example, arguments ) by any following method or property. It "tolerates" for Let on LHS also (returning empties) (but not for [color=blue]Set[/color] in the case of similar line involving Ranges..)..But Rory thinks it would never be needed there anyway, which means it most likely doesn't.[/color]
   
    [color=blue]Next[/color] rws
 
 [color=blue]Let[/color] RngD.Value = arrOut()
 
[color=blue]End[/color] [color=blue]Sub[/color] [color=lightgreen]'VBAArrayOfRanges2[/color]
 
 
[color=blue]Sub[/color] G13_RangeObjectCapture()
[color=lightgreen]'The entire range is captured as One Range Object and its Value2 values accesed and used[/color]
[color=lightgreen]'then as before VBA Make Array for Output. Output in a "Output Value One Liner"[/color]
 [color=blue]Dim[/color] wksLG [color=blue]As[/color] Worksheet: [color=blue]Set[/color] wksLG = ThisWorkbook.Worksheets("LeftSpeedsDeutsch")
 [color=blue]Dim[/color] RngName [color=blue]As[/color] Range, RngD [color=blue]As[/color] Range
 [color=blue]Dim[/color] lr [color=blue]As[/color] [color=blue]Long[/color], rws [color=blue]As[/color] [color=blue]Long[/color]
 [color=blue]Let[/color] lr = wksLG.Cells(Rows.Count, 1).End(xlUp).Row
 Dim sr [color=blue]As[/color] Long: [color=blue]Let[/color] sr = 21
 [color=blue]Set[/color] RngName = wksLG.Range("A" & sr & ":A" & lr & ""): [color=blue]Set[/color] RngD = wksLG.Range("D" & sr & ":D" & lr & "")
 
 Dim CapturedRangeObject [color=blue]As[/color] Range [color=lightgreen]'One Range Object for entire range[/color]
 Set CapturedRangeObject = RngName [color=lightgreen]'Direct assignmet to existing [color=blue]Dim[/color]ensioned Array[/color]
 
 [color=blue]Dim[/color] arrOut() As [color=blue]String[/color] [color=lightgreen]'We can use string as in the looping below as we are not relying on (/seeing) a range object to return us an array of values.[/color]
 [color=blue]Re[color=blue]Dim[/color][/color] arrOut(sr [color=blue]To[/color] lr, 1 To 1) [color=lightgreen]'Antoher way to look at it is to say we have a fixed, rather than dynamiy array, and as VBA does not allow a direct assigning one liner in this case it is also not necerssarily expecting to see an object. For Let it is likely to expect to see some value, and for [color=blue]Set[/color] an object (Would expect an Range Object if indicies of arrOut were so defined by arrOut() [color=blue]As[/color] String initially[/color]
 
    [color=blue]For[/color] rws = sr [color=blue]To[/color] lr [color=blue]Step[/color] 1 [color=lightgreen]'Input Array of Ranges[/color]
                           [color=lightgreen]'Let arrOut(rws, 1) = CapturedRangeObject.Value2(rws - sr + 1, 1) 'Conventionally the Value2 values are in an Array starting at ( 1, 1) and extending over the two (in this case just a 1 dimensional array). So a bit of adjusting with the indicies is necerssary[/color]
    [color=blue]Let[/color] arrOut(rws, 1) = Left(CapturedRangeObject.Value2(rws - sr + 1, 1), 4)
    [color=lightgreen]'Let arrOut(rws, 1) = Left(CapturedRangeObject.Value2()(rws - sr + 1, 1), 4) ' because of how VBA “works”, This extra () will ensure that indices are always returned to the resulting array (and not occasionally, for example, arguments ) by any following method or property, or passed to any method or property, (In the "bodge subs it is assigned each time to the full object[/color]
    [color=blue]Next[/color] rws
   
 [color=blue]Let[/color] RngD.Value = arrOut()
 
[color=blue]End[/color] [color=blue]Sub[/color] [color=lightgreen]'RangeObjectCapture()[/color]
[color=blue]Sub[/color] G13b_RangeObjectCapture()
[color=lightgreen]'The entire range is captured as One Range Object and its Value2 values accesed and used[/color]
[color=lightgreen]'then as before VBA Make Array for Output. Output in a "Output Value One Liner"[/color]
 [color=blue]Dim[/color] wksLG [color=blue]As[/color] Worksheet: [color=blue]Set[/color] wksLG = ThisWorkbook.Worksheets("LeftSpeedsDeutsch")
 [color=blue]Dim[/color] RngName [color=blue]As[/color] Range, RngD [color=blue]As[/color] Range
 Dim lr [color=blue]As[/color] [color=blue]Long[/color], rws [color=blue]As[/color] [color=blue]Long[/color]
 [color=blue]Let[/color] lr = wksLG.Cells(Rows.Count, 1).End(xlUp).Row
 Dim sr [color=blue]As[/color] Long: [color=blue]Let[/color] sr = 21
 [color=blue]Set[/color] RngName = wksLG.Range("A" & sr & ":A" & lr & ""): [color=blue]Set[/color] RngD = wksLG.Range("D" & sr & ":D" & lr & "")
 
 [color=blue]Dim[/color] CapturedRangeObject [color=blue]As[/color] Range [color=lightgreen]'One Range Object for entire range[/color]
 Set CapturedRangeObject = RngName [color=lightgreen]'Direct assignmet to existing [color=blue]Dim[/color]ensioned Array[/color]
 
 [color=blue]Dim[/color] arrOut() As [color=blue]String[/color] [color=lightgreen]'We can use string as in the looping below as we are not relying on (/seeing) a range object to return us an array of values.[/color]
 [color=blue]Re[color=blue]Dim[/color][/color] arrOut(sr To lr, 1 [color=blue]To[/color] 1) [color=lightgreen]'Antoher way to look at it is to say we have a fixed, rather than dynamiy array, and as VBA does not allow a direct assigning one liner in this case it is also not necerssarily expecting to see an object. For Let it is likely to expect to see some value, and for [color=blue]Set[/color] an object (Would expect an Range Object if indicies of arrOut were so defined by arrOut() [color=blue]As[/color] String initially[/color]
 
  [color=blue]Dim[/color] vTemp() [color=blue]As[/color] Variant [color=lightgreen]'Post from #20  - #24 .. return the array to a variable and then reference the elements through that variable, in which case you don't need to worry about the extra () . The usual "To see an object which returns a field" requirement to be dimensioned as [color=blue]Variant[/color][/color]
    [color=lightgreen]'  http://www.mrexcel.com/forum/excel-questions/832103-using-microsoft-scripting-runtime-dictionary-store-then-retrieve-range-objects-3.html[/color]
   
    [color=blue]For[/color] rws = sr [color=blue]To[/color] lr [color=blue]Step[/color] 1 [color=lightgreen]'Input Array of Ranges[/color]
    [color=blue]Let[/color] vTemp = CapturedRangeObject.Value2 [color=lightgreen]'Works vTemp is Array of variants values, a Data field[/color]
   
    [color=blue]Let[/color] arrOut(rws, 1) = Left(vTemp(rws - sr + 1, 1), 4)
    [color=lightgreen]'Let arrOut(rws, 1) = Left(vTemp()(rws - sr + 1, 1), 4)'This will not work..[/color]
    [color=blue]Next[/color] rws
   
 [color=blue]Let[/color] RngD.Value = arrOut()
 
[color=blue]End[/color] [color=blue]Sub[/color] [color=lightgreen]'RangeObjectCapture()[/color]
[color=blue]Sub[/color] G13c_RangeObjectCapture()
[color=lightgreen]'The entire range is captured as One Range Object and its Value2 values accesed and used[/color]
[color=lightgreen]'then as before VBA Make Array for Output. Output in a "Output Value One Liner"[/color]
 [color=blue]Dim[/color] wksLG [color=blue]As[/color] Worksheet: [color=blue]Set[/color] wksLG = ThisWorkbook.Worksheets("LeftSpeedsDeutsch")
 Dim RngName [color=blue]As[/color] Range, RngD [color=blue]As[/color] Range
 Dim lr [color=blue]As[/color] [color=blue]Long[/color], rws [color=blue]As[/color] [color=blue]Long[/color]
 [color=blue]Let[/color] lr = wksLG.Cells(Rows.Count, 1).End(xlUp).Row
 [color=blue]Dim[/color] sr [color=blue]As[/color] Long: [color=blue]Let[/color] sr = 21
 [color=blue]Set[/color] RngName = wksLG.Range("A" & sr & ":A" & lr & ""): [color=blue]Set[/color] RngD = wksLG.Range("D" & sr & ":D" & lr & "")
 
 [color=blue]Dim[/color] CapturedRangeObject [color=blue]As[/color] Range [color=lightgreen]'One Range Object for entire range[/color]
 Set CapturedRangeObject = RngName [color=lightgreen]'Direct assignmet to existing [color=blue]Dim[/color]ensioned Array[/color]
 
 [color=blue]Dim[/color] arrOut() As [color=blue]String[/color] [color=lightgreen]'We can use string as in the looping below as we are not relying on (/seeing) a range object to return us an array of values.[/color]
 [color=blue]Re[color=blue]Dim[/color][/color] arrOut(sr To lr, 1 To 1) [color=lightgreen]'Antoher way to look at it is to say we have a fixed, rather than dynamiy array, and as VBA does not allow a direct assigning one liner in this case it is also not necerssarily expecting to see an object. For Let it is likely to expect to see some value, and for [color=blue]Set[/color] an object (Would expect an Range Object if indicies of arrOut were so defined by arrOut() [color=blue]As[/color] String initially[/color]
 
  [color=blue]Dim[/color] vTemp [color=blue]As[/color] Variant [color=lightgreen]'Post from #20  - #24 .. return the array to a variable and then reference the elements through that variable, in which case you don't need to worry about the extra () . (The usual "To see an (Range) object which returns a field" requirement to be dimensioned as [color=blue]Variant[/color] - Post #13 Post #14 http://www.excelforum.com/excel-programming-vba-macros/1058171-return-row-index-and-column-index-of-a-cell-in-a-range.html[/color]
    [color=lightgreen]'  http://www.mrexcel.com/forum/excel-questions/832103-using-microsoft-scripting-runtime-dictionary-store-then-retrieve-range-objects-3.html[/color]
 
  [color=blue]Let[/color] vTemp = CapturedRangeObject.Value2 [color=lightgreen]'Works vTemp is Array of variants values, a Data field[/color]
   
    [color=blue]For[/color] rws = sr To lr [color=blue]Step[/color] 1 [color=lightgreen]'Input Array of Ranges[/color]
                
                    [color=lightgreen]'Let arrOut()(rws, 1) = Left(vTemp(rws - sr + 1, 1), 4) 'Tolerates the Extra () on the LHS but rerurns empties and takes usually lots longer, here (for 33928 Rows) 30.5s .. compared to _-[/color]
    [color=blue]Let[/color] arrOut(rws, 1) = Left(vTemp(rws - sr + 1, 1), 4) [color=lightgreen]'  ... takes 0.325s for 33928 Rows.[/color]
      [color=lightgreen]'Let arrOut(rws, 1) = Left(vTemp()(rws - sr + 1, 1), 4) 'wont work ????? ####1 Error 9: Index out of valid Range[/color]
    [color=blue]Next[/color] rws
   
 [color=blue]Let[/color] RngD.Value = arrOut()
 
[color=blue]End[/color] [color=blue]Sub[/color] [color=lightgreen]'RangeObjectCaptureC()[/color]
[color=lightgreen]'[/color]
'
[color=blue]Sub[/color] G13_RangeObjectCaptureExcelForumDemo()
[color=lightgreen]'The entire range is captured as One Range Object and its Value2 values accesed and used[/color]
[color=lightgreen]'then in VBA Make an Array for Output. Output in a "Output Value One Liner"[/color]
[color=lightgreen]'(Demonstrating also advantage and characteristics of temporary intermediateArray)[/color]
 Dim wksLG [color=blue]As[/color] Worksheet: [color=blue]Set[/color] wksLG = ThisWorkbook.Worksheets("LeftSpeedsDeutsch")
 Dim RngName [color=blue]As[/color] Range, RngD [color=blue]As[/color] Range
 [color=blue]Dim[/color] lr [color=blue]As[/color] [color=blue]Long[/color], rws [color=blue]As[/color] [color=blue]Long[/color]
 [color=blue]Let[/color] lr = wksLG.Cells(Rows.Count, 1).End(xlUp).Row
 Dim sr [color=blue]As[/color] Long: [color=blue]Let[/color] sr = 21
 [color=blue]Set[/color] RngName = wksLG.Range("A" & sr & ":A" & lr & ""): [color=blue]Set[/color] RngD = wksLG.Range("D" & sr & ":D" & lr & "")
 
 Dim CapturedRangeObject [color=blue]As[/color] Range [color=lightgreen]'          One Range Object for entire range[/color]
 Set CapturedRangeObject = RngName [color=lightgreen]'         Direct assignmet to existing Dimensioned Array[/color]
 
 Dim arrOut() As [color=blue]String[/color] [color=lightgreen]'We can use string as in the looping below as we are not relying on (/seeing) a range object to return us an array of values.[/color]
 [color=blue]ReDim[/color] arrOut(sr To lr, 1 To 1) [color=lightgreen]'Antoher way to look at it is to say we have a fixed, rather than dynamiy array, and as VBA does not allow a direct assigning one liner in this case it is also not necerssarily expecting to see an object. For Let it is likely to expect to see some value, and for Set an object (Would expect an Range Object if indicies of arrOut were so defined by arrOut() [color=blue]As[/color] String initially[/color]
 
  Dim vTemp As Variant [color=lightgreen]'                                       Post from #20  - #24 .. return the array to a variable and then reference the elements through that variable, in which case you don't need to worry about the extra () . (The usual "To see an (Range) object which returns a field" requirement to be dimensioned as Variant - Post #13 Post #14 http://www.excelforum.com/excel-programming-vba-macros/1058171-return-row-index-and-column-index-of-a-cell-in-a-range.html[/color]
                                                                                              [color=lightgreen]'  http://www.mrexcel.com/forum/excel-questions/832103-using-microsoft-scripting-runtime-dictionary-store-then-retrieve-range-objects-3.html[/color]
  [color=blue]Let[/color] vTemp = CapturedRangeObject.Value2 [color=lightgreen]'Works vTemp is Array of variants values, a Data field[/color]
   
    [color=blue]For[/color] rws = sr To lr [color=blue]Step[/color] 1 [color=lightgreen]'Input Array of Ranges[/color]
   
    [color=blue]Let[/color] arrOut(rws, 1) = Left(CapturedRangeObject.Value2(rws - sr + 1, 1), 4)  [color=lightgreen]'Works  1651.5s 33928 Rows. 3.85 1654 Rows                                           Conventionally the Value2 values are in an Array starting at ( 1, 1) and extending over the two (in this case just a 1 dimensional array). So a bit of adjusting with the indicies is necerssary[/color]
    [color=blue]Let[/color] arrOut(rws, 1) = Left(CapturedRangeObject.Value2()(rws - sr + 1, 1), 4) [color=lightgreen]'Works  1667s 33928 Rows.  3.85 1654 Rows                                                        because of how VBA “works”, This extra () will ensure that indices are always returned to the resulting array (and not occasionally, for example, arguments ) by any following method or property, or passed to any method or property, (In the "bodge subs it is assigned each time to the full object[/color]
    [color=blue]Let[/color] arrOut()(rws, 1) = Left(CapturedRangeObject.Value2(rws - sr + 1, 1), 4) [color=lightgreen]'Returns Empties ????? #2) 991.5s 33928 Rows. 3.85 1654 Rows[/color]
    [color=blue]Let[/color] arrOut()(rws, 1) = Left(CapturedRangeObject.Value2()(rws - sr + 1, 1), 4) [color=lightgreen]'Returns Empties ????? #2) 1696s 33928 Rows. 3.85 1654 Rows[/color]
       
    [color=blue]Let[/color] arrOut(rws, 1) = Left(vTemp(rws - sr + 1, 1), 4) [color=lightgreen]'Works 0.325s for 33928 Rows. 0.018 1654 Rows.      This amazing speed is easilly explained as in this SIMPLIFIED examplse file the code is working similar to the "VBA Array" version of my typical answers to sorting Threads which demonstrates the advantage of working with arrays over my alternative "Spreadsheet" type Solution which I usually also give in the Sorting Threads that I answer..[/color]
      [color=blue]Let[/color] arrOut(rws, 1) = Left(vTemp()(rws - sr + 1, 1), 4) [color=lightgreen]'wont work ????? #1 Error 9: Index out of valid Range[/color]
    [color=blue]Let[/color] arrOut()(rws, 1) = Left(vTemp(rws - sr + 1, 1), 4) [color=lightgreen]'Returns Empties. ????? #2) 30.5s 33928 Rows.. 0.088 1654 Rows    Tolerates the Extra () on the LHS but rerurns empties and takes usually lots longer 30.5s 33928 Rows..[/color]
      [color=blue]Let[/color] arrOut(rws, 1) = Left(vTemp()(rws - sr + 1, 1), 4) [color=lightgreen]'wont work ????? #1 Error 9: Index out of valid Range[/color]
   
    [color=blue]Next[/color] rws
   
 [color=blue]Let[/color] RngD.Value = arrOut() [color=lightgreen]'                  the Array of Values is outputted in the typical one liner exclusively allowed to values only[/color]
 
[color=blue]End[/color] [color=blue]Sub[/color] [color=lightgreen]'G13_RangeObjectCaptureExcelForumDemo()[/color]
 
 
 
 
 
[color=lightgreen]'[/color]
'
[color=blue]Sub[/color] G14_MicrosoftScriptingRuntimeDictionaryRangeOfRangesKeysItems1()
[color=lightgreen]'Similar to the Array of Range ranges, except that the Ranges are held in a full MSRD[/color]
[color=lightgreen]'Lots of interaction with the spreadsheet, including the use of a temporary cell for use of unique key characteristic.[/color]
 [color=blue]Dim[/color] wksLG [color=blue]As[/color] Worksheet: [color=blue]Set[/color] wksLG = ThisWorkbook.Worksheets("LeftSpeedsDeutsch")
 [color=blue]Dim[/color] RngName [color=blue]As[/color] Range, RngD [color=blue]As[/color] Range
 [color=blue]Dim[/color] lr [color=blue]As[/color] [color=blue]Long[/color], rws [color=blue]As[/color] [color=blue]Long[/color]
 [color=blue]Let[/color] lr = wksLG.Cells(Rows.Count, 1).End(xlUp).Row
 [color=blue]Dim[/color] sr [color=blue]As[/color] Long: [color=blue]Let[/color] sr = 21
 [color=blue]Set[/color] RngName = wksLG.Range("A" & sr & ":A" & lr & ""): [color=blue]Set[/color] RngD = wksLG.Range("D" & sr & ":D" & lr & "")
 
[color=lightgreen]' 1)  'Part 1: Setting up Scriptimg Runtime Stuff-----------------------------[/color]
[color=lightgreen]' Attempting Using the Microsooft Scripting Runtime Dictionary to store Range Objects[/color]
 
[color=lightgreen]'We put the unique values now into a Dictionary for later look up purposes:[/color]
[color=lightgreen]'--requires library reference to MS Scripting Runtime (Early Binding)-[/color]
[color=lightgreen]'        Tools>>References>>scrolldown and check the box next to Microsoft Scripting Runtime[/color]
[color=lightgreen]'  ..Or crashes at next line.....[/color]
 [color=blue]Dim[/color] dicLookupTable [color=blue]As[/color] Scripting.Dictionary [color=lightgreen]'Data held with a unique "Key"or Part Number.[/color]
 [color=blue]Set[/color] dicLookupTable = [color=blue]New[/color] Scripting.Dictionary
[color=lightgreen]' 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.[/color]
[color=lightgreen]'        Dim dicLookupTable As Object[/color]
[color=lightgreen]'        Set dicLookupTable = CreateObject("Scripting.Dictionary")[/color]
[color=lightgreen]' Late Binding is better when sharing files as I am here. Early Binding has the advantage that Excel intellisense[/color]
[color=lightgreen]' will then work for the Microsoft Scripüting Runtime stuff and give you suggestions after you type the .dot thing[/color]
 
     dicLookupTable.CompareMode = vbTextCompare [color=lightgreen]'Not quite sure wot this does yet[/color]
 
[color=lightgreen]'.  A Dictionary in VBA is a collection of objects :you can store all kinds of things in it.[/color]
[color=lightgreen]'.  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.[/color]
[color=lightgreen]'.  (Although the Dictionary has not been designed for that purpose it's a nice side effect.)[/color]
 
[color=lightgreen]'End of Part 1 initial set up Of Scripting Runtime------------------------[/color]
 
 [color=lightgreen]'Dim j As Long ', i [color=blue]As[/color] Long  'LoopBoundVariableCounts used in looping here and at end-----[/color]
 
 [color=blue]Dim[/color] TempColumn [color=blue]As[/color] Long: [color=blue]Let[/color] TempColumn = Columns.Count: [color=blue]Let[/color] TempColumn = 6  [color=lightgreen]'Usually when not debugging comment out last let so Temp Column is last in sheet given by Columns.count....[/color]
 [color=blue]Dim[/color] TempCell [color=blue]As[/color] Range: [color=blue]Set[/color] TempCell = wksLG.Cells(1, TempColumn): [color=blue]Dim[/color] TempCellOffset [color=blue]As[/color] [color=blue]Long[/color]: [color=blue]Let[/color] TempCellOffset = 0 [color=lightgreen]'....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 )[/color]
 [color=lightgreen]'2a) Part2a) Looping to put Range Objects in MRSD[/color]
    [color=lightgreen]'For i = StartColumnTableOutput To LastColumnTableOutput Step 1[/color]
        [color=blue]For[/color] rws = sr [color=blue]To[/color] lr [color=blue]Step[/color] 1
          [color=blue]If[/color] wksLG.Cells(rws, 1).Value <> "" [color=blue]Then[/color] [color=lightgreen]'If cell is not empty then...[/color]
               [color=blue]If[/color] [color=blue]Not[/color] dicLookupTable.Exists(wksLG.Cells(rws, 1).Value) [color=blue]Then[/color] [color=lightgreen]'check that the unique value does not already exist. ##NOTE[/color]
                  dicLookupTable.Add wksLG.Cells(rws, 1).Value, wksLG.Cells(rws, 1) [color=lightgreen]'it is easier to understand as well as kind of explicit the first argument does a CStr and the Second Takes anything[/color]
               [color=blue]Else[/color] [color=lightgreen]'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[/color]
               [color=blue]Let[/color] TempCellOffset = TempCellOffset + 1
               [color=blue]Let[/color] TempCell.Offset(TempCellOffset, 0).Value = "Duplicate at   " & rws & " | " & 1 & ""
               wksLG.Cells(rws, 1).Interior.Color = 10987519
               dicLookupTable.Add TempCell.Offset(TempCellOffset, 0).Value, wksLG.Cells(rws, 1) [color=lightgreen]'In case of duplicate we need a unique key, but we stillinclude the Duplicate Range[/color]
               [color=blue]End[/color] [color=blue]If[/color]
           [color=blue]Else[/color] [color=lightgreen]'Case r an empty cell - inform of empty cell by writing message in that cell via the Tempory cell[/color]
           [color=blue]Let[/color] TempCellOffset = TempCellOffset + 1 [color=lightgreen]'Go to next free tempory cell in tempory column[/color]
           [color=blue]Let[/color] TempCell.Offset(TempCellOffset, 0).Value = "Empty Cell at   " & rws & " | " & 1 & ""
           dicLookupTable.Add TempCell.Offset(TempCellOffset, 0).Value, TempCell.Offset(TempCellOffset, 0)
           [color=blue]End[/color] [color=blue]If[/color]
        [color=blue]Next[/color] rws
    [color=lightgreen]'Next i[/color]
'End Part 2-----------------------------------------------------------
 
 [color=lightgreen]'3) Part 3)--transfer range objects from dictionary to array of ranges in one go, typical Array assignment "One Liner" - The quick way to place data into an array is to dimension a variable ( for example rResults ) ....>>[/color]
 [color=blue]Dim[/color] IntermediateArray() As [color=blue]Variant[/color] [color=lightgreen]'... [color=blue]As[/color] a Variant and then the "Let IntermediateArray  = " code line Using a variant allows BOTH .-1) for capturing Objects, text, numbers, blanks  errors etc. from those cells and also 2) allows rResults to be an array variable.....[/color]
 [color=blue]Let[/color] IntermediateArray() = dicLookupTable.Items() [color=lightgreen]'... In this case it will also accept us quasi pre - defining as Array with the pair of parentheses IntermediateArray()[/color]
 [color=lightgreen]'End part 3)--- NOTE: this gives automatically the 0 to _ convention in IntermediateArray Array!.        >>>.....and the output held in the Array is Variant type and is an OBJECT of the sort like a Range. (This compares with a similar code utilising An Array of Ranges rather than the MicrosoftScriptimeRuntimeDictionary. (In the Array of Ranges case we could Dim as Range or Variant here. - Important however in that case is that the Dynamic IntermediateArray() Array and the (in that Array of Ranges case non dynamic) arrIn() Array are of the same type. - Either both Range to return an Array of element Type Range or both Variant to Return an Array of element Type Of Objects of the Range Sort : - RoryA . You can only assign one array to another directly (i.e. without looping....... and the two arrays are the same type. http://www.excelforum.com/excel-new-users-basics/1058406-range-dimensioning-range-and-value-referencing-and-referring-to-arrays.html[/color]
 
 [color=blue]Dim[/color] arrOut() As [color=blue]String[/color] [color=lightgreen]'We can use string as in the looping below as we are not relying on (/seeing) a range object to rturn us an array of values.[/color]
 [color=blue]ReDim[/color] arrOut(sr [color=blue]To[/color] lr, 1 [color=blue]To[/color] 1) [color=lightgreen]'Antoher way to look at it is to say we have a fixed, rather than dynamiy array, and as VBA does not allow a direct assigning one liner in this case it is also not necerssarily expecting to see an object. For Let it is likely to expect to see some value, and for Set an object (Would expect an Range Object if indicies of arrOut were so defined by arrOut() [color=blue]As[/color] String initially[/color]
 
    [color=blue]For[/color] rws = sr To lr [color=blue]Step[/color] 1 [color=lightgreen]'Input Array of Ranges[/color]
        [color=lightgreen]'Let arrOut(rws, 1) = IntermediateArray(rws - sr).Value 'VBA would appear to recognise this array element as A range as it gives me the Method, Object and property selkection to choose from via intellisense brought in by typing . Dot after the Array elemant[/color]
[color=lightgreen]'    Let arrOut(rws, 1) = Left(dicLookupTable.Items(rws - sr).Value, 4)[/color]
[color=lightgreen]'    Let arrOut(rws, 1) = Left(dicLookupTable.Items()(rws - sr).Value, 4)[/color]
   
[color=lightgreen]'    Let arrOut(rws, 1) = Left(IntermediateArray(rws - sr).Value, 4) 'Even A function on the RHS of the = is accepted Here. So again for a non dynamic Array it is not relying on what the function to "define" the type[/color]
[color=lightgreen]'    Let arrOut(rws, 1) = Left(IntermediateArray()(rws - sr).Value, 4)[/color]
 
[color=lightgreen]'    Let arrOut(rws, 1) = Left(dicLookupTable.Keys(rws - sr), 4)[/color]
    [color=blue]Let[/color] arrOut(rws, 1) = Left(dicLookupTable.Keys()(rws - sr), 4)
    [color=blue]Next[/color] rws
 
 [color=blue]Let[/color] RngD.Value = arrOut()
 [color=lightgreen]'   Let RngD.Value = IntermediateArray() 'This should not do anything.. interestingly gives value from first Cell in RngName,[/color]
 
 [color=blue]Set[/color] dicLookupTable = [color=blue]Nothing[/color] [color=lightgreen]'Genarally good practice to turn these thimgs off. 'May not be needed but to keep program flexible should alterations need it.[/color]
 
[color=blue]End[/color] [color=blue]Sub[/color] [color=lightgreen]'MicrosoftScriptimeRuntimeDictionaryRangeOfRangesKeysItems1()[/color]
 
 
 
 
[color=lightgreen]'[/color]
'
[color=blue]Sub[/color] G15_MicrosoftScriptimeRuntimeDictionaryRangeOfRangesKeys()
[color=lightgreen]'Similar to the Array of Range ranges, except that the Ranges are held in the MSRD Key. Strange but it can!![/color]
[color=lightgreen]'A bit less Lots of interaction with the spreadsheet, as the temp for the unique is not there - we are using the key,[/color]
[color=lightgreen]'so all ranges are unique keys we simply include that duplicateentry, that is to say the output array may be a bit shorter.[/color]
[color=lightgreen]'Also the cell my be empty but the RANGE cannot be="" so for it's "value" VBA writes "Empty" !![/color]
 [color=blue]Dim[/color] wksLG [color=blue]As[/color] Worksheet: [color=blue]Set[/color] wksLG = ThisWorkbook.Worksheets("LeftSpeedsDeutsch")
 [color=blue]Dim[/color] RngName [color=blue]As[/color] Range, RngD [color=blue]As[/color] Range
 [color=blue]Dim[/color] lr [color=blue]As[/color] [color=blue]Long[/color], rws [color=blue]As[/color] Long
 [color=blue]Let[/color] lr = wksLG.Cells(Rows.Count, 1).End(xlUp).Row
 [color=blue]Dim[/color] sr [color=blue]As[/color] Long: [color=blue]Let[/color] sr = 21
 [color=blue]Set[/color] RngName = wksLG.Range("A" & sr & ":A" & lr & ""): [color=blue]Set[/color] RngD = wksLG.Range("D" & sr & ":D" & lr & "")
 
[color=lightgreen]' 1)  'Part 1b: Setting up Scriptimg Runtime Stuff-----------------------------[/color]
[color=lightgreen]'Using the Microsoft Scripting Runtime Dictionary KEYS ONLY to store Range Objects... A bit like saying "....(It is certainly a crazy concept if you think about it….Like saying in a Filing Cabinet I have a piece of paper for every House in a town with all the plans and details of the house in it. The parallel idea to the Keys being able to be almost anything would be that instead of the piece of paper I could a Duplicate of every House in the filing cabinet!!! ). ...." Alan :- Post #10 http://www.mrexcel.com/forum/excel-questions/832103-using-microsoft-scripting-runtime-dictionary-store-then-retrieve-range-objects.html[/color]
 
[color=lightgreen]'We put the unique values now into a Dictionary for later look up purposes:[/color]
[color=lightgreen]'--requires library reference to MS Scripting Runtime (Early Binding)-[/color]
[color=lightgreen]'        Tools>>References>>scrolldown and check the box next to Microsoft Scripting Runtime[/color]
[color=lightgreen]'  ..Or crashes at next line.....[/color]
 [color=blue]Dim[/color] dicLookupTable As Scripting.Dictionary [color=lightgreen]'Data held with a unique "Key"or Part Number.[/color]
 [color=blue]Set[/color] dicLookupTable = [color=blue]New[/color] Scripting.Dictionary
[color=lightgreen]' 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.[/color]
[color=lightgreen]'        Dim dicLookupTable As Object[/color]
[color=lightgreen]'        Set dicLookupTable = CreateObject("Scripting.Dictionary")[/color]
[color=lightgreen]' Late Binding is better when sharing files as I am here. Early Binding has the advantage that Excel intellisense[/color]
[color=lightgreen]' will then work for the Microsoft Scripüting Runtime stuff and give you suggestions after you type the .dot thing[/color]
 
     dicLookupTable.CompareMode = vbTextCompare [color=lightgreen]'Not quite sure wot this does yet[/color]
 
[color=lightgreen]'.  A Dictionary in VBA is a collection of objects :you can store all kinds of things in it.[/color]
[color=lightgreen]'.  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.[/color]
[color=lightgreen]'.  (Although the Dictionary has not been designed for that purpose it's a nice side effect.)[/color]
 
[color=lightgreen]'End of Part 1b initial set up Of Scripting Runtime------------------------[/color]
 
   [color=lightgreen]'Dim j As Long ', i As Long  'LoopBoundVariableCounts used in looping here and at end-----[/color]
 [color=lightgreen]'Dim TempCell [color=blue]As[/color] Range: Set TempCell = wksLG.Cells(1, Columns.Count): Dim TempCellOffset As Long: Let TempCellOffset = 0 'We choose a cell (or through the later use of the offset a column) to use for Duplicate or Empty cells. We use the last column in the sheet. (This is genarally a good practice as it will not effect attempts with .End(XltoLeft) to find last column[/color]
 [color=lightgreen]'2a) Part2a) Looping to put Range Objects in MRSD[/color]
    [color=lightgreen]'For i = StartColumnTableOutput [color=blue]To[/color] LastColumnTableOutput Step 1[/color]
        [color=blue]For[/color] rws = sr [color=blue]To[/color] lr [color=blue]Step[/color] 1
           [color=blue]If[/color] wksLG.Cells(rws, 1).Value <> "" [color=blue]Then[/color] [color=lightgreen]'If RANGE.value is not empty...[/color]
[color=lightgreen]'               If Not dicLookupTable.Exists(wksLG.Cells(rws, 1).Value) Then 'check that the unique value does not already exist. ##NOTE[/color]
                  dicLookupTable.Add wksLG.Cells(rws, 1), [color=blue]Nothing[/color] [color=lightgreen]'it is easier to understand as well as kind of explicit the first argument does a CStr and the Second Takes anything[/color]
[color=lightgreen]'               Else 'The key is the Range which is always unique[/color]
[color=lightgreen]'               End If[/color]
           [color=blue]Else[/color] [color=lightgreen]'Case r an empty cell. We habe a choice by virtue of us using ###Newlr below to do nothing.. or..[/color]
           [color=blue]Let[/color] wksLG.Cells(rws, 1).Value = "Anything" [color=lightgreen]'.. we could have done nothing - for the case of the Let function it does not erro just gives nothing[/color]
           dicLookupTable.Add wksLG.Cells(rws, 1), [color=blue]Nothing[/color] [color=lightgreen]'.. chose here it to give key anyway and..[/color]
           [color=blue]End[/color] [color=blue]If[/color]
        [color=blue]Next[/color] rws
    [color=lightgreen]'Next i[/color]
'End Part 2-----------------------------------------------------------
 
 [color=lightgreen]'3) Part 3)--transfer range objects from dictionary to array of ranges in one go, typical Array assignment "One Liner" - The quick way to place data into an array is to dimension a variable ( for example rResults ) ....>>[/color]
 [color=blue]Dim[/color] IntermediateArray() As [color=blue]Variant[/color] [color=lightgreen]'... [color=blue]As[/color] a Variant and then the "Let IntermediateArray  = " code line Using a variant allows BOTH .-1) for capturing Objects, text, numbers, blanks  errors etc. from those cells and also 2) allows rResults to be an array variable.....[/color]
 [color=blue]Let[/color] IntermediateArray() = dicLookupTable.Keys() [color=lightgreen]'... In this case it will also accept us quasi pre - defining as Array with the pair of parentheses IntermediateArray()[/color]
 [color=lightgreen]'End part 3)--- NOTE: this gives automatically the 0 to _ convention in IntermediateArray Array!.        >>>.....and the output held in the Array is Variant type and is an OBJECT of the sort like a Range. (This compares with a similar code utilising An Array of Ranges rather than the MicrosoftScriptimeRuntimeDictionary. (In the Array of Ranges case we could Dim as Range or Variant here. - Important however in that case is that the Dynamic IntermediateArray() Array and the (in that Array of Ranges case non dynamic) arrIn() Array are of the same type. - Either both Range to return an Array of element Type Range or both Variant to Return an Array of element Type Of Objects of the Range Sort : - RoryA . You can only assign one array to another directly (i.e. without looping....... and the two arrays are the same type. http://www.excelforum.com/excel-new-users-basics/1058406-range-dimensioning-range-and-value-referencing-and-referring-to-arrays.html[/color]
 
[color=lightgreen]'      'Dim Newlr As Long: Let Newlr = UBound(IntermediateArray(), 1) + sr '###This is importent when looping through dicLookupTable.Keys so that for one or more empty cell not given a key we do not try to loop too far[/color]
 [color=blue]Dim[/color] arrOut() As [color=blue]String[/color] [color=lightgreen]'We can use string as in the looping below as we are not relying on (/seeing) a range object to rturn us an array of values.[/color]
 [color=blue]ReDim[/color] arrOut(sr [color=blue]To[/color] Newlr, 1 [color=blue]To[/color] 1) [color=lightgreen]'Antoher way to look at it is to say we have a fixed, rather than dynamiy array, and as VBA does not allow a direct assigning one liner in this case it is also not necerssarily expecting to see an object. For Let it is likely to expect to see some value, and for Set an object (Would expect an Range Object if indicies of arrOut were so defined by arrOut() As String initially. We could leave Nerlr as lr - doesn't matter if output array is bit too big[/color]
 
    [color=blue]For[/color] rws = sr To Newlr [color=blue]Step[/color] 1 [color=lightgreen]'Input Array of Ranges[/color]
            [color=lightgreen]'Let arrOut(rws, 1) = IntermediateArray(rws - sr).Value 'VBA would appear to recognise this array element as A range as it gives me the Method, Object and property selkection to choose from via intellisense brought in by typing . Dot after the Array elemant[/color]
    [color=blue]Let[/color] arrOut(rws, 1) = Left(dicLookupTable.Keys(rws - sr).Value, 4) [color=lightgreen]'Remember.. write in .Value - Do not rely on the implicit!![/color]
    [color=lightgreen]'Let arrOut(rws, 1) = Left(dicLookupTable.Keys()(rws - sr).Value, 4)[/color]
    [color=lightgreen]'Let arrOut(rws, 1) = Left(IntermediateArray(rws - sr).Value, 4) 'Even A function on the RHS of the = is accepted Here. So again for a non dynamic Array it is not relying on what the function to "define" the type[/color]
    [color=lightgreen]'Let arrOut(rws, 1) = Left(IntermediateArray()(rws - sr).Value, 4)[/color]
 
    [color=blue]Next[/color] rws
 
 [color=blue]Let[/color] RngD.Value = arrOut()
 
 [color=blue]Set[/color] dicLookupTable = [color=blue]Nothing[/color] [color=lightgreen]'Genarally good practice to turn these thimgs off. 'May not be needed but to keep program flexible should alterations need it.[/color]
 
[color=blue]End[/color] [color=blue]Sub[/color] [color=lightgreen]'MicrosoftScriptimeRuntimeDictionaryRangeOfRangesKeys()[/color]
 
 
[color=green]'[/color]
'
 
'
 
 
 
 
 
[color=lightgreen]'[/color]
[color=blue]Sub[/color] G18_MicrosoftScriptimeRuntimeDictionaryRangeObjectKeysItemsBodge1()
[color=lightgreen]'Similar to the Array of Range ranges, except that the Ranges are held in a full MSRD[/color]
[color=lightgreen]'Less interaction with the spreadsheet, just the use of a temporary cell for use of unique key characteristic.[/color]
[color=lightgreen]'Hopefully can get all infomation from that one big Range..Don't know for sure yet...Post #11 http://www.mrexcel.com/forum/excel-questions/832103-using-microsoft-scripting-runtime-dictionary-store-then-retrieve-range-objects-2.html[/color]
[color=lightgreen]'So Temporárilly put entire CapturedRangeObject in each item (except for duplicates and empty cells, which for now still access the Spreadsheet[/color]
[color=lightgreen]'This requires extra Bodges in Emptys and Duplicates and explanations of new Explicits here Post #14 - post #19  http://www.mrexcel.com/forum/excel-questions/832103-using-microsoft-scripting-runtime-dictionary-store-then-retrieve-range-objects-2.html[/color]
 [color=blue]Dim[/color] wksLG [color=blue]As[/color] Worksheet: [color=blue]Set[/color] wksLG = ThisWorkbook.Worksheets("LeftSpeedsDeutsch")
 [color=blue]Dim[/color] RngName [color=blue]As[/color] Range, RngD [color=blue]As[/color] Range
 [color=blue]Dim[/color] lr [color=blue]As[/color] [color=blue]Long[/color], rws [color=blue]As[/color] [color=blue]Long[/color]
 [color=blue]Let[/color] lr = wksLG.Cells(Rows.Count, 1).End(xlUp).Row
 [color=blue]Dim[/color] sr [color=blue]As[/color] Long: [color=blue]Let[/color] sr = 21
 [color=blue]Set[/color] RngName = wksLG.Range("A" & sr & ":A" & lr & ""): [color=blue]Set[/color] RngD = wksLG.Range("D" & sr & ":D" & lr & "")
 
[color=lightgreen]' 1)  'Part 1b: Setting up Scriptimg Runtime Stuff-----------------------------[/color]
[color=lightgreen]' Attempting Using the Microsooft Scripting Runtime Dictionary to store Range Objects[/color]
 
[color=lightgreen]'We put the unique values now into a Dictionary for later look up purposes:[/color]
[color=lightgreen]'--requires library reference to MS Scripting Runtime (Early Binding)-[/color]
[color=lightgreen]'        Tools>>References>>scrolldown and check the box next to Microsoft Scripting Runtime[/color]
[color=lightgreen]'  ..Or crashes at next line.....[/color]
 [color=blue]Dim[/color] dicLookupTable [color=blue]As[/color] Scripting.Dictionary [color=lightgreen]'Data held with a unique "Key"or Part Number.[/color]
 [color=blue]Set[/color] dicLookupTable = [color=blue]New[/color] Scripting.Dictionary
[color=lightgreen]' 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.[/color]
[color=lightgreen]'        Dim dicLookupTable As Object[/color]
[color=lightgreen]'        Set dicLookupTable = CreateObject("Scripting.Dictionary")[/color]
[color=lightgreen]' Late Binding is better when sharing files as I am here. Early Binding has the advantage that Excel intellisense[/color]
[color=lightgreen]' will then work for the Microsoft Scripüting Runtime stuff and give you suggestions after you type the .dot thing[/color]
 
     dicLookupTable.CompareMode = vbTextCompare [color=lightgreen]'Not quite sure wot this does yet[/color]
 
[color=lightgreen]'.  A Dictionary in VBA is a collection of objects :you can store all kinds of things in it.[/color]
[color=lightgreen]'.  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.[/color]
[color=lightgreen]'.  (Although the Dictionary has not been designed for that purpose it's a nice side effect.)[/color]
 
[color=lightgreen]'End of Part 1b initial set up Of Scripting Runtime------------------------[/color]
 
 [color=lightgreen]'Dim j As Long ', i [color=blue]As[/color] Long  'LoopBoundVariableCounts used in looping here and at end-----[/color]
 [color=blue]Dim[/color] TempCell [color=blue]As[/color] Range: [color=blue]Set[/color] TempCell = wksLG.Cells(1, Columns.Count): [color=blue]Dim[/color] TempCellOffset [color=blue]As[/color] Long: [color=blue]Let[/color] TempCellOffset = 0 [color=lightgreen]'We choose a cell (or through the later use of the offset a column) to use for Duplicate or Empty cells. We use the last column in the sheet. (This is genarally a good practice as it will not effect attempts with .End(XltoLeft) to find last column[/color]
 
 [color=lightgreen]'2a) Direct Array  Capture[/color]
 
 [color=blue]Dim[/color] CapturedRangeObject [color=blue]As[/color] Range [color=lightgreen]'One Range Object for entire range[/color]
 [color=blue]Set[/color] CapturedRangeObject = RngName [color=lightgreen]'Direct assignmet to existing Dimensioned Array[/color]
 
 
 [color=lightgreen]'2b) Part2b) Looping to put Range Objects in MRSD[/color]
    [color=lightgreen]'For i = StartColumnTableOutput To LastColumnTableOutput Step 1[/color]
        [color=blue]For[/color] rws = sr [color=blue]To[/color] lr [color=blue]Step[/color] 1
          [color=blue]If[/color] CapturedRangeObject.Value2(rws - sr + 1, 1) <> "" [color=blue]Then[/color] [color=lightgreen]'If cell is not empty then...[/color]
               [color=blue]If[/color] [color=blue]Not[/color] dicLookupTable.Exists(wksLG.Cells(rws, 1).Value) [color=blue]Then[/color] [color=lightgreen]'check that the unique value does not already exist. ##NOTE[/color]
                  dicLookupTable.Add CapturedRangeObject.Value2(rws - sr + 1, 1), CapturedRangeObject [color=lightgreen]'it is easier to understand as well as kind of explicit the first argument does a CStr and the Second Takes anything[/color]
               [color=blue]Else[/color] [color=lightgreen]'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[/color]
               [color=blue]Let[/color] TempCellOffset = TempCellOffset + 1
               [color=blue]Let[/color] TempCell.Offset(TempCellOffset, 0).Value = "Duplicate at   " & rws & " | " & 1 & ""
               wksLG.Cells(rws, 1).Interior.Color = 10987519
               [color=lightgreen]'dicLookupTable.Add TempCell.Offset(TempCellOffset, 0).Value, wksLG.Cells(rws, 1) 'In case of duplicate we need a unique key, but we stillinclude the Duplicate Range[/color]
               dicLookupTable.Add TempCell.Offset(TempCellOffset, 0).Value, CapturedRangeObject [color=lightgreen]'Must bodge also this line or problem that for my Temp Range has a Value2 of NOT an array()[/color]
               [color=blue]End[/color] [color=blue]If[/color]
           [color=blue]Else[/color] [color=lightgreen]'Case r an empty cell - inform of empty cell by writing message in that cell via the Tempory cell[/color]
           [color=blue]Let[/color] TempCellOffset = TempCellOffset + 1 [color=lightgreen]'Go to next free tempory cell in tempory column[/color]
           [color=blue]Let[/color] TempCell.Offset(TempCellOffset, 0).Value = "Empty Cell at   " & rws & " | " & 1 & ""
           [color=lightgreen]'dicLookupTable.Add TempCell.Offset(TempCellOffset, 0).Value, TempCell.Offset(TempCellOffset, 0)[/color]
           dicLookupTable.Add TempCell.Offset(TempCellOffset, 0).Value, CapturedRangeObject [color=lightgreen]'Must bodge also this line or problem that for my Temp Range has a Value2 of NOT an array()[/color]
           [color=blue]End[/color] [color=blue]If[/color]
        [color=blue]Next[/color] rws
    [color=lightgreen]'Next i[/color]
 
 
   
   
[color=lightgreen]'End Part 2-----------------------------------------------------------[/color]
 
 [color=lightgreen]'3) Part 3)--transfer range objects from dictionary to array of ranges in one go, typical Array assignment "One Liner" - The quick way to place data into an array is to dimension a variable ( for example rResults ) ....>>[/color]
 [color=blue]Dim[/color] IntermediateArray() As [color=blue]Variant[/color] [color=lightgreen]'... [color=blue]As[/color] a Variant and then the "Let rResults  = " code line Using a variant allows BOTH .-1) for capturing Objects, text, numbers, blanks  errors etc. from those cells and also 2) allows rResults to be an array variable.....[/color]
 [color=blue]Let[/color] IntermediateArray() = dicLookupTable.Items() [color=lightgreen]'... In this case it will also accept us quasi pre - defining as Array with the pair of parentheses IntermediateArray()[/color]
 [color=lightgreen]'End part 3)--- NOTE: this gives automatically the 0 to _ convention in IntermediateArray Array!.        >>>.....and the output held in the Array is Variant type and is an OBJECT of the sort like a Range. (This compares with a similar code utilising An Array of Ranges rather than the MicrosoftScriptimeRuntimeDictionary. (In the Array of Ranges case we could Dim as Range or Variant here. - Important however in that case is that the Dynamic IntermediateArray() Array and the (in that Array of Ranges case non dynamic) arrIn() Array are of the same type. - Either both Range to return an Array of element Type Range or both Variant to Return an Array of element Type Of Objects of the Range Sort : - RoryA . You can only assign one array to another directly (i.e. without looping....... and the two arrays are the same type. http://www.excelforum.com/excel-new-users-basics/1058406-range-dimensioning-range-and-value-referencing-and-referring-to-arrays.html[/color]
 
[color=lightgreen]'4) Part 4)---Produce output array by looping[/color]
 [color=blue]Dim[/color] arrOut() As [color=blue]String[/color] [color=lightgreen]'We can use string as in the looping below as we are not relying on (/seeing) a range object to rturn us an array of values.[/color]
 [color=blue]ReDim[/color] arrOut(sr [color=blue]To[/color] lr, 1 [color=blue]To[/color] 1) [color=lightgreen]'Antoher way to look at it is to say we have a fixed, rather than dynamiy array, and as VBA does not allow a direct assigning one liner in this case it is also not necerssarily expecting to see an object. For Let it is likely to expect to see some value, and for Set an object (Would expect an Range Object if indicies of arrOut were so defined by arrOut() As String initially[/color]
   
    [color=blue]For[/color] rws = sr To lr [color=blue]Step[/color] 1 [color=lightgreen]'Input Array of Ranges  Note ## >> ’.. because of how VBA “works”, This extra () will ensure that indices are always returned to the resulting array (and not occasionally, for example, arguments ) by any following method or property, or passed to any method or property[/color]
        [color=lightgreen]'Let arrOut(rws, 1) = CapturedRangeObject.Value2(rws - sr + 1, 1) 'Works.. but  ...[/color]
        [color=lightgreen]'Let arrOut(rws, 1) = CapturedRangeObject.Value2()(rws - sr + 1, 1) '...better ##[/color]
        [color=lightgreen]'Let arrOut(rws, 1) = dicLookupTable.Items(rws - sr).Value2(rws - sr + 1, 1) 'Wont work[/color]
        [color=lightgreen]'Let arrOut(rws, 1) = dicLookupTable.Items(rws - sr).Value2()(rws - sr + 1, 1) 'Works ##[/color]
        [color=lightgreen]'Let arrOut(rws, 1) = IntermediateArray(rws - sr).Value2(rws - sr + 1, 1) 'Won't work[/color]
        [color=lightgreen]'Let arrOut(rws, 1) = IntermediateArray(rws - sr).Value2()(rws - sr + 1, 1) 'Works ##[/color]
    [color=blue]Let[/color] arrOut(rws, 1) = Left(dicLookupTable.Items(rws - sr).Value2()(rws - sr + 1, 1), 4) [color=lightgreen]'Works ##[/color]
        'Let arrOut(rws, 1) = Left(IntermediateArray(rws - sr).Value2()(rws - sr + 1, 1), 4) 'Works ##
    [color=blue]Next[/color] rws
 
[color=lightgreen]'End Part 4-----------------------------------[/color]
 
 [color=blue]Let[/color] RngD.Value = arrOut()
 
 [color=blue]Set[/color] dicLookupTable = [color=blue]Nothing[/color] [color=lightgreen]'Genarally good practice to turn these thimgs off. 'May not be needed but to keep program flexible should alterations need it.[/color]
 
[color=blue]End[/color] [color=blue]Sub[/color] [color=lightgreen]'MicrosoftScriptimeRuntimeDictionaryRangeObjectKeysItemsBodge1()[/color]
 
 
 
[color=lightgreen]'[/color]
'
'
'
'
'
 
 
 
[color=lightgreen]'[/color]
[color=blue]Sub[/color] G19_MicrosoftScriptimeRuntimeDictionaryRangeObjectKeysItemsBodge2()
[color=lightgreen]'Similar to the Array of Range ranges, except that the Ranges are held in a full MSRD[/color]
[color=lightgreen]'Less interaction with the spreadsheet, just the use of a temporary cell for use of unique key characteristic.[/color]
[color=lightgreen]'Hopefully can get all infomation from that one big Range..Don't know for sure yet...Post #11 http://www.mrexcel.com/forum/excel-questions/832103-using-microsoft-scripting-runtime-dictionary-store-then-retrieve-range-objects-2.html[/color]
[color=lightgreen]'So Temporárilly put entire CapturedRangeObject in each item (except for duplicates and empty cells, which for now still access the Spreadsheet[/color]
[color=lightgreen]'This requires extra Bodges in Emptys and Duplicates and explanations of an alternative way to avoid the extra () from last code (MicrosoftScriptimeRuntimeDictionaryRangeObjectKeysItemsBodge2())  Post #14 - post #19  http://www.mrexcel.com/forum/excel-questions/832103-using-microsoft-scripting-runtime-dictionary-store-then-retrieve-range-objects-2.html[/color]
 [color=blue]Dim[/color] wksLG [color=blue]As[/color] Worksheet: [color=blue]Set[/color] wksLG = ThisWorkbook.Worksheets("LeftSpeedsDeutsch")
 [color=blue]Dim[/color] RngName [color=blue]As[/color] Range, RngD [color=blue]As[/color] Range
 [color=blue]Dim[/color] lr [color=blue]As[/color] [color=blue]Long[/color], rws [color=blue]As[/color] [color=blue]Long[/color]
 [color=blue]Let[/color] lr = wksLG.Cells(Rows.Count, 1).End(xlUp).Row
 [color=blue]Dim[/color] sr [color=blue]As[/color] Long: [color=blue]Let[/color] sr = 21
 [color=blue]Set[/color] RngName = wksLG.Range("A" & sr & ":A" & lr & ""): [color=blue]Set[/color] RngD = wksLG.Range("D" & sr & ":D" & lr & "")
 
[color=lightgreen]' 1)  'Part 1b: Setting up Scriptimg Runtime Stuff-----------------------------[/color]
[color=lightgreen]' Attempting Using the Microsooft Scripting Runtime Dictionary to store Range Objects[/color]
 
[color=lightgreen]'We put the unique values now into a Dictionary for later look up purposes:[/color]
[color=lightgreen]'--requires library reference to MS Scripting Runtime (Early Binding)-[/color]
[color=lightgreen]'        Tools>>References>>scrolldown and check the box next to Microsoft Scripting Runtime[/color]
[color=lightgreen]'  ..Or crashes at next line.....[/color]
 [color=blue]Dim[/color] dicLookupTable [color=blue]As[/color] Scripting.Dictionary [color=lightgreen]'Data held with a unique "Key"or Part Number.[/color]
 [color=blue]Set[/color] dicLookupTable = [color=blue]New[/color] Scripting.Dictionary
[color=lightgreen]' 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.[/color]
[color=lightgreen]'        Dim dicLookupTable As Object[/color]
[color=lightgreen]'        Set dicLookupTable = CreateObject("Scripting.Dictionary")[/color]
[color=lightgreen]' Late Binding is better when sharing files as I am here. Early Binding has the advantage that Excel intellisense[/color]
[color=lightgreen]' will then work for the Microsoft Scripüting Runtime stuff and give you suggestions after you type the .dot thing[/color]
 
     dicLookupTable.CompareMode = vbTextCompare [color=lightgreen]'Not quite sure wot this does yet[/color]
 
[color=lightgreen]'.  A Dictionary in VBA is a collection of objects :you can store all kinds of things in it.[/color]
[color=lightgreen]'.  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.[/color]
[color=lightgreen]'.  (Although the Dictionary has not been designed for that purpose it's a nice side effect.)[/color]
 
[color=lightgreen]'End of Part 1b initial set up Of Scripting Runtime------------------------[/color]
 
 [color=lightgreen]'Dim j As Long ', i [color=blue]As[/color] Long  'LoopBoundVariableCounts used in looping here and at end-----[/color]
 [color=blue]Dim[/color] TempCell [color=blue]As[/color] Range: [color=blue]Set[/color] TempCell = wksLG.Cells(1, Columns.Count): [color=blue]Dim[/color] TempCellOffset [color=blue]As[/color] Long: [color=blue]Let[/color] TempCellOffset = 0 [color=lightgreen]'We choose a cell (or through the later use of the offset a column) to use for Duplicate or Empty cells. We use the last column in the sheet. (This is genarally a good practice as it will not effect attempts with .End(XltoLeft) to find last column[/color]
 
 [color=lightgreen]'2a) Direct Array  Capture[/color]
 
 [color=blue]Dim[/color] CapturedRangeObject [color=blue]As[/color] Range [color=lightgreen]'One Range Object for entire range[/color]
 [color=blue]Set[/color] CapturedRangeObject = RngName [color=lightgreen]'Direct assignmet to existing Dimensioned Array[/color]
 
 
 [color=lightgreen]'2b) Part2b) Looping to put Range Objects in MRSD[/color]
    [color=lightgreen]'For i = StartColumnTableOutput To LastColumnTableOutput Step 1[/color]
        [color=blue]For[/color] rws = sr [color=blue]To[/color] lr [color=blue]Step[/color] 1
          [color=blue]If[/color] CapturedRangeObject.Value2(rws - sr + 1, 1) <> "" [color=blue]Then[/color] [color=lightgreen]'If cell is not empty then...[/color]
               [color=blue]If[/color] [color=blue]Not[/color] dicLookupTable.Exists(wksLG.Cells(rws, 1).Value) [color=blue]Then[/color] [color=lightgreen]'check that the unique value does not already exist. ##NOTE[/color]
                  dicLookupTable.Add CapturedRangeObject.Value2(rws - sr + 1, 1), CapturedRangeObject [color=lightgreen]'it is easier to understand as well as kind of explicit the first argument does a CStr and the Second Takes anything[/color]
               [color=blue]Else[/color] [color=lightgreen]'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[/color]
               [color=blue]Let[/color] TempCellOffset = TempCellOffset + 1
               [color=blue]Let[/color] TempCell.Offset(TempCellOffset, 0).Value = "Duplicate at   " & rws & " | " & 1 & ""
               wksLG.Cells(rws, 1).Interior.Color = 10987519
               [color=lightgreen]'dicLookupTable.Add TempCell.Offset(TempCellOffset, 0).Value, wksLG.Cells(rws, 1) 'In case of duplicate we need a unique key, but we stillinclude the Duplicate Range[/color]
               dicLookupTable.Add TempCell.Offset(TempCellOffset, 0).Value, CapturedRangeObject [color=lightgreen]'Must bodge also this line or problem that for my Temp Range has a Value2 of NOT an array()[/color]
               [color=blue]End[/color] [color=blue]If[/color]
           [color=blue]Else[/color] [color=lightgreen]'Case r an empty cell - inform of empty cell by writing message in that cell via the Tempory cell[/color]
           [color=blue]Let[/color] TempCellOffset = TempCellOffset + 1 [color=lightgreen]'Go to next free tempory cell in tempory column[/color]
           [color=blue]Let[/color] TempCell.Offset(TempCellOffset, 0).Value = "Empty Cell at   " & rws & " | " & 1 & ""
           [color=lightgreen]'dicLookupTable.Add TempCell.Offset(TempCellOffset, 0).Value, TempCell.Offset(TempCellOffset, 0)[/color]
           dicLookupTable.Add TempCell.Offset(TempCellOffset, 0).Value, CapturedRangeObject [color=lightgreen]'Must bodge also this line or problem that for my Temp Range has a Value2 of NOT an array()[/color]
           [color=blue]End[/color] [color=blue]If[/color]
        [color=blue]Next[/color] rws
    [color=lightgreen]'Next i[/color]
 
 
   
   
[color=lightgreen]'End Part 2-----------------------------------------------------------[/color]
 
 [color=lightgreen]'3) Part 3)--transfer range objects from dictionary to array of ranges in one go, typical Array assignment "One Liner" - The quick way to place data into an array is to dimension a variable ( for example rResults ) ....>>[/color]
 [color=blue]Dim[/color] IntermediateArray() As [color=blue]Variant[/color] [color=lightgreen]'... [color=blue]As[/color] a Variant and then the "Let rResults  = " code line Using a variant allows BOTH .-1) for capturing Objects, text, numbers, blanks  errors etc. from those cells and also 2) allows rResults to be an array variable.....[/color]
 [color=blue]Let[/color] IntermediateArray() = dicLookupTable.Items() [color=lightgreen]'... In this case it will also accept us quasi pre - defining as Array with the pair of parentheses IntermediateArray()[/color]
 [color=lightgreen]'End part 3)--- NOTE: this gives automatically the 0 to _ convention in rResults Array!.        >>>.....and the output held in the Array is Variant type and is an OBJECT of the sort like a Range. (This compares with a similar code utilising An Array of Ranges rather than the MicrosoftScriptimeRuntimeDictionary. (In the Array of Ranges case we could Dim as Range or Variant here. - Important however in that case is that the Dynamic IntermediateArray() Array and the (in that Array of Ranges case non dynamic) arrIn() Array are of the same type. - Either both Range to return an Array of element Type Range or both Variant to Return an Array of element Type Of Objects of the Range Sort : - RoryA . You can only assign one array to another directly (i.e. without looping....... and the two arrays are the same type. http://www.excelforum.com/excel-new-users-basics/1058406-range-dimensioning-range-and-value-referencing-and-referring-to-arrays.html[/color]
 
[color=lightgreen]'4) Part 4)---Produce output array by looping[/color]
 [color=blue]Dim[/color] vTemp [color=blue]As[/color] [color=blue]Variant[/color] [color=lightgreen]'Post from #20  - #24 .. return the array to a variable and then reference the elements through that variable, in which case you don't need to worry about the extra () . The usual "To see an object which returns a field" requirement to be dimensioned as Variant[/color]
    [color=lightgreen]'  http://www.mrexcel.com/forum/excel-questions/832103-using-microsoft-scripting-runtime-dictionary-store-then-retrieve-range-objects-3.html[/color]
 [color=blue]Dim[/color] arrOut() As [color=blue]String[/color] [color=lightgreen]'We can use string as in the looping below as we are not relying on (/seeing) a range object to rturn us an array of values.[/color]
 [color=blue]ReDim[/color] arrOut(sr [color=blue]To[/color] lr, 1 [color=blue]To[/color] 1) [color=lightgreen]'Antoher way to look at it is to say we have a fixed, rather than dynamiy array, and as VBA does not allow a direct assigning one liner in this case it is also not necerssarily expecting to see an object. For Let it is likely to expect to see some value, and for Set an object (Would expect an Range Object if indicies of arrOut were so defined by arrOut() As String initially[/color]
   
    [color=blue]For[/color] rws = sr To lr [color=blue]Step[/color] 1 [color=lightgreen]'Input Array of Ranges  Note ## >> ’.. because of how VBA “works”, This extra () will ensure that indices are always returned to the resulting array (and not occasionally, for example, arguments ) by any following method or property, or passed to any method or property, (In the "bodge it is assigned each time to the full object[/color]
 
[color=lightgreen]'    '    Let arrOut(rws, 1) = CapturedRangeObject.Value2(rws - sr + 1, 1) 'Works.. but  ...[/color]
[color=lightgreen]'    '    Let arrOut(rws, 1) = CapturedRangeObject.Value2()(rws - sr + 1, 1) '...better ##[/color]
[color=lightgreen]'    '    'Let arrOut(rws, 1) = dicLookupTable.Items(rws - sr).Value2(rws - sr + 1, 1) 'Wont work[/color]
[color=lightgreen]'    '    Let arrOut(rws, 1) = dicLookupTable.Items(rws - sr).Value2()(rws - sr + 1, 1) 'Works ##[/color]
    [color=blue]Let[/color] vTemp = dicLookupTable.Items(rws - sr).Value2 [color=lightgreen]'Works vTemp is Array of variants values, a Data field[/color]
      [color=lightgreen]'Let vTemp = dicLookupTable.Items(rws - sr).Value2() 'Works also!!![/color]
    [color=lightgreen]'Let vTemp = IntermediateArray(rws - sr).Value2 'Works vTemp is Array of variants values, a Data fild[/color]
      [color=lightgreen]'Let vTemp = IntermediateArray(rws - sr).Value2()'Also works!!![/color]
   
[color=lightgreen]'                'Let arrOut(rws, 1) = vTemp(rws - sr + 1, 1) 'Works[/color]
[color=lightgreen]'            '    'Let arrOut(rws, 1) = IntermediateArray(rws - sr).Value2(rws - sr + 1, 1) 'Won't work[/color]
[color=lightgreen]'            '    Let arrOut(rws, 1) = IntermediateArray(rws - sr).Value2()(rws - sr + 1, 1) 'Works ##[/color]
[color=lightgreen]'            '    Let arrOut(rws, 1) = Left(dicLookupTable.Items(rws - sr).Value2()(rws - sr + 1, 1), 4) 'Works ##[/color]
[color=lightgreen]'            '    Let arrOut(rws, 1) = Left(IntermediateArray(rws - sr).Value2()(rws - sr + 1, 1), 4) 'Works ##[/color]
    [color=blue]Let[/color] arrOut(rws, 1) = Left(vTemp(rws - sr + 1, 1), 4) [color=lightgreen]'Works[/color]
    [color=blue]Next[/color] rws
 
[color=lightgreen]'End Part 4-----------------------------------[/color]
 
 [color=blue]Let[/color] RngD.Value = arrOut()
 
 [color=blue]Set[/color] dicLookupTable = [color=blue]Nothing[/color] [color=lightgreen]'Genarally good practice to turn these thimgs off. 'May not be needed but to keep program flexible should alterations need it.[/color]
 
[color=blue]End[/color] [color=blue]Sub[/color] [color=lightgreen]'MicrosoftScriptimeRuntimeDictionaryRangeObjectKeysItemsBodge2()[/color]
[color=lightgreen]'[/color]
 
 
 
 
 
 
[color=lightgreen]'[/color]
[color=blue]Sub[/color] G20_MicrosoftScriptimeRuntimeDictionaryRangeObjectKeysItemsBodge3()
[color=lightgreen]'Similar to the Array of Range ranges, except that the Ranges are held in a full MSRD[/color]
[color=lightgreen]'Less interaction with the spreadsheet, just the use of a temporary cell for use of unique key characteristic.[/color]
[color=lightgreen]'Hopefully can get all infomation from that one big Range..Don't know for sure yet...Post #11 http://www.mrexcel.com/forum/excel-questions/832103-using-microsoft-scripting-runtime-dictionary-store-then-retrieve-range-objects-2.html[/color]
[color=lightgreen]'So Temporárilly put entire CapturedRangeObject in each item (except for duplicates and empty cells, which for now still access the Spreadsheet[/color]
[color=lightgreen]'This requires extra Bodges in Emptys and Duplicates and explanations of an alternative way to avoid the extra () from last code (MicrosoftScriptimeRuntimeDictionaryRangeObjectKeysItemsBodge2())  Post #14 - post #19  http://www.mrexcel.com/forum/excel-questions/832103-using-microsoft-scripting-runtime-dictionary-store-then-retrieve-range-objects-2.html[/color]
 [color=blue]Dim[/color] wksLG [color=blue]As[/color] Worksheet: [color=blue]Set[/color] wksLG = ThisWorkbook.Worksheets("LeftSpeedsDeutsch")
 [color=blue]Dim[/color] RngName [color=blue]As[/color] Range, RngD [color=blue]As[/color] Range
 [color=blue]Dim[/color] lr [color=blue]As[/color] [color=blue]Long[/color], rws [color=blue]As[/color] [color=blue]Long[/color]
 [color=blue]Let[/color] lr = wksLG.Cells(Rows.Count, 1).End(xlUp).Row
 [color=blue]Dim[/color] sr [color=blue]As[/color] Long: [color=blue]Let[/color] sr = 21
 [color=blue]Set[/color] RngName = wksLG.Range("A" & sr & ":A" & lr & ""): [color=blue]Set[/color] RngD = wksLG.Range("D" & sr & ":D" & lr & "")
 
[color=lightgreen]' 1)  'Part 1b: Setting up Scriptimg Runtime Stuff-----------------------------[/color]
[color=lightgreen]' Attempting Using the Microsooft Scripting Runtime Dictionary to store Range Objects[/color]
 
[color=lightgreen]'We put the unique values now into a Dictionary for later look up purposes:[/color]
[color=lightgreen]'--requires library reference to MS Scripting Runtime (Early Binding)-[/color]
[color=lightgreen]'        Tools>>References>>scrolldown and check the box next to Microsoft Scripting Runtime[/color]
[color=lightgreen]'  ..Or crashes at next line.....[/color]
 [color=blue]Dim[/color] dicLookupTable [color=blue]As[/color] Scripting.Dictionary [color=lightgreen]'Data held with a unique "Key"or Part Number.[/color]
 [color=blue]Set[/color] dicLookupTable = [color=blue]New[/color] Scripting.Dictionary
[color=lightgreen]' 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.[/color]
[color=lightgreen]'        Dim dicLookupTable As Object[/color]
[color=lightgreen]'        Set dicLookupTable = CreateObject("Scripting.Dictionary")[/color]
[color=lightgreen]' Late Binding is better when sharing files as I am here. Early Binding has the advantage that Excel intellisense[/color]
[color=lightgreen]' will then work for the Microsoft Scripüting Runtime stuff and give you suggestions after you type the .dot thing[/color]
 
     dicLookupTable.CompareMode = vbTextCompare [color=lightgreen]'Not quite sure wot this does yet[/color]
 
[color=lightgreen]'.  A Dictionary in VBA is a collection of objects :you can store all kinds of things in it.[/color]
[color=lightgreen]'.  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.[/color]
[color=lightgreen]'.  (Although the Dictionary has not been designed for that purpose it's a nice side effect.)[/color]
 
[color=lightgreen]'End of Part 1b initial set up Of Scripting Runtime------------------------[/color]
 
 [color=lightgreen]'Dim j As Long ', i [color=blue]As[/color] Long  'LoopBoundVariableCounts used in looping here and at end-----[/color]
 [color=blue]Dim[/color] TempCell [color=blue]As[/color] Range: [color=blue]Set[/color] TempCell = wksLG.Cells(1, Columns.Count): [color=blue]Dim[/color] TempCellOffset [color=blue]As[/color] Long: [color=blue]Let[/color] TempCellOffset = 0 [color=lightgreen]'We choose a cell (or through the later use of the offset a column) to use for Duplicate or Empty cells. We use the last column in the sheet. (This is genarally a good practice as it will not effect attempts with .End(XltoLeft) to find last column[/color]
 
 [color=lightgreen]'2a) Direct Array  Capture[/color]
 
 [color=blue]Dim[/color] CapturedRangeObject [color=blue]As[/color] Range [color=lightgreen]'One Range Object for entire range[/color]
 [color=blue]Set[/color] CapturedRangeObject = RngName [color=lightgreen]'Direct assignmet to existing Dimensioned Array[/color]
 
 
 [color=lightgreen]'2b) Part2b) Looping to put Range Objects in MRSD[/color]
    [color=lightgreen]'For i = StartColumnTableOutput To LastColumnTableOutput Step 1[/color]
        [color=blue]For[/color] rws = sr [color=blue]To[/color] lr [color=blue]Step[/color] 1
          [color=blue]If[/color] CapturedRangeObject.Value2(rws - sr + 1, 1) <> "" [color=blue]Then[/color] [color=lightgreen]'If cell is not empty then...[/color]
               [color=blue]If[/color] [color=blue]Not[/color] dicLookupTable.Exists(wksLG.Cells(rws, 1).Value) [color=blue]Then[/color] [color=lightgreen]'check that the unique value does not already exist. ##NOTE[/color]
                  dicLookupTable.Add CapturedRangeObject.Value2(rws - sr + 1, 1), CapturedRangeObject [color=lightgreen]'it is easier to understand as well as kind of explicit the first argument does a CStr and the Second Takes anything[/color]
               [color=blue]Else[/color] [color=lightgreen]'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[/color]
               [color=blue]Let[/color] TempCellOffset = TempCellOffset + 1
               [color=blue]Let[/color] TempCell.Offset(TempCellOffset, 0).Value = "Duplicate at   " & rws & " | " & 1 & ""
               wksLG.Cells(rws, 1).Interior.Color = 10987519
               [color=lightgreen]'dicLookupTable.Add TempCell.Offset(TempCellOffset, 0).Value, wksLG.Cells(rws, 1) 'In case of duplicate we need a unique key, but we stillinclude the Duplicate Range[/color]
               dicLookupTable.Add TempCell.Offset(TempCellOffset, 0).Value, CapturedRangeObject [color=lightgreen]'Must bodge also this line or problem that for my Temp Range has a Value2 of NOT an array()[/color]
               [color=blue]End[/color] [color=blue]If[/color]
           [color=blue]Else[/color] [color=lightgreen]'Case r an empty cell - inform of empty cell by writing message in that cell via the Tempory cell[/color]
           [color=blue]Let[/color] TempCellOffset = TempCellOffset + 1 [color=lightgreen]'Go to next free tempory cell in tempory column[/color]
           [color=blue]Let[/color] TempCell.Offset(TempCellOffset, 0).Value = "Empty Cell at   " & rws & " | " & 1 & ""
           [color=lightgreen]'dicLookupTable.Add TempCell.Offset(TempCellOffset, 0).Value, TempCell.Offset(TempCellOffset, 0)[/color]
           dicLookupTable.Add TempCell.Offset(TempCellOffset, 0).Value, CapturedRangeObject [color=lightgreen]'Must bodge also this line or problem that for my Temp Range has a Value2 of NOT an array()[/color]
           [color=blue]End[/color] [color=blue]If[/color]
        [color=blue]Next[/color] rws
    [color=lightgreen]'Next i[/color]
 
 
   
   
[color=lightgreen]'End Part 2-----------------------------------------------------------[/color]
 
 [color=lightgreen]'3) Part 3)--transfer range objects from dictionary to array of ranges in one go, typical Array assignment "One Liner" - The quick way to place data into an array is to dimension a variable ( for example rResults ) ....>>[/color]
 [color=blue]Dim[/color] IntermediateArray() As [color=blue]Variant[/color] [color=lightgreen]'... [color=blue]As[/color] a Variant and then the "Let rResults  = " code line Using a variant allows BOTH .-1) for capturing Objects, text, numbers, blanks  errors etc. from those cells and also 2) allows rResults to be an array variable.....[/color]
 [color=blue]Let[/color] IntermediateArray() = dicLookupTable.Items() [color=lightgreen]'... In this case it will also accept us quasi pre - defining as Array with the pair of parentheses IntermediateArray()[/color]
 [color=lightgreen]'End part 3)--- NOTE: this gives automatically the 0 to _ convention in rResults Array!.        >>>.....and the output held in the Array is Variant type and is an OBJECT of the sort like a Range. (This compares with a similar code utilising An Array of Ranges rather than the MicrosoftScriptimeRuntimeDictionary. (In the Array of Ranges case we could Dim as Range or Variant here. - Important however in that case is that the Dynamic IntermediateArray() Array and the (in that Array of Ranges case non dynamic) arrIn() Array are of the same type. - Either both Range to return an Array of element Type Range or both Variant to Return an Array of element Type Of Objects of the Range Sort : - RoryA . You can only assign one array to another directly (i.e. without looping....... and the two arrays are the same type. http://www.excelforum.com/excel-new-users-basics/1058406-range-dimensioning-range-and-value-referencing-and-referring-to-arrays.html[/color]
 
[color=lightgreen]'4) Part 4)---Produce output array by looping[/color]
 [color=blue]Dim[/color] vTemp [color=blue]As[/color] [color=blue]Variant[/color] [color=lightgreen]'Post from #20  - #24 .. return the array to a variable and then reference the elements through that variable, in which case you don't need to worry about the extra () . The usual "To see an object which returns a field" requirement to be dimensioned as Variant[/color]
    [color=lightgreen]'  http://www.mrexcel.com/forum/excel-questions/832103-using-microsoft-scripting-runtime-dictionary-store-then-retrieve-range-objects-3.html[/color]
 [color=blue]Let[/color] vTemp = dicLookupTable.Items(3).Value2 [color=lightgreen]'Works vTemp is Array of variants values, a Data field. In bodge 3 set to an arbritrary item number as in this stupid bodge they are all the same[/color]
 
 [color=blue]Dim[/color] arrOut() As [color=blue]String[/color] [color=lightgreen]'We can use string as in the looping below as we are not relying on (/seeing) a range object to rturn us an array of values.[/color]
 [color=blue]ReDim[/color] arrOut(sr [color=blue]To[/color] lr, 1 [color=blue]To[/color] 1) [color=lightgreen]'Antoher way to look at it is to say we have a fixed, rather than dynamiy array, and as VBA does not allow a direct assigning one liner in this case it is also not necerssarily expecting to see an object. For Let it is likely to expect to see some value, and for Set an object (Would expect an Range Object if indicies of arrOut were so defined by arrOut() As String initially[/color]
   
    [color=blue]For[/color] rws = sr To lr [color=blue]Step[/color] 1 [color=lightgreen]'Input Array of Ranges  Note ## >> ’.. because of how VBA “works”, This extra () will ensure that indices are always returned to the resulting array (and not occasionally, for example, arguments ) by any following method or property, or passed to any method or property, (In the "bodge it is assigned each time to the full object[/color]
 
[color=lightgreen]'    Let arrOut(rws, 1) = CapturedRangeObject.Value2(rws - sr + 1, 1) 'Works.. but  ...[/color]
[color=lightgreen]'    Let arrOut(rws, 1) = CapturedRangeObject.Value2()(rws - sr + 1, 1) '...better ##[/color]
[color=lightgreen]'    'Let arrOut(rws, 1) = dicLookupTable.Items(rws - sr).Value2(rws - sr + 1, 1) 'Wont work[/color]
[color=lightgreen]'    Let arrOut(rws, 1) = dicLookupTable.Items(rws - sr).Value2()(rws - sr + 1, 1) 'Works ##[/color]
   
    [color=lightgreen]'Let vTemp = dicLookupTable.Items(rws - sr).Value2() 'Works also!!![/color]
    [color=lightgreen]'Let vTemp = IntermediateArray(rws - sr).Value2 'Works vTemp is Array of variants values, a Data fild[/color]
    [color=lightgreen]'Let vTemp = IntermediateArray(rws - sr).Value2()'Also works!!![/color]
   
    [color=lightgreen]'Let arrOut(rws, 1) = vTemp(rws - sr + 1, 1) 'Works[/color]
[color=lightgreen]'    'Let arrOut(rws, 1) = IntermediateArray(rws - sr).Value2(rws - sr + 1, 1) 'Won't work[/color]
[color=lightgreen]'    Let arrOut(rws, 1) = IntermediateArray(rws - sr).Value2()(rws - sr + 1, 1) 'Works ##[/color]
[color=lightgreen]'    Let arrOut(rws, 1) = Left(dicLookupTable.Items(rws - sr).Value2()(rws - sr + 1, 1), 4) 'Works ##[/color]
[color=lightgreen]'    Let arrOut(rws, 1) = Left(IntermediateArray(rws - sr).Value2()(rws - sr + 1, 1), 4) 'Works ##[/color]
    [color=blue]Let[/color] arrOut(rws, 1) = Left(vTemp(rws - sr + 1, 1), 4) [color=lightgreen]'Works[/color]
    
    [color=blue]Next[/color] rws
 
[color=lightgreen]'End Part 4-----------------------------------[/color]
 
 [color=blue]Let[/color] RngD.Value = arrOut()
 
 [color=blue]Set[/color] dicLookupTable = [color=blue]Nothing[/color] [color=lightgreen]'Genarally good practice to turn these thimgs off. 'May not be needed but to keep program flexible should alterations need it.[/color]
 
[color=blue]End[/color] [color=blue]Sub[/color] [color=lightgreen]'MicrosoftScriptimeRuntimeDictionaryRangeObjectKeysItemsBodge3()[/color]








…. And just for completeness the Newest Rory Left Pubic Function UDF updated with amongst other things the extra (mad) experiment of a simple string version of the Left UDF within the main RoaryLeftPubic UDF !!!

Code:
[color=blue]Option[/color] [color=blue]Explicit[/color]
[color=blue]Public[/color] [color=blue]Function[/color] RoaryLeftPubic([color=blue]ByVal[/color] cell [color=blue]As[/color] Range, [color=blue]ByVal[/color] TheLength [color=blue]As[/color] [color=blue]Long[/color]) [color=blue]As[/color] [color=blue]Variant[/color] [color=lightgreen]'When an Array is assigned through Let to this function, it returns an Array which then through effectively A "Let One Liner" becomes a modified Range based on the Supplied range and any Additional Arguments. It can be thought as a normal Function working on a input Range. A Particular characteristic here is that the Output is created in a loop which specifically assigns each cell within the range. This probably ensures that VBA in any further workings "Know" or "allows" for an Array and so for example ensures that this Function can be used in Evaluate Function "One liners" without the usual "coercing stuff". I think variant is the only type of Function capable of returning an Array[/color]
 
    [color=blue]Dim[/color] x [color=blue]As[/color] [color=blue]Long[/color], y [color=blue]As[/color] Long [color=lightgreen]'We build a collection of output by looping into an Array. So these variables will be used for both Row,Column indicies for the cell Range coming into the Function, as well as the Array Indicies. 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.[/color]
    [color=blue]Dim[/color] vOut() [color=blue]As[/color] [color=blue]Variant[/color] [color=lightgreen]'Typically in such a line the type requied may need suit a Function or Object that is used to return the actual values. So usually it will need to be Variant rather than the type of the final items in the Array[/color]
    [color=blue]ReDim[/color] vOut(1 [color=blue]To[/color] cell.Rows.Count, 1 [color=blue]To[/color] cell.Columns.Count) [color=lightgreen]'As we are filling in an array with a loop below it is necerssary to have the Array "There" as it were, so Sized. Also Needs to be at least big enough. Here it is made exactly the correct size by setting it to the size of the in coming array. Te "1 To" bit is important as otherwise Arrays tend to have an annoying tendancy to start otherwise (by default) at zero rather than 1![/color]
       
        [color=blue]For[/color] x = 1 [color=blue]To[/color] cell.Rows.Count [color=lightgreen]'We take each row in turn and fo that row we go along....[/color]
            [color=blue]For[/color] y = 1 [color=blue]To[/color] cell.Columns.Count [color=lightgreen]'...each cloumn. (This convention is good to choose, as this is a typical sequence in which VBA tends to store things "internally" in one long "item" list.)[/color]
                    [color=lightgreen]'The Main part of Thje Function: Each Array element is set to something which is obtained by a formula similar to what one would use in a VBA code to put something in a cell.[/color]
                    [color=lightgreen]'Important Note here: Often at this point in a function we work with the one Input. Indeed we are here as well, that is to say one cell from the Range. A typical mistake therefore in any formulas below would be to forget the extra (x, y).Value required as we are working with an Inputed Array[/color]
                    [color=lightgreen]'Let vOut(x, y) = Left(cell(x, y).Value, TheLength) 'First Argument is often a  type of "LookUp ValuE-see note above".[/color]
                                 [color=lightgreen]'Let vOut(x, y) = [color=red]GetLeftstr[/color] (cell(x, y).Value, TheLength)'Just for extra academic experiments with a Pubic Fuction in a Pubic Function... [color=red]!Mad I Know[/color]”!!![/color]
                        [color=lightgreen]'Debug.Print vOut(x, y)'I found in practice that in a Code calling a [color=blue]Function[/color] strange things sometimes happen when attempting Step through with F8. So A Debug.Print was found to be sometimes prefferable to assist in degugging. Possibly a Bug The problem does not always happen![/color]
            [color=blue]Next[/color] y
        [color=blue]Next[/color] x
       
        [color=blue]Let[/color] RoaryLeftPubic = vOut() [color=lightgreen]' At This point RoaryLeftPubic becomes an Array or Rather an Object with collections. By Virtue of a typical let Range.Value = RoaryLeftPubic(Rng ,   ____) the range will be filled  with the values from the Array. Thid is the normal one line allowed exclisively for puutting just values in. Must be done at end to assign the array of values to a Dynamic Array[/color]
 
[color=blue]End[/color] Function [color=lightgreen]'RoaryLeftPubic[/color]




Code:
[color=blue]Public[/color] [color=blue]Function[/color] GetLeftstr([color=blue]ByVal[/color] strName [color=blue]As[/color] [color=blue]String[/color], [color=blue]ByVal[/color] TheLength [color=blue]As[/color] [color=blue]Long[/color]) [color=blue]As[/color] [color=blue]String[/color] [color=lightgreen]'Function returns a simple single string value, so simple to Dim as String[/color]
     [color=lightgreen]'Lists the Hyperlink Address for a Given Cell[/color]
              GetLeftstr = Left(strName, TheLength) [color=lightgreen]'Calculation returns a simple single string value, so can directly assign Function to it (Do not need a one liner array indicie assigner to get the Fucvtion to be an array[/color]
[color=blue]End[/color] [color=blue]Function[/color]





… Speed test Codes used are similar to those given in the Penultimate Code Window in Post #87
 
Upvote 0
… an initial follow Up,( as Some results / codes may be need to be referenced I other threads)– just posting with first result for comparison codes for Hyperlinks.Address. Not fully complete as some timing experiments for larger files are proving very long!! ..


Excel 2007
Brief Description of Code
Typical Run -​
Time in -
Seconds​
Brief Description of Code
Typical Run -​
Time in -
Seconds​
Hyperlinks.Address
Computer1 XL 2007 33928 Rows​
Computer1 1654 Rows
Computer2 XL 2010 33928Rows​
Left Function
Computer1 XL 2007 33928 Rows​
Computer1 1654 Rows
Computer2 XL 2010 33928Rows​
HG1Simplist Loop
71​
0.64 0.73
G1Simplist Loop
6.3 6.9​
0.4
12.59 18.2 7.75​
HG1 " " replace Formula with Public Function
G1 " " replace Formula with Public Function
8.1​
7.75 7.9 7.75​
HG2Typical Evaluate Alternative
No Standard -
Speadsheet -
Function
G2Typical Evaluate Alternative
.515​
0.02
0.51 0.47​
HG2 " " replace Formula with Public Function
No Standard -
Speadsheet -
Function
G2 " " replace Formula with Public Function
.38​
.31​
HG3Typical .Formula in a With EndWith
No Standard -
Speadsheet -
Function
G3Typical .Formula in a With EndWith
.085 0.175​
0.008
0.476 0.487 0.25​
HG3 " " replace Formula with Public Function
31​
0.165 0.16
G3 " " replace Formula with Public Function
0.325​
0.71​
HG4Typical .FormulaR1C1 in a With EndWith
No Standard -
Speadsheet -
Function
G4Typical .FormulaR1C1 in a With EndWith
0.17 0.1​
0.007
0.092 0.186 0.091 0.08​
HG4 " " replace Formula with Public Function
30​
0.16
G4 " " replace Formula with Public Function
1.89​
0.86​
HG5.Formula in a Loop
No Standard -
Speadsheet -
Function
G5.Formula in a Loop
94.2​
0.7
426.6​
HG5 " " replace Formula with Public Function
109​
0.99
G5 " " replace Formula with Public Function
1969.2​
3513.6 2649.6​
HG6 FormulaR1C1 in a Loop
No Standard -
Speadsheet -
Function
G6 FormulaR1C1 in a Loop
95.5​
0.6
HG6 " " replace Formula with Public Function
109​
0.98
G6 " " replace Formula with Public Function
83.8​
354.2​
HG7Evalute using Roary HypAddress UDF
117​
.445
G7Evalute using Roary Left UDF
1.65​
0.1
1.29 1.32​
HG7 " " replace Formula with Public Function
117​
.475
G7 " " replace Formula with Public Fucntion
1.78​
1.34​
L HG _ -VBA Left - =(String___, needs Range!….
Don't Work
L G _ -VBA Left - =(String___, needs Range!….
Don't Work
Don't Work
HG8Roary HypAddress UDF - Direct =(Range____
58.5​
.255
G8Roary Left UDF - Direct =(Range____
1.1 1.3​
0.06
0.96 0.87​
HG8 " " replace Formula with Public Function
58.5​
.265
G8 " " replace Formula with Public Function
1.48​
HG8bRange Object HypAddress (i) PP Kyle
29.5​
.15
HG8b " " replace Formula with Public Function
29.7​
.15
HG8cRange Object HypAddress (ii) Get Let Statement Pair
30​
.145
HG8c " " replace Formula with Public Function
30​
.145
HG9VBA Array Of Ranges (1a)
284.5 283​
0.425 0.42
G9VBA Array Of Ranges (1a)
1.5​
.07
1.38​
HG9VBA Array Of Ranges () (1a)
517.5​
.625
G9VBA Array Of Ranges () (1a)
218​
0.22
820​
HG10VBA Array Of Ranges (1aa)
31 - 0.005​
0.21 - 0.01
G10VBA Array Of Ranges (1aa)
2.5-0.5​
0.13 - .07
4.31 - 1.08​
HG10VBA Array Of Ranges () (1aa)
257 - 0.005​
0.37 - 0.01
G10VBA Array Of Ranges () (1aa)
217-0.5​
0.29 - .07
761.5 - 1.5​
HG11VBA Array Of Ranges (1b) First use of intermediateArray
59​
.25
G11VBA Array Of Ranges (1b) First use of intermediateArray
1.38​
.08
1.49​
HG11VBA Array Of Ranges () (1b) First use of intermediateArray
283​
.43
G11VBA Array Of Ranges () (1b) First use of intermediateArray
219.5​
0.22
757.6​
HG12VBA Array Of Ranges (2)
59​
3.3 0.245
G12VBA Array Of Ranges (2)
1.5​
.07
1.59​
HG12VBA Array Of Ranges () (2)
178.5​
3.3 0.35
G12VBA Array Of Ranges () (2)
115.5​
0.18
293.7​
HG13RangeObjectCapture Hyperlinks (___) Address
4.75 4.2
G13RangeObjectCapture value2 (___)
1651.5​
3.85
1388​
HG13RangeObjectCapture Hyperlinks () (___) Address
4.75 4.35
G13RangeObjectCapture value2 () (___)
1667​
3.86
1399​
HG13bRangeObjectCapture Hyperlinks (___) Address
Cannot Directly do a one liner vtemp
G13bRangeObjectCapture value2 (___)
2457.5​
3.6
3250​
HG13bRangeObjectCapture Hyperlinks () (___) Address
Don't Work
G13bRangeObjectCapture value2 () (___)
Don't Work
Don't Work
HG13cRangeObjectCapture Hyperlinks (___) Address
Cannot Directly do a one liner vtemp
G13cRangeObjectCapture value2 (___)
0.325​
0.018
0.34​
HG13cRangeObjectCapture Hyperlinks () (___) Address
Don't Work
G13cRangeObjectCapture value2 () (___)
Don't Work
Don't Work
HG14MSRDKeysItems item (___)
.76
G14MSRDKeysItems item (___)
380​
.65
989.5​
HG14MSRDKeysItems item () (___)
.76
G14MSRDKeysItems item () (___)
379​
.66
932​
HG14MSRDKeysItems intermediteArray (___).
.25
G14MSRDKeysItems intermediteArray (___).
3.35​
.16
3.15​
HG14MSRDKeysItems intermediteArray () (___).
.81
G14MSRDKeysItems intermediteArray () (___).
377​
.65
954.5​
HG14MSRDKeysItems Keys (As values)
G14MSRDKeysItems Keys (As values)
897​
2.1
2178 1638​
HG14MSRDKeysItems Keys () (As values)
G14MSRDKeysItems Keys () (As values)
905.5​
2.1
1777.7​
HG15MSRDKeys (As Full Range Objects)
.67
G15MSRDKeys (As Full Range Objects)
362.5 315​
.56
975.6 861​
HG15MSRDKeys () (As Full Range Objects)
.67
G15MSRDKeys () (As Full Range Objects)
.56
853​
HG15MSRDKeys intermediateArray (As Full Range Objects)
0.16 0.165
G15MSRDKeys intermediateArray (As Full Range Objects)
1.88​
.08
1.66​
HG15MSRDKeys intermediateArray () (As Full Range Objects)
.735
G15MSRDKeys intermediateArray () (As Full Range Objects)
.56
971.6​
HG16
G16
HG17
G17
HG18Big Range Object-MSDR Array of Range Objects "Bodge 2"
G18Big Range Object-MSDR Array of Range Objects "Bodge 2"
5374​
12
5466.5​
() (___)
Don't Work
() (___)
Don't Work
Don't Work
Ditto.. IntermediateArray
Ditto.. IntermediateArray
4390​
() (___)
() (___)
HG19Big Range Object-MSDR Array of Range Objects "Bodge 2"
G19Big Range Object-MSDR Array of Range Objects "Bodge 2"
12
5203​
() (___)
Don't Work
() (___)
Don't Work
Don't Work
Ditto.. IntermediateArray
Ditto.. IntermediateArray
4786​
() (___)
() (___)
HG20Big Range Object-MSDR Array of Range Objects "Bodge 3"
G20Big Range Object-MSDR Array of Range Objects "Bodge 3"
7.5
3579​
() (___)
Don't Work
() (___)
Don't Work
Don't Work
Ditto.. IntermediateArray
Ditto.. IntermediateArray
4705​
() (___)
() (___)


Normal Module Codes
Codes where possible corresponding to the first 8 basic Types for the Left Function work from Posts #86 to #89 .


Code:
[color=lightgreen]'See   http://www.mrexcel.com/forum/excel-questions/806702-visual-basic-applications-evaluate-range-vlookup-9.html[/color]
[color=lightgreen]'and especially for new Object (8b - 8c)   http://www.mrexcel.com/forum/excel-questions/839369-retrieving-properties-large-range-objects-using-visual-basic-applications-%93one-liner%94.html?[/color]
[color=lightgreen]'   and  here    http://www.excelforum.com/excel-new-users-basics/1058406-range-dimensioning-range-and-value-referencing-and-referring-to-arrays-2.html[/color]
[color=blue]Option[/color] [color=blue]Explicit[/color]
[color=blue]Sub[/color] HG1_ravi4everLoop() [color=lightgreen]'http://www.mrexcel.com/forum/excel-questions/616749-getting-hyperlink-address-excel-2003-visual-basic-applications.html[/color]
   
    [color=blue]Dim[/color] wksLookUpTable [color=blue]As[/color] Worksheet: [color=blue]Set[/color] wksLookUpTable = ThisWorkbook.Worksheets("HypSpeedsDeutsch") [color=lightgreen]'Give Abbreviation methods and properties of Object Worksheets[/color]
[color=lightgreen]'                        '            '    Dim CellAddress As String 'Link in String form required to input in Browser Search[/color]
    [color=blue]Dim[/color] Hyp_LinkRow [color=blue]As[/color] [color=blue]Long[/color], LastRowHyp_Link [color=blue]As[/color] Long: [color=blue]Let[/color] LastRowHyp_Link = wksLookUpTable.Cells(Rows.Count, 1).End(xlUp).Row [color=lightgreen]'BoundLoopVariable and Last entry in column 1 found by going to end of Spreadsheet, then coming back up until an entry is found, then get the row property from that Range (Cell)  object[/color]
     
          [color=blue]For[/color] Hyp_LinkRow = 21 [color=blue]To[/color] LastRowHyp_Link [color=blue]Step[/color] 1 [color=lightgreen]'Go through each Row starting at Row 2[/color]
              [color=blue]If[/color] wksLookUpTable.Range("A" & Hyp_LinkRow & "").Hyperlinks.Count = 1 [color=blue]Then[/color] [color=lightgreen]'One way to check that a hyperlink is there. If no hyperöonks is ther do not try to find it or gives error #####[/color]
       
            [color=lightgreen]'                    '                                         'Application.StatusBar = "At Row " & Hyp_LinkRow & " of " & LastRowHyp_Link[/color]
        [color=lightgreen]'        '                        ''                               'Let CellAddress = Range("A" & Hyp_LinkRow & "").Hyperlinks(1).Address                    'Let CellAddress = Replace(Range("A" & Hyp_LinkRow & "").Hyperlinks(1).Address, "mailto:", "")[/color]
              [color=blue]Let[/color] wksLookUpTable.Range("B" & Hyp_LinkRow & "").value = wksLookUpTable.Range("A" & Hyp_LinkRow & "").Hyperlinks(1).Address [color=lightgreen]'The 1 in ( ) is just to get the syntax right. It can only be 1 for 1 cell. But for a given range of n cells it could be 1 to n. Interesing for an empt cell it will give error 9 - index out of valid range#####[/color]
              [color=lightgreen]'Let wksLookUpTable.Range("B" & Hyp_LinkRow & "").Value = GetURLstr(wksLookUpTable.Range("A" & Hyp_LinkRow & "")) '[/color]
              [color=blue]Else[/color]
              [color=blue]End[/color] [color=blue]If[/color]
          [color=blue]Next[/color] Hyp_LinkRow
                [color=lightgreen]'      Else[/color]
                '      End If
[color=lightgreen]'                    ''                                             Application.StatusBar = False 'Reset to default[/color]
[color=blue]End[/color] [color=blue]Sub[/color] [color=lightgreen]'ravi4everLoop()[/color]
[color=blue]Sub[/color] HG_3_4FormulaWithRange()
 
    [color=blue]Dim[/color] wksLookUpTable [color=blue]As[/color] Worksheet: [color=blue]Set[/color] wksLookUpTable = ThisWorkbook.Worksheets("HypSpeedsDeutsch") [color=lightgreen]'Give Abbreviation methods and properties of Object Worksheets[/color]
    [color=blue]Dim[/color] Hyp_LinkRow [color=blue]As[/color] [color=blue]Long[/color], LastRowHyp_Link [color=blue]As[/color] Long: [color=blue]Let[/color] LastRowHyp_Link = wksLookUpTable.Cells(Rows.Count, 1).End(xlUp).Row [color=lightgreen]'BoundLoopVariable and Last entry in column 1 found by going to end of Spreadsheet, then coming back up until an entry is found, then get the row property from that Range (Cell)  object[/color]
    [color=blue]Dim[/color] rngHypLink [color=blue]As[/color] Range, rngUrlstr [color=blue]As[/color] Range
    [color=blue]Set[/color] rngHypLink = wksLookUpTable.Range("A21:A" & LastRowHyp_Link): [color=blue]Set[/color] rngUrlstr = wksLookUpTable.Range("B21:B" & LastRowHyp_Link)
   
      [color=blue]With[/color] rngUrlstr
        [color=lightgreen]'Note do not necerssarily need no check here for no hyperlink in cell: The formula there will eror but not the VBA code which puts it in[/color]
        [color=lightgreen]'.Formula = "=getURLstr(" & rngHypLink(1, 1).Address(0, 0) & ")" 'Note:- Anything other than 0,0 in Address(0, 0) gives fixed $Address based on Cell in range given by ...rngHypLink(Row, Column). So (Row,Column) here is relative referencing from rngUrlstr in our case 1,1 nooffset[/color]
     
        .FormulaR1C1 = "=getURLstr(R[0]C[-1])" [color=lightgreen]'. Syntax: FormulaR1C1="here the formula ". The [] makes it relative referrencing.[/color]
  
                        
   [color=lightgreen]'.Value = .Value 'Removes Formula(Putsvalue in)[/color]
   [color=lightgreen]'.Replace What:=0,Replacement:="", LookAt:=xlWhole, SearchFormat:=False 'Get rid of zeros[/color]
    [color=blue]End[/color] [color=blue]With[/color]
[color=blue]End[/color] [color=blue]Sub[/color] [color=lightgreen]'FormulaWithRange()[/color]
 
 
 
 
 
[color=blue]Sub[/color] HG_5_6FormulaWithLoop()
 
    [color=blue]Dim[/color] wksLookUpTable [color=blue]As[/color] Worksheet: [color=blue]Set[/color] wksLookUpTable = ThisWorkbook.Worksheets("HypSpeedsDeutsch") [color=lightgreen]'Give Abbreviation methods and properties of Object Worksheets[/color]
    [color=blue]Dim[/color] Hyp_LinkRow [color=blue]As[/color] [color=blue]Long[/color], LastRowHyp_Link [color=blue]As[/color] Long: [color=blue]Let[/color] LastRowHyp_Link = wksLookUpTable.Cells(Rows.Count, 1).End(xlUp).Row [color=lightgreen]'BoundLoopVariable and Last entry in column 1 found by going to end of Spreadsheet, then coming back up until an entry is found, then get the row property from that Range (Cell)  object[/color]
    [color=blue]Dim[/color] rngHypLink [color=blue]As[/color] Range, rngUrlstr [color=blue]As[/color] Range
    [color=blue]Set[/color] rngHypLink = wksLookUpTable.Range("A21:A" & LastRowHyp_Link): [color=blue]Set[/color] rngUrlstr = wksLookUpTable.Range("B21:B" & LastRowHyp_Link)
 
  
      [color=blue]For[/color] Hyp_LinkRow = 21 [color=blue]To[/color] LastRowHyp_Link [color=blue]Step[/color] 1 [color=lightgreen]'Go through each Row starting at Row 2[/color]
                            [color=lightgreen]'                '        Application.StatusBar = "At Row " & Hyp_LinkRow & " of " & LastRowHyp_Link[/color]
      [color=lightgreen]'Let wksLookUpTable.Cells(Hyp_LinkRow, 2).Formula = "=getURLstr(" & rngHypLink(Hyp_LinkRow - 20, 1).Address(0, 0) & ")"[/color]
      [color=blue]Let[/color] wksLookUpTable.Cells(Hyp_LinkRow, 2).Formula = "=getURLstr(R[0]C[-1])"
      [color=blue]Next[/color] Hyp_LinkRow
  
  
 
 
[color=blue]End[/color] [color=blue]Sub[/color] [color=lightgreen]'FormulaWithLoop()[/color]
 
[color=blue]Sub[/color] HG7_EvaluateRoary() [color=lightgreen]'[/color]
   
    [color=blue]Dim[/color] wksLookUpTable [color=blue]As[/color] Worksheet: [color=blue]Set[/color] wksLookUpTable = ThisWorkbook.Worksheets("HypSpeedsDeutsch") 'Give Abbreviation methods and properties of Object Worksheets
    [color=blue]Dim[/color] Hyp_LinkRow [color=blue]As[/color] [color=blue]Long[/color], LastRowHyp_Link [color=blue]As[/color] Long: [color=blue]Let[/color] LastRowHyp_Link = wksLookUpTable.Cells(Rows.Count, 1).End(xlUp).Row [color=lightgreen]'BoundLoopVariable and Last entry in column 1 found by going to end of Spreadsheet, then coming back up until an entry is found, then get the row property from that Range (Cell)  object[/color]
    [color=blue]Dim[/color] rngHypLink [color=blue]As[/color] Range, rngUrlstr [color=blue]As[/color] Range
    [color=blue]Set[/color] rngHypLink = wksLookUpTable.Range("A21:A" & LastRowHyp_Link): [color=blue]Set[/color] rngUrlstr = wksLookUpTable.Range("B21:B" & LastRowHyp_Link)
           
                        [color=lightgreen]'Let rngUrlstr.Value = Evaluate("" & rngHypLink.Address & "").Hyperlinks(1).Address   'Evaluate for an Address is a special case and returns a Range Object (See here: http://usefulgyaan.wordpress.com/2013/06/19/avoid-loop-for-range-calculations-evaluate/comment-page-1/#comment-358 ). So we can further apply the . to give further range properties and methods. But we need a trick to coerce all array values or we just get the first row[/color]
                        [color=lightgreen]'Let rngUrlstr.Value = Evaluate("IF(Row()," & "" & rngHypLink.Address & "" & ")").Hyperlinks(1).Address 'Unfortunately a Row() trick ( see here: http://www.excelfox.com/forum/f2/multiple-columns-into-single-column-using-data-text-to-column-1891/index2.html) can not here be used here as we then no longer have a range object to further apply the . to[/color]
                        [color=lightgreen]'To get this idea to work, first make a public Spreadsheet function.. meine did not work... but Rory's did.[/color]
    [color=blue]Let[/color] rngUrlstr.value = Evaluate("GetURLRoaryA(" & "" & rngHypLink.Address & "" & ")") [color=lightgreen]'Again this normally had just returned the first value, so "coerce it":...Post #82  http://www.mrexcel.com/forum/excel-questions/806702-visual-basic-applications-evaluate-range-vlookup-9.html[/color]
   
                        [color=lightgreen]'    Let rngUrlstr.Value = Evaluate("IF(Row()," & "GetURLRoaryA(" & "" & rngHypLink.Address & "" & ")" & ")") 'Neither of[/color]
                        [color=lightgreen]'    Let rngUrlstr.Value = Evaluate("IF(1," & "GetURLRoaryA(" & "" & rngHypLink.Address & "" & ")" & ")") 'of these.. or endless others had worked. ..[/color]
 
[color=blue]End[/color] [color=blue]Sub[/color] [color=lightgreen]'rEvaluateRoaryA()[/color]
 
[color=lightgreen]'[/color]
'
'
[color=blue]Sub[/color] HG_8_RoaryDirectWorksheetFunction() '
   
    [color=blue]Dim[/color] wksLookUpTable [color=blue]As[/color] Worksheet: [color=blue]Set[/color] wksLookUpTable = ThisWorkbook.Worksheets("HypSpeedsDeutsch") [color=lightgreen]'Give Abbreviation methods and properties of Object Worksheets[/color]
    [color=blue]Dim[/color] Hyp_LinkRow [color=blue]As[/color] [color=blue]Long[/color], LastRowHyp_Link [color=blue]As[/color] Long: [color=blue]Let[/color] LastRowHyp_Link = wksLookUpTable.Cells(Rows.Count, 1).End(xlUp).Row [color=lightgreen]'BoundLoopVariable and Last entry in column 1 found by going to end of Spreadsheet, then coming back up until an entry is found, then get the row property from that Range (Cell)  object[/color]
    [color=blue]Dim[/color] rngHypLink [color=blue]As[/color] Range, rngUrlstr [color=blue]As[/color] Range
    [color=blue]Set[/color] rngHypLink = wksLookUpTable.Range("A21:A" & LastRowHyp_Link): [color=blue]Set[/color] rngUrlstr = wksLookUpTable.Range("B21:B" & LastRowHyp_Link)
      
 [color=blue]Let[/color] rngUrlstr.value = GetURLRoaryA(rngHypLink)
 
 
[color=blue]End[/color] [color=blue]Sub[/color] [color=lightgreen]'HG_8RoaryDirectWorksheetFunction()[/color]

………………………………
. The following new types 8b) 8c) involve using Custom made Objects developed here
http://www.mrexcel.com/forum/excel-...isual-basic-applications-%93one-liner%94.html
and here
Range Dimensioning, Range and Value Referencing and Referring to Arrays - Page 2

Code:
[color=blue]Sub[/color] HG8bKyle()
 
    [color=blue]Dim[/color] wksLookUpTable [color=blue]As[/color] Worksheet: [color=blue]Set[/color] wksLookUpTable = ThisWorkbook.Worksheets("HypSpeedsDeutsch") [color=lightgreen]'Give Abbreviation methods and properties of Object Worksheets[/color]
    [color=blue]Dim[/color] Hyp_LinkRow [color=blue]As[/color] [color=blue]Long[/color], LastRowHyp_Link [color=blue]As[/color] Long: [color=blue]Let[/color] LastRowHyp_Link = wksLookUpTable.Cells(Rows.Count, 1).End(xlUp).Row [color=lightgreen]'BoundLoopVariable and Last entry in column 1 found by going to end of Spreadsheet, then coming back up until an entry is found, then get the row property from that Range (Cell)  object[/color]
    [color=blue]Dim[/color] rngUrlstr [color=blue]As[/color] Range [color=lightgreen]',rngHypLink As Range[/color]
    [color=blue]Set[/color] rngUrlstr = wksLookUpTable.Range("B21:B" & LastRowHyp_Link) [color=lightgreen]': Set rngHypLink = wksLookUpTable.Range("A21:A" & LastRowHyp_Link)[/color]
   
 
    [color=lightgreen]'        Dim obj As HypKyleKlasse[/color]
    [color=lightgreen]'        Set obj = New HypKyleKlasse[/color]
[color=blue]Dim[/color] obj [color=blue]As[/color] AlanPlops
[color=blue]Set[/color] obj = [color=blue]New[/color] AlanPlops
 
[color=blue]Dim[/color] arrOut() [color=blue]As[/color] [color=blue]Variant[/color]
    [color=lightgreen]'        Let arrOut() = obj.HypAddressKyle[/color]
[color=blue]Let[/color] arrOut() = obj.HypAddressAlanKyle
[color=blue]Let[/color] rngUrlstr.value = arrOut()
 
[color=blue]End[/color] [color=blue]Sub[/color]
[color=lightgreen]'[/color]
'
'
'
[color=blue]Sub[/color] HG8cAlan()
 
    [color=blue]Dim[/color] wksLookUpTable [color=blue]As[/color] Worksheet: [color=blue]Set[/color] wksLookUpTable = ThisWorkbook.Worksheets("HypSpeedsDeutsch") [color=lightgreen]'Give Abbreviation methods and properties of Object Worksheets[/color]
    [color=blue]Dim[/color] Hyp_LinkRow [color=blue]As[/color] [color=blue]Long[/color], LastRowHyp_Link [color=blue]As[/color] Long: [color=blue]Let[/color] LastRowHyp_Link = wksLookUpTable.Cells(Rows.Count, 1).End(xlUp).Row [color=lightgreen]'BoundLoopVariable and Last entry in column 1 found by going to end of Spreadsheet, then coming back up until an entry is found, then get the row property from that Range (Cell)  object[/color]
    [color=blue]Dim[/color] rngUrlstr [color=blue]As[/color] Range, rngHypLink [color=blue]As[/color] Range
    [color=blue]Set[/color] rngUrlstr = wksLookUpTable.Range("B21:B" & LastRowHyp_Link): [color=blue]Set[/color] rngHypLink = wksLookUpTable.Range("A21:A" & LastRowHyp_Link)
   
 
[color=blue]Dim[/color] obj [color=blue]As[/color] AlanPlops
[color=blue]Set[/color] obj = [color=blue]New[/color] AlanPlops
 
obj.HypAddressAlanKylePair = rngHypLink
[color=blue]Dim[/color] arrOut() [color=blue]As[/color] [color=blue]Variant[/color]
 
[color=blue]Let[/color] arrOut() = obj.HypAddressAlanKylePair
 
 
[color=blue]Let[/color] rngUrlstr.value = arrOut()
 
[color=blue]End[/color] [color=blue]Sub[/color]
[color=lightgreen]'[/color]
'

……………………….
Further codes from type 9 ot type 12 Codes where possible corresponding to the first those Types for the Left Function work from Posts #86 to #89 .


Code:
[color=blue]Sub[/color] HG_9VBAArrayOfRanges1a()
[color=lightgreen]'Loop Range of Ranges. VBA Make Array for Output. Output in a "Output Value One Liner"[/color]
[color=lightgreen]'Typical application requiring seperate loops for the (often differnt sized) input and output arrays[/color]
[color=lightgreen]'All Ranges come in, so in the output making loop a check must as with the simple looping be made to prevent trying to get an address from a non existant hyperlink#####[/color]
 [color=blue]Dim[/color] wksHG [color=blue]As[/color] Worksheet: [color=blue]Set[/color] wksHG = ThisWorkbook.Worksheets("HypSpeedsDeutsch")
 [color=blue]Dim[/color] RngName [color=blue]As[/color] Range, RngD [color=blue]As[/color] Range
 [color=blue]Dim[/color] lr [color=blue]As[/color] [color=blue]Long[/color], rws [color=blue]As[/color] [color=blue]Long[/color]
 [color=blue]Let[/color] lr = wksHG.Cells(Rows.Count, 1).End(xlUp).Row
 [color=blue]Dim[/color] sr [color=blue]As[/color] Long: [color=blue]Let[/color] sr = 21
 [color=blue]Set[/color] RngName = wksHG.Range("A" & sr & ":A" & lr & ""): [color=blue]Set[/color] RngD = wksHG.Range("D" & sr & ":D" & lr & "")
 
 [color=blue]Dim[/color] arrIn() [color=blue]As[/color] Range [color=lightgreen]'Variant 'In the looping, the Set would appear to be responsible for bringing **Ranges into the Array The variable type remains as defined here: Either a range for As Range or a Variant Object for [color=blue]As[/color] Variant[/color]
 [color=blue]ReDim[/color] arrIn(sr [color=blue]To[/color] lr, 1 [color=blue]To[/color] 1) [color=lightgreen]'We must give array a size as we give specific value in a loop. ReDim Must be used rather than Dim as [color=blue]Dim[/color] only takes Numbers not variables[/color]
 
    [color=blue]For[/color] rws = sr [color=blue]To[/color] lr [color=blue]Step[/color] 1 [color=lightgreen]'Input Array of Ranges[/color]
        [color=lightgreen]'Set arrIn(rws, 1) = Range("A" & rws & "")[/color]
        [color=blue]Set[/color] arrIn(rws, 1) = wksHG.Range("A" & rws & "") [color=lightgreen]'This would be tolerate** The Set would not appear to harmed by seeing an object..[/color]
    [color=blue]Next[/color] rws
 
 Dim arrOut() As [color=blue]String[/color] [color=lightgreen]'We can use string as in the looping below as we are not relying on (/seeing) a range object to rturn us an array of values.[/color]
 [color=blue]ReDim[/color] arrOut(sr [color=blue]To[/color] lr, 1 To 1) [color=lightgreen]'Antoher way to look at it is to say we have a fixed, rather than dynamiy array, and as VBA does not allow a direct assigning one liner in this case it is also not necerssarily expecting to see an object. For Let it is likely to expect to see some value, and for Set an object (Would expect an Range Object if indicies of arrOut were so defined by arrOut() As String initially[/color]
 
    [color=blue]For[/color] rws = sr [color=blue]To[/color] lr [color=blue]Step[/color] 1 [color=lightgreen]'Make values Output Array[/color]
        [color=blue]If[/color] arrIn()(rws, 1).Hyperlinks.Count = 1 [color=blue]Then[/color]
                        [color=lightgreen]'Let arrOut(rws, 1) = arrIn(rws, 1).Value 'Works 'VBA would appear to recognise this array element as A range as it gives me the Method, Object and property selkection to choose from via intellisense brought in by typing . Dot after the Array elemant[/color]
                        [color=lightgreen]'Let arrOut(rws, 1) = arrIn()(rws, 1).Value 'Works'.. because of how VBA “works”, This extra () will ensure that indices are always returned to the resulting array (and not occasionally, for example, arguments ) by any following method or property.[/color]
                           [color=lightgreen]'Let arrOut()(rws, 1) = arrIn()(rws, 1).Value 'Doesn't - Rory said it aint ever needed on the LHS,  so it aint[/color]
                [color=lightgreen]'   Let arrOut(rws, 1) = Left(arrIn(rws, 1).Value, 4) 'Even A function on the RHS of the = is accepted Here. So again for a non dynamic Array it is not relying on what the function to "define" the type[/color]
                [color=lightgreen]'   Let arrOut(rws, 1) = Left(arrIn()(rws, 1).Value, 4) 'Works[/color]
                          [color=lightgreen]'Let arrOut()(rws, 1) = Left(arrIn()(rws, 1).Value, 4) 'Works[/color]
        [color=blue]Let[/color] arrOut(rws, 1) = arrIn(rws, 1).Hyperlinks(1).Address [color=lightgreen]'The 1 in ( ) is just to get the syntax right. It can only be 1 for 1 cell. But for a given range of n cells it could be 1 to n[/color]
        [color=lightgreen]'Let arrOut(rws, 1) = arrIn()(rws, 1).Hyperlinks(1).Address[/color]
        [color=blue]Else[/color]
        [color=blue]End[/color] [color=blue]If[/color]
    [color=blue]Next[/color] rws
[color=lightgreen]'         Possibility to Note here:          Dim IntermediateArray() [color=blue]As[/color] Range 'Variant  'Note RoryA Post #2You can only assign one array to another directly (i.e. without looping) if the destination array is dynamic AND THE TWO ARRAYS ARE THE SAME TYPE.[/color]
[color=lightgreen]'                                          '  Re[color=blue]Dim[/color] IntermediateArray(sr [color=blue]To[/color] lr, 1 [color=blue]To[/color] 1)'THIS Line Will NOT Work: RoryA Post #2 http://www.excelforum.com/excel-new-users-basics/1058406-range-dimensioning-range-and-value-referencing-and-referring-to-arrays.html    - You can only assign one array to another directly (i.e. without looping) if the destination array is dynamic[/color]
[color=lightgreen]'                                            Let IntermediateArray() = arrIn()[/color]
 [color=blue]Let[/color] RngD.value = arrOut() [color=lightgreen]'This is the typical allowed one liner to give values of a Range the values in an  Array (VBA does not allow this one liner in any way for assigning the ranges. There is no way of getting over having to paste each Range Object in a loop.[/color]
 
 [color=blue]End[/color] [color=blue]Sub[/color] [color=lightgreen]'VBAArrayOfRanges1a[/color]
[color=blue]Sub[/color] HG_10VBAArrayOfRanges1aa()
[color=lightgreen]'Loop Range of Ranges. VBA Make Array for Output. Output in a "Output Value One Liner"[/color]
[color=lightgreen]'Typical application requiring seperate loops for the (often differnt sized) input and output arrays[/color]
[color=lightgreen]'Simple bit posibly novel idead for missong out empty cells. (So automatically no need to check for no hyperlink in input cell#####)[/color]
 [color=blue]Dim[/color] wksHG [color=blue]As[/color] Worksheet: [color=blue]Set[/color] wksHG = ThisWorkbook.Worksheets("HypSpeedsDeutsch")
 [color=blue]Dim[/color] RngName [color=blue]As[/color] Range, RngD [color=blue]As[/color] Range
 [color=blue]Dim[/color] lr [color=blue]As[/color] [color=blue]Long[/color], rws [color=blue]As[/color] [color=blue]Long[/color]
 [color=blue]Let[/color] lr = wksHG.Cells(Rows.Count, 1).End(xlUp).Row
 [color=blue]Dim[/color] sr [color=blue]As[/color] Long: [color=blue]Let[/color] sr = 21
 [color=blue]Set[/color] RngName = wksHG.Range("A" & sr & ":A" & lr & ""): [color=blue]Set[/color] RngD = wksHG.Range("D" & sr & ":D" & lr & "")
 
 Dim arrIn() As Range [color=lightgreen]'Variant 'In the looping, the Set would appear to be responsible for bringing **Ranges into the Array The variable type remains as defined here: Either a range for [color=blue]As[/color] Range or a Variant Object for [color=blue]As[/color] Variant[/color]
 [color=blue]ReDim[/color] arrIn(sr [color=blue]To[/color] lr, 1 [color=blue]To[/color] 1) [color=lightgreen]'We must give array a size as we give specific value in a loop. ReDim Must be used rather than [color=blue]Dim[/color] as [color=blue]Dim[/color] only takes Numbers not variables[/color]
 
 Dim EmtpyInArrIndiciesCount As Long: [color=blue]Let[/color] EmtpyInArrIndiciesCount = 0 [color=lightgreen]'Here possibility to Redim ArrIn if any extra conitions, such as MSRD etc unique entries being ommited, leading to unused indicies.. then###[/color]
 
 
    [color=blue]For[/color] rws = sr To lr [color=blue]Step[/color] 1 [color=lightgreen]'Make values Output Array[/color]
        [color=blue]If[/color] Range("A" & rws & "").value <> "" [color=blue]Then[/color] [color=lightgreen]'automatically no need to check for no hyperlink in input cell#####[/color]
        [color=blue]Set[/color] arrIn(rws - EmtpyInArrIndiciesCount, 1) = Range("A" & rws & "")  [color=lightgreen]'The extra "  - Emtp...." will take inidie niumber back accordingly to fill just after next free indicie[/color]
        [color=lightgreen]'Set arrIn((rws - EmtpyInArrIndiciesCount, 1) = wksHG.Range("A" & rws & "") 'This would be tolerate**[/color]
        [color=blue]Else[/color]
        [color=blue]Let[/color] EmtpyInArrIndiciesCount = EmtpyInArrIndiciesCount + 1
        [color=blue]End[/color] [color=blue]If[/color]
    [color=blue]Next[/color] rws
 
 Dim arrOut() As [color=blue]String[/color] [color=lightgreen]'We can use string as in the looping below as we are not relying on (/seeing) a range object to rturn us an array of values.[/color]
 [color=blue]ReDim[/color] arrOut(sr To lr - EmtpyInArrIndiciesCount, 1 To 1) [color=lightgreen]'Antoher way to look at it is to say we have a fixed, rather than dynamiy array, and as VBA does not allow a direct assigning one liner in this case it is also not necerssarily expecting to see an object. For Let it is likely to expect to see some value, and for Set an object (Would expect an Range Object if indicies of arrOut were so defined by arrOut() As String initially[/color]
   
    [color=blue]For[/color] rws = sr To lr - EmtpyInArrIndiciesCount [color=blue]Step[/color] 1 [color=lightgreen]'Make values Output Array'The extra   - Emtp.... prevents looping to far[/color]
    [color=lightgreen]'Let arrOut(rws, 1) = arrIn(rws, 1).Hyperlinks(1).Address[/color]
    [color=blue]Let[/color] arrOut(rws, 1) = arrIn()(rws, 1).Hyperlinks(1).Address
        [color=lightgreen]'            'Let arrOut(rws, 1) = arrIn(rws, 1).Value 'Works 'VBA would appear to recognise this array element as A range as it gives me the Method, Object and property selkection to choose from via intellisense brought in by typing . Dot after the Array elemant[/color]
        [color=lightgreen]'            'Let arrOut(rws, 1) = arrIn()(rws, 1).Value 'Works'.. because of how VBA “works”, This extra () will ensure that indices are always returned to the resulting array (and not occasionally, for example, arguments ) by any following method or property.[/color]
               [color=lightgreen]'Let arrOut()(rws, 1) = arrIn()(rws, 1).Value 'Dont Work gives empty but Rory said it aint ever needed on the LHS,  so it aint[/color]
            [color=lightgreen]'            Let arrOut(rws, 1) = Left(arrIn(rws, 1).Value, 4) 'Even A function on the RHS of the = is accepted Here. So again for a non dynamic Array it is not relying on what the function to "define" the type[/color]
            [color=lightgreen]'        '    Let arrOut(rws, 1) = Left(arrIn()(rws, 1).Value, 4) 'Works[/color]
            [color=lightgreen]'                      'Let arrOut()(rws, 1) = Left(arrIn()(rws, 1).Value, 4) 'Works[/color]
    [color=blue]Next[/color] rws
[color=lightgreen]'         Possibility to Note here:          Dim IntermediateArray() [color=blue]As[/color] Range 'Variant  'Note RoryA Post #2You can only assign one array to another directly (i.e. without looping) if the destination array is dynamic AND THE TWO ARRAYS ARE THE SAME TYPE.[/color]
[color=lightgreen]'                                          '  ReDim IntermediateArray(sr To lr, 1 To 1)'THIS Line Will NOT Work: RoryA Post #2 http://www.excelforum.com/excel-new-users-basics/1058406-range-dimensioning-range-and-value-referencing-and-referring-to-arrays.html    - You can only assign one array to another directly (i.e. without looping) if the destination array is dynamic[/color]
[color=lightgreen]'                                            Let IntermediateArray() = arrIn()[/color]
 [color=blue]Let[/color] RngD.Resize(lr - sr - EmtpyInArrIndiciesCount + 1, 1).value = arrOut() [color=lightgreen]'This is the typical allowed one liner to give values of a Range the values in an  Array (VBA does not allow this one liner in any way for assigning the ranges. There is no way of getting over having to paste each Range Object in a loop. 'The extra size corrections prevents a NoValue error placed in last cell if trying to assign to indicies that are not there[/color]
 
[color=lightgreen]''        'Long winded alternative to give an empty indicie rather than no indicie to prevent6 output error[/color]
[color=lightgreen]''        ' 1)Because we assign the Array using the Value property of a range, the returned array has lower bounds[/color]
[color=lightgreen]''        ' of 1 for each dimension. When we redim it without providing lower bounds explicitly,[/color]
[color=lightgreen]''        ' the redim tries to assign each dimension the default lower bound, which is 0 giving an error.[/color]
[color=lightgreen]''        ' So we need to explicitly provide the lower bounds[/color]
[color=lightgreen]''        ' 2) Only the size of the last dimension can be changed for a non dynamic arrange. We want to change the first.[/color]
[color=lightgreen]''        ' So we do a transpose trick for that problem[/color]
[color=lightgreen]''        ' 3) Preseve ensures we do not loose the info already there.   (Post #11   http://www.mrexcel.com/forum/excel-questions/830139-proper-redim-preserve-syntax-best-practice-2.html#post4049584)[/color]
[color=lightgreen]''        ' 4) Would only be needed if arrOut has only 1 column as the Transpose does some thing wiered .. does not give 1 to 1 back.. gives normal array...just 1 indicie in ()[/color]
[color=lightgreen]'        Dim TempTranspose() [color=blue]As[/color] Variant 'Must be variant as seeing a Function below in a "one Liner" which returns a collection which VBA will always guess as an Array because Rory-a-Romping Archibald said so to me... a few times now!!![/color]
[color=lightgreen]'        Let TempTranspose = Application.WorksheetFunction.Transpose(arrOut) 'This woulöd annoyingly take for example 21 to 23 , 1 to 1   and give back ... 1 to 3   ONLY!![/color]
[color=lightgreen]'        ReDim Preserve arrOut(sr [color=blue]To[/color] lr - EmtpyInArrIndiciesCount, 1 [color=blue]To[/color] 2) 'This  extra bodge 4  '- Seems to be necerssary to make at least bigger than 1 column - goes from for example 21-23, 1 to 1   > Redim Preserve > 21-23, 1 to 2[/color]
[color=lightgreen]'        Let TempTranspose = Application.WorksheetFunction.Transpose(arrOut) 'Important.. transposes, but > is 1 to 2, ... 1 to 3 ... so would appoear always to start at 1[/color]
[color=lightgreen]'        ReDim Preserve TempTranspose(1 To 2, 1 [color=blue]To[/color] lr - sr + EmtpyInArrIndiciesCount) 'This increase from 3 to 4 columns[/color]
[color=lightgreen]'          'ReDim Preserve TempTranspose(1 [color=blue]To[/color] 2, sr To lr)' This will NOT work!![/color]
[color=lightgreen]'        Let TempTranspose = Application.WorksheetFunction.Transpose(TempTranspose) 'We have the increased row size bot are stuck with the convention of rows starting at 1[/color]
[color=lightgreen]'        Re[color=blue]Dim[/color] Preserve TempTranspose(1 To lr - sr + EmtpyInArrIndiciesCount, 1 To 1) 'This is extra bodge 4 Part 2[/color]
[color=lightgreen]'[/color]
'        Let RngD.Value = TempTranspose
 
 [color=blue]End[/color] [color=blue]Sub[/color] [color=lightgreen]'VBAArrayOfRanges1aa[/color]
[color=lightgreen]'[/color]
'
''
[color=blue]Sub[/color] HG_11VBAArrayOfRanges1b()
[color=lightgreen]'Loop Range of Ranges. VBA Make Array for Output. Output in a "Output Value One Liner"[/color]
[color=lightgreen]'Typical application requiring seperate loops for the (often differnt sized) input and output arrays[/color]
[color=lightgreen]'Just an extra direct assigniong bit to demonstrate possibillity of assigning a non dynamic array to a dynamic array in one go, noting [color=blue]Dim[/color] characteristics[/color]
 [color=blue]Dim[/color] wksHG [color=blue]As[/color] Worksheet: [color=blue]Set[/color] wksHG = ThisWorkbook.Worksheets("HypSpeedsDeutsch")
 [color=blue]Dim[/color] RngName [color=blue]As[/color] Range, RngD [color=blue]As[/color] Range
 Dim lr [color=blue]As[/color] [color=blue]Long[/color], rws [color=blue]As[/color] [color=blue]Long[/color]
 [color=blue]Let[/color] lr = wksHG.Cells(Rows.Count, 1).End(xlUp).Row
 Dim sr As Long: [color=blue]Let[/color] sr = 21
 [color=blue]Set[/color] RngName = wksHG.Range("A" & sr & ":A" & lr & ""): [color=blue]Set[/color] RngD = wksHG.Range("D" & sr & ":D" & lr & "")
 
 Dim arrIn() [color=blue]As[/color] Range [color=lightgreen]'Variant 'In the looping, the Set would appear to be responsible for bringing **Ranges into the Array The variable type remains as defined here: Either a range for [color=blue]As[/color] Range or a Variant Object for As Variant[/color]
 [color=blue]Re[color=blue]Dim[/color][/color] arrIn(sr To lr, 1 To 1) [color=lightgreen]'We must give array a size as we give specific value in a loop. ReDim Must be used rather than Dim as [color=blue]Dim[/color] only takes Numbers not variables[/color]
 
    [color=blue]For[/color] rws = sr To lr [color=blue]Step[/color] 1 [color=lightgreen]'Input Array of Ranges[/color]
    [color=lightgreen]'Set arrIn()(rws, 1) = Range("A" & rws & "") 'Does not work, that is to say produces error later####!!!![/color]
    [color=blue]Set[/color] arrIn(rws, 1) = Range("A" & rws & "") [color=lightgreen]'no error later - we are setting, that is to say "making an object, or rather putting? one in an[/color]
    [color=lightgreen]'Set arrIn(rws, 1) = wksHG.Range("A" & rws & "") 'This would be tolerate**[/color]
    [color=blue]Next[/color] rws
   
   
Dim IntermediateArray() As Range [color=lightgreen]'Variant  'Note RoryA Post #2You can only assign one array to another directly (i.e. without looping) if the destination array is dynamic AND THE TWO ARRAYS ARE THE SAME TYPE.[/color]
[color=lightgreen]'                                          '  ReDim IntermediateArray(sr To lr, 1 To 1)'THIS Line Will NOT Work: RoryA Post #2 http://www.excelforum.com/excel-new-users-basics/1058406-range-dimensioning-range-and-value-referencing-and-referring-to-arrays.html    - You can only assign one array to another directly (i.e. without looping) if the destination array is dynamic[/color]
[color=blue]Let[/color] IntermediateArray() = arrIn() [color=lightgreen]'  ......and the output held in the Array is Variant type and is an OBJECT of the sort like a Range. (This compares with a similar code utilising An Array of Ranges rather than the MicrosoftScriptimeRuntimeDictionary. (In the Array of Ranges case we could Dim as Range or Variant here. - Important however in that case is that the Dynamic IntermediateArray() Array and the (in that Array of Ranges case non dynamic) arrIn() Array are of the same type. - Either both Range to return an Array of element Type Range or both Variant to Return an Array of element Type Of Objects of the Range Sort : - RoryA . You can only assign one array to another directly (i.e. without looping....... and the two arrays are the same type. http://www.excelforum.com/excel-new-users-basics/1058406-range-dimensioning-range-and-value-referencing-and-referring-to-arrays.html[/color]
 
 
 Dim arrOut() As [color=blue]String[/color] [color=lightgreen]'We can use string as in the looping below as we are not relying on (/seeing) a range object to rturn us an array of values.[/color]
 [color=blue]ReDim[/color] arrOut(sr To lr, 1 To 1) [color=lightgreen]'Antoher way to look at it is to say we have a fixed, rather than dynamiy array, and as VBA does not allow a direct assigning one liner in this case it is also not necerssarily expecting to see an object. For Let it is likely to expect to see some value, and for Set an object (Would expect an Range Object if indicies of arrOut were so defined by arrOut() As String initially[/color]
 
    [color=blue]For[/color] rws = sr To lr [color=blue]Step[/color] 1 [color=lightgreen]'Make values Output Array[/color]
                [color=lightgreen]'Let arrOut(rws, 1) = IntermediateArray(rws, 1).Value 'VBA would appear to recognise this array element as A range as it gives me the Method, Object and property selection to choose from via intellisense brought in by typing . Dot after the Array elemant[/color]
        [color=blue]If[/color] IntermediateArray(rws, 1).Hyperlinks.Count = 1 [color=blue]Then[/color] [color=lightgreen]'Usual check to avoid error if trying to find an address of a non existant Hyperlink.[/color]
        [color=lightgreen]'Let arrOut(rws, 1) = IntermediateArray(rws, 1).Hyperlinks(1).Address '####here comes the error by replaceing Set arrIn(rws, 1) with Set arrIn()(rws, 1) or in the following similar lines[/color]
        [color=blue]Let[/color] arrOut(rws, 1) = IntermediateArray()(rws, 1).Hyperlinks(1).Address [color=lightgreen]'.. because of how VBA “works”, This extra () will ensure that indices are always returned to the resulting array (and not occasionally, for example, arguments ) by any following method or property.[/color]
                    [color=lightgreen]'    Let arrOut()(rws, 1) = IntermediateArray(rws, 1).Value'Dos not work anyway it aint ever needed on the LHS said Rory,  so it aint[/color]
                        [color=lightgreen]'Let arrOut(rws, 1) = IntermediateArray()(rws, 1).Value[/color]
        [color=lightgreen]'        '   Let arrOut(rws, 1) = Left(IntermediateArray(rws, 1).Value, 4) 'Even A function on the RHS of the = is accepted Here. So again for a non dynamic Array it is not relying on what the function to "define" the type[/color]
        [color=lightgreen]'                       'Let arrOut()(rws, 1) = Left(IntermediateArray(rws, 1).Value, 4) 'Givers empty[/color]
        [color=lightgreen]'                       'Let arrOut()(rws, 1) = Left(IntermediateArray()(rws, 1).Value, 4)'Gives empty[/color]
        [color=lightgreen]'           Let arrOut(rws, 1) = Left(IntermediateArray()(rws, 1).Value, 4)[/color]
        [color=blue]Else[/color]
        [color=blue]End[/color] [color=blue]If[/color]
    [color=blue]Next[/color] rws
   
 [color=blue]Let[/color] RngD.value = arrOut() [color=lightgreen]'This is the typical allowed one liner to give values of a Range the valiues in an  Array (VBA does not allow this one liner in any way for assigning the ranges. There is no wy of getting over having to paste each Range Object in in a loop.[/color]
 
 [color=blue]End[/color] [color=blue]Sub[/color] [color=lightgreen]'VBAArrayOfRanges1b[/color]
 [color=lightgreen]'[/color]
 
 
 
 
[color=lightgreen]'[/color]
[color=blue]Sub[/color] HG_12VBAArrayOfRanges2()
[color=lightgreen]'Loop Range of Ranges. VBA Make Array for Output. Output in a "Output Value One Liner"[/color]
[color=lightgreen]'less typical application where any workings can be done within one loop and Input and Output arrays may be similarly sized[/color]
 [color=blue]Dim[/color] wksHG [color=blue]As[/color] Worksheet: [color=blue]Set[/color] wksHG = ThisWorkbook.Worksheets("HypSpeedsDeutsch")
 [color=blue]Dim[/color] RngName [color=blue]As[/color] Range, RngD [color=blue]As[/color] Range
 [color=blue]Dim[/color] lr [color=blue]As[/color] [color=blue]Long[/color], rws [color=blue]As[/color] [color=blue]Long[/color]
 [color=blue]Let[/color] lr = wksHG.Cells(Rows.Count, 1).End(xlUp).Row
 [color=blue]Dim[/color] sr [color=blue]As[/color] Long: [color=blue]Let[/color] sr = 21
 [color=blue]Set[/color] RngName = wksHG.Range("A" & sr & ":A" & lr & ""): [color=blue]Set[/color] RngD = wksHG.Range("D" & sr & ":D" & lr & "")
 
 [color=blue]Dim[/color] arrIn()  [color=blue]As[/color] Range, arrOut() [color=blue]As[/color] [color=blue]String[/color] [color=lightgreen]'[/color]
 [color=blue]ReDim[/color] arrIn(sr [color=blue]To[/color] lr, 1 [color=blue]To[/color] 1): [color=blue]ReDim[/color] arrOut(sr [color=blue]To[/color] lr, 1 To 1)
    [color=blue]For[/color] rws = sr To lr [color=blue]Step[/color] 1 [color=lightgreen]'Input Array of Ranges[/color]
    [color=blue]Set[/color] arrIn(rws, 1) = Range("A" & rws & "")
       
        [color=blue]If[/color] arrIn(rws, 1).Hyperlinks.Count = 1 [color=blue]Then[/color]
        [color=lightgreen]'Let arrOut(rws, 1) = arrIn(rws, 1).Hyperlinks(1).Address[/color]
        [color=blue]Let[/color] arrOut(rws, 1) = arrIn()(rws, 1).Hyperlinks(1).Address
        [color=lightgreen]'            '        '    Let arrOut()(rws, 1) = Left(arrIn(rws, 1).Value, 4) 'Takes 30.5s and returns empties[/color]
        [color=lightgreen]'            '        '    Let arrOut()(rws, 1) = Left(arrIn()(rws, 1).Value, 4)'Takes 146s and returns empties[/color]
        [color=lightgreen]'            'Let arrOut(rws, 1) = Left(arrIn(rws, 1).Value, 4)'Takes 1.5s. "Works"[/color]
        [color=lightgreen]'            Let arrOut(rws, 1) = Left(arrIn()(rws, 1).Value, 4) 'Takes 115s.  ."Works". because of how VBA “works”, This extra () will ensure that indices are always returned to the resulting array (and not occasionally, for example, arguments ) by any following method or property. It "tolerates" for Let on LHS also (returning empties) (but not for Set in the case of similar line involving Ranges..)..But Rory thinks it would never be needed there anyway, which means it most likely doesn't.[/color]
        [color=blue]Else[/color]
        [color=blue]End[/color] [color=blue]If[/color]
    [color=blue]Next[/color] rws
 
 [color=blue]Let[/color] RngD.value = arrOut()
 
[color=blue]End[/color] [color=blue]Sub[/color] [color=lightgreen]'VBAArrayOfRanges2[/color]


…..
Important comments for code types 13 and above, repeated again here:


''
'. Content Order Conventions in large Range Objects
'. Very important (new) point here: There are conventions which can catch you out..
'. For thingy like .Values2 (as used in the Left Function codes) the order held is in an array convention mirroring the Excel Spreadsheet convention: start at the top left of a range; then go along a row; then along the next row down; and so on until the bottom right of a range is reached.

'. ### For things like items, (as is the case for the Hyperlinks considered here) they are held effectively in a long 1 dimensional column array in the order they were placed in the sheet.. This could put a spanner in the works when using the following codes which rely on a "sensible" ordering of the Hyperlink address list. After becoming aware of this through a Forum Thread:
' Sheet Range Object Item List Reorder [SOLVED]
'.. I went on to write a code there which works for any 2 dimensional range to "Re-Order" items into a sensible rational order… This code may need to be run after adding items for the following codes not to give jumbled up output list. I did not yet pay too much attention to the speed of that code yet.. For now I assume I do not need to do that too often. I may improve it later, based partly on results of speed test here….
'.. Further important, in that program empty cells and Duplicates are handled in a Particular way, which would need to be further considered in a "Real Life" Application of the following programs. This would be particularly important for 2 dimensional lists where the convention used to relate Rows then Column to the long list should be considered..
'.. For Simplicity There will no longer be checks in the following programs for empty cells.
'
'

Code:
[color=blue]Sub[/color] HG_13RangeObjectCapture()
[color=lightgreen]'The entire range is captured as One Range Object and its Value2 values accesed and used[/color]
[color=lightgreen]'then as before VBA Make Array for Output. Output in a "Output Value One Liner"[/color]
 [color=blue]Dim[/color] wksHG [color=blue]As[/color] Worksheet: [color=blue]Set[/color] wksHG = ThisWorkbook.Worksheets("HypSpeedsDeutsch")
 [color=blue]Dim[/color] RngName [color=blue]As[/color] Range, RngD [color=blue]As[/color] Range
 [color=blue]Dim[/color] lr [color=blue]As[/color] [color=blue]Long[/color], rws [color=blue]As[/color] [color=blue]Long[/color]
 [color=blue]Let[/color] lr = wksHG.Cells(Rows.Count, 1).End(xlUp).Row
 [color=blue]Dim[/color] sr [color=blue]As[/color] Long: [color=blue]Let[/color] sr = 21
 [color=blue]Set[/color] RngName = wksHG.Range("A" & sr & ":A" & lr & ""): [color=blue]Set[/color] RngD = wksHG.Range("D" & sr & ":D" & lr & "")
 
 [color=blue]Dim[/color] CapturedRangeObject [color=blue]As[/color] Range [color=lightgreen]'One Range Object for entire range[/color]
 [color=blue]Set[/color] CapturedRangeObject = RngName [color=lightgreen]'Direct assignmet to existing Dimensioned Array[/color]
 
 Dim arrOut() [color=blue]As[/color] [color=blue]String[/color] [color=lightgreen]'We can use string as in the looping below as we are not relying on (/seeing) a range object to return us an array of values.[/color]
 [color=blue]ReDim[/color] arrOut(sr [color=blue]To[/color] lr, 1 [color=blue]To[/color] 1) [color=lightgreen]'Antoher way to look at it is to say we have a fixed, rather than dynamiy array, and as VBA does not allow a direct assigning one liner in this case it is also not necerssarily expecting to see an object. For Let it is likely to expect to see some value, and for Set an object (Would expect an Range Object if indicies of arrOut were so defined by arrOut() As String initially[/color]
 
    [color=blue]For[/color] rws = sr To lr [color=blue]Step[/color] 1 [color=lightgreen]'Make values Output Array[/color]
    [color=lightgreen]'                    '        Let arrOut(rws, 1) = CapturedRangeObject.Value2(rws - sr + 1, 1) 'Conventionally the Value2 values are in an Array starting at ( 1, 1) and extending over the two (in this case just a 1 dimensional array). So a bit of adjusting with the indicies is necerssary[/color]
    [color=lightgreen]'Let arrOut(rws, 1) = CapturedRangeObject.Hyperlinks(rws - sr + 1).Address '### For things like items, they are held effectively in a long 1 dimensional column array[/color]
    [color=blue]Let[/color] arrOut(rws, 1) = CapturedRangeObject.Hyperlinks()(rws - sr + 1).Address
    [color=lightgreen]'            Let arrOut(rws, 1) = Left(CapturedRangeObject.Value2(rws - sr + 1, 1), 4)[/color]
    [color=lightgreen]'            'Let arrOut(rws, 1) = Left(CapturedRangeObject.Value2()(rws - sr + 1, 1), 4) ' because of how VBA “works”, This extra () will ensure that indices are always returned to the resulting array (and not occasionally, for example, arguments ) by any following method or property, or passed to any method or property, (In the "bodge subs it is assigned each time to the full object[/color]
    [color=blue]Next[/color] rws
   
 [color=blue]Let[/color] RngD.value = arrOut()
 
[color=blue]End[/color] [color=blue]Sub[/color] [color=lightgreen]'RangeObjectCapture()[/color]
 
 
 
 
 
 
[color=blue]Sub[/color] HG_14MicrosoftScriptingRuntimeDictionaryRangeOfRangesKeysItems1()
[color=lightgreen]'Similar to the Array of Range ranges, except that the Ranges are held in a full MSRD[/color]
[color=lightgreen]'Lots of interaction with the spreadsheet, including the use of a temporary cell for use of unique key characteristic.[/color]
 [color=blue]Dim[/color] wksHG [color=blue]As[/color] Worksheet: [color=blue]Set[/color] wksHG = ThisWorkbook.Worksheets("HypSpeedsDeutsch")
 [color=blue]Dim[/color] RngName [color=blue]As[/color] Range, RngD [color=blue]As[/color] Range
 [color=blue]Dim[/color] lr [color=blue]As[/color] [color=blue]Long[/color], rws [color=blue]As[/color] [color=blue]Long[/color]
 [color=blue]Let[/color] lr = wksHG.Cells(Rows.Count, 1).End(xlUp).Row
 [color=blue]Dim[/color] sr [color=blue]As[/color] Long: [color=blue]Let[/color] sr = 21
 [color=blue]Set[/color] RngName = wksHG.Range("A" & sr & ":A" & lr & ""): [color=blue]Set[/color] RngD = wksHG.Range("D" & sr & ":D" & lr & "")
 
[color=lightgreen]' 1)  'Part 1: Setting up Scriptimg Runtime Stuff-----------------------------[/color]
[color=lightgreen]' Attempting Using the Microsooft Scripting Runtime Dictionary to store Range Objects[/color]
 
[color=lightgreen]'We put the unique values now into a Dictionary for later look up purposes:[/color]
[color=lightgreen]'--requires library reference to MS Scripting Runtime (Early Binding)-[/color]
[color=lightgreen]'        Tools>>References>>scrolldown and check the box next to Microsoft Scripting Runtime[/color]
[color=lightgreen]'  ..Or crashes at next line.....[/color]
 [color=blue]Dim[/color] dicLookupTable [color=blue]As[/color] Scripting.Dictionary [color=lightgreen]'Data held with a unique "Key"or Part Number.[/color]
 [color=blue]Set[/color] dicLookupTable = [color=blue]New[/color] Scripting.Dictionary
[color=lightgreen]' 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.[/color]
[color=lightgreen]'        Dim dicLookupTable As Object[/color]
[color=lightgreen]'        Set dicLookupTable = CreateObject("Scripting.Dictionary")[/color]
[color=lightgreen]' Late Binding is better when sharing files as I am here. Early Binding has the advantage that Excel intellisense[/color]
[color=lightgreen]' will then work for the Microsoft Scripüting Runtime stuff and give you suggestions after you type the .dot thing[/color]
 
     dicLookupTable.CompareMode = vbTextCompare [color=lightgreen]'Not quite sure wot this does yet[/color]
 
[color=lightgreen]'.  A Dictionary in VBA is a collection of objects :you can store all kinds of things in it.[/color]
[color=lightgreen]'.  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.[/color]
[color=lightgreen]'.  (Although the Dictionary has not been designed for that purpose it's a nice side effect.)[/color]
 
[color=lightgreen]'End of Part 1 initial set up Of Scripting Runtime------------------------[/color]
 
 [color=lightgreen]'Dim j As Long ', i [color=blue]As[/color] Long  'LoopBoundVariableCounts used in looping here and at end-----[/color]
 
 [color=blue]Dim[/color] TempColumn [color=blue]As[/color] Long: [color=blue]Let[/color] TempColumn = Columns.Count: [color=blue]Let[/color] TempColumn = 6  [color=lightgreen]'Usually when not debugging comment out last let so Temp Column is last in sheet given by Columns.count....[/color]
 [color=blue]Dim[/color] TempCell [color=blue]As[/color] Range: [color=blue]Set[/color] TempCell = wksHG.Cells(1, TempColumn): [color=blue]Dim[/color] TempCellOffset [color=blue]As[/color] Long: [color=blue]Let[/color] TempCellOffset = 0 [color=lightgreen]'....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 )[/color]
 [color=lightgreen]'2a) Part2a) Looping to put Range Objects in MRSD[/color]
    [color=lightgreen]'For i = StartColumnTableOutput To LastColumnTableOutput Step 1[/color]
        [color=blue]For[/color] rws = sr [color=blue]To[/color] lr [color=blue]Step[/color] 1
          [color=blue]If[/color] wksHG.Cells(rws, 1).value <> "" [color=blue]Then[/color] [color=lightgreen]'If cell is not empty then...[/color]
               [color=blue]If[/color] [color=blue]Not[/color] dicLookupTable.Exists(wksHG.Cells(rws, 1).value) [color=blue]Then[/color] [color=lightgreen]'check that the unique value does not already exist. ##NOTE[/color]
                  dicLookupTable.Add wksHG.Cells(rws, 1).value, wksHG.Cells(rws, 1) [color=lightgreen]'it is easier to understand as well as kind of explicit the first argument does a CStr and the Second Takes anything[/color]
               [color=blue]Else[/color] [color=lightgreen]'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[/color]
               [color=blue]Let[/color] TempCellOffset = TempCellOffset + 1
               [color=blue]Let[/color] TempCell.Offset(TempCellOffset, 0).value = "Duplicate at   " & rws & " | " & 1 & ""
               wksHG.Cells(rws, 1).Interior.Color = 10987519
               dicLookupTable.Add TempCell.Offset(TempCellOffset, 0).value, wksHG.Cells(rws, 1) [color=lightgreen]'In case of duplicate we need a unique key, but we stillinclude the Duplicate Range[/color]
               [color=blue]End[/color] [color=blue]If[/color]
           [color=blue]Else[/color] [color=lightgreen]'Case r an empty cell - inform of empty cell by writing message in that cell via the Tempory cell[/color]
           [color=blue]Let[/color] TempCellOffset = TempCellOffset + 1 [color=lightgreen]'Go to next free tempory cell in tempory column[/color]
           [color=blue]Let[/color] TempCell.Offset(TempCellOffset, 0).value = "Empty Cell at   " & rws & " | " & 1 & ""
           dicLookupTable.Add TempCell.Offset(TempCellOffset, 0).value, TempCell.Offset(TempCellOffset, 0)
           [color=blue]End[/color] [color=blue]If[/color]
        [color=blue]Next[/color] rws
    [color=lightgreen]'Next i[/color]
'End Part 2-----------------------------------------------------------
 
 [color=lightgreen]'3) Part 3)--transfer range objects from dictionary to array of ranges in one go, typical Array assignment "One Liner" - The quick way to place data into an array is to dimension a variable ( for example rResults ) ....>>[/color]
 [color=blue]Dim[/color] IntermediateArray() As [color=blue]Variant[/color] [color=lightgreen]'... [color=blue]As[/color] a Variant and then the "Let IntermediateArray  = " code line Using a variant allows BOTH .-1) for capturing Objects, text, numbers, blanks  errors etc. from those cells and also 2) allows rResults to be an array variable.....[/color]
 [color=blue]Let[/color] IntermediateArray() = dicLookupTable.Items() [color=lightgreen]'... In this case it will also accept us quasi pre - defining as Array with the pair of parentheses IntermediateArray()[/color]
 [color=lightgreen]'End part 3)--- NOTE: this gives automatically the 0 to _ convention in IntermediateArray Array!.        >>>.....and the output held in the Array is Variant type and is an OBJECT of the sort like a Range. (This compares with a similar code utilising An Array of Ranges rather than the MicrosoftScriptimeRuntimeDictionary. (In the Array of Ranges case we could Dim as Range or Variant here. - Important however in that case is that the Dynamic IntermediateArray() Array and the (in that Array of Ranges case non dynamic) arrIn() Array are of the same type. - Either both Range to return an Array of element Type Range or both Variant to Return an Array of element Type Of Objects of the Range Sort : - RoryA . You can only assign one array to another directly (i.e. without looping....... and the two arrays are the same type. http://www.excelforum.com/excel-new-users-basics/1058406-range-dimensioning-range-and-value-referencing-and-referring-to-arrays.html[/color]
 
 [color=blue]Dim[/color] arrOut() As [color=blue]String[/color] [color=lightgreen]'We can use string as in the looping below as we are not relying on (/seeing) a range object to rturn us an array of values.[/color]
 [color=blue]ReDim[/color] arrOut(sr [color=blue]To[/color] lr, 1 [color=blue]To[/color] 1) [color=lightgreen]'Antoher way to look at it is to say we have a fixed, rather than dynamiy array, and as VBA does not allow a direct assigning one liner in this case it is also not necerssarily expecting to see an object. For Let it is likely to expect to see some value, and for Set an object (Would expect an Range Object if indicies of arrOut were so defined by arrOut() As String initially[/color]
 
    [color=blue]For[/color] rws = sr To lr [color=blue]Step[/color] 1 [color=lightgreen]'Input Array of Ranges[/color]
    [color=lightgreen]'                'Let arrOut(rws, 1) = IntermediateArray(rws - sr).Value 'VBA would appear to recognise this array element as A range as it gives me the Method, Object and property selkection to choose from via intellisense brought in by typing . Dot after the Array elemant[/color]
    [color=lightgreen]'        '    Let arrOut(rws, 1) = Left(dicLookupTable.Items(rws - sr).Value, 4)[/color]
    [color=lightgreen]'        '    Let arrOut(rws, 1) = Left(dicLookupTable.Items()(rws - sr).Value, 4)[/color]
    [color=lightgreen]'Let arrOut(rws, 1) = dicLookupTable.Items(rws - sr).Hyperlinks(1).Address[/color]
    [color=lightgreen]'Let arrOut(rws, 1) = dicLookupTable.Items()(rws - sr).Hyperlinks(1).Address[/color]
    [color=lightgreen]'[/color]
    '        '    Let arrOut(rws, 1) = Left(IntermediateArray(rws - sr).Value, 4) 'Even A function on the RHS of the = is accepted Here. So again for a non dynamic Array it is not relying on what the function to "define" the type
    [color=lightgreen]'        '    Let arrOut(rws, 1) = Left(IntermediateArray()(rws - sr).Value, 4)[/color]
    [color=lightgreen]'Let arrOut(rws, 1) = IntermediateArray(rws - sr).Hyperlinks(1).Address[/color]
    [color=blue]Let[/color] arrOut(rws, 1) = IntermediateArray()(rws - sr).Hyperlinks(1).Address
    [color=lightgreen]'[/color]
    '        '    Let arrOut(rws, 1) = Left(dicLookupTable.Keys(rws - sr), 4)
    [color=lightgreen]'            Let arrOut(rws, 1) = Left(dicLookupTable.Keys()(rws - sr), 4)[/color]
    [color=blue]Next[/color] rws
 
 [color=blue]Let[/color] RngD.value = arrOut()
    [color=lightgreen]'        '   Let RngD.Value = IntermediateArray() 'This should not do anything.. interestingly gives value from first Cell in RngName,[/color]
 
 [color=blue]Set[/color] dicLookupTable = [color=blue]Nothing[/color] [color=lightgreen]'Genarally good practice to turn these thimgs off. 'May not be needed but to keep program flexible should alterations need it.[/color]
 
[color=blue]End[/color] [color=blue]Sub[/color] [color=lightgreen]'MicrosoftScriptimeRuntimeDictionaryRangeOfRangesKeysItems1()[/color]
[color=lightgreen]'[/color]
 
 
 
[color=lightgreen]'[/color]
'
[color=blue]Sub[/color] HG_15MicrosoftScriptimeRuntimeDictionaryRangeOfRangesKeys()
[color=lightgreen]'Similar to the Array of Range ranges, except that the Ranges are held in the MSRD Key. Strange but it can!![/color]
[color=lightgreen]'A bit less Lots of interaction with the spreadsheet, as the temp for the unique is not there - we are using the key,[/color]
[color=lightgreen]'so all ranges are unique keys we simply include that duplicateentry, that is to say the output array may be a bit shorter.[/color]
[color=lightgreen]'Also the cell my be empty but the RANGE cannot be="" so for it's "value" VBA writes "Empty" !![/color]
 [color=blue]Dim[/color] wksHG [color=blue]As[/color] Worksheet: [color=blue]Set[/color] wksHG = ThisWorkbook.Worksheets("HypSpeedsDeutsch")
 [color=blue]Dim[/color] RngName [color=blue]As[/color] Range, RngD [color=blue]As[/color] Range
 [color=blue]Dim[/color] lr [color=blue]As[/color] [color=blue]Long[/color], rws [color=blue]As[/color] [color=blue]Long[/color]
 [color=blue]Let[/color] lr = wksHG.Cells(Rows.Count, 1).End(xlUp).Row
 [color=blue]Dim[/color] sr [color=blue]As[/color] Long: [color=blue]Let[/color] sr = 21
 [color=blue]Set[/color] RngName = wksHG.Range("A" & sr & ":A" & lr & ""): [color=blue]Set[/color] RngD = wksHG.Range("D" & sr & ":D" & lr & "")
 
[color=lightgreen]' 1)  'Part 1b: Setting up Scriptimg Runtime Stuff-----------------------------[/color]
[color=lightgreen]'Using the Microsoft Scripting Runtime Dictionary KEYS ONLY to store Range Objects... A bit like saying "....(It is certainly a crazy concept if you think about it….Like saying in a Filing Cabinet I have a piece of paper for every House in a town with all the plans and details of the house in it. The parallel idea to the Keys being able to be almost anything would be that instead of the piece of paper I could a Duplicate of every House in the filing cabinet!!! ). ...." Alan :- Post #10 http://www.mrexcel.com/forum/excel-questions/832103-using-microsoft-scripting-runtime-dictionary-store-then-retrieve-range-objects.html[/color]
 
[color=lightgreen]'We put the unique values now into a Dictionary for later look up purposes:[/color]
[color=lightgreen]'--requires library reference to MS Scripting Runtime (Early Binding)-[/color]
[color=lightgreen]'        Tools>>References>>scrolldown and check the box next to Microsoft Scripting Runtime[/color]
[color=lightgreen]'  ..Or crashes at next line.....[/color]
 [color=blue]Dim[/color] dicLookupTable [color=blue]As[/color] Scripting.Dictionary [color=lightgreen]'Data held with a unique "Key"or Part Number.[/color]
 [color=blue]Set[/color] dicLookupTable = [color=blue]New[/color] Scripting.Dictionary
[color=lightgreen]' 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.[/color]
[color=lightgreen]'        Dim dicLookupTable As Object[/color]
[color=lightgreen]'        Set dicLookupTable = CreateObject("Scripting.Dictionary")[/color]
[color=lightgreen]' Late Binding is better when sharing files as I am here. Early Binding has the advantage that Excel intellisense[/color]
[color=lightgreen]' will then work for the Microsoft Scripüting Runtime stuff and give you suggestions after you type the .dot thing[/color]
 
     dicLookupTable.CompareMode = vbTextCompare [color=lightgreen]'Not quite sure wot this does yet[/color]
 
[color=lightgreen]'.  A Dictionary in VBA is a collection of objects :you can store all kinds of things in it.[/color]
[color=lightgreen]'.  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.[/color]
[color=lightgreen]'.  (Although the Dictionary has not been designed for that purpose it's a nice side effect.)[/color]
 
[color=lightgreen]'End of Part 1b initial set up Of Scripting Runtime------------------------[/color]
 
   [color=lightgreen]'Dim j As Long ', i As Long  'LoopBoundVariableCounts used in looping here and at end-----[/color]
 [color=lightgreen]'Dim TempCell As Range: Set TempCell = wksHG.Cells(1, Columns.Count): Dim TempCellOffset [color=blue]As[/color] Long: Let TempCellOffset = 0 'We choose a cell (or through the later use of the offset a column) to use for Duplicate or Empty cells. We use the last column in the sheet. (This is genarally a good practice as it will not effect attempts with .End(XltoLeft) to find last column[/color]
 [color=lightgreen]'2a) Part2a) Looping to put Range Objects in MRSD[/color]
    [color=lightgreen]'For i = StartColumnTableOutput To LastColumnTableOutput Step 1[/color]
        [color=blue]For[/color] rws = sr [color=blue]To[/color] lr [color=blue]Step[/color] 1
           [color=blue]If[/color] wksHG.Cells(rws, 1).value <> "" [color=blue]Then[/color] [color=lightgreen]'If RANGE.value is not empty...[/color]
[color=lightgreen]'               If Not dicLookupTable.Exists(wksHG.Cells(rws, 1).Value) Then 'check that the unique value does not already exist. ##NOTE[/color]
                  dicLookupTable.Add wksHG.Cells(rws, 1), [color=blue]Nothing[/color] [color=lightgreen]'it is easier to understand as well as kind of explicit the first argument does a CStr and the Second Takes anything[/color]
[color=lightgreen]'               Else 'The key is the Range which is always unique[/color]
[color=lightgreen]'               End If[/color]
           [color=blue]Else[/color] [color=lightgreen]'Case r an empty cell. We habe a choice by virtue of us using ###Newlr below to do nothing.. or..[/color]
           [color=blue]Let[/color] wksHG.Cells(rws, 1).value = "Anything" [color=lightgreen]'.. we could have done nothing - for the case of the Let function it does not erro just gives nothing[/color]
           dicLookupTable.Add wksHG.Cells(rws, 1), [color=blue]Nothing[/color] [color=lightgreen]'.. chose here it to give key anyway and..[/color]
           [color=blue]End[/color] [color=blue]If[/color]
        [color=blue]Next[/color] rws
    [color=lightgreen]'Next i[/color]
'End Part 2-----------------------------------------------------------
 
 [color=lightgreen]'3) Part 3)--transfer range objects from dictionary to array of ranges in one go, typical Array assignment "One Liner" - The quick way to place data into an array is to dimension a variable ( for example rResults ) ....>>[/color]
 [color=blue]Dim[/color] IntermediateArray() As [color=blue]Variant[/color] [color=lightgreen]'... [color=blue]As[/color] a Variant and then the "Let IntermediateArray  = " code line Using a variant allows BOTH .-1) for capturing Objects, text, numbers, blanks  errors etc. from those cells and also 2) allows rResults to be an array variable.....[/color]
 [color=blue]Let[/color] IntermediateArray() = dicLookupTable.Keys() [color=lightgreen]'... In this case it will also accept us quasi pre - defining as Array with the pair of parentheses IntermediateArray()[/color]
 [color=lightgreen]'End part 3)--- NOTE: this gives automatically the 0 to _ convention in IntermediateArray Array!.        >>>.....and the output held in the Array is Variant type and is an OBJECT of the sort like a Range. (This compares with a similar code utilising An Array of Ranges rather than the MicrosoftScriptimeRuntimeDictionary. (In the Array of Ranges case we could Dim as Range or Variant here. - Important however in that case is that the Dynamic IntermediateArray() Array and the (in that Array of Ranges case non dynamic) arrIn() Array are of the same type. - Either both Range to return an Array of element Type Range or both Variant to Return an Array of element Type Of Objects of the Range Sort : - RoryA . You can only assign one array to another directly (i.e. without looping....... and the two arrays are the same type. http://www.excelforum.com/excel-new-users-basics/1058406-range-dimensioning-range-and-value-referencing-and-referring-to-arrays.html[/color]
 
 [color=blue]Dim[/color] Newlr [color=blue]As[/color] Long: [color=blue]Let[/color] Newlr = [color=blue]UBound[/color](IntermediateArray(), 1) + sr [color=lightgreen]'###This is importent when looping through dicLookupTable.Keys so that for one or more empty cell not given a key we do not try to loop too far[/color]
 [color=blue]Dim[/color] arrOut() As [color=blue]String[/color] [color=lightgreen]'We can use string as in the looping below as we are not relying on (/seeing) a range object to rturn us an array of values.[/color]
 [color=blue]ReDim[/color] arrOut(sr [color=blue]To[/color] Newlr, 1 [color=blue]To[/color] 1) [color=lightgreen]'Antoher way to look at it is to say we have a fixed, rather than dynamiy array, and as VBA does not allow a direct assigning one liner in this case it is also not necerssarily expecting to see an object. For Let it is likely to expect to see some value, and for Set an object (Would expect an Range Object if indicies of arrOut were so defined by arrOut() As String initially. We could leave Nerlr as lr - doesn't matter if output array is bit too big[/color]
 
    [color=blue]For[/color] rws = sr [color=blue]To[/color] Newlr [color=blue]Step[/color] 1 [color=lightgreen]'Input Array of Ranges[/color]
            [color=lightgreen]'Let arrOut(rws, 1) = IntermediateArray(rws - sr).Value 'VBA would appear to recognise this array element as A range as it gives me the Method, Object and property selkection to choose from via intellisense brought in by typing . Dot after the Array elemant[/color]
    [color=lightgreen]'            Let arrOut(rws, 1) = Left(dicLookupTable.Keys(rws - sr).Value, 4) 'Remember.. write in .Value - Do not rely on the implicit!![/color]
    [color=lightgreen]'            'Let arrOut(rws, 1) = Left(dicLookupTable.Keys()(rws - sr).Value, 4)[/color]
    [color=lightgreen]'            'Let arrOut(rws, 1) = Left(IntermediateArray(rws - sr).Value, 4) 'Even A function on the RHS of the = is accepted Here. So again for a non dynamic Array it is not relying on what the function to "define" the type[/color]
    [color=lightgreen]'            'Let arrOut(rws, 1) = Left(IntermediateArray()(rws - sr).Value, 4)[/color]
    [color=lightgreen]'Let arrOut(rws, 1) = dicLookupTable.Keys(rws - sr).Hyperlinks(1).Address[/color]
    [color=lightgreen]'Let arrOut(rws, 1) = dicLookupTable.Keys()(rws - sr).Hyperlinks(1).Address[/color]
    [color=lightgreen]'Let arrOut(rws, 1) = IntermediateArray(rws - sr).Hyperlinks(1).Address[/color]
    [color=blue]Let[/color] arrOut(rws, 1) = IntermediateArray()(rws - sr).Hyperlinks(1).Address
    [color=blue]Next[/color] rws
 
 [color=blue]Let[/color] RngD.value = arrOut()
 
 [color=blue]Set[/color] dicLookupTable = [color=blue]Nothing[/color] [color=lightgreen]'Genarally good practice to turn these thimgs off. 'May not be needed but to keep program flexible should alterations need it.[/color]
 
[color=blue]End[/color] [color=blue]Sub[/color] [color=lightgreen]'MicrosoftScriptimeRuntimeDictionaryRangeOfRangesKeys()[/color]
…………………….
………………………………………………………………………………………………………………………..


. Finally for completeness here the Class module Codes required for Codes 8b) and 8c)


Code:
[color=lightgreen]'[/color]
'
'3) Kyle Quasi "Method Pair" "Setter Getter" (No [color=blue]Set[/color]ter available- replace that with the event type function which occure when a Class is first called)
[color=lightgreen]'  ### Private ppInitEvent_Range As Range'Errors if here[/color]
[color=blue]Private[/color] [color=blue]Sub[/color] Class_Initialize() [color=lightgreen]'Replaces Typical Public Property Let[/color]
    Set ppInitEvent_Range = Worksheets("HypSpeedsDeutsch").Range("A21:A33948")
    [color=lightgreen]'            Set ppInitEvent_Range = Worksheets("HypSpeedsEnglish").Range("A21:A1674")[/color]
    [color=lightgreen]'            [color=blue]Set[/color] p_Range = Worksheets("KyleMrExcel").Range("A3:B10")[/color]
[color=blue]End[/color] [color=blue]Sub[/color]
 
[color=blue]Public[/color] [color=blue]Property[/color] [color=blue]Get[/color] HypAddressAlanKyle() [color=blue]As[/color] [color=blue]Variant[/color]
 
    [color=blue]Dim[/color] var() [color=blue]As[/color] [color=blue]Variant[/color]
    [color=blue]Dim[/color] temp [color=blue]As[/color] Range
   
    [color=blue]Dim[/color] rowCount [color=blue]As[/color] Long: rowCount = ppInitEvent_Range.Rows.Count
    [color=blue]Dim[/color] columnCount [color=blue]As[/color] Long: columnCount = ppInitEvent_Range.Columns.Count
   
    [color=blue]Dim[/color] x [color=blue]As[/color] [color=blue]Long[/color]
    [color=blue]Dim[/color] y [color=blue]As[/color] [color=blue]Long[/color]
   
    [color=blue]If[/color] (rowCount = 1 And columnCount = 1) [color=blue]Then[/color]
        HypAddressAlanKyle = ppInitEvent_Range.Hyperlinks(1).Address
            [color=lightgreen]'HypAddressAlanKyle = GetURLstr(ppInitEvent_Range) ''Extra Possibility, GetURLstr(Onecell) is a simple function simply doing Hyperlinks(1).Address for the given 1 cell[/color]
        [color=blue]Exit[/color] [color=blue]Property[/color]
    [color=blue]End[/color] [color=blue]If[/color]
   
      
    [color=blue]ReDim[/color] var(1 [color=blue]To[/color] rowCount, 1 [color=blue]To[/color] columnCount)
   
    [color=blue]For[/color] x = 1 [color=blue]To[/color] rowCount
        [color=blue]For[/color] y = 1 [color=blue]To[/color] columnCount
            [color=lightgreen]'var(x, y) = ppInitEvent_Range.Cells(x, y).Hyperlinks(1).Address[/color]
                var(x, y) = GetURLstr(ppInitEvent_Range.Cells(x, y)) [color=lightgreen]''Extra Possibility, GetURLstr(Onecell) is a simple function simply doing Hyperlinks(1).Address for the given 1 cell[/color]
        [color=blue]Next[/color] y
    [color=blue]Next[/color] x
   
    HypAddressAlanKyle = var
   
[color=blue]End[/color] [color=blue]Property[/color]
[color=lightgreen]'[/color]
'
'
'
'
'
[color=lightgreen]'[/color]
'
'
'4)   A "Let Get Pair of Property method Statements"
[color=blue]Public[/color] [color=blue]Property[/color] [color=blue]Let[/color] HypAddressAlanKylePair([color=blue]ByVal[/color] Rng_in [color=blue]As[/color] [color=blue]Variant[/color])  [color=lightgreen]'Variant is required to match Public Property Get. It remains a Variant type, a collection (of Ranges here)[/color]
 
    Set p_Range = Rng_in
 
[color=blue]End[/color] [color=blue]Property[/color]
[color=blue]Public[/color] [color=blue]Property[/color] [color=blue]Get[/color] HypAddressAlanKylePair() [color=blue]As[/color] [color=blue]Variant[/color] [color=lightgreen]'Variant is the only variable that will return a collection (Array)[/color]
 
    [color=blue]Dim[/color] var() [color=blue]As[/color] [color=blue]Variant[/color]
    [color=blue]Dim[/color] temp [color=blue]As[/color] Range
   
    [color=blue]Dim[/color] rowCount [color=blue]As[/color] Long: rowCount = p_Range.Rows.Count
    [color=blue]Dim[/color] columnCount [color=blue]As[/color] Long: columnCount = p_Range.Columns.Count
   
    [color=blue]Dim[/color] x [color=blue]As[/color] [color=blue]Long[/color]
    [color=blue]Dim[/color] y [color=blue]As[/color] [color=blue]Long[/color]
   
    [color=blue]If[/color] (rowCount = 1 And columnCount = 1) [color=blue]Then[/color]
        HypAddressAlanKyle = p_Range.Hyperlinks(1).Address
                [color=lightgreen]'HypAddressAlanKyle = GetURLstr(p_Range) ''Extra Possibility, GetURLstr(Onecell) is a simple function simply doing Hyperlinks(1).Address for the given 1 cell[/color]
        [color=blue]Exit[/color] [color=blue]Property[/color]
    [color=blue]End[/color] [color=blue]If[/color]
   
      
    [color=blue]ReDim[/color] var(1 [color=blue]To[/color] rowCount, 1 [color=blue]To[/color] columnCount)
   
    [color=blue]For[/color] x = 1 [color=blue]To[/color] rowCount
        [color=blue]For[/color] y = 1 [color=blue]To[/color] columnCount
            var(x, y) = p_Range.Cells(x, y).Hyperlinks(1).Address
                [color=lightgreen]'var(x, y) = GetURLstr(p_Range.Cells(x, y)) ''Extra Possibility, GetURLstr(Onecell) is a simple function simply doing Hyperlinks(1).Address for the given 1 cell[/color]
        [color=blue]Next[/color] y
    [color=blue]Next[/color] x
   
    HypAddressAlanKylePair = var
   
[color=blue]End[/color] [color=blue]Property[/color]
[color=lightgreen]' This Public Function can be put here without error even though it is elsewhere in a Module.... because I have it in a module elsewhere I can also comment it out!![/color]
[color=blue]Public[/color] [color=blue]Function[/color] GetURLstr([color=blue]ByVal[/color] Hyplinkcell [color=blue]As[/color] Range) [color=lightgreen]'. By val uses the value held in the value within the sub (Function) , rather than referencing the allocated source "bucket" of the variable. So any given value to the Variable outside the Sub (Function) are not changed[/color]
     [color=lightgreen]'Lists the Hyperlink Address for one Given Cell[/color]
              GetURLstr = Hyplinkcell.Hyperlinks(1).Address [color=lightgreen]'The 1 in ( ) is just to get the syntax right. It can only be 1 for 1 cell. But for a given range of n cells it could be 1 to n[/color]
[color=blue]End[/color] [color=blue]Function[/color]
 
Upvote 0

Forum statistics

Threads
1,214,539
Messages
6,120,100
Members
448,944
Latest member
SarahSomethingExcel100

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top