如何使用VBA创建公式来引用单元格的动态偏移范围?

时间:2018-11-28 14:34:15

标签: excel vba

这是一个非常奇怪的特定需求,最后我需要完成我的新宏套件。

Example Image

注意:工作表顶部的“ ---”代表同一份报告的前几个月返回

如您在上面的图像中所见,我有两个突出显示的部分。我需要根据上一个报告的编号,将G列设为E和F的总和。由于每天都会添加一组新数据,因此我无法引用特定的单元格,并且它必须是动态的。这里更大的问题是我的客户数量会经常变化。它将上升,并且总是以相同的顺序;即使失去客户,他们也会留在同一地点的报告中。

关于如何完成此操作的唯一理论是:

  1. 找到客户A的倒数第二个实例,并基于右侧的偏移量单元格定义一个rng。我的问题是,据我所知,即使一直填写该公式也只会给我一个价值。
  2. =SUM((INDIRECT(ADDRESS(ROW()-5,COLUMN()-2))):(INDIRECT(ADDRESS(ROW()-5,COLUMN()-1))))添加到空白单元格。我的问题是,偏移量中的-5可以更改,甚至用空白单元格的数量来定义它也会在第一次有新客户出现时引起错误。

任何见识将不胜感激。如果您有任何疑问,请告诉我;我很乐意根据需要回答/编辑原始帖子。

2 个答案:

答案 0 :(得分:0)

@Gserg在我面前得到了一个答案,他的解决方案是一条很好的路线,尽管我认为这是假设每天那里都会有物品(如果我没记错的话),并且您的屏幕截图建议他们可能并非一直都是连续几天。

如果您仍在寻找VBA解决方案,我会做这样的事情:

Option Explicit    
Sub addOffsetFormula()

    'Declare and set your workbook
    Dim wb As Workbook: Set wb = ActiveWorkbook

    'Declare and set your spreadsheet
    Dim shData As Worksheet: Set shData = wb.Worksheets("Data")

    'Set your last row/column for a dynamic aproach
    Dim lRow As Long: lRow = shData.Cells(1, 1).End(xlDown).Row
    Dim lCol As Long: lCol = shData.Cells(1, shData.Columns.Count).End(xlToLeft).Column

    'Declare some further variables to help
    Dim R As Long, X As Long
    Dim sumFormula As String

    'Declare and set your array to hold your data - much faster to iterate through the array than spreadsheet itself
    Dim tblData(): tblData = shData.Range(shData.Cells(1, 1), shData.Cells(lRow, lCol))

    For R = LBound(tblData) + 1 To UBound(tblData)              'Iterate through your data
        For X = LBound(tblData) + 1 To UBound(tblData)          'Iterate through the same data again
            If tblData(R, 4) = tblData(X, 4) And X > R Then     'Check for match with the next client found (assuming clients are unique)

                'Set your formula to a variable, helps with debugging
                sumFormula = "=SUM(R[-" & X - R & "]C[-2]+R[-" & X - R & "]C[-1])"

                'Assign the formula to the respective cell _
                    If the spreadsheet is massive, you might need to add some optimisation _
                    (ie: assign everything to an array first, then dump into the spreadsheet)
                shData.Cells(X, 7).FormulaR1C1 = sumFormula
            End If
        Next X
    Next R

End Sub

注意:它不会在前几行或新客户端中添加任何内容,因为之前没有任何匹配项,但我希望它也适用于任何公式。

答案 1 :(得分:-1)

实际上可以通过预先计算范围来进一步优化它,但是简单的版本是:

=SUMIFS([Outstanding Mail],[Date],LOOKUP([@Date]-1,[Date]),[Customer],[@Customer])
+SUMIFS([Outstanding Faxes],[Date],LOOKUP([@Date]-1,[Date]),[Customer],[@Customer])

这取决于您对日期进行排序的事实,并且LOOKUP返回的最后一个值不大于所提供的值,因此[@Date]-1使其查找的最大日期是少于提供的日期。无法在未排序的范围内使用。