vba/excel - 如何使用 RC 表示法从不同的 sheet 复制公式,同时保持相对引用

vba/excel - How to use RC notation to copy formula from different sheet while maintaining relative references

我正在尝试将公式从另一个 sheet(“SCE_Tables”)复制到中央 sheet(“主”)。 “SCE_Tables”包含我正在复制到主目录的参考表,基于用户填写的表格中的 selections。

“SCE_Tables”中的公式使用 RC 表示法从第 2 列左侧 ('Prebill') 和第 1 列 ('Post BESS Bill') 中减去值'BESS Savings' 列中的单元格: 在下面突出显示的单元格中:

公式: =RC[-2]-RC[-1] .此单元格位于第 15 行第 6 列

当我尝试用这些表格填充“主要”sheet 范围时出现问题。这些表格所在的“主要”sheet 范围与参考表格具有相同的格式: 下面突出显示的单元格(在“主”sheet 上)位于第 21 行第 18 列。此单元格中的公式为:

公式: =R[-6]C[-14]-R[-6]C[-13]

复制到“Main”的 RC 引用 sheet 将 RC 引用转换回“SCE_Tables”sheet 中的 RC 引用,导致公式试图计算:

(R15, C4) - (R15, C5) 在主要 sheet 上,当我想要的公式是:

(R21, C16) - (R21, C15)

有没有办法动态创建一个公式来计算“主”单元格左侧第 2 个单元格和第 1 个单元格之间的差异 sheet?

编辑:包括我的一些 VBA 代码 处理 ListBox selections:

Public Sub FormatListboxSelections(ByVal selectionNameArray As Variant)
    testInt = 0

    'Entire possible area for tables
    Dim tableRange As Range
    Set tableRange = Range("TableRange")
    Dim SDR As Range
    Set SDR = Range("ScenarioDetailsRange")
    
    
    'Electricity Provider
    Dim i As Integer, elecProvider As String
    elecProvider = Range("input_electricity_provider").Value
    
    'Clear range
    tableRange.ClearContents
    SDR.ClearContents
    
    Dim currRow As Integer, leftCol As Integer, startingCell As Range
    currRow = 1
    
    'Loop through all selections
    For i = LBound(selectionNameArray) To UBound(selectionNameArray)
        Dim selectionTableObj As Variant
        
        Dim scenario As String
        scenario = selectionNameArray(i)
        'If arr(i) == 0, we've reached end of the selected values
        If Len(scenario) = 0 Then
            Debug.Print "Exiting loop at index " & i
            Exit For
        Else
            'Check for each scenario type
            'PV only scenario
            If scenario = "PV Only" Then
                Set selectionTableObj = HandlePVOnly(electricityProvider:=elecProvider, scenario:=scenario)
            ElseIf scenario = "2hr Only" Or scenario = "4hr Only" Then
                Set selectionTableObj = HandleBESSOnly(electricityProvider:=elecProvider, scenario:=scenario)
            Else
                Set selectionTableObj = HandleComboScenario(electricityProvider:=elecProvider, scenario:=scenario)
            End If
        selectionTableObj.UpdateAllFields
        testInt = testInt + 1
        End If
        
        Dim x As Integer
        'Iterate through all rows in the selected table
        For x = 1 To selectionTableObj.m_table.Rows.Count
            Dim dummy As Variant
            Set dummy = Application.WorksheetFunction.Index(selectionTableObj.m_table.Rows, x, 0)
            Dim selectionTableRow As Variant
            Set selectionTableRow = selectionTableObj.m_table.Rows(x)
            
            'Update single row
            '***HERE IS WHERE THE SELECTED TABLES GET WRITTEN TO THE MAIN 
            'WORKSHEET***
            Dim j As Integer
            For j = 1 To dummy.Columns.Count
                tableRange(currRow, j).Formula = dummy(1, j).Formula
            Next j
        
            'increment currRow
            currRow = currRow + 1
        
        Next x
        
    Next
    
    'If full selection, also show respective extra inputs
    If UBound(selectionNameArray) = 7 Then
        PopulateExtraInputs elecProvider
    End If
End Sub

为了处理 BESS 场景(用户可以使用表单 select 的 3 种场景类型之一),我使用工厂模块并调用 BESSScenarioTable class 中的 'InitiateProperties' 子例程模块:

Public Function CreateBESSScenarioTable(ByVal table As Range, scenario As String, scenarioDetailsArray As Variant, tableLength As Integer, ByVal result As ScenarioResult, tariffs As Variant)
    Set CreateBESSScenarioTable = New BESSScenarioTable
    CreateBESSScenarioTable.InitiateProperties table:=table, scenario:=scenario, scenarioDetailsArray:=scenarioDetailsArray, tableLength:=tableLength, result:=result, tariffs:=tariffs
End Function
'Constructor
Public Sub InitiateProperties(table As Range, scenario As String, scenarioDetailsArray As Variant, tableLength As Integer, result As ScenarioResult, tariffs As Variant)
    Set m_table = table
    'Using Formula instead of Value to capture column relationships in "Source of Truth" tables (PGE_Tables, SDGE_Tables, SCE_Tables worksheets)
    Debug.Print "Address: " & m_table.address
    Dim xc As Integer, yc As Integer
    For xc = 1 To m_table.Rows.Count
        For yc = 1 To m_table.Columns.Count
            Debug.Print "(" & xc & ", " & yc & ") - Formula: " & m_table.Cells(xc, yc).Formula
        Next yc
    Next xc
    m_table.FormulaR1C1 = table.FormulaR1C1
    m_scenario = scenario
    m_scenarioDetailsArray = scenarioDetailsArray
    m_tableLength = tableLength
    Set m_result = result
    m_tariffs = tariffs
End Sub

弄清楚了 - 结果在我的 VBA 代码中我复制了 table,我需要使用 tableRange(currRow, j).FormulaR1C1 = dummy(1, j).FormulaR1C1,而不是我以前的代码:tableRange(currRow, j).Formula = dummy(1, j).Formula

这个 link 有助于了解 Excel 使用的不同符号:https://powerspreadsheets.com/r1c1-formular1c1-vba/