简体   繁体   中英

VBA function to iterate through cells

I'm developing a VBA function for Excel. It will take input parameters of an integer (we'll call it ref_num), and a range. It will search through the range, looking for ref_num as the value of a cell. When it finds ref_num (which may or may not be present), it will go to the second row of the column that ref_num is in, and store that value as a string in the return variable (the value is a date, and 1-31 each have their own column). Every time ref_num is found in a column, the value in the second row will be appended to the return string.

Slightly more concrete example: ref_num is 2, and 2 occurs in columns A, B, and C. The values in A2, B2, and C2 are 1, 2, and 3, respectively, so the function must return "1, 2, 3".

This is my pseudo-code, but I need some help filling in the blanks... Note that this currently does not work, and that the algorithm is very much brute force. I just want to get something working.

Function GetDays(ref_num As Integer, range_o_cells As Range) As String
    Dim num_dates As Integer
    Dim day As String
    Set num_dates = 0

    'iterate through all the cells and see if the value is ref_num
    For Each c In range_o_cells

        If c.Value = ref_num Then
            'get the cell's column, then reference the second row and get the value. Note that this will be an int that we need to convert to a string
            'I seriously doubt the following line will work
            day = CStr(Cells(c.Column, 2).Value)

            'Once you have the value, append it to the return value
            If num_dates = 0 Then
                'This is the first value we've found, so we don't need to prepend a comma
                GetDays = day
                num_dates = 1
            Else
                'This is probably not valid VBA syntax...
                GetDays = GetDays & ", " & day
         End If

    Next c
End Function

Note that currently, if I call it like this: =GetDays(AG39, $P$3:$W$500) where AG39 is the cell containing ref_num, I get #NUM!

There are multiple issues in your code

  1. You don't use Set for integers
  2. Missing an End If
  3. As you suspected, your indexing into Cells is iffy
  4. You should build your return string into day and assign it to the function in one place
  5. Looping over a range is Slow
  6. You should declare all variables

Better approach is to move the data to a variant array, and loop that. Also include the header data in the range passed to range_o_cells (I'm guessing thats $P$1:$W$500 )

Here's your code refactored

Function GetDays( _
  ref_num As Long, _
  range_o_cells As Range, _
  Optional Sep As String = ", ") As String

    Dim dat As Variant
    Dim rw As Long, col As Long
    Dim day As String

    dat = range_o_cells.Value

    For col = 1 To UBound(dat, 2)
    For rw = 3 To UBound(dat, 1)
        If dat(rw, col) = ref_num Then
            day = day & dat(2, col) & Sep
        End If
    Next rw, col
    If Len(day) > 0 Then day = Left$(day, Len(day) - Len(Sep))
    GetDays = day
End Function

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM