Excel公式将条件应用于所有工作表相同的整列

时间:2015-10-01 08:03:19

标签: excel excel-formula openoffice-calc

这个问题可以看作几个小问题,但主要目标是唯一的。

TL; DR;

我想在工作表N处应用excel公式,在完整的所有其他工作表中考虑所有相应的列,同时应用所有列的相同条件。

详细信息:

我的电子表格是一个非常简单的基本费用会计,其中包含多年的工作表和日期2015.042015.052015.06等。 第一行始终是标题(时间,日期,金额,项目,类别等),列始终对应(例如,在所有工作表列H中将为类别,D将为金额)< / p>

起始公式为:

    =SUMIF('2015.07'.H2:H67;C20;'2015.07'.D2:D67)
// C20 is only a search condition like "travel", or "F&B"

它适用于这种简化的手动模式,但由于我们有计算机,并且我有一个程序员M.O,我想让它自动化一点,因此我的问题:

1 - 如何将此公式应用于所有工作表,即使稍后添加/删除某些工作表,例如相当于&#34;表格通配符&#34;

 =SUMIF('*'.H2:H67;C20;'*'.D2:D67) // all sheets

=SUMIF('2015*'.H2:H67;C20;'2015*'.D2:D67) // all year

2 - 由于列长度不同,应用手动范围似乎很愚蠢,所以我试过

  =SUMIF('2015.07'.H:H;C20;'2015.07'.D:D) 

但它给了我几个不同的错误。

3 - 我能理解的其中一个错误,那就是第一行TITLE不是数字,所以我试过了

=SUMIF('2015.07'.H1:H67;C20;ISNUMBER('2015.07'.D1:D99) )// err 504

并尝试了

=SUMIF('2015.07'.H1:H67;C20;IF(ISNUMBER('2015.07'.D1:D99) ))// err 509

=SUMIF('2015.07'.H1:H67;C20;sum(IF(ISNUMBER('2015.07'.D1:D99)) ))// err 508

现在,我知道我可以采用简单的工作开始公式,将它放在每一页,选择没有标题的确切范围,然后在最后一个夏季页面参考所有其他 - 但严重的是,我也可以使用ABACUS,这不是为什么像excel这样的工具被发明的原因。还是我假设这个工具太多了?那是原始的吗?我不知何故拒绝相信它,只是因为我不应该知道它而责备自己。

我也知道我可以写一个VBA宏,但是在这一点上,我需要花费更少的精力和时间来让some PHP excel库编写一些PHP行,在SQL中全部转储并执行对的 。但同样 - 这是我的错(可能)还是擅长?

P.S取代。如果重要的话,使用OpenOffice Calc,但在excel中尝试更改语法和不同的错误代码。

编辑I - 解决方案

在看了@Axel Richards的回答之后,即使它不能帮我解决问题,它确实帮助了我找到了解决方法。

首先,我发现我遇到的错误是由于纸张本身的命名。 显然,2005.07(一个点)这样的名称会给err 501,而2005-07(连字符)会给err 502。这让我明白,我之前的一些尝试实际上是正确的 - 但是命名方案产生了错误。

所以最终的公式对我有用。 请注意,这是一个数组公式,因此需要使用CTRL+SHIFT+ENTER输入,而不仅仅是ENTER,这会生成大括号(之前我不知道..)

{=SUMIF((INDIRECT("20150"&COLUMN(C$1:I$1)&".H"&ROW(A$1:A$500)));$J16;INDIRECT("20150"&COLUMN(C$1:I$1)&".D"&ROW(A$1:A$500)))}

没有通配符的事实只有一半是正确的,因为解决方案是定义一个起始期和结束期,公式将计算中间的所有单页。这是我的目的的某种通配符。

像这样:

{=SUMIF((INDIRECT("start"&".H"&ROW(A$1:A$500)));$J16;INDIRECT("END"&".D"&ROW(A$1:A$500)))}

使用COLUMN(C$1:I$1)实际上是创建一个数组(3-9),而ROW(A$1:A$500)告诉你公式要考虑500行的所有内容。

这不是一个灵活或优雅的解决方案,但它确实有效。

2 个答案:

答案 0 :(得分:1)

