什么';如果月份名称间隔为1,在VBA中返回TRUE的最佳逻辑是什么?

什么';如果月份名称间隔为1,在VBA中返回TRUE的最佳逻辑是什么?,vba,excel,excel-2010,excel-vba,excel-formula,Vba,Excel,Excel 2010,Excel Vba,Excel Formula,对于以下示例,我想返回True: 示例1 日期1:2014年7月31日 日期2:2014年8月1日 示例2 日期1:2007年12月31日 日期2:1/1/16(通知一年为2007年) 和False,用于以下示例: 示例3 日期1:2014年7月31日 日期2:2014年9月1日 最聪明的方法是什么?我知道我可以使用Month()函数来测试月份是否不同于1或11,但简单的布尔逻辑和数学就足够了 Sub dts() Dim Date1 As Date, Date2 As Date

对于以下示例,我想返回
True

示例1

日期1:2014年7月31日
日期2:2014年8月1日
示例2

日期1:2007年12月31日
日期2:1/1/16(通知一年为2007年)
False
,用于以下示例:

示例3

日期1:2014年7月31日
日期2:2014年9月1日

最聪明的方法是什么?我知道我可以使用
Month()
函数来测试月份是否不同于
1
11
,但简单的布尔逻辑和数学就足够了

Sub dts()
    Dim Date1 As Date, Date2 As Date

    Date1 = DateSerial(2014, 7, 31)
    Date2 = DateSerial(2014, 8, 1)
    Debug.Print CBool(Abs((Month(Date1) - (Month(Date1) = 1) * 12) - (Month(Date2) - (Month(Date2) = 1) * 12)) = 1)

    Date1 = DateSerial(2007, 12, 31)
    Date2 = DateSerial(2016, 1, 1)
    Debug.Print CBool(Abs((Month(Date1) - (Month(Date1) = 1) * 12) - (Month(Date2) - (Month(Date2) = 1) * 12)) = 1)

    Date1 = DateSerial(2014, 7, 31)
    Date2 = DateSerial(2014, 9, 1)
    Debug.Print CBool(Abs((Month(Date1) - (Month(Date1) = 1) * 12) - (Month(Date2) - (Month(Date2) = 1) * 12)) = 1)

End Sub
结果:

dts
True
True
False

您在问题中添加了和。如果用作工作表公式,请记住TRUE为1,而不是VBA TRUE中的-1。

简单的布尔逻辑和数学就足够了

Sub dts()
    Dim Date1 As Date, Date2 As Date

    Date1 = DateSerial(2014, 7, 31)
    Date2 = DateSerial(2014, 8, 1)
    Debug.Print CBool(Abs((Month(Date1) - (Month(Date1) = 1) * 12) - (Month(Date2) - (Month(Date2) = 1) * 12)) = 1)

    Date1 = DateSerial(2007, 12, 31)
    Date2 = DateSerial(2016, 1, 1)
    Debug.Print CBool(Abs((Month(Date1) - (Month(Date1) = 1) * 12) - (Month(Date2) - (Month(Date2) = 1) * 12)) = 1)

    Date1 = DateSerial(2014, 7, 31)
    Date2 = DateSerial(2014, 9, 1)
    Debug.Print CBool(Abs((Month(Date1) - (Month(Date1) = 1) * 12) - (Month(Date2) - (Month(Date2) = 1) * 12)) = 1)

End Sub
结果:

dts
True
True
False

您在问题中添加了和。如果用作工作表公式,请记住TRUE为1,而不是VBA TRUE中的-1。

如果您不关心年份,则使用内置的
函数似乎是完全合法的(甚至是最好的),如下所示:

Public Function AreMonthsOneApart(date1 As Date, date2 As Date) As Boolean

    Dim lMonthsApart As Long
    lMonthsApart = Abs(Month(date1) - Month(date2))
    AreMonthsOneApart = (lMonthsApart = 1 Or lMonthsApart = 11)

