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/
我正在尝试将公式从另一个 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/