简体   繁体   English

在多个工作表中更新外部单元格引用(使用vba宏)

[英]Updating external cell references across multiple worksheets (using vba macro)

I'm completely new to VBA and Excel macros in general so I'll try to explain my predicament as clearly as possible. 一般来说,我对VBA和Excel宏是完全陌生的,所以我将尝试尽可能清楚地解释我的困境。 Basically I've got two workbooks, the source workbook which contains a single worksheet with nearly thousands of rows and columns and another workbook with 90+ worksheets, each with two tables that references cells from the source workbook (the tables cover monthly data for the last four fiscal years). 基本上,我有两个工作簿,一个是源工作簿,它包含一个具有近数千行和几列的工作表,另一个是具有90多个工作表的工作簿,每个工作簿都有两个表,这些表引用了源工作簿中的单元格(这些表涵盖了每月的数据最近四个会计年度)。

I've shoe-stringed together an automation macro that mostly works, but my primary concern is that it could be done better, specifically I've got one section of code: 我已经将大部分可以正常工作的自动化宏串在一起,但是我主要担心的是它可以做得更好,特别是我有一段代码:

'October
cellVarO = ActiveSheet.Range("B8").Formula
cellVarO = Right(cellVarO, 5)
Range("B8").Select
ActiveCell.Formula = "=OFFSET('C:\external\[reference_sheet.xls]Mnthly Rdgs'!" & cellVarO & ",0," & fyNum * 12 & ")"

One thing to note is that this code repeats 24 times, one for each month, and another iteration to use MID so that I'm still selecting the right cell value from the active cell formula (after changing the original formula to include OFFSET). 需要注意的是,此代码重复24次,每个月重复一次,并使用MID进行另一次迭代,以便我仍在从活动单元格公式中选择正确的单元格值(将原始公式更改为包括OFFSET后)。 I find this bulky and unnecessary but it's the only way I can wrap my mind around the problem. 我觉得这很笨重,没有必要,但这是我解决问题的唯一方法。 Another issue, it considers that the cell reference will always be 5 characters long. 另一个问题是,它认为单元格引用将始终为5个字符长。 There are instances where this is not the case. 在某些情况下并非如此。

But basically my months are laid out by column and my years are laid out by row, what I was aiming to do here was look in the cell formula for the cell reference, select the cell value, then use OFFSET to shift the value 12 columns to the most recent one, and print the new value to the most recent year. 但是基本上我的月份是按列排列的,而我的年份是按行排列的,我的目的是查看单元格引用的单元格公式,选择单元格值,然后使用OFFSET将值移动12列到最新的值,并将新值打印到最近的一年。 Suppose if I have the cell formula: 假设我有单元格公式:

='C:\external\[reference_sheet.xls]Mnthly Rdgs'!QR938

My goal is to take the cell value here (QR938) and shift it right 12 columns. 我的目标是在此处获取单元格值(QR938)并将其右移12列。 Is there any way to pick out the cell value (other than using MID/RIGHT) and assign it to a variable to offset? 有什么方法可以选择单元格值(使用MID / RIGHT除外)并将其分配给要偏移的变量? Is there a better way to shift the cell value 12 columns other than using OFFSET? 除了使用OFFSET之外,还有更好的方法将单元格值移动12列吗? Finally, is there any way to perform that same operation across multiple similarly formatted worksheets? 最后,有没有办法在多个格式相似的工作表上执行相同的操作?

See if this helps 看看是否有帮助

For testing the main code: 用于测试主要代码:

Sub Tester()

    'offset 12 cols to right
    OffsetFormulaReference ActiveSheet.Range("B8"), 0, 12

    'offset 12 cols to left
    OffsetFormulaReference ActiveSheet.Range("B9"), 0, -12

    'offset 12 rows down
    OffsetFormulaReference ActiveSheet.Range("B10"), 12, 0

    'offset 12 rows up
    OffsetFormulaReference ActiveSheet.Range("B11"), -12, 0


    'EDIT: loop over sheets and edit a specific range
    Dim c As Range, sht as WorkSheet
    For Each sht in ThisWorkbook.Sheets
        For each c in sht.Range("B8:B20").Cells
            OffsetFormulaReference c, 12, 0
        Next c
    Next sht

End Sub

Utility method for taking the formula from a cell with an external reference and moving it over by the specified number of rows/columns: 从带有外部引用的单元格中获取公式并将其移至指定的行数/列数的实用方法:

Sub OffsetFormulaReference(c As Range, offsetRows, offsetCols)

    Dim origForm As String, origAddr As String
    Dim arr, rng As Range, newAddr As String

    If c.HasFormula Then
        origForm = c.Formula
        '(e.g.)  ='C:\external\[reference_sheet.xls]Mnthly Rdgs'!QR938

        If InStr(origForm, "!") > 0 Then

            arr = Split(origForm, "!") 'arr(1) = "QR938"
            Set rng = ActiveSheet.Range(arr(1)) 'get a range reference
            Set rng = rng.Offset(offsetRows, offsetCols) 'move the reference
            newAddr = rng.Address(False, False) 'get the offset address
            'replace old formula with new offset reference
            c.Formula = arr(0) & "!" & newAddr
        End If
    End If
End Sub

Note: you'll get an error if you try to use Offset() to move the rng reference beyond the limits of the sheet (eg. row or column < 1). 注意:如果尝试使用Offset()rng引用移到图纸的限制之外(例如,行或列<1),则会出现错误。 You can add logic to handle that if it might be an issue. 您可以添加逻辑以处理可能的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM