【问题标题】:Change variable result each time used in sub vba每次在 sub vba 中使用时更改变量结果
【发布时间】:2021-02-06 12:39:02
【问题描述】:

我有代码可以将结果从一个工作表排序并复制到另一个工作表。有时我需要将复制的范围粘贴到选定工作表上的下一个空白单元格,为此我需要使用 ActiveSheet.Cells(Rows.Count, 1).End(xlUp).Row。

        Worksheets("Wallets").AutoFilterMode = False

        Worksheets("Wallets").Range("$A$1:$J10000").AutoFilter Field:=5, Criteria1:="*TRANSFER*"
        Worksheets("Wallets").Range("$A$1:$J10000").AutoFilter Field:=7, Criteria1:=">0"
                 Worksheets("Wallets").Range("B2:I" & Worksheets("Wallets").Cells(Rows.Count, 1).End(xlUp).Row).Copy
                 Worksheets("Transfers").Cells(Worksheets("Transfers").Cells(Rows.Count, 1).End(xlUp).Row, 1).Offset(1, 0).PasteSpecial Paste:=xlPasteValue

        Worksheets("Wallets").AutoFilterMode = False

        Worksheets("Wallets").Range("$A$1:$J10000").AutoFilter Field:=5, Criteria1:="*EXCHANGE*"
        Worksheets("Wallets").Range("$A$1:$J10000").AutoFilter Field:=7, Criteria1:=">0"
                 Worksheets("Wallets").Range("B2:I" & Worksheets("Wallets").Cells(Rows.Count, 1).End(xlUp).Row).Copy
                 Worksheets("Transfers").Cells(Worksheets("Transfers").Cells(Rows.Count, 1).End(xlUp).Row, 1).Offset(1, 0)..PasteSpecial Paste:=xlPasteValues

我正在考虑更改代码,以便如果我需要为某些工作表使用其他列,我可以更轻松地替换这部分。有没有办法让变量每次在 sub 中使用时都重新计算?下面的部分代码只是保存第一个结果并使用它,但我需要为当前使用的每个工作表更新行数(最好不使用 Worksheets.Select)。

Sub Sort_Wallets()
Dim x As Long

       x = ActiveSheet.Cells(Rows.Count, 1).End(xlUp).Row
    

        Worksheets("Wallets").AutoFilterMode = False
        Worksheets("Wallets").Select
        Worksheets("Wallets").Range("$A$1:$J10000").AutoFilter Field:=5, Criteria1:="*TRANSFER*"
        Worksheets("Wallets").Range("$A$1:$J10000").AutoFilter Field:=7, Criteria1:=">0"
                 Worksheets("Wallets").Range("B2:I" & x).Copy
                 Worksheets("Transfers").Select
                 Worksheets("Transfers").Cells(x, 1).Offset(1, 0).PasteSpecial Paste:=xlPasteValues
                 

        Worksheets("Wallets").AutoFilterMode = False
        Worksheets("Wallets").Range("$A$1:$J10000").AutoFilter Field:=5, Criteria1:="*EXCHANGE*"
        Worksheets("Wallets").Range("$A$1:$J10000").AutoFilter Field:=7, Criteria1:=">0"
                 Worksheets("Wallets").Range("B2:I" & x).Copy
                 Worksheets("Transfers").Cells(x, 1).Offset(1, 0).PasteSpecial Paste:=xlPasteValues
End Sub

【问题讨论】:

  • 你忘了问问题。
  • x = ActiveSheet.Cells(Rows.Count, 1).End(xlUp).Row - 你应该使用有问题的工作表而不是ActiveSheet
  • @BigBen 哪个?因为每次都不同,我不想每次更改时都添加此行。
  • @GeertBellekens 你是什么意思?
  • 我有点困惑你想要做什么,但在你的第二个代码 sn-p 你使用ActiveSheet 来获取最后一行,然后过滤硬编码的@987654326 @工作表。

标签: excel vba


【解决方案1】:

如果您正在循环浏览工作表,则可以,但如果您只使用两个工作表,则不能。您将需要指定工作表。您在每种情况下都使用x 作为最后一行,我怀疑这是真的。如果要查找最后一行,为什么要设置J10000?此外,您似乎只想在过滤后复制可见单元格。您需要指定只需要可见单元格。如果您Set 变量、范围和工作表,则更容易遵循您的代码,以免重复长行。这是我刚才使用您的代码所说的示例。甚至可能有更好的解决方案,但这比您拥有的更具可读性。

