VBA - 用于跨多个范围的其他尚未创建的新工作表添加值的主工作表

VBA - Main worksheet to add values across other new not yet created worksheets across multilpe ranges

我是 VBA 的新手,喜欢挑战自己,但在这个项目上却不知所措。

我有一个工作簿,其中有很多用于各种计算和求和的选项卡。 "PDP Base" 主选项卡包含所有 "PDP BaseX" 选项卡,并将所有 "PDP BaseX" 选项卡中同一单元格的所有值添加到主选项卡中。当只有 5 个左右 "PDP BaseX" 选项卡时,这很容易手动处理,但如果可能有很多选项卡要加在一起(10+),梳理每个选项卡会很痛苦。如果有多种情况要向 (PNP;PBP;PUD;PBL - 每个都有 Base 和 Sens 修饰符) 添加公式,情况会变得更糟。

每个新的 "PDP BaseX" 选项卡都是由其他代码(尚未完成)从模板 运行 复制粘贴的,具有新的 "X+1" 值,所以我不想只需复制粘贴一个公式,将新选项卡添加到主选项卡中。

最终结果将包含每个类别的所有主要选项卡的代码,但如果我可以获得一个主要选项卡来执行我想要的操作,我可以从那里开始。

下面是一些我觉得很接近的代码,但它在其中某处循环到无穷大并且不会移动通过初始单元格 B29(当结果应该是 10 时溢出到 PDP Base B29;PDP Base1 B29 = 2; PDP Base2 B29 = 6; PDP Base3 B29 = 4)

Private Sub Worksheet_Calculate()
Dim ws As Worksheet, mainws As Worksheet
Dim rng As Range, mainrng As Range
Dim x As Single, y As Single
Dim tVar As Double

Set mainws = ActiveWorkbook.Worksheets("PDP Base")

With mainws
 For y = 2 To 4
  For x = 29 To 43
   For Each ws In ActiveWorkbook.Worksheets
    If ws.Name Like "PDP Base*" And ws.CodeName <> "PDPBase" Then 
              'the main tab has a codename assigned to it to not add itself
     With ws
      With .Range(Cells(x, y))
       tVar = tVar + .Range(Cells(x, y)).Value

      End With
     End With
    End If
   Next ws

  Set mainrng = Cells(x, y)
  mainrng.Value = tVar
  tVar = 0

 Next x
Next y
End With
End Sub

有人可以对此发表一些见解吗?谢谢!

未经测试但应该做你想做的事:

Private Sub Worksheet_Calculate()

    Const MAIN_WS_NAME As String = "PDP Base" 'use a constant for fixed values

    Dim ws As Worksheet, mainws As Worksheet, wb As Workbook
    Dim x As Long, y As Long 'Long not Single
    Dim tVar As Double

    Set wb = ActiveWorkbook
    Set mainws = wb.Worksheets(MAIN_WS_NAME)

    For y = 2 To 4
        For x = 29 To 43
            tVar = 0
            For Each ws In wb.Worksheets
                If ws.Name Like MAIN_WS_NAME & "*" And ws.Name <> MAIN_WS_NAME Then
                    tVar = tVar + ws.Cells(x, y).Value
                End If
            Next ws
            mainws.Cells(x, y).Value = tVar
        Next x
    Next y

End Sub

自从我 post 编辑了最初的问题以来已经有一段时间了,但从那时起我已经取得了更多进展,只是想 post 我的进步供其他人使用,以防他们需要类似的东西.

还有很多清洁工作可以做,还没有完成,但是基本的想法确实非常很好。该代码采用几个 codenamed(不是选项卡名称;允许用户将选项卡名称更改为不同的名称)主要 sheets 并循环遍历每个,添加动态添加单元格的公式类似命名的 subsheets 进入主 sheet 跨越多个单元格块。

还要感谢 Tim Williams 再次提供的原始答案,因为它极大地帮助我朝着正确的方向前进,并且是下面代码的基础。

使用风险自负。 我听说 CodeNames 并使用 VBProject 类型的代码,如果它们损坏,会给您带来糟糕的一天。

下面的主要代码

Public Sub Sheet_Initilization()

Dim ws As Worksheet, mainws As Worksheet, wb As Workbook
Dim codename As String
Dim mainwsname As String

Set wb = ActiveWorkbook

'block code to run code smoother
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Application.EnableEvents = False

'PLACEHOLDER FOR LATER USE CaseNames = Array("PDPBase", "PDPSens", "PBPBase", "PBPSens", "PNPBase", "PNPSens", "PUDBase", "PUDSens")

CaseNames = Array("PDPBase", "PBPBase", "PNPBase", "PUDBase") 'main 4 cases, more to come

For Each c In CaseNames     'cycle through each "Main" case sheet
    codename = c
    Set mainws = wb.Sheets(CN(wb, codename)) 'calls function to retrieve code name of the main case sheet
                                             'allows users to change main case tab names without messing up the codes
                                             'must change security settings to use, looking into alternatives

    mainwsname = mainws.Name 'probably could do without with some optimization

For Each b In Range("InputAdditionCells").Cells 'uses named range of multiple blocks of cells, B29:D34  M29:O43  I53:J68 for example
                                                'cycles through each cell in every block

    mainws.Range(b.Address).Formula = "=" 'initial formula
    For Each ws In wb.Worksheets 'cycles through each sheet
        If ws.Name Like mainwsname & "*" And ws.Name <> mainwsname Then    'finds similarily named sub sheets (PDP Base 1, PDP Base 2...etc)
                                                                           ', but won't use the main sheet (PDP Base)

            If b.Address Like "$Y*" Then 'special column to use different offset formula
                mainws.Range(b.Address).Formula = mainws.Range(b.Address).Formula & "+'" & ws.Name & "'!" & b.Offset(0, 4).Address
            Else
                mainws.Range(b.Address).Formula = mainws.Range(b.Address).Formula & "+'" & ws.Name & "'!" & b.Address
            End If
        End If
    Next ws
Next b

For Each d In Range("InputWeightedCells").Cells 'same idea as before, different main formula (weighted average)
    mainws.Range(d.Address).Formula = "="
    For Each ws In wb.Worksheets
        If ws.Name Like mainwsname & "*" And ws.Name <> mainwsname Then
            If d.Address Like "*" Then 'special row to use different offset formula
                mainws.Range(d.Address).Formula = mainws.Range(d.Address).Formula & "+('" & ws.Name & "'!" & d.Address _
                & "*'" & ws.Name & "'!" & d.Offset(-21, 23).Address & ")"
            Else
                mainws.Range(d.Address).Formula = mainws.Range(d.Address).Formula & "+('" & ws.Name & "'!" & d.Address _
                & "*'" & ws.Name & "'!" & d.Offset(-24, 23).Address & ")"
            End If
        End If
    Next ws
Next d

MsgBox (mainwsname) 'DELETE; makes sure code is running properly/codebreak without using the break feature

Next c

'reactivate original block code
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
Application.EnableEvents = True

End Sub 'cool beans

调用的函数(需要将信任中心设置中的宏设置从 excel 选项更改为 运行)。再次使用风险自负。

Function CN(wb As Workbook, codename As String) As String

CN = wb.VBProject.VBComponents(codename).Properties("Name").Value

End Function