在保存事件之前,需要帮助以同时循环两个单元格

Posted

技术标签:

【中文标题】在保存事件之前,需要帮助以同时循环两个单元格【英文标题】:before save event, need help for looping two cells at the same time 【发布时间】:2017-02-21 14:18:28 【问题描述】:

我正在尝试执行 beforesave 事件,如果两个给定单元格之一为空,则不允许用户保存。到目前为止,我设法将第 13 列(M)和单元格 A4 链接起来。

我想做的是将事件应用于两个范围和行的组合,A4-A19 和 M4-M19。这样:如果A4不为空且M4为空,则会出现一个msgbox并阻止保存等等..A5-M5,A6-M6...直到A19-M19。如果两个对应的单元格同时为空,则应该可以保存。

Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)

    Dim i As Integer, MyWb As Object
    i = 13
    Set MyWb = ThisWorkbook.Sheets("Planning").Cells
    Do While MyWb(4, i).Value <> ""
    i = i + 1
    Loop
    If i = 13 Then
        If ThisWorkbook.Sheets("Planning").Range("A4") <> "" Then
            MsgBox ("You will need to enter topics before saving"), vbCritical
            Cancel = True
        End If
    End If
End Sub

基于 Wolfie 的代码,我设法获得了我想要的,只需为 A 列添加一个 If not isempty 并替换 19 而不是 13。

Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)

Dim plansht As Worksheet
Set plansht = ThisWorkbook.Sheets("Planning")

' Loop over rows
Dim rw As Integer
For rw = 4 To 19
    ' Test if both the A and M column in row "rw" are blank
    If Not IsEmpty(plansht.Range("A" & rw)) And plansht.Range("M" & rw).Value = "" Then
        MsgBox ("You will need to enter topics before saving"), vbCritical
        Cancel = True
    End If
Next rw

End Sub

【问题讨论】:

您从我的答案中创建的代码检查:“如果 Ai 不为空且 Mi 为空,则 ...”,请注意 Not 仅适用于 @ 之前的第一个条件987654324@!我不确定这是否是您想要的? 是的,这正是我想要的,当我得到你的第一个答案时,我意识到我最初的请求不正确......实际上我想要这种行为:如果 A 不是空的,M 是空然后.......:) 啊,好的,感谢您的帮助,我已经编辑了我的答案,以获取有关使用逻辑运算的一些注释:) 谢谢。很有用! 【参考方案1】:

试试这个:

For i = 4 to 19
    If ThisWorkbook.Sheets("Planning").Range("A" & i) <> "" AND _
       ThisWorkbook.Sheets("Planning").Range("M" & i) <> ""  Then
          MsgBox("Hey bro you didn't wrote properly on line " & i)
          Cancel = True

Next i

【讨论】:

For 1 = 4 to 19 应该是For i = 4 to 19。错别字很有趣! :) 感谢这个错字:)【参考方案2】:

您可以遍历这些行,只需测试AM 列,以测试它们对于给定行是否都为空。请参阅下面的代码...

Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)

Dim plansht as Worksheet
Set plansht = ThisWorkbook.Sheets("Planning")

' Loop over rows
Dim rw as Integer
For rw = 4 to 13  
    ' Test if both the A and M column in row "rw" are blank
    If plansht.Range("A" & rw).Value = "" And plansht.Range("M" & rw).Value = "" Then
        MsgBox ("You will need to enter topics before saving"), vbCritical
        Cancel = True   
    End If    
Next rw

End Sub

编辑:

您的编辑建议您希望一些不同的单元格组合为空。以下是针对不同结果的 If 语句的一些示例

' If BOTH are empty
If plansht.Range("A" & rw).Value = "" And plansht.Range("M" & rw).Value = "" Then ...

If IsEmpty(plansht.Range("A" & rw)) And IsEmpty(plansht.Range("M" & rw)) Then ...

' If EITHER is empty
If plansht.Range("A" & rw).Value = "" OR plansht.Range("M" & rw).Value = "" Then ...

If IsEmpty(plansht.Range("A" & rw)) Or IsEmpty(plansht.Range("M" & rw)) Then ...

' If BOTH are NOT empty
If plansht.Range("A" & rw).Value <> "" And plansht.Range("M" & rw).Value <> "" Then ...

If Not IsEmpty(plansht.Range("A" & rw)) And Not IsEmpty(plansht.Range("M" & rw)) Then ...

请注意,当您开始使用多个条件引入 Not 时,逻辑很快就会变得难以解释。您可以使用方括号将条件与Not 组合在一起,但您会得到类似这样的逻辑含义:

If Not IsEmpty(plansht.Range("A" & rw)) And Not IsEmpty(plansht.Range("M" & rw)) Then ...
If Not (IsEmpty(plansht.Range("A" & rw)) Or IsEmpty(plansht.Range("M" & rw))) Then ...

【讨论】:

我刚刚意识到我的描述不正确,我想做的恰恰相反。我编辑了描述。 如果是空的(而不是both),只需使用Or 代替And! :) 谢谢,是真的:)【参考方案3】:

试试这个:

Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)

    Const FIRST_ROW as integer = 4
    Const LAST_ROW as integer = 19
    Const ColA As Integer = 4
    Const ColM as integer = 13
    Dim MyWb As Worksheet
    Dim CurRow as Integer

    Set MyWb = ThisWorkbook.Sheets("Planning")
    For CurRow = FIRST_ROW to LAST_ROW
      If len(mywb.cells(CurRow, ColA)) = 0 and len(mywb.cells(CurRow, ColM)) = 0 then
        MsgBox ("You will need to enter topics before saving"), vbCritical
        Cancel = True
        Exit For
      End If
    Next
End Sub

未经测试的代码(我不记得是 (Row,Col) 还是 (Col,Row)),但我认为这会让你得到你想要的。这将中止第一对的保存,它们都是空白的。

如果这行得通,您可以花哨并突出显示空白对,删除 OK 对的突出显示(以防它们之前突出显示),处理通过所有对并删除 Exit For 并提供一条错误消息,指出需要注意突出显示的任何内容。

有人告诉我Len(string) = 0 是比string = vbNullString 更快地确定字符串是否为空的方法。不能保证是否适合目的,但这是我学到的。

【讨论】:

它有效,但我意识到我的描述是错误的......我会编辑它。 你是对的,它是Cells(row, col),很容易记住,因为它与Range相反;-) 你也可以在Cells中按列字母引用,而不是@987654328 @ 和 ColM 你可以使用 "A""M" :)

以上是关于在保存事件之前,需要帮助以同时循环两个单元格的主要内容,如果未能解决你的问题,请参考以下文章

将多个值写入一个单元格 - VBA

循环遍历过滤的单元格列表以检查值是不是出现在另一列中,然后复制/粘贴

JS给页面添加标签的同时添加标签的onclick事件

计算单元格excel中显示的空行数

设置日历单元格格式以在添加事件时更改颜色

如何在表格视图单元格中快速迭代for循环