1

I have a large list of text strings. I know that some strings occur more than once in this list. The frequency with which the strings occur are in the next column.

Now, let's say the text string "hello" occurs 17 times. How would I get all positions of this text within the list?

Any help is appreciated.

Community
  • 1
  • 1
Pieter
  • 647
  • 4
  • 9
  • 16
  • What kind of List are you using? Since you say "column", I'm now suspicious that it may be a ListBox, is this right? – Tony Day Nov 15 '10 at 09:49
  • Hi Tony, it's basically just a column with text strings. Every cell in this column contains 1 string. – Pieter Nov 15 '10 at 09:52

2 Answers2

1

Pieter,

Check out this post of Stack Overflow.

I have also attempted to adjust their sample code to match your case, I'm sorry though that this may not compile, I cannot test it at the moment and my VBA is a little rusty, but you get the idea.

Function CheckValues1(byval columnToCheck as Integer, byval stringToFind as String) as Integer()
    dim rwIndex As Integer
    dim index as Integer
    dim occurrences() As Integer
    index = 0

    For rwIndex = 0 to Cells(Rows.Count, columnToCheck).End(xlUp).Row

       ReDim Preserve occurrences(0 to index)

       If Cells(rwIndex, columnToCheck).Value = stringToFind Then
           occurrences(index) = rwIndex
           index = index + 1
       End If

    Next rwIndex

    dim output as String
    output = output & (Len(occurrences)-1) & " occurrences found." & vbcrlf & vbcrlf
    For index = 0 to LBound(occurrences)

        output = output & "Line: " & index & vbcrlf

    Next index
    MsgBox output

End Sub

This function should return an array of all of the occurances for which you can handle however your like. You just need to pass in the String your are looking for and the column number to search within.

I hope this helps!

Tony

Community
  • 1
  • 1
Tony Day
  • 2,170
  • 19
  • 25
  • Thanks for this extensive reply. For now it doesn't work yet (I get a #value! error) but I'll keep tinkering and report back tomorrow. – Pieter Nov 15 '10 at 11:01
  • Hi Tony, tried making this work but to no avail.. In my worksheet, I input =CheckValues1(7,G1); the strings are in column G. My VBA skills are by no means sufficient so I'd appreciate your insights on this: as far as I can see the program goes through all cells in the column and checks whether their value is equal to the current cell. But what happens if this is true? False? Where does the program instruct the function print the array of positions? And what does 'occurances(index)' do? Thank you. ps: I removed the '=' after the '<>' in the code. – Pieter Nov 16 '10 at 02:44
  • 1
    Hi Pieter, I'm sorry but I'm struggling to provide sufficient information. My VBA skills go no further than access, I have never used Excel with VBA. Occurrences(index) basically adds the row number to the occurrences array. I have added the code to print to a message box to show your how. – Tony Day Nov 16 '10 at 09:51
  • No worries Tony, your help is greatly appreciated. - upvoted your answer & comment. – Pieter Nov 16 '10 at 10:42
1

Asuming that all your strings are in one column, you can add a second column with their position (line number) and do a pivot table across the strings displaying the counts.

In order to get the position(s) of a string you are interested in, you use the pivot table's drill-down function (double click on the count next to a string) which will create a new sheet with all detail records - and the position will be displayed

Hope that helps

Good lock

EDIT after comments exchanged:

I would go for a solution that scans your data only 1 time and not recursively, copying values to a second sheet:

for each string in sourcetable
   if found in targettable
      increase targettable.counter by 1 (remark: in column_2)
   else
      put sourcetable.string at end of targettable
      put "1" in targettable.counter (remark: occurence = 1 in column_2)
   endif
   put sourcetable.index into targettable.column(counter+2)
next

so far the metacode .... do you need more help to actually code this in VBA?

EDIT 2

OK .... made a quick & dirty one ....

Sub CountString()
Dim S As Range, T As Range, Idx As Long, Jdx As Long

    Set S = Worksheets("Sheet1").[A2] ' first row is header
    Set T = Worksheets("Sheet2").[A2] ' first row is header
    Idx = 1

    Do While S(Idx, 1) <> ""
        Jdx = FindInRange(T, S(Idx, 1))
        If T(Jdx, 1) = "" Then
            T(Jdx, 1) = S(Idx, 1)
            T(Jdx, 2) = 1
            T(Jdx, 3) = Idx
        Else
            T(Jdx, 2) = T(Jdx, 2) + 1
            T(Jdx, T(Jdx, 2) + 2) = Idx
        End If
        Idx = Idx + 1
    Loop
End Sub

Function FindInRange(R As Range, A As String) As Long
Dim Idx As Long

    Idx = 1
    Do While R(Idx, 1) <> ""
        If R(Idx, 1) = A Then
            Exit Do
        End If
        Idx = Idx + 1
    Loop
    FindInRange = Idx
End Function

tested with 500 words from "Lorem ipsum" - takes below 1 second, output in sheet_2 looks like

String     Count   Position ...                                                        
Lorem        1        1                                                        
ipsum        6        2        45        65       232       323       462                
dolor        5        3        42       214       321       335                        
sit          6        4        79       148       249       295       415                
amet         6        5        80       149       250       296       416                
consectetur  8        6       117       288       298       396       457       473        486
adipiscing   3        7       180       402                                        

Hope that helps

MikeD
  • 8,861
  • 2
  • 28
  • 50
  • Hi Mike, thanks for your suggestion but my list has thousands of entries.. I'm really looking for a way to do this automatically rather than manually. – Pieter Nov 16 '10 at 03:41
  • OK ... so if a pivot that you create one time and then refresh (by one key press) doesn't do the job, how do you want to have it done? you enter a string in an input box and want a result of the form "found ### times", or you want a list string/count .... can you elaborate a bit? – MikeD Nov 16 '10 at 09:01
  • Let's just say that column A consists of a couple of thousand strings, which may or may not be unique to that column. Their position in the column is to be preserved, however, so sorting is not an option. Column B shows the amount of times the particular string in that row occurs in column A. My ideal solution would, given the parameters in A and B, come up with a list in columns C to n, where each element in that list equals the row numbers of all strings equal to the one in A. Hope this is clear.. sorry for the formatting, commenting does not allow for paragraphs.. – Pieter Nov 16 '10 at 09:54
  • clear now ... thinking ... the limit here is that if string X occurs more than 254 times, Excel column limits will not allow to capture all occurences of that string ... but that's maybe a minor detail ... will edit my reply after thinking ;-) – MikeD Nov 16 '10 at 10:32
  • Did a quick check and the maximum amount of times that any string occurs is 32 times. Thanks for your help :) – Pieter Nov 16 '10 at 10:40
  • Brilliant! Works, and fast. Thanks a lot Mike. – Pieter Nov 17 '10 at 03:44