VBA在某些条件不满足时切换到下一张工作表

huangapple go评论67阅读模式
英文:

VBA to move to next sheet if certain condition is not met

问题

我有一段正在运行的代码。 该代码从用户那里获取输入字符串,然后在所有工作表中查找该字符串。 找到后,执行其他与该字符串相关的任务(如复制必要的关联数据),然后将数据输出到一个空白工作表上。 问题是有些工作表中没有用户定义的字符串。 在这种情况下,它会失败并显示错误(自然而然地无法找到所要查找的内容)。 现在我的问题是,如果VBA代码无法找到用户输入的字符串,是否有办法跳过该工作表并转到下一个工作表? 我尝试使用if语句,但if语句内部的next ws不起作用。

Sub Get_w_Data()

Dim ws As Worksheet
Dim shtName As String
Dim exists As Boolean
Dim i As Integer
Dim wName As String
Dim mydate As Date

Dim i_DateCounter As Integer
Dim DataColCounter As Integer
Dim wData(1 To 1, 1 To 11) As Variant
Dim Target As Range
Dim DataToDelete As Range

Application.ScreenUpdating = True

shtName = "Test Sheet"
wName = Sheets(shtName).Range("C1").Value

    For i = 1 To Worksheets.Count
        If Worksheets(i).Name = shtName Then
            exists = True
        End If
    Next i

    If Not exists Then
        ThisWorkbook.Worksheets.Add(After:=ThisWorkbook.Sheets(Sheets.Count)).Name = shtName
    End If
      
'===========================================================================================
' ************* 从先前选择的wName中删除数据
'===========================================================================================

    With Worksheets("Test Sheet")

        Set DataToDelete = .Range("B6:K6", .Range("B" & .Rows.Count).End(xlUp))

        DataToDelete.ClearContents

    End With
                 
'********************************************************************************************
    For Each ws In ThisWorkbook.Worksheets
    
     ws.Select
     
        If ws.Name = shtName Then
            Exit Sub
        End If
        
  Range("B25:U64").Find(What:=wName, MatchCase:=True, LookAt:=xlWhole).Select
'当wName不存在于任何工作表中时,代码会失败。 如何设置代码以使其在wName不存在时跳过到下一个工作表?

'''执行一些任务的一些代码            

    Next ws
           
          
    Application.ScreenUpdating = False
    
End Sub
英文:

I have an up a running code. The code takes an input string from the user, finds it in all of the sheets. When found, performs other tasks for that particular string (like copying necessary associated data) and then spits out that data onto a blank sheet. The issue is that there are sheets where user defined string is not present. In such a case, it fails and gives error (naturally it is unable to find what its been asked to find). Now my question is, is there a way to skip the sheet and move to the next sheet incase if VBA code is unable to find user input string? I tried with if statement, but within if, next ws doesn't work.

Sub Get_w_Data()

Dim ws As Worksheet
Dim shtName As String
Dim exists As Boolean
Dim i As Integer
Dim wName As String
Dim mydate As Date

Dim i_DateCounter As Integer
Dim DataColCounter As Integer
Dim wData(1 To 1, 1 To 11) As Variant
Dim Target As Range
Dim DataToDelete As Range

Application.ScreenUpdating = True

shtName = "Test Sheet"
wName = Sheets(shtName).Range("C1").Value

    For i = 1 To Worksheets.Count
        If Worksheets(i).Name = shtName Then
            exists = True
        End If
    Next i

    If Not exists Then
        ThisWorkbook.Worksheets.Add(After:=ThisWorkbook.Sheets(Sheets.Count)).Name = shtName
    End If
      
'===========================================================================================
' ************* Deleting data from previously selected wName
'===========================================================================================

    With Worksheets("Test Sheet")

        Set DataToDelete = .Range("B6:K6", .Range("B" & .Rows.Count).End(xlUp))

        DataToDelete.ClearContents


    End With
                 
'********************************************************************************************
    For Each ws In ThisWorkbook.Worksheets
    
     ws.Select
     
        If ws.Name = shtName Then
            Exit Sub
        End If
        
        
  Range("B25:U64").Find(What:=wName, MatchCase:=True, LookAt:=xlWhole).Select
' when wName doesn't exist in any of the sheets, code fails. How can I setup the code in a way that when wName doesn't exist, it skips to next ws? 

''' some code to perform some task            
    
    Next ws
           
          
    Application.ScreenUpdating = False
    
