VBA Dictionary - Subscript out of range

Mallesh23

Well-known Member
Joined
Feb 4, 2009
Messages
976
Office Version
  1. 2010
Platform
  1. Windows
Hi Team,

I am Learning dictionary. In Below example getting error message subscript out of Range.for below line.

ar_Eng(i, 1) = .Item(ary_find(i, 1))(0)

I know only one approach this get the answer.
are there any other way to achieve the task using dictionary.

Below is my Attempted Code.

VBA Code:
Sub Print_dict_Dynamically()
  Dim dict As New Scripting.Dictionary
  Dim i As Long
 
  Dim rg As Range
  Set rg = ThisWorkbook.Worksheets(1).Range("A1").CurrentRegion
 
  Dim ary As Variant
  ary = rg.Offset(1).Resize(rg.Rows.Count - 1).Value2
 
  Dim ary_find As Variant
  ary_find = Range("H2:H7").Value2
 
 
  With dict
    .CompareMode = TextCompare
    For i = LBound(ary, 1) To UBound(ary, 1)
      If Not .Exists(ary(i, 1)) Then
        .Add ary(i, 1), Array(ary(i, 2), ary(i, 3), ary(i, 4))
      End If
    Next i
   
  
    Dim ar_Eng As Variant
    Dim ar_Math As Variant
    Dim ar_Sci As Variant
     
   ReDim ar_Eng(LBound(ary_find, 1), UBound(ary_find), 1)
   ReDim ar_Math(LBound(ary_find, 1), UBound(ary_find), 1)
   ReDim ar_Sci(LBound(ary_find, 1), UBound(ary_find), 1)
  
'Store into array variable
For i = LBound(ary_find, 1) To UBound(ary_find, 1)
        If .Exists(ary_find(i, 1)) Then
           ar_Eng(i, 1) = .Item(ary_find(i, 1))(0)  'Getting error at subscript out of dictionary
            ar_Math(i, 1) = .Item(ary_find(i, 1))(0)
           ar_Sci(i, 1) = .Item(ary_find(i, 1))(0)
        End If

Next i

End With

'Print Items
With ThisWorkbook.Worksheets(1)
    .Range("I2").Resize(UBound(ary_find)).Value = ar_rng
    .Range("J2").Resize(UBound(ary_find)).Value = ar_Math
    .Range("k2").Resize(UBound(ary_find)).Value = ar_Sci
End With
 

'ThisWorkbook.Worksheets(1).Range("I2").Resize(dict.Count, 3).Value = Application.Index(dict.Items, 0, 0)
 
  MsgBox "Macro Success"
Set dict = Nothing
 
End Sub


