如何在Muenchian分组求和完成后生成正确的总计汇总?
解决Muenchian分组后汇总分组绝对值求和的总计问题
核心思路
你需要先获取所有Muenchian分组的代表节点,然后对每个分组的Amount求和结果取绝对值,最后将这些绝对值汇总得到总计——这样就能和明细行中输出的每个分组的绝对值求和值的总和完全一致,避免正负抵消的问题。
具体实现步骤
定义变量存储所有分组的代表节点
先把所有分组的第一个节点(也就是你for-each循环里遍历的节点)存到变量中,方便后续计算总计:<xsl:variable name="allGroupHeaders" select="Export/Record[generate-id() = generate-id(key('kRcdGroup', concat(generate-id(..), AccountNo, Description, vb:GetOverrideCode(DeptOverride,LedgerCode)))[1])]" />计算总计值
遍历所有分组代表节点,对每个节点对应的分组计算Amount的求和值,取绝对值后再汇总:<xsl:variable name="grandTotal" select="sum($allGroupHeaders/abs(sum(key('kRcdGroup', concat(generate-id(..), AccountNo, Description, vb:GetOverrideCode(DeptOverride,LedgerCode))/Amount))))" />在页脚输出总计
按照你要求的固定格式(99为页脚标识),格式化输出总计值:<!-- 页脚行 --> <xsl:text>99|</xsl:text> <xsl:value-of select="format-number($grandTotal, '#.00')" /> <xsl:text> </xsl:text> <!-- 换行符,根据输出需求调整 -->
整合到你的现有代码示例
把上述代码嵌入到你的XSLT中,完整的关键部分示例如下:
<!-- 你的分组键定义 --> <xsl:key name="kRcdGroup" match="Export/Record" use="concat(generate-id(..), AccountNo, Description, vb:GetOverrideCode(DeptOverride,LedgerCode))" /> <!-- 存储所有分组代表节点的变量 --> <xsl:variable name="allGroupHeaders" select="Export/Record[generate-id() = generate-id(key('kRcdGroup', concat(generate-id(..), AccountNo, Description, vb:GetOverrideCode(DeptOverride,LedgerCode)))[1])]" /> <!-- 计算总计 --> <xsl:variable name="grandTotal" select="sum($allGroupHeaders/abs(sum(key('kRcdGroup', concat(generate-id(..), AccountNo, Description, vb:GetOverrideCode(DeptOverride,LedgerCode))/Amount))))" /> <!-- 输出表头(01行) --> <xsl:text>01|表头内容... </xsl:text> <!-- 输出明细(02行) --> <xsl:for-each select="$allGroupHeaders"> <xsl:variable name="vkeyGroup" select="key('kRcdGroup', concat(generate-id(..), AccountNo, Description, vb:GetOverrideCode(DeptOverride,LedgerCode)))" /> <xsl:text>02|</xsl:text> <!-- 输出你的其他字段内容 --> <xsl:choose> <xsl:when test="sum($vkeyGroup/Amount) > 0"> <xsl:value-of select="format-number(sum($vkeyGroup/Amount),'#.00')" /> <xsl:text>|50</xsl:text> <!-- 正标记 --> </xsl:when> <xsl:otherwise> <xsl:value-of select="format-number(sum($vkeyGroup/Amount)*-1,'#.00')" /> <xsl:text>|40</xsl:text> <!-- 负标记 --> </xsl:otherwise> </xsl:choose> <xsl:text> </xsl:text> </xsl:for-each> <!-- 输出页脚(99行) --> <xsl:text>99|</xsl:text> <xsl:value-of select="format-number($grandTotal, '#.00')" /> <xsl:text> </xsl:text>
关键说明
- 使用
abs()函数确保每个分组的求和值都转为正数后再汇总,完全匹配你明细行中输出的绝对值求和逻辑。 - 复用了你的分组键逻辑,确保总计计算和分组逻辑完全一致,避免因分组规则不一致导致的误差。
内容的提问来源于stack exchange,提问作者Greg Gregerson
相关产品推荐
相关产品推荐

