1

我在 vb 中编写的函数有问题。该工具会打开一个 Excel 工作表,并在该工作表中搜索两个值。

Excel 工作表的结构如下:

表格中的示例图片

我编写的函数,查看同一行中“M”列和“N”列中的值是否与 Creterium 1 和 2 相同。如果是这样,它将返回“O”列中的值"

我的代码如下所示:

    Function twoStrSearch(ByVal criteria1 As String, ByVal criteria2 As String, ByVal strPrimarySearchColumn As String, _
                      ByVal Offset_Krit2 As Integer, ByVal Offset_result As Integer, _
                      ByVal objWorksheet As Microsoft.Office.Interop.Excel.Worksheet) As VariantType
    '********************************************************************************************
    'Function for Searching an Excel Sheet.
    'If the Sheet Contains the two Criterias in the same row it will return the search Value
    '********************************************************************************************
    'Parameter:                 Explanation:         
    'criteria1                  The first comparison value
    'criteria2                  The second comparison value
    'strPrimarySearchColumn     The Name of the Row where the first comparsion value is
    'Offset_Krit2               The Offset Value where the second comparison value is
    'Offset_Ergebnis            The Offset Value where the Search result is what will be returned
    'objWorksheet               The object of the Excel Sheet that should be searched in
    '********************************************************************************************

    Dim strAddress As String
    Dim area As Microsoft.Office.Interop.Excel.Range
    Dim range As Microsoft.Office.Interop.Excel.Range
    'Get's the letter of the Column
    strAddress = objWorksheet.Cells.Find(What:=strPrimarySearchColumn).Address
    strAddress = Mid(strAddress, 2, 1)
    area = objWorksheet.Columns(strAddress & ":" & strAddress) 'Range over the Column
    For Each range In area
        'If both criteria in the same Row are True then get the result
        If range.Value2.ToString = criteria1 And range.Offset(0, Offset_Krit2).Value = criteria2 Then
            twoStrSearch = range.Offset(0, Offset_result).Value
            Exit Function
        End If
    Next
    twoStrSearch = "--" 'if nothing found result is "--"
End Function

如果他将单元格值与 Criteria1 和 2 进行比较,则 Eroor 发生在 For Each 循环中。

我现在坚持了一段时间,我想也许你们中的一些人有一个想法!

4

2 回答 2

2

For Each Loop两个主要问题:它遍历列中的所有范围,而没有指定您真正想要的单元格(一列是一个范围,一堆单元格是一个范围等),默认情况下,它假定您想要遍历整个列并因此.Value2触发错误(它不能应用于许多单元格)。此外,您在使用.ToString时未确认给定单元格中的值不为空(不是Nothing)。更正的代码:

For Each range In area.Cells
    'If both criteria in the same Row are True then get the result
    If (range.Value2 IsNot Nothing) Then
        If range.Value2.ToString = criteria1 And range.Offset(0, Offset_Krit2).Value = criteria2 Then
            twoStrSearch = range.Offset(0, Offset_result).Value
            Exit Function
        End If
    End If
Next

您的代码还有其他一些问题,例如:

strAddress = objWorksheet.Cells.Find(What:=strPrimarySearchColumn).Address

如果找不到预期的内容,此行将触发错误。更合适的方法是:

strAddress = ""
Dim tempRange As Microsoft.Office.Interop.Excel.Range = objWorksheet.Cells.Find(What:=strPrimarySearchColumn)
If (tempRange IsNot Nothing) Then
    strAddress = tempRange.Address
End If

您可以直接从范围 ( ) 中获取行/列tempRange,而不是使用当前方法。请参阅上面 Siddharth Rout 的评论。

于 2013-10-16T08:55:54.263 回答
2

不为积分(仅用于解释目的)

概括。

  1. 如果搜索文本在说 Col 中,您提取地址的方式会给您错误AA1
  2. 您不需要地址来构建您的范围。您可以使用列号。
  3. 没有必要循环遍历所有单元格(在 xl2007+ 的情况下为 1048576)通过在搜索列中找到最后一行来构建相关范围

假设您的数据如下所示

在此处输入图像描述

代码:(在 VS 2010 Ultimate + Office 2010 Prof. 中试用和测试)

尝试这个。我已经评论了代码,所以让我知道是否有任何不合理的地方。

Imports Excel = Microsoft.Office.Interop.Excel

Public Class Form1
    '~~> Define your Excel Objects
    Dim xlApp As New Excel.Application
    Dim xlWorkBook As Excel.Workbook
    Dim objWorksheet As Excel.Worksheet

    Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
        '~~> Open relevant file
        xlWorkBook = xlApp.Workbooks.Open("C:\MyFile.xlsx")

        '~~> Display Excel
        xlApp.Visible = True

        '~~> Set your first worksheet
        objWorksheet = xlWorkBook.Sheets(1)

        Dim Ret = twoStrSearch("1", "text-x", "TextNumber", -1, 1)

        MsgBox (Ret)

        '~~> Close the File
        xlWorkBook.Close (False)

        '~~> Quit the Excel Application
        xlApp.Quit()

        '~~> Clean Up
        releaseObject (objWorksheet)
        releaseObject (xlWorkBook)
        releaseObject (xlApp)
    End Sub

    Function twoStrSearch(ByVal criteria1 As String, ByVal criteria2 As String, ByVal strPrimarySearchColumn As String,
    ByVal Offset_Krit2 As Integer, ByVal Offset_result As Integer) As String
        Dim area As Excel.Range = Nothing
        Dim range As Excel.Range = Nothing
        Dim aCell As Excel.Range = Nothing
        Dim ColNo As Integer, lRow As Integer

        '~~> Find which column as the search text
        aCell = objWorksheet.Cells.Find(What:=strPrimarySearchColumn)

        '~~> Set it to "--" in case nothing is found
        twoStrSearch = "--"

        '~~> if found
        If aCell IsNot Nothing Then
            '~~> Get the column number
            ColNo = aCell.Column

            '~~> Get last row of that column
            lRow = objWorksheet.Cells(objWorksheet.Rows.Count, ColNo).End(Excel.XlDirection.xlUp).Row

            '~~> Construct your range from row 2 onwards. Row1 has headers
            area = objWorksheet.range(objWorksheet.Cells(2, ColNo), objWorksheet.Cells(lRow, ColNo))

            For Each range In area
                'If both criteria in the same Row are True then get the result
                If range.Value2.ToString = criteria1 And range.Offset(, Offset_Krit2).Value = criteria2 Then
                    twoStrSearch = range.Offset(, Offset_result).Value
                    Exit For
                End If
            Next
        End If

        releaseObject (area)
        releaseObject (range)
        releaseObject (aCell)

        Return twoStrSearch
    End Function

    '~~> Release the objects
    Private Sub releaseObject(ByVal obj As Object)
        Try
            System.Runtime.InteropServices.Marshal.ReleaseComObject (obj)
            obj = Nothing
        Catch ex As Exception
            obj = Nothing
        Finally
            GC.Collect()
        End Try
    End Sub
End Class

输出:

在此处输入图像描述

于 2013-10-16T09:49:37.413 回答