我会尝试回答你的问题。

  1. 工作表通配符
  2. 这是不可能的。为什么?因为'2015.07'.H2:H67中的工作表名称不仅仅是字符串而是引用。如果您从&#34; 2015.07&#34;更改工作表名称在&#34;无论什么&#34;那么引用这张表的所有公式中的所有引用都将改变。

    1. 引用整列和/或整行
    2. 这在Openoffice(Libreoffice)中是不可能的。在Excel中=SUMIF('2015.07'!H:H,C20,'2015.07'!D:D)将起作用。在Openoffice中,我们必须引用第一个单元格和最后一个单元格=SUMIF($H$1:$H$1048576,C20,$D$1:$D$1048576)

      顺便说一句:如果您在Openoffice中尝试=SUMIF('2015.07'.H:H;C20;'2015.07'.D:D),则该错误应为#NAME?,因为H和D不是定义的名称。这与不是数字的东西无关。除了错误值之外,SUMIF可以处理其总和范围内的数字内容。

      1. 错误代码的含义
      2. https://help.libreoffice.org/Calc/Error_Codes_in_Calc

        那我该做什么:

        假设以下示例(在我的Libreoffice中是逗号的公式参数分隔符):

        enter image description here

        如您所见K2中的公式

        =SUMIF($H$1:$H$1048576,$J2,$D$1:$D$1048576)
        

        J2中的公式是

        =$'Sheet N'.$C$20
        

        这是对&#34; Sheet N&#34;的引用。细胞C20。

        表N看起来像:

        enter image description here

        D20中的公式是

        =SUM(Begin.K2:End.K2)
        

        这是一个3D参考。来自工作表&#34;开始&#34;的所有工作表中的所有单元格K2直到表#34;结束&#34;将总结。

        表格&#34;开始&#34;和&#34;结束&#34;只是空床单。

        现在您可以复制表格&#34; 2015.01&#34;随心所欲,将副本放在表格之间&#34;开始&#34;和&#34;结束&#34;。您可以根据新月份更改复印纸张的内容。只要在J2的所有副本中=$'Sheet N'.$C20K2中的SUMIF公式都是D20公式,那么{&1;}中的SUMIF表格为#{1}} 34;将是所有C20的总和,这些UNION将依赖于SUMIF&#34;表N&#34;。

        但最后提到你了:

          

        我也知道我可以写一个VBA宏,但此时需要   我花费更少的精力和时间来学习一些PHP excel库   PHP行,在SQL中全部转储并正确执行。

        你对SQL的提示是正确的。但是在SQL中,你每个月都没有自己的表,然后拿走所有这些表的=SUMIF...+SUMIF...+SUMIF...。您将在一个表中将所有费用记帐,并将月份作为字段。如果在电子表格中也是如此,那么Public Function SUMIFOS(sSheetName as String, lColSearch as Long, vSearchValue as Variant, lColSum as Long) as Variant oDoc = Thiscomponent sFormula = "" vResult = 0 oTextSearch = CreateUnoService("com.sun.star.util.TextSearch") oOptions = CreateUnoStruct("com.sun.star.util.SearchOptions") oOptions.algorithmType = com.sun.star.util.SearchAlgorithms.REGEXP oOptions.searchString = sSheetName oTextSearch.setOptions(oOptions) For Each oSheet in oDoc.Sheets oFound = oTextSearch.searchForward(oSheet.Name, 0, Len(oSheet.Name)) If oFound.subRegExpressions <> 0 then sPath = ThisComponent.URL sSearchColumn = oSheet.Columns(lColSearch-1).AbsoluteName sSumColumn = oSheet.Columns(lColSum-1).AbsoluteName sSearchColumn = "'" & sPath & "'#" & sSearchColumn sSumColumn = "'" & sPath & "'#" & sSumColumn sFormula = "=SUMIF(" & sSearchColumn & ";""" & vSearchValue & """;" & sSumColumn & ")" oDocTMP = CreateUnoService("com.sun.star.sheet.SpreadsheetDocument") oSheetTMP = oDocTMP.createInstance("com.sun.star.sheet.Spreadsheet") oDocTMP.Sheets.insertByName("MySheet", oSheetTMP) oRangeTMP = oSheetTMP.getCellRangeByName("A1") oRangeTMP.Formula = sFormula vResult = vResult + oRangeTMP.Value oDocTMP = Nothing oSheetTMP = Nothing oRangeTMP = Nothing End If Next SUMIFOS = vResult End Function 会很容易,不会吗?

        关于宏观问题:

        不,因为PHP只能将长Public Function SUMIFOS(sSheetName As String, lColSearch As Long, vSearchValue As Variant, lColSum As Long) As Variant Set oWB = ThisWorkbook vResult = 0 Set oRegExp = CreateObject("vbscript.regexp") oRegExp.Pattern = sSheetName For Each oSheet In oWB.Sheets If oRegExp.test(oSheet.Name) Then Set rSearchColumn = oSheet.Columns(lColSearch) Set rSumColumn = oSheet.Columns(lColSum) vResult = vResult + WorksheetFunction.SumIf(rSearchColumn, vSearchValue, rSumColumn) End If Next SUMIFOS = vResult End Function 公式放入单元格中。使用VBA或Starbasic,您可以拥有UDF(用户定义函数)。这更加灵活。

        示例Openoffice Libreoffice

        =SUMIFOS("2015.0[1,4]",8,C20,4)
        

        示例VBA

        C20

        用作公式:

        {{1}}

        匹配&#34; 2015.0 [1,4]&#34;如果第8列包含值{{1}}。

答案 1 :(得分:0)

提供此代码:

Sub CreateSumIfFormulaForAllSheets()
  Tmp = ""
  For i = 1 To Sheets.Count
    Tmp = Tmp & IIf(Tmp = "", "=SUMIF('" & Sheets(i).Name & "'!H:H,C20,D:D)", "+SUMIF('" & Sheets(i).Name & "'!H:H,C20,D:D)")
  Next i
Range("A1").Formula = Tmp
End Sub

假设您试图在所有工作表中C20位于H列的所有工作表上的D列中获取所有值的单个总和,这将起作用。只需改变&#34; A1&#34;对于你的公式通常所在的任何单元格。除非你的列D中有错误值,否则你不必担心ISNUMBER,因为SUMIF会忽略文本。

如果您确实需要定义这些列范围(例如H2:H67),而不是仅仅查看整个列,那么您需要指定在编码之前用于进行确定的标准进入这个宏。你确实说过&#34;整列&#34;,这肯定会看整个专栏。