从VBA中的子例程调用自定义函数时出错

时间:2015-08-14 21:16:31

标签: vba function excel-vba excel

我有一个Excel的VBA脚本,它有一个子功能和一个自定义功能。当我尝试从sub调用函数时,退出函数时出错。

  

运行时错误'424':需要对象

我尝试了几种不同的东西,但没有运气。为了使这项工作正常,我需要做些什么?谢谢!

Public Sub FindValues()
    Dim sh As Worksheet
    Dim rn As Range
    Dim RowCount As Integer
    Dim currRow As Integer
    Dim currValue As String
    Dim firstRow As Boolean

    Set sh = Worksheets("MetaData")

    'for each row in Worksheets("MetaData")
    For Each rn In sh.Rows
        currRow = rn.Row

        If (currRow = 1 And firstRow = False) Then
            'Set flag
            firstRow = True
        ElseIf sh.Cells(rn.Row, 1).Value = "" Then
            Exit For
        Else
            'get value from column A
            currValue = sh.Cells(currRow, "A").Value

            'search for value in column B & C in item relations spreadsheet
            Dim FoundVal As Variant
            Set FoundVal = FindItemRelations(currValue)

            MsgBox ("String value found: " & vFound.Value & ", Column: " & vFound.Column)
            MsgBox (FoundVal)
            RowCount = RowCount + 1
        End If        
    Next rn
End Sub

Public Function FindItemRelations(cv As String) As Variant
    Dim found As Boolean
    found = False

    With Worksheets("ItemRelations")

        Set rFoundB = .Columns("B").Find(What:=cv)

        If Not rFoundB Is Nothing Then
            'if value found in B, set value and exit
            FindItemRelations = rFoundB
            found = True

        Else
            'search column C for value
            Set rFoundC = .Columns("C").Find(What:=cv)

            'if value found in C, set value and exit
            FindItemRelations = rFoundC
            found = True
        End If

        If found = False Then
            FindItemRelations = Nothing
            'Exit Function
        End If       
    End With
End Function

2 个答案:

答案 0 :(得分:0)

我已经更改了几个位以从FindItemRelations返回一个Range并适当地使用Set。希望这就是你所需要的。

Public Sub FindValues()
    Dim sh As Worksheet
    Dim rn As Range
    Dim RowCount As Integer
    Dim currRow As Integer
    Dim currValue As String
    Dim firstRow As Boolean

    Set sh = Worksheets("MetaData")

    'for each row in Worksheets("MetaData")
    For Each rn In sh.Rows
        currRow = rn.Row

        If (currRow = 1 And firstRow = False) Then
            'Set flag
            firstRow = True
        ElseIf sh.Cells(rn.Row, 1).Value = "" Then
            Exit For
        Else
            'get value from column A
            currValue = sh.Cells(currRow, "A").Value

            'search for value in column B & C in item relations spreadsheet
            Dim FoundVal As Variant
            Set FoundVal = FindItemRelations(currValue)

            If Not FoundVal Is Nothing Then
                MsgBox ("String value found: " & FoundVal.Value & ", Column: " & FoundVal.Column)
            End If
            'MsgBox (FoundVal)
            RowCount = RowCount + 1
        End If
    Next rn
End Sub

Public Function FindItemRelations(cv As String) As Range
    Dim found As Boolean
    found = False
    Dim rFoundB, rFoundC As Range


    With Worksheets("ItemRelations")

        Set rFoundB = .Columns("B").Find(What:=cv)

        If Not rFoundB Is Nothing Then
            'if value found in B, set value and exit
            Set FindItemRelations = rFoundB
            found = True

        Else
            'search column C for value
            Set rFoundC = .Columns("C").Find(What:=cv)

            'if value found in C, set value and exit
            Set FindItemRelations = rFoundC
            found = True
        End If

        If found = False Then
            FindItemRelations = Nothing
            'Exit Function
        End If
    End With
End Function

答案 1 :(得分:0)

似乎你的else语句总是将找到的var设置为true,即使找不到rFoundB和rFoundC:

bar

这应该可以解决问题:

WITH sTotal AS (
SELECT    AgendaList.AID, AgendaList.Item, COUNT( SpeakerList.SPID) as SpeakerTotal
FROM      AgendaList 
LEFT JOIN SpeakerLIST ON AgendaList.AID = SpeakerList.AID
GROUP BY  AgendaList.AID, AgendaList.Item
),
sActive AS (
SELECT    AgendaList.AID, AgendaList.Item, COUNT( SpeakerList.SPID) as SpeakerActive
FROM      AgendaList 
LEFT JOIN SpeakerLIST ON AgendaList.AID = SpeakerList.AID
WHERE SpeakerLIST.Spoken = 0
GROUP BY  AgendaList.AID, AgendaList.Item
)
SELECT sTotal.*, sActive.SpeakerActive
FROM sTotal left join
     sActive on sTotal.AID = sActive.AID