简述:
有一个输入数据的sheet,主要内容是工程场景、工程标记和编号的输入,在这个页面需要设计两个按钮,一个负责清除,一个负责更新(写入)。
具体实现过程:
第一步:
第二步:
详解:
Set wsRun = ThisWorkbook.Sheets("Run")
Set wsWorking = ThisWorkbook.Sheets("Working")
notFoundSheets = ""
Set
关键字在VBA中用于分配对象引用给变量,在这里它用于将名为 “Run” 的工作表对象分配给 wsRun
变量。ThisWorkbook
是一个VBA对象,它引用包含执行代码的当前工作簿。Sheets("Run")
是获取工作簿中名为 “Run” 的工作表的方法。
声明了一个名为 notFoundSheets
的变量,并初始化为空字符串 (""
)。在代码的后续部分,这个变量会被用来存储那些在循环过程中没有找到对应工作表名称的字符串。每当代码尝试查找E列提到的工作表而失败时,就会将其名称和行号添加到 notFoundSheets
字符串中。这样,最后可以通过一个警告框来提示用户哪些工作表没有找到。
总的来说,创建一个引用当前工作簿中 “Run” 工作表的变量 wsRun
和把名为 “Working” 的工作表对象分配给 wsWorking
变量;初始化 notFoundSheets
变量。
' 循环D列的值
For Each cell In wsRun.Range("D4", wsRun.Range("D4").End(xlDown))
value = cell.Value
If value = "" Then Exit For
If cell.Offset(0, 2).Value = "是" Then ' 检查F列是否为"是"
wsRun.Range("B2").Value = value
wsWorking.Calculate ' 刷新working表
cell
是循环中使用的变量,代表当前正在处理的单元格。wsRun
上的 D4
单元格开始,直到该列最后一个非空单元格(xlDown
是Excel VBA中的一个枚举,表示向下),简单来说,它类似于在Excel中按下Ctrl+向下箭头键
的操作。。value = cell.Value
是将当前循环单元格的值赋给变量 value
。If value = "" Then Exit For
: 这是一个条件判断,它检查 value
是否为空字符串(即当前单元格是否为空)。如果为空,则执行 Exit For
,这会立即终止循环。cell.Offset(0, 2)
返回一个单元格的引用,这个单元格位于当前 cell
(D列中的单元格)的同一行,但是在它右边第二列(即F列)。wsWorking.Calculate
: 这行代码用来刷新或重新计算名为Working的工作表上的所有公式。这实际上是模拟了用户按下F9
键的操作,确保所有的公式都基于新的数据重新计算,保证了数据的更新。 ' 检查E列对应的工作表是否存在
sheetName = cell.Offset(0, 1).Value
On Error Resume Next
Set targetSheet = ThisWorkbook.Sheets(sheetName)
isSheetFound = Not targetSheet Is Nothing
On Error GoTo 0
If isSheetFound Then
' 如果存在则复制working表的内容到目标表
wsWorking.Cells.Copy
With targetSheet.Cells
.PasteSpecial Paste:=xlPasteValues
.PasteSpecial Paste:=xlPasteFormats
Application.CutCopyMode = False
End With
Else
' 如果没有找到sheet,记录下来
notFoundSheets = notFoundSheets & cell.Row & " (" & sheetName & "), "
End If
Set targetSheet = Nothing
cell.Offset(0, 1).Value
获取当前循环中D列单元格相邻的E列单元格的值,这个值假设为工作表的名称,并将其赋给变量sheetName
。On Error Resume Next
是一个错误处理的语句,它告诉VBA如果遇到错误就忽略它,并继续执行下一行代码(将sheetName
对应的工作表设置给变量targetSheet
)。这在尝试访问可能不存在的工作表时很有用,因为如果工作表不存在,尝试设置它会产生错误。Not targetSheet Is Nothing
检查变量targetSheet
是否已成功设置为一个工作表对象。如果targetSheet
不是Nothing
,这意味着工作表存在,isSheetFound
将被设为True
。notFoundSheets
是一个字符串变量,用来累加所有未找到工作表的信息。这里通过连接字符串的方式,将当前循环的行号cell.Row
和工作表名称sheetName
添加到这个字符串中,每个条目之间用逗号隔开。On Error GoTo 0
将错误处理重置为默认状态,这意味着在这之后的代码中如果发生错误,程序将不再忽略错误,而是会停止执行并显示一个错误消息。wsWorking.Cells.Copy
将名为Working
的工作表中所有单元格的内容复制到剪贴板。With targetSheet.Cells
语句块开始,在这个块内部,我们处理之前找到的工作表targetSheet
的单元格。.PasteSpecial Paste:=xlPasteValues
将复制的值粘贴到targetSheet
的单元格中,不包括公式,只是值。.PasteSpecial Paste:=xlPasteFormats
接着将复制的单元格格式粘贴到targetSheet
的单元格中。Application.CutCopyMode = False
关闭剪贴板,这是一个用来清除剪贴板的好方法,它也防止了之后的粘贴操作。targetSheet
重置为Nothing
可以帮助释放内存中的对象。Sub Button_Click()
Dim wsRun, wsWorking, targetSheet As Worksheet
Dim cell As Range
Dim value As Variant
Dim sheetName As String
Dim notFoundSheets As String
Dim isSheetFound As Boolean
Set wsRun = ThisWorkbook.Sheets("Run")
Set wsWorking = ThisWorkbook.Sheets("Working")
notFoundSheets = ""
' 循环D列的值
For Each cell In wsRun.Range("D4", wsRun.Range("D4").End(xlDown))
value = cell.Value
If value = "" Then Exit For
If cell.Offset(0, 2).Value = "是" Then ' 检查F列是否为"是"
wsRun.Range("B2").Value = value
wsWorking.Calculate ' 刷新working表
' 检查E列对应的工作表是否存在
sheetName = cell.Offset(0, 1).Value
On Error Resume Next
Set targetSheet = ThisWorkbook.Sheets(sheetName)
isSheetFound = Not targetSheet Is Nothing
On Error GoTo 0
If isSheetFound Then
' 如果存在则复制working表的内容到目标表
wsWorking.Cells.Copy
With targetSheet.Cells
.PasteSpecial Paste:=xlPasteValues
.PasteSpecial Paste:=xlPasteFormats
Application.CutCopyMode = False
End With
Else
' 如果没有找到sheet,记录下来
notFoundSheets = notFoundSheets & cell.Row & " (" & sheetName & "), "
End If
Set targetSheet = Nothing
End If
Next cell
' 如果有未找到的sheet,显示警告信息
If notFoundSheets <> "" Then
notFoundSheets = Left(notFoundSheets, Len(notFoundSheets) - 2) ' 移除最后的逗号和空格
MsgBox "These sheets can not be found: " & notFoundSheets
End If
End Sub
Sub ClearDataBelowHeaders()
Dim wsRun, wsTarget As Worksheet
Dim cell As Range
Set wsRun = ThisWorkbook.Sheets("Run")
' 循环E列的值
For Each cell In wsRun.Range("E4", wsRun.Range("E4").End(xlDown))
' 判断同一行的F列的值是否为"是"
If wsRun.Cells(cell.Row, "F").Value = "是" Then
' 如果是"是",处理工作表
On Error Resume Next
Set wsTarget = ThisWorkbook.Sheets(cell.Value)
On Error GoTo 0
If Not wsTargt Is Nothing Then
' 清除目标表的内容(除了标题)
wsTarget.Rows("2:" & wsTarget.Rows.Count).ClearContents
Set targetSheet = Nothing ' 重置目标工作表变量
End If
End If
Next cell
End Sub