【问题标题】:How To Call Excel Macro on number of dynamic rows如何在动态行数上调用 Excel 宏
【发布时间】:2020-11-11 16:07:15
【问题描述】:

我想运行一个宏:在一个单元格中插入来自另一个单元格的信息,然后运行一个宏将该工作表转换为 PDF。我有一种方法可以使用多个 if-then 语句,但我想知道是否有更清洁、更简单的方法。下面是我的代码。单元格的数量可能会有所不同,因为它基于另一个将信息放入其中的宏。下面是代码。

Sub sub1()

Dim ws, ws1, ws2 As Worksheet
Dim LastRow As Long
Set ws = Worksheets("sht1")
Set ws1 = Worksheets("sht2")
Set ws2 = Worksheets("sht3")
LastRow = ws.Cells(Rows.Count, 1).End(xlUp).Row

With ws1
    .Cells.ClearContents
End With

With ws
    .AutoFilterMode = False
    .Range("A1:T" & LastRow).AutoFilter Field:=7, Criteria1:="=" & Date
End With

ws.Columns(1).Copy Destination:=ws1.Columns(1)

With ws
    .AutoFilterMode = False
End With

If ws1.Range("A2").Value <> "" Then

ws2.Range("D13").ClearContents
ws2.Range("D13").Value = ws1.Range("A2").Value
Call PDFCreate

    Else
End If

If ws1.Range("A3").Value <> "" Then

ws2.Range("D13").ClearContents
ws2.Range("D13").Value = ws1.Range("A3").Value
Call PDFCreate

    Else
End If

If ws1.Range("A4").Value <> "" Then

ws2.Range("D13").ClearContents
ws2.Range("D13").Value = ws1.Range("A4").Value
Call PDFCreate

    Else
End If

If ws1.Range("A5").Value <> "" Then

ws2.Range("D13").ClearContents
ws2.Range("D13").Value = ws1.Range("A5").Value
Call PDFCreate

    Else
End If

If ws1.Range("A6").Value <> "" Then

ws2.Range("D13").ClearContents
ws2.Range("D13").Value = ws1.Range("A6").Value
Call PDFCreate

    Else
End If

If ws1.Range("A7").Value <> "" Then

ws2.Range("D13").ClearContents
ws2.Range("D13").Value = ws1.Range("A7").Value
Call PDFCreate

    Else
End If

If ws1.Range("A8").Value <> "" Then

ws2.Range("D13").ClearContents
ws2.Range("D13").Value = ws1.Range("A8").Value
Call PDFCreate

    Else
End If

If ws1.Range("A9").Value <> "" Then

ws2.Range("D13").ClearContents
ws2.Range("D13").Value = ws1.Range("A9").Value
Call PDFCreate

    Else
End If

If ws1.Range("A10").Value <> "" Then

ws2.Range("D13").ClearContents
ws2.Range("D13").Value = ws1.Range("A10").Value
Call PDFCreate

    Else
End If

ws2.Range("D13").ClearContents

结束子

【问题讨论】:

  • 听起来你需要一个循环。只需找到ws1 上的最后一行,然后循环For Each cell in ws1.Range("A2:A" &amp; lastRow)
  • @BigBen 我不熟悉循环。试过这个,但它对每个单元格都不起作用 ws1.Range("A2:A" & nRows) ws2.Range("D13").ClearContents ws2.Range("D13").cell.Value Next cell跨度>
  • 网上有很多关于如何循环的教程。你试过阅读吗?这是学习基本技能的绝佳机会。

标签: excel vba


【解决方案1】:

@Jay 请遵循@BigBen 的合理建议并做一些在线教程来提高你的循环和其他东西的 VBA 技能。 Google 搜索“Excel VBA 循环教程”会返回数千条结果。

您说您正在寻找一种“更清洁、更简单的方法”。您可以做几件事来提高代码的效率。以下是对当前代码的一些观察和建议。

选项显式。养成将此添加到您的潜艇顶部的习惯。它强制你声明所有变量。

“Dim ws, ws1, ws2 as Worksheet”只是将 ws2 声明为 Worksheet——前两个被声明为 Variant。需要“dim ws as Worksheet, ws1 as Worksheet, ws2 as Worksheet”。

在这种情况下,我认为您真的不需要找到最后一行 - 只会将过滤后的数据复制到工作表 2。

您将进入一个痛苦的世界,将工作表 2 称为“ws1”,将工作表 3 称为“ws2”。如果您必须使它们成为变量,而在这种情况下您不必这样做,那么请帮自己一个忙并更直观地引用它们 - 工作表 1 为 ws1,工作表 2 为 ws2 等。或者,您可以简单地将它们称为“Sheet1”等

你真的不需要 With…End With 块来做一些简单的事情,比如清理一张纸。

Else 仅用于 If…End If 块中,如果您打算在测试为 False 的情况下在其后放置替代代码。在您的情况下,没有其他选择跟随它的使用,因此 False 返回将简单地跳到下一行代码。

我不知道为什么每次你总是用表 2 中的值覆盖数据时,你为什么要清除表 3 上 D13 的内容。

如果您的其他子“PDFCreate”只是将 Sheet3 导出为 PDF - 您可以在此模块中编写代码。只需复制代码并覆盖Call PDFCreate 行。

让我知道您如何使用下面的代码。它假定您的“sht1”实际上是工作簿中的 Sheet1(等等)。

Option Explicit    
Sub ConvertToPDF()
Dim c As Range

Sheet2.Cells.ClearContents

With Sheet1
    .Range("A1").AutoFilter Field:=7, Criteria1:="=" & Date
    .Columns(1).Copy Sheet2.Columns(1)
    .AutoFilterMode = False
End With
    
'This is the Loop
For Each c In Sheet2.Range("A2:A10")    
        If c.Value <> "" Then
           Sheet3.Range("D13").Value = c.Value
           Call PDFCreate
        End If    
Next c
    
End Sub

【讨论】:

  • 谢谢!它工作得很好,看起来更干净。它绝对帮助我理解了如何循环,我会继续研究。这是一个非常有用的评论,我会记住你所说的一切,以备将来的 VBA 使用
猜你喜欢
  • 2019-02-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-19
  • 2012-12-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多