Sub Sort_Wallets()
    Dim destlr As Long
    Dim sourcelr As Long
    Dim wk1 As Worksheet
    Dim wk2 As Worksheet
    Dim FiltRng As Range
    
    Set wk1 = ThisWorkbook.Worksheets("Wallets")
    Set wk2 = ThisWorkbook.Worksheets("Transfers")
    
    
    destlr = wk2.Cells(Rows.Count, 1).End(xlUp).Row
    sourcelr = wk1.Cells(Rows.Count, 1).End(xlUp).Row
    
    Set FiltRng = wk1.Range(wk1.Cells(1, 1), wk1.Cells(sourcelr, 10))
    
    wk1.AutoFilterMode = False
       
    FiltRng.AutoFilter Field:=5, Criteria1:="*TRANSFER*"
    FiltRng.AutoFilter Field:=7, Criteria1:=">0"
    wk1.Range("B2:I" & sourcelr).SpecialCells(xlCellTypeVisible).Copy

    wk2.Cells(destlr, 1).Offset(1, 0).PasteSpecial Paste:=xlPasteValues
             

    wk1.AutoFilterMode = False
    FiltRng.AutoFilter Field:=5, Criteria1:="*EXCHANGE*"
    FiltRng.AutoFilter Field:=7, Criteria1:=">0"
    wk1.Range("B2:I" & sourcelr).SpecialCells(xlCellTypeVisible).Copy
    
    wk2.Cells(destlr, 1).Offset(1, 0).PasteSpecial Paste:=xlPasteValues
    
End Sub

【讨论】:

  • 基本上我有一个名为 Wallets 的工作表,它每天和每天都有不同的行数工作表。是的,它只复制可见数据并且效果很好,对此没有任何疑问。有时我需要将数据复制到的工作表已经有一些信息,这就是为什么我需要找到第一个未使用的单元格并将数据粘贴到它。并给出。 Cells(Rows.Count, 1).End(xlUp).Row 工作表编号在哪里找到最后一行是我目前在我正在使用的第一个代码中所做的
  • 问题是是否有任何办法不这样做,但更改代码,它将确定当前在该特定代码行中处于活动状态的工作表,并使用该活动工作表的最后一行没有名称。您的示例与我的示例一样,首先使用变量。
  • 你在两张表中都使用了x。不建议使用ActiveSheet,因为您可能不是从所需的工作表开始。就像我说的那样,如果您要循环并使用 Worksheets 集合说 For each sh in ThisWorkbook.Worksheets,那么您可以对每张工作表使用相同的变量。否则需要具体说明,最好具体说明。
  • 循环不起作用,因为我为每个工作表使用不同的过滤器,唯一相同的是在每个工作表中找到最后一行。太糟糕了,我希望每次我需要找到最后一行但最终开始使用变量时,有什么办法不重复这个 Cells(Rows.Count, 1).End(xlUp).Row。
【解决方案2】:

假设您使用的是数据表等工作表,请使用“表格”。对于每个数据表,突出显示它并“插入表”,然后进入表功能区(仅当光标在该表内时可用)并将表的名称从它的任何名称(“Table5”)更改为某物这对你来说很有意义。

在 VBA 中,这些称为 ListObjects。只要知道这些表的名称,就可以通过以下代码获取:

'Returns the specified object from a collection
'Returns Nothing if the value in the collection doesn't exist.
'Throws no errors
Private Function GetFromCollection(col As Collection, sKey As String) As Object
    On Error Resume Next
    Set GetFromCollection = col.item(sKey)
    Err.Clear
End Function

Public Function GetListObjectFromWorkbook(sTableName As String, Optional bRecache As Boolean = False) As ListObject
    Static bInitialized As Boolean
    Static col As Collection
    Dim lo As ListObject
    Dim sht As Worksheet
    
    If bRecache Or Not bInitialized Then
        Set col = New Collection
        For Each sht In Sheets
            For Each lo In sht.ListObjects
                col.Add lo, lo.Name
            Next lo
        Next sht
        bInitialized = True
    End If
    Set GetListObjectFromWorkbook = GetFromCollection(col, sTableName)
End Function

从那里,您不需要知道最后一行在哪里!添加新行是:

Dim listrow As ListRow
Set listrow = GetListObjectFromWorkbook(sTableName).ListRows.Add

您可以通过 listrow.Range 操作新 ListRow 的值

仅供参考:您也可以对 ListObjects 进行排序。 VB代码见https://docs.microsoft.com/en-us/dotnet/api/microsoft.office.tools.excel.listobject.sort?view=vsto-2017

【讨论】:

    猜你喜欢
    • 2016-01-27
    • 1970-01-01
    • 1970-01-01
    • 2015-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-06
    • 2013-11-30
    相关资源
    最近更新 更多