End Sub

答案1

得分: 1

在循环中跳过工作表当找不到单元格时

Sub Get_w_Data() ' 确定你可以做得更好!

    ' 定义常量。

    Const SRC_RANGE As String = "B25:U64"
    Const DST_SHEET As String = "测试工作表"
    Const DST_FIRST_ROW As String = "B6:K6"

    ' 引用工作簿。

    Dim wb As Workbook: Set wb = ThisWorkbook ' 包含此代码的工作簿

    ' 引用目标工作表。

    ' 尝试引用目标工作表。
    Dim dws As Worksheet
    On Error Resume Next
        Set dws = wb.Sheets(DST_SHEET)
    On Error GoTo 0

    ' 首先关闭它,稍后再打开它!
    Application.ScreenUpdating = False

    ' 检查尝试是否成功。
    If dws Is Nothing Then ' 未引用工作表(未找到)。
        MsgBox "未找到工作表“" & DST_SHEET & "”。", _
            vbCritical
        Exit Sub
        ' 由于稍后会从空工作表中读取单元格C1的值以下代码如何有用
        'Set dws = wb.Sheets.Add(After:=wb.Sheets(wb.Sheets.Count))
        'dws.Name = DST_SHEET
    End If

    ' 在变量中存储搜索字符串。
    ' 可能使用更具体且更可读的内容,如“WorkerName”。
    Dim wName As String: wName = CStr(dws.Range("C1").Value)

    ' 清除目标工作表中的先前数据。

    With dws.Range(DST_FIRST_ROW)
        ' 这会清除工作表的第一行到底行,但无论如何都是有效的。
        .Resize(dws.Rows.Count - .Row + 1).ClearContents
    End With

    ' 循环。简要描述你在其中执行的操作。

    ' 声明在循环中使用的新变量。
    Dim sws As Worksheet, srg As Range, sCell As Range
'    Dim Target As Range
'    Dim wData(1 To 1, 1 To 11) As Variant
'    Dim i As Long
'    Dim mydate As Date
'    Dim i_DateCounter As Long
'    Dim DataColCounter As Long

    For Each sws In wb.Worksheets

        ' 检查是否不是目标工作表。
        If StrComp(sws.Name, DST_SHEET, vbTextCompare) <> 0 Then ' 不是

            Set srg = sws.Range(SRC_RANGE)

            ' 设置参数以查找搜索字符串的最左上出现位置。
            Set sCell = srg.Find(What:=wName, _
                After:=srg.Cells(srg.Cells.CountLarge), LookIn:=xlValues, _
                LookAt:=xlWhole, SearchOrder:=xlByRows, MatchCase:=True)
                ' 你确定要使用“MatchCase”吗,即“Peter<>peter”吗?

            If Not sCell Is Nothing Then

                ' 执行某些任务的一些代码

            'Else ' 未找到等于'wName'的单元格;什么也不做

            End If

        'Else ' 这是目标工作表;什么也不做

        End If

    Next sws

    ' 现在再打开它。
    Application.ScreenUpdating = True

    ' 通知。
    MsgBox "任务已执行。", vbInformation

End Sub
英文:

Skipping a Worksheet in a Loop When No Cell Found

<!-- language: lang-vb -->