Below is the Table with expected output in Range("I:K)

Book11.xlsm
ABCDEFGHIJK
1NameEnglishMathsScienceTotalNameEnglishMathsScience
2Sachin926294248Sachin926294
3Dhoni806690236Dhoni806690
4Yuvraj628394239Adam Gilchrist979383
5Virat997997275Gayle709685
6Steve waugh818892261Fleming999685
7Ricky Ponting666395224
8Adam Gilchrist979383273
9Gayle709685251
10Fleming999685280
Sheet1


Thanks
mg
 

Excel Facts

What does custom number format of ;;; mean?
Three semi-colons will hide the value in the cell. Although most people use white font instead.
This line (& the next two)
VBA Code:
ReDim ar_Eng(LBound(ary_find, 1), UBound(ary_find), 1)
should be
VBA Code:
ReDim ar_Eng(LBound(ary_find, 1) to UBound(ary_find), 1 to 1)
 
Upvote 0
Hi Fluff,

Perfect ! it worked.
am I using very lengthy approach to get the output ,
are there any other way using to get the output using dictionary.


VBA Code:
Sub Print_dict_Dynamically()
  Dim dict As New Scripting.Dictionary
  Dim i As Long
 
  Dim rg As Range
  Set rg = ThisWorkbook.Worksheets(1).Range("A1").CurrentRegion
 
  Dim ary As Variant
  ary = rg.Offset(1).Resize(rg.Rows.Count - 1).Value2
 
  Dim ary_find As Variant
  ary_find = Range("H2:H7").Value2
 
 
  With dict
    .CompareMode = TextCompare
    For i = LBound(ary, 1) To UBound(ary, 1)
      If Not .Exists(ary(i, 1)) Then
        .Add ary(i, 1), Array(ary(i, 2), ary(i, 3), ary(i, 4))
      End If
    Next i
   
  
    Dim ar_Eng As Variant
    Dim ar_Math As Variant
    Dim ar_Sci As Variant
     
    ReDim ar_Eng(LBound(ary_find, 1) To UBound(ary_find), 1 To 1)
   ReDim ar_Math(LBound(ary_find, 1) To UBound(ary_find), 1 To 1)
   ReDim ar_Sci(LBound(ary_find, 1) To UBound(ary_find), 1 To 1)
  

For i = LBound(ary_find, 1) To UBound(ary_find, 1)
        If .Exists(ary_find(i, 1)) Then
           ar_Eng(i, 1) = .Item(ary_find(i, 1))(0) 
            ar_Math(i, 1) = .Item(ary_find(i, 1))(1)
           ar_Sci(i, 1) = .Item(ary_find(i, 1))(2)
        Else
       
        ar_Eng(i, 1) = "Not Found" 
            ar_Math(i, 1) = "Not Found"
           ar_Sci(i, 1) = "Not Found"
        End If

Next i

End With

With ThisWorkbook.Worksheets(1)
    .Range("I2").Resize(UBound(ary_find)).Value = ar_Eng
    .Range("J2").Resize(UBound(ary_find)).Value = ar_Math
    .Range("k2").Resize(UBound(ary_find)).Value = ar_Sci
End With
 
 
  Set dict = Nothing
 
'ThisWorkbook.Worksheets(1).Range("I2").Resize(dict.Count, 3).Value = Application.Index(dict.Items, 0, 0)
 
  MsgBox "Macro Success"
 
End Sub



Thanks
mg
 
Upvote 0
Just depends on what you want to do, there are always multiple different ways.
 
Upvote 0
Hi Fluff,

Agreed there are multiple solutions for a single task.

I come across this scenario multiple times , hence want to create a Dynamic function for it.
is it possible?..

VBA Code:
With dict
    .CompareMode = TextCompare
    For i = LBound(ary, 1) To UBound(ary, 1)
      If Not .Exists(ary(i, 1)) Then
        .Add ary(i, 1), Array(ary(i, 2), ary(i, 3), ary(i, 4))
      End If
    Next i
 end with

'Attempted Function (expected item Columns 1 to 5)

VBA Code:
Function Store_Dictionary(byval ary as variant, lookup_key as long, items as long) as dictionary

Dim i as long
Dim dict as new scripting dictionary

With dict
    .CompareMode = TextCompare
    For i = LBound(ary, 1) To UBound(ary, 1)
      If Not .Exists(ary(i, lookup_key)) Then
        If Items = 4 Then
            .Add ary(i, lookup_key), Array(ary(i, 2), ary(i, 3), ary(i, 4), ary(i, 5))
        ElseIf Items = 3 Then
            .Add ary(i, lookup_key), Array(ary(i, 2), ary(i, 3), ary(i, 4))
        ElseIf Items = 1 Then
            .Add ary(i, lookup_key), Array(ary(i, 2), ary(i, 3))
        Else
            .Add ary(i, lookup_key), Array(ary(i, 2))
        End If


    End If


      End If
    Next i
End With


Store_Dictionary = Dict

end function
 
Last edited:
Upvote 0
You could do something like
VBA Code:
Sub Mallesh()
   Dim Ary As Variant, Tmp As Variant
   Dim r As Long, c As Long
   
   Ary = Sheet1.Range("a1").CurrentRegion.Value2
   With CreateObject("scripting.dictionary")
      For r = 1 To UBound(Ary)
         If Not .Exists(Ary(r, 1)) Then
            ReDim Tmp(1 To UBound(Ary, 2) - 1)
            For c = 2 To UBound(Ary, 2)
               Tmp(c - 1) = Ary(r, c)
            Next c
            .Add Ary(r, 1), Tmp
         End If
      Next r
      Sheet1.Range("K2").Resize(.count).Value = Application.Transpose(.Keys)
      Sheet1.Range("l2").Resize(.count, UBound(Tmp)).Value = Application.Index(.items, 0, 0)
   End With
End Sub
 
Upvote 0
Hi Fluff,

Thanks once again for, Providing ,one more option , will practice on it. (y)


Thanks
mg
 
Upvote 0
You're welcome & thanks for the feedback.
 
Upvote 0

Forum statistics

Threads
1,214,520
Messages
6,120,017
Members
448,937
Latest member
BeerMan23

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