You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

VBA公式自动填充引用列错误求助:修正跨工作表股票收益率计算

Fixing VBA AutoFill Issue for Stock Return Calculation

Hey there, let's work through this AutoFill problem you're hitting. The core issue is that your target worksheet uses consecutive columns for returns, but the source price columns in the "Input" sheet are spaced out. AutoFill relies on relative references to increment columns automatically, which doesn't align with the non-consecutive layout of your input data—hence the wrong column references like D5/D$5 instead of the intended F5/F$5.

Why Your Original Code Fails

Your initial formula uses relative column references (C[1]) in FormulaR1C1. When you run AutoFill, Excel automatically increments that relative column index for each new target column. But since your Input sheet's price columns aren't consecutive, this incremental shift doesn't match the actual columns you need to reference.

The Solution: Manual Column Mapping Instead of AutoFill

Instead of relying on AutoFill, we'll explicitly map each target column to the correct price column in the Input sheet. This gives you full control over which Input column is used for each return calculation.

Here's the revised code, with breakdowns:

Sub CalculateStockReturns()
    Dim wsInput As Worksheet
    Dim wsTarget As Worksheet
    Dim inputPriceCols As Collection
    Dim lastTargetCol As Integer
    Dim targetCol As Integer
    Dim inputCol As Integer
    
    ' Set references to your worksheets (replace "TargetSheet" with your actual target sheet name)
    Set wsInput = ThisWorkbook.Worksheets("Input")
    Set wsTarget = ThisWorkbook.Worksheets("TargetSheet")
    
    ' Step 1: Collect column numbers of price data in Input sheet
    ' Assumption: Row 3 in Input sheet has stock names/price column headers
    Set inputPriceCols = New Collection
    For col = 1 To wsInput.Cells(3, wsInput.Columns.Count).End(xlToLeft).Column
        If wsInput.Cells(3, col).Value <> "" Then
            inputPriceCols.Add col ' Only add columns with valid header data
        End If
    Next col
    
    ' Step 2: Get last column in target sheet (matches your original logic)
    lastTargetCol = wsTarget.Cells(3, wsTarget.Columns.Count).End(xlToLeft).Column
    
    ' Step 3: Write formula to each target column with correct Input column mapping
    For targetCol = 2 To lastTargetCol ' Start at column B (2) as per your original setup
        ' Avoid exceeding the number of price columns in Input
        If targetCol - 1 <= inputPriceCols.Count Then
            inputCol = inputPriceCols(targetCol - 1) ' Map target column to Input price column
            
            ' Formula uses absolute row reference for base price (Row 5)
            wsTarget.Cells(4, targetCol).FormulaR1C1 = _
                "='" & wsInput.Name & "'!RC" & inputCol & "/'" & wsInput.Name & "'!R5C" & inputCol & "*100"
                
            ' Optional: Uncomment to fill formula down rows beyond row 4
            ' wsTarget.Range(wsTarget.Cells(4, targetCol), wsTarget.Cells(wsTarget.Cells(wsTarget.Rows.Count, targetCol).End(xlUp).Row, targetCol)).FillDown
        End If
    Next targetCol
End Sub

Key Details:

  • Explicit Column Mapping: We first collect all price columns in the Input sheet (using row 3 as the header row—adjust this if your headers are in a different row). This ensures we only reference columns that contain stock price data.
  • Absolute Row Reference: The formula uses R5C" & inputCol for the denominator, locking the row to 5 (your base price row). This means when you fill the formula down rows later, the denominator always points to row 5 of the correct Input column.
  • Flexibility: If you already know the exact column numbers of your price data (e.g., columns 6, 9, 12 for F, I, L), you can replace the collection setup with a static array like inputPriceCols = Array(6,9,12) for a simpler implementation.

Simplified Version for Known Columns

If you don't need to dynamically collect columns, use this trimmed-down code:

Sub CalculateStockReturnsStatic()
    Dim wsInput As Worksheet
    Dim wsTarget As Worksheet
    Dim inputPriceCols As Variant
    Dim lastTargetCol As Integer
    Dim targetCol As Integer
    
    Set wsInput = ThisWorkbook.Worksheets("Input")
    Set wsTarget = ThisWorkbook.Worksheets("TargetSheet")
    
    ' Define your Input price columns directly (e.g., F=6, I=9, L=12)
    inputPriceCols = Array(6, 9, 12)
    
    lastTargetCol = wsTarget.Cells(3, wsTarget.Columns.Count).End(xlToLeft).Column
    
    For targetCol = 2 To lastTargetCol
        If targetCol - 1 <= UBound(inputPriceCols) + 1 Then
            wsTarget.Cells(4, targetCol).FormulaR1C1 = _
                "='" & wsInput.Name & "'!RC" & inputPriceCols(targetCol - 2) & "/'" & wsInput.Name & "'!R5C" & inputPriceCols(targetCol - 2) & "*100"
        End If
    Next targetCol
End Sub

This approach eliminates AutoFill's guesswork and ensures each return column references exactly the right price column in your Input sheet.

内容的提问来源于stack exchange,提问作者Santis789

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:53:39