End Function
事实上,除了使用
Month
函数之外,使用其他函数可能会更加复杂


(即使@Jeeped的解决方案在计算中也使用了
Month
。这将是非常困难的——使用
Month
!)

如果你不关心年份,那么使用内置的
Month
功能似乎是完全合法的(甚至是最好的),如下所示:

Public Function AreMonthsOneApart(date1 As Date, date2 As Date) As Boolean

    Dim lMonthsApart As Long
    lMonthsApart = Abs(Month(date1) - Month(date2))
    AreMonthsOneApart = (lMonthsApart = 1 Or lMonthsApart = 11)

End Function
事实上,除了使用
Month
函数之外,使用其他函数可能会更加复杂


(即使@Jeeped的解决方案在计算中也使用了
Month
。这将是非常困难的——使用
Month
!)

我认为最简单的方法是将
Abs()
Mod()
组合在下面的公式中:

Abs(Month(Date1) - Month(Date2)) Mod 10 = 1
例如:

Dim Date1 As Date, Date2 As Date

Date1 = DateSerial(2014, 7, 31)
Date2 = DateSerial(2014, 8, 1)
Debug.Print Abs(Month(Date1) - Month(Date2)) Mod 10 = 1

Date1 = DateSerial(2007, 12, 31)
Date2 = DateSerial(2016, 1, 1)
Debug.Print Abs(Month(Date1) - Month(Date2)) Mod 10 = 1

Date1 = DateSerial(2014, 7, 31)
Date2 = DateSerial(2014, 9, 1)
Debug.Print Abs(Month(Date1) - Month(Date2)) Mod 10 = 1
输出:

True
真的
假的

我认为最简单的方法是将
Abs()
Mod()
组合在以下公式中:

Abs(Month(Date1) - Month(Date2)) Mod 10 = 1
例如:

Dim Date1 As Date, Date2 As Date

Date1 = DateSerial(2014, 7, 31)
Date2 = DateSerial(2014, 8, 1)
Debug.Print Abs(Month(Date1) - Month(Date2)) Mod 10 = 1

Date1 = DateSerial(2007, 12, 31)
Date2 = DateSerial(2016, 1, 1)
Debug.Print Abs(Month(Date1) - Month(Date2)) Mod 10 = 1

Date1 = DateSerial(2014, 7, 31)
Date2 = DateSerial(2014, 9, 1)
Debug.Print Abs(Month(Date1) - Month(Date2)) Mod 10 = 1
输出:

True
真的
假的

你看过
DateDiff
了吗?最后一个例子可能是错误的,因为相隔两个月(7月和9月)。对不起,我应该再看一遍标题。我肯定看错了帖子,删除了我(不正确)的答案。抱歉,不用担心。我认为Jeeped有一个非常聪明的解决方案。你有没有研究过
DateDiff
?最后一个例子可能是错误的,因为它相隔两个月(7月和9月)。对不起,我应该再读一遍标题。我肯定看错了帖子,删除了我(不正确)的答案。抱歉,不用担心。我认为Jeeped有一个非常聪明的解决方案你忘了补偿十二月到一月的一对。你忘了补偿十二月到一月的一对。这是一个很好的解决方案,谢谢。Cbool绝对必要吗?它不是已经默认为布尔类型了吗?如果是这样的话,我应该为另一个测试添加一个CInt()吗?我使用的
CBool
比我需要的多,因为我经常依赖数字来判断是真是假。CBool只是帮助我直观地看到,我把数字当作布尔值,而不是数字。事实上,虚假为零,任何不虚假的东西都是真实的。这是一个很好的解决方案,谢谢。Cbool绝对必要吗?它不是已经默认为布尔类型了吗?如果是这样的话,我应该为另一个测试添加一个CInt()吗?我使用的
CBool
比我需要的多,因为我经常依赖数字来判断是真是假。CBool只是帮助我直观地看到,我把数字当作布尔值,而不是数字。事实上,虚假为零,任何不虚假的东西都是真实的。