
![]() | ![]() |
Function XIRR_FLEX(values As Range, dates As Range, Optional guess As Double = 0.1) As Variant Dim vArr() As Double Dim dArr() As Variant Dim cell As Range Dim area As Range Dim i As Long Dim hasPositive As Boolean Dim hasNegative As Boolean ' 收集现金流 i = 0 For Each area In values.Areas For Each cell In area If IsNumeric(cell.Value) And cell.Value <> "" Then i = i + 1 ReDim Preserve vArr(1 To i) vArr(i) = CDbl(cell.Value) If vArr(i) > 0 Then hasPositive = True If vArr(i) < 0 Then hasNegative = True End If Next cell Next area ' 收集日期 i = 0 For Each area In dates.Areas For Each cell In area If IsDate(cell.Value) And cell.Value <> "" Then i = i + 1 ReDim Preserve dArr(1 To i) dArr(i) = CDbl(cell.Value) End If Next cell Next area ' 校验 If UBound(vArr) <> UBound(dArr) Then XIRR_FLEX = CVErr(xlErrValue) Exit Function End If If UBound(vArr) < 2 Then XIRR_FLEX = CVErr(xlErrNum) Exit Function End If If Not (hasPositive And hasNegative) Then XIRR_FLEX = CVErr(xlErrNum) Exit Function End If ' 计算 On Error GoTo ErrorHandler XIRR_FLEX = Application.WorksheetFunction.Xirr(vArr, dArr, guess) Exit Function ErrorHandler: XIRR_FLEX = CVErr(xlErrNum) End Function |
这个增强函数XIRR_FLEX用法如下:

XIRR 配合 VSTACK 函数用这种方法,完全不需要任何 VBA 自定义函数,就能实现在不影响源数据,无需构造中间数据或辅助列的情况下,任意引用原始数据计算IRR。以前所有问题的根源,在于Excel无法灵活地构造XIRR函数所需的金额和日期数组参数,而有了VSTACK这个数组堆叠函数,可以直击痛点,一切问题迎刃而解。泡叔还是用一个保险计划建议书为例,看下它如何在不添加任何辅助数据的情况下,一个公式搞定所有问题。
先计算第20年末的IRR,在H22单元格输入下面公式:
=XIRR(VSTACK(B$3:B$7,-G22), VSTACK(DATE(A$3:A$7+2026,1,1),DATE(A22+2026,12,31)),10%)
立刻得到结果5.8%,按住该单元格向上拖动到第5年,Done! 各年份IRR全部自动算出!VSTACK()函数的推出,真是大大提升了XIRR()函数的灵活性和可用性。

。所有代码秒出,没有任何语法错误,从未发生编译问题。代码严谨规范,结构和排版清晰,注释到位,可读性非常好。只是我不敢确认内在逻辑是否完全正确,还需要做适度检查测试。
最早的XIRR_FLEX()版本中,AI并不是构造好数组再调用内置XIRR()函数,竟然直接给出了牛顿迭代法的代码,等于是重写了XIRR()函数的核心算法。这点让我大感意外,是个程序员都知道尽量利用成熟代码模块,不要重新造轮子,在AI这里似乎不存在的,大概对它来说都一样简单。但在后续对话中,AI敏锐地发现了问题,在后续版本中,全部主动采用了调用内置函数的方式,相当聪明。
这只是次初级得不能再初级的AI coding尝试,脱离IT已久的泡叔,很难想象Clause Code, Cursor, GitHub Copilot这些大型产业化AI开发平台和工具已经发展到何种程度。最近又看到最新的国产智谱GLM-5.1 和Kimi K2.6在编程上的恐怖表现,深感这世界正在加速进化。只有积极主动拥抱AI,老登们才不会被时代无情抛弃
。。。
The End.