Sum()跨动态页数

时间:2013-02-05 21:41:17

标签: excel excel-vba excel-formula excel-2010 vba

大家好,感谢您的帮助,

我有一张excel表,仅用于获取多张纸的总和。最好也是最简单的说法,公式类似于=sum(Sheet1!A1,Sheet2!A1,Sheet3!A1,Sheet4!A1)。但有一些问题使问题复杂化。首先,我不知道要总和的床单的数量或顺序,也不知道他们的名字。这个公式将被复制到~150个其他单元格中,因此我需要动态求和,而不是每次都将表格物理地添加到~150个单元格。 (此外,工作表的配置和命名也不允许轻松拖动公式。)

首先,我想我可以使用indirect()引用来编写它。我创建了一个列来列出将添加到每个单元格中的所有工作表名称。不幸的是,concatenate()不能用于数组,所以我不得不求助于下面的UDF:

Function CONCAT(Delimiter As Variant, ParamArray CellRanges() As Variant) As String
Dim Cell As Range, Area As Variant
If IsMissing(Delimiter) Then Delimiter = ""
For Each Area In CellRanges
If TypeName(Area) = "Range" Then
For Each Cell In Area
If Len(Cell.Value) Then CONCAT = CONCAT & Delimiter & Cell.Value
Next
Else
CONCAT = CONCAT & Delimiter & Area
End If
Next
CONCAT = Mid(CONCAT, Len(Delimiter) + 1)
End Function

使用UDF,我可以使用正确的语法(如=CONCAT("'!A"&(B1+1)&",'",Array_of_Sheets)&"'!A"&(B1+1))获取一个大字符串。 CONCAT()将分隔符作为第一个参数,将数组作为第二个参数。然后我在字符串的末尾添加“分隔符”以输出诸如Sheet1'!A1,'Sheet2'!A1之类的内容。我想在这一点上,一个简单的=sum(indirect(STRING))就足够了,但=sum(indirect("Sheet1!A1,Sheet2!A1,Sheet3!A1,Sheet4!A1"))不起作用,因为indirect()似乎无法处理逗号。

为了解决这个问题,我将=CONCAT()切换为=CONCAT("'!A"&(B1+1)&"+'",Array_of_Sheets)&"'!A"&(B1+1)以输出Sheet1'!A1+'Sheet2'!A1。现在我写了另一个UDF来迫使它评估如下所示:

Function EVAL(RefCell As String)
Application.Volatile
EVAL = Evaluate(RefCell)
End Function

这很有效!太棒了吧?经过一些使用和测试后,似乎不太一致。当我们打开其他工作表时,它并不总是评估(我们将打开其他工作表)。在UDF中使用volatile时,我读到了一些其他的不一致之处,但我找不到它们。

所以对于我的理想,我想在没有任何VBA的情况下这样做,但我怀疑这是不可能的。我宁愿不依赖于用户手动重新计算工作表(部分原因是volatile)。最后,我只想以一致的方式将它sum(),所以如果用户打开文档然后点击打印,用户就不需要确认函数是否正确评估(检查#REF错误或手动加起来)值以确保它们是正确的)。我希望找到使用eval()等式的替代方法。

编辑以获取

下面的其他信息

我曾尝试过使用3D数组,但我遇到了一些问题。可以说工作簿有八张。在这八张纸中,只有两张可以送入这张纸。有setup表,total表,data entry表和data analysis表。 total表单总计data analysis张。通常,data entry工作表与data analysis工作表重合。因此,用户可以复制data entrydata analysis张。工作表的最合乎逻辑的顺序将从setup工作表开始,然后是data entrydata analysis工作表以及total工作表的每个配对。显然,此设置不适用于3D阵列。我们必须重新排序纸张并确保用户知道纸张的顺序实际上是重要的(非典型配置)。还会有data analysis张中不会包含一张或两张total张的情况。因此,我们最终可能会使用setup \ data entry (1) \ data entry (2) \ START \ data anaylsis (1) \ data analysis (2) \ END \ totals \ data entry (3) \ data entry (4) \ data anaylsis (3) \ data analysis (4)的工作表配置。我的感觉是3D阵列配置几乎会使动态添加。我宁愿有一个明确的清单,然后取决于用户有信心移动工作表以获得正确的总数。

2 个答案:

答案 0 :(得分:13)

好消息!通过使用3D公式,您可以简化生活:

如果您使用此公式:=SUM(Sheet1:Sheet3!$A$1:$B$2),则A1:B2中的所有单元格将相加 - 从Sheet1到Sheet3的所有工作表!

通常,使用两个“帮助”工作表处理打开/更改数量的工作表会很有帮助:

  1. 插入两个名为 START END
  2. 的工作表
  3. 在这两张纸上展示您的3D公式
  4. 在这些工作表之间移动所有工作表或移动 START END 工作表(当然,这也可以在步骤1中完成)
  5. 隐藏两个帮助工作表
  6. 请查看此link以获取进一步说明。

答案 1 :(得分:1)

这是另一种方法:

假设您的用户的数据输入表是根据某种必须严格遵守的系统进行标记的(例如“数据输入1”,“数据输入2”等),您可以使用以下方式构建汇总表INDIRECT - 然后将此表格合计。

详细地说,你的'Totals'表中有一个帮助表,看起来像这样:

   Col A         Col B    Col C    Col D
1                         C5       X7
2  Sheet name    Exists?  Value 1  Value 2
3  Data entry 1  TRUE          10       20
4  Data entry 2  FALSE          0        0
5  Data entry 3  TRUE          20       30
6  ...
.
.
.
20 More sheet names than you'll ever get just to be sure!
  • 在单元格C1和以下列中,您将写入要合计的单元格的地址。如果你有一个模板,并希望保持引用动态(通常地址的静态性质是这里的bug的来源),使用=ADDRESS(ROW(Template!C5);COLUMN(Template!C5))来获取动态地址。
  • 在B栏中,您将使用以下公式:=NOT(ISERROR(INDIRECT(ADDRESS(1,1,,,A3))))
  • 在C列和以下列中,使用:=IF(B3,INDIRECT("'"&A3&"'!"&C$1),0)

现在你只需要对C列进行总计等等。