【问题标题】:Select sheet using a variable使用变量选择工作表
【发布时间】:2020-12-18 14:19:11
【问题描述】:

我正在尝试根据值选择特定工作表。我有客户列表设置,旁边有该客户的工作表名称。从列表中查找工作表的名称是有效的,但是当我尝试设置工作表变量时,它会出错。这是我正在使用的代码:

Public Sub SeparateClients()
Dim MainL As Range: Set MainL = ML.Range("A2", ML.Range("A2").End(xlDown))
Dim ClientsF As Range
Dim cClientS As String
Dim cClient As Worksheet
Dim cClientNR As Range

For Each MainL In MainL.Cells
    If MainL.Value = "" Then Exit For
    Set ClientsF = CL.Range("A:A")
    If ClientsF.Find(MainL.Offset(0, 1).Value, , , xlWhole) Is Nothing Then
        MsgBox "Client not found: " & MainL.Offset(0, 1).Value, vbOKOnly, "ERROR: Client not found"
    Else
        cClientS = ClientsF.Find(MainL.Offset(0, 1).Value, , , xlWhole).Offset(0, 1).Value
        Set cClient = Sheets(cClientS)
        Set cClientNR = cClient.Range("A1").End(xlDown).Offset(1, 0)
        
        With cClientNR
            .Value = MainL.Offset(0, 3).Value
            .Offset(0, 1).Value = MainL.Offset(0, 5).Value
            .Offset(0, 2).Value = Mid(MainL.Offset(0, 6).Text, 1, 10)
            .Offset(0, 3).Value = MainL.Offset(0, 8).Value
            .Offset(0, 4).Value = MainL.Offset(0, 15).Value
            .Offset(0, 5).Value = MainL.Offset(0, 17).Value
            .Offset(0, 6).Value = MainL.Offset(0, 23).Value
            .Offset(0, 7).Value = MainL.Offset(0, 28).Value
        End With
    End If
Next MainL

End Sub

当它到达set cClient = sheets(cClientS) 时,它不会为工作表变量设置工作表。我已经在 Google 上搜索了几个小时,但我似乎无法弄清楚我做错了什么。

【问题讨论】:

  • 当行执行给您带来麻烦时,cClientS 的值是多少?
  • cClientS = ClientsF.Find(MainL.Offset(0, 1).Value, , , xlWhole).Offset(0, 1).Value 这样的构造不受欢迎,因为它们变化无常。如果找不到cClientSSet cClient = Sheets(cClientS) 将无法成功。在那里插入另一个测试。顺便说一句,避免像MainL.Offset(0, 1).Value 这样的语法。更好的是,在寻址单元格时使用语法来寻址单元格:您正在谈论ML.Cells(MainL.Row, "B")ML.Cells(MainL.Row, 2).Value。将此应用于 .Offset(0, 7).Value = MainL.Offset(0, 28).Value,您将看到透明度的差异。

标签: excel vba


【解决方案1】:

您可以尝试以下方法吗:

debug.print(cClientS) ' < -- as requested by Excel Hero, let us know
set cClient = thisworkbook.sheets(cClientS) ' < -

【讨论】:

    【解决方案2】:

    小贴士

    1. Optimizing the VBA Code and improve the performance
    2. 无论何时使用.Find,始终检查.Find 是否成功。您可能想阅读.Find and .FindNext
    3. 避免使用xlDown 来查找最后一行。您可能想阅读Error in finding last used cell in Excel with VBA
    4. For Each MainL In MainL.Cells 小心使用你的物品,否则你最终会迷惑自己。就像我在浏览您的代码时感到困惑一样。
    5. 在设置工作表名称时,请检查它是否为有效名称,否则您的代码会出错。
    6. 仅当您不确定单元格地址时才使用.Offset。 (只是我的意见。如果您仍然想使用它,请随意使用它。)。正如@Variatus 提到的,如果您知道范围的地址,请使用它。代码将更容易阅读和理解。

    这是你正在尝试的吗? (未经测试

    我已经对下面的代码进行了注释,但如果您仍然遇到问题,请直接询问。

    代码

    Option Explicit
    
    Public Sub SeparateClients()
        Dim ML As Worksheet
        Dim CL As Worksheet
        
        '~~> Change these to relevant sheets
        Set ML = Sheet1
        Set CL = Sheet2
        
        '~~> Search range
        Dim ClientsF As Range
        Set ClientsF = CL.Range("A:A")
        
        Dim lRow As Long, i As Long
        Dim aCell As Range
        Dim cClientS As String
        Dim cClient As Worksheet
        
        With ML
            '~~> Find last row in column A of ML sheet
            lRow = .Range("A" & .Rows.Count).End(xlUp).Row
            
            '~~> Loop through the range
            For i = 2 To lRow
                Set aCell = ClientsF.Find(What:=.Range("B" & i).Value2, LookIn:=xlFormulas, _
                LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
                MatchCase:=False, SearchFormat:=False)
                 
                If Not aCell Is Nothing Then
                    cClientS = aCell.Value2
                    
                    On Error Resume Next
                    Set cClient = Sheets(cClientS)
                    On Error GoTo 0
                    
                    '~~> Check if we managed to get the sheet object
                    If cClient Is Nothing Then
                        Debug.Print cClientS & " doesn't have a valid sheet name"
                    Else
                        '~~> With the new sheet, find the last empty row to write
                        With cClient
                            lRow = .Range("A" & .Rows.Count).End(xlUp).Row + 1
                            
                            '~~> Write your values
                            .Range("A" & lRow).Value = .Range("D" & i).Value2
                            .Range("B" & lRow).Value = Mid(.Range("E" & i).Value2, 1, 10)
                            
                            '
                            '~~> And so on...
                            '
                        End With
                        
                        '~~> Clear the object for the next loop
                        Set cClient = Nothing
                    End If
                Else
                    Debug.Print "Client not found: " & .Range("B" & i).Value2, vbOKOnly, "ERROR: Client not found"
                End If
            Next i
        End With
    End Sub
    

    【讨论】:

      猜你喜欢
      • 2022-11-29
      • 1970-01-01
      • 2015-10-12
      • 2016-05-26
      • 1970-01-01
      • 1970-01-01
      • 2020-07-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多