Sub Get_w_Data() &#39; surely you can do better!
&#39; Define constants.
Const SRC_RANGE As String = &quot;B25:U64&quot;
Const DST_SHEET As String = &quot;Test Sheet&quot;
Const DST_FIRST_ROW As String = &quot;B6:K6&quot;
&#39; Reference the workbook.
Dim wb As Workbook: Set wb = ThisWorkbook &#39; workbook containing this code
&#39; Reference the destination worksheet.
&#39; Attempt to reference the destination worksheet.
Dim dws As Worksheet
On Error Resume Next
Set dws = wb.Sheets(DST_SHEET)
On Error GoTo 0
&#39; First turn it off, later turn it back on!
Application.ScreenUpdating = False
&#39; Check if the attempt was successful.
If dws Is Nothing Then &#39; worksheet not referenced (not found).
MsgBox &quot;The worksheet &quot;&quot;&quot; &amp; DST_SHEET &amp; &quot;&quot;&quot; was not found.&quot;, _
vbCritical
Exit Sub
&#39; How would the following be useful since you later would be reading
&#39; the value in cell `C1` from an empty worksheet?
&#39;Set dws = wb.Sheets.Add(After:=wb.Sheets(wb.Sheets.Count))
&#39;dws.Name = DST_SHEET
End If
&#39; Store the search string in a variable.
&#39; Maybe use something less generic and more readable like &#39;WorkerName&#39;.
Dim wName As String: wName = CStr(dws.Range(&quot;C1&quot;).Value)
&#39; Clear previous data in the destination worksheet.
With dws.Range(DST_FIRST_ROW)
&#39; This clears from the first row to the bottom row of the worksheet
&#39; but it&#39;s efficient anyway.
.Resize(dws.Rows.Count - .Row + 1).ClearContents
End With
&#39; The loop. Shortly describe what you&#39;re doing in it.
&#39; Declare new variables used in the loop.
Dim sws As Worksheet, srg As Range, sCell As Range
&#39;    Dim Target As Range
&#39;    Dim wData(1 To 1, 1 To 11) As Variant
&#39;    Dim i As Long
&#39;    Dim mydate As Date
&#39;    Dim i_DateCounter As Long
&#39;    Dim DataColCounter As Long
For Each sws In wb.Worksheets
&#39; Check if it&#39;s not the destination worksheet.
If StrComp(sws.Name, DST_SHEET, vbTextCompare) &lt;&gt; 0 Then &#39; it&#39;s not
Set srg = sws.Range(SRC_RANGE)
&#39; The parameters are setup to find the top-most left-most
&#39; occurrence of the search string.
Set sCell = srg.Find(What:=wName, _
After:=srg.Cells(srg.Cells.CountLarge), LookIn:=xlValues, _
LookAt:=xlWhole, SearchOrder:=xlByRows, MatchCase:=True)
&#39; are you sure about &#39;MatchCase&#39; i.e. &#39;Peter &lt;&gt; peter&#39;?
If Not sCell Is Nothing Then
&#39; some code to perform some task
&#39;Else &#39; a cell equal to &#39;wName&#39; was not found; do nothing
End If
&#39;Else &#39; it&#39;s the destination worksheet; do nothing
End If
Next sws
&#39; Now turn it back on.
Application.ScreenUpdating = True
&#39; Inform.
MsgBox &quot;Task performed.&quot;, vbInformation
End Sub

答案2

得分: 0

你可以使用以下代码中的try-concept:

Private Function tryFindRangeInSheet(rgToSearchIn As Range, strFindText As String, _
ByRef rgFound As Range) As Boolean
On Error Resume Next
Set rgFound = rgToSearchIn.Find(What:=strFindText, MatchCase:=True, LookAt:=xlWhole)
If Not rgFound Is Nothing Then tryFindRangeInSheet = True
On Error GoTo 0
End Function

这样,你可以轻松地在主程序中使用该函数:

Public Sub get_w_Data()
Dim wName As String
Dim rgToSearchIn As Range, rgFound As Range
Dim ws As Worksheet
For Each ws In ThisWorkbook.Worksheets
Set rgToSearchIn = ws.Range("B25:U64")
If tryFindRangeInSheet(rgToSearchIn, wName, rgFound) = True Then
'对rgFound进行需要的操作
End If
Next
End Sub
英文:

You can use the try-concept:

Private Function tryFindRangeInSheet(rgToSearchIn As Range, strFindText As String, _
ByRef rgFound As Range) As Boolean
On Error Resume Next
Set rgFound = rgToSearchIn.Find(What:=strFindText, MatchCase:=True, LookAt:=xlWhole)
If Not rgFound Is Nothing Then tryFindRangeInSheet = True
On Error GoTo 0
End Function

Like this you can easily use the function within your main routine:

Public Sub get_w_Data()
Dim wName As String
Dim rgToSearchIn As Range, rgFound As Range
Dim ws As Worksheet
For Each ws In ThisWorkbook.Worksheets
Set rgToSearchIn = ws.Range(&quot;B25:U64&quot;)
If tryFindRangeInSheet(rgToSearchIn, wName, rgFound) = True Then
&#39;do what you need with rgFound
End If
Next
End Sub

huangapple
  • 本文由 发表于 2023年6月26日 13:03:08
  • 转载请务必保留本文链接:https://go.coder-hub.com/76553634.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定