1

I am trying to create "my first" formula-function, but can't get it to work.
It returns an error.

First I tested the function as a standard module and rendered the output in the debug console to test the outcome. All worked well.

However I can't get the same module to work as a function

Below the function: It is called in this way =TEST(val;rng) | resulting in #value!

Function TEST(val As String, rng As Range) As String
    Dim a, b As String
    Dim cel, itm, tst, s As Range
    Dim row, l, i As Integer
    '-----------------------------------------------------
    a = ""
    b = ""
    val = "ROX.RFL.avi.Rmd.ice"
    Set rng = Range(Sheets("DGR").Cells(3, 3), Cells(3, 34))
    '-----------------------------------------------------
    For Each cel In rng.Cells
        If InStr(UCase(val), UCase(cel)) Then
            a = a & UCase(cel) & ","
            row = Sheets("DGR").Cells(Rows.Count, cel.Column).End(xlUp).row
            If row <> 3 Then
                For Each itm In Range(Sheets("DGR").Cells(4, cel.Column), Cells(row, cel.Column))
                    b = b & UCase(itm) & ","
                Next itm
            End If
        End If
    Next cel
    '-----------------------------------------------------
    For Each tst In Split(a, ",")
        If InStr(b, tst) > 0 Then TEST = tst
    Next tst
End Function

Below the tested function as a module: (this worked properly)

Sub MKDGR()
    Dim val, a, b As String
    Dim rng, cel, itm, tst, s As Range
    Dim row, l, i As Integer
    '-----------------------------------------------------
    a = ""
    b = ""
    val = "ROX.RFL.avi.Rmd.ice"
    Set rng = Range(Sheets("DGR").Cells(3, 3), Cells(3, 34))
    '-----------------------------------------------------
    For Each cel In rng.Cells
        If InStr(UCase(val), UCase(cel)) Then
            a = a & UCase(cel) & ","
            row = Sheets("DGR").Cells(Rows.Count, cel.Column).End(xlUp).row
            If row <> 3 Then
                For Each itm In Range(Sheets("DGR").Cells(4, cel.Column), Cells(row, cel.Column))
                    b = b & UCase(itm) & ","
                Next itm
            End If
        End If
    Next cel
    '-----------------------------------------------------
    For Each tst In Split(a, ",")
        If InStr(b, tst) > 0 Then Debug.Print tst
    Next tst
End Sub
Pᴇʜ
  • 56,719
  • 10
  • 49
  • 73
MK01111000
  • 770
  • 2
  • 9
  • 16
  • 2
    First, when you have a `Dim` statement as: `Dim a, b As String`, you are basically declaring `b` as `string` but `a` as a `variant`. You have to declare each individually (i.e. `Dim a As String, b As String`). Second, A `Sub` doesn't return a value, only `Function` does. In your module, you are setting your UDF as a `Sub`.. which will never return a value. Those are your 2 major issues. Fix those and report your code here and we can advice further – Zac Feb 15 '19 at 09:38
  • 1
    I would start at [qualifying all your `Range` and `Cells` calls](https://stackoverflow.com/q/17733541/11683). – GSerg Feb 15 '19 at 09:39
  • @Zac, Thank you for your explanation. – MK01111000 Feb 15 '19 at 09:57

1 Answers1

4

There are lot of things which will or can go wrong. Let's address them one by one

  1. Val is a reservd word in VBA. Avoid using that. Use something which is not a reserved word. For example inptS
  2. Unlike Vb.Net, in VBA when you declare variables you have to explicitly declare each of them. Otherwise they are declared as Variant
  3. When you are dealing with rows in Excel, use Long instead of Integer else you may get an Overflow Error
  4. Use Error handling. This way the code will not break down and gracefully complete the execution and also let you know the problem if any.
  5. Use Line Numbers in your code so that you can use Erl to get the line causing the error. Get MZTools Ver 3. It is free.
  6. Fully qualify your objects. For example, If you don't qualify your range objects then the range object will refer to the Activesheet and the Activesheet may not be the sheet you think it is.

Now let's incorporate all the above in your code.

Code

Option Explicit

Function TEST(inptS As String, rng As Range) As String
          Dim a As String, b As String
          Dim cel As Range, itm As Range
          Dim tst As Variant
          Dim row As Long, l As Long, i As Long

          '~~> Use error handling
10            On Error GoTo Whoa

          '~~> Fully qualify your range objects
20            With Sheets("DGR")
30                For Each cel In rng.Cells
40                    If InStr(UCase(inptS), UCase(cel)) Then
50                        a = a & UCase(cel) & ","
60                        row = .Cells(.Rows.Count, cel.Column).End(xlUp).row

70                        If row <> 3 Then
80                            For Each itm In .Range(.Cells(4, cel.Column), .Cells(row, cel.Column))
90                                b = b & UCase(itm) & ","
100                           Next itm
110                       End If
120                   End If
130               Next cel
140           End With

150           For Each tst In Split(a, ",")
160               If InStr(b, tst) > 0 Then
170                   If TEST = "" Then
180                       TEST = tst
190                   Else
200                       TEST = TEST & vbNewLine & tst
210                   End If
220               End If
230           Next tst

240           Exit Function
Whoa:
250           TEST = "Unable to calculate value (" & _
          Err.Description & _
          ", Error in line " & Erl & ")"
End Function
Siddharth Rout
  • 147,039
  • 17
  • 206
  • 250
  • your code results in "Object Required". The following line should be ignored, like you said it is already a parameter `'inptS = "ROX.RFL.avi.Rmd.ice" '??? Why this? It is already a parameter` – MK01111000 Feb 15 '19 at 09:54
  • ps. The following line should become a user defined range `Set rng = .Range(.Cells(3, 3), .Cells(3, 34))` – MK01111000 Feb 15 '19 at 09:55
  • `your code results in "Object Required".` Step through the code and tell me which line gives you the error. Also i updated the code above. Copy it with the line numbers. Paste here the message that you get in the cell. – Siddharth Rout Feb 15 '19 at 10:00
  • Also do explain the role of `Sheets("DGR")` in the entire code? What exactly are you trying to achieve? – Siddharth Rout Feb 15 '19 at 10:02
  • Now I get the following error `Unable to calculate value (Object required, Error in line 0)` showing an error on line 0 – MK01111000 Feb 15 '19 at 10:07
  • 1
    Did you copy the code with the line numbers? I added those numbers for a reason ;) – Siddharth Rout Feb 15 '19 at 10:12
  • I believe you will get this after you put the numbers `Unable to calculate value (Object required, Error in line 150)` – Siddharth Rout Feb 15 '19 at 10:14
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/188470/discussion-between-siddharth-rout-and-mk01111000). – Siddharth Rout Feb 15 '19 at 10:16
  • @Vityata: Added the link for you in case you want it ;) – Siddharth Rout Feb 15 '19 at 10:54
  • 1
    @SiddharthRout - thanks, I am using version 8. Still, the 3. one is quite old I guess and they have removed the link from their site for a good reason. VBA developers should make money as well ;) – Vityata Feb 15 '19 at 10:57