如何禁用Excel复制/粘贴后自动更改单元格引用?

43

我正在处理一个非常庞大的Excel 2003电子表格,其中有很多涉及大量单元格引用的大型公式。以下是一个简单示例。

='Sheet'!AC69+'Sheet'!AC52+'Sheet'!AC53)*$D$3+'Sheet'!AC49

大多数情况比这个更复杂,但这个例子可以很好地说明我所面对的问题。 这些单元格引用中很少有绝对引用($s)。我想能够将这些单元格复制到不同的位置而不改变单元格引用。 我知道我可以使用f4使引用变为绝对引用,但是数据量很大,我可能需要稍后使用填充功能。有没有办法在复制粘贴/填充时临时禁用单元格引用的更改而不使引用成为绝对引用?

编辑:我刚刚发现可以通过将单元格内容复制为文本而不是公式来使用VBA做到这一点。 不过,我不想这样做,因为我想一次性复制整行/列。 我是否遗漏了简单的解决方案?


很好的问题!在VBA中,循环不能解决您剩余的问题吗? - Jonas Heidelberg
13个回答

56

http://spreadsheetpage.com/index.php/tip/making_an_exact_copy_of_a_range_of_formulas_take_2

  1. 将 Excel 切换到公式视图模式。最简单的方法是按 Ctrl+` 键。(该键位于同一键上,通常带有 ~(波浪线)字符)。
  2. 选择要复制的区域。
  3. 按下 Ctrl+C
  4. 打开 Windows 记事本。
  5. 按下 Ctrl+V 将复制的数据粘贴到记事本中。
  6. 在记事本中,按下 Ctrl+A 然后按下 Ctrl+C 复制文本。
  7. 激活 Excel 并激活您想要粘贴公式的左上角单元格。并确保您要复制到的工作表处于公式视图模式。
  8. 按下 Ctrl+V 进行粘贴。
  9. 按下 Ctrl+` 以切换出公式视图模式。

注:如果将数据粘贴回 Excel 时出现问题,很可能是您最近使用了 Excel 的“文本转列”功能,并且 Excel 尝试通过记住上次如何解析数据来帮助您。您需要启动“文本转列向导”。选择“分隔符”选项并单击“下一步”。清除除“制表符”之外的所有分隔符选项复选标记。

或从http://spreadsheetpage.com/index.php/tip/making_an_exact_copy_of_a_range_of_formulas/

If you're a VBA programmer, you can simply execute the following code: 
With Sheets("Sheet1")
 .Range("A11:D20").Formula = .Range("A1:D10").Formula
End With

看起来你可以将内容粘贴到不在公式视图模式下的工作表中;尽管其他所有内容都是严格必要的,但按照字面意思做也没有坏处。因为这非常有帮助且易于理解,所以我给它加了一个赞。我不明白为什么Excel会假设我们想要引用另一个文件中的单元格,但至少有一个很好的解决方法。 - ZeroK
4
这个回答很棒 - 我希望我能够为原始作者接受它。作为一名程序员,VBA对我来说并不可怕,但如果可以避免的话,我不会使用它来仅复制和粘贴一些单元格... Excel 真的应该内置一个“粘贴而不更新公式”的选项。 - JPhi1618
@JPhi1618 是的,完全正确。我不知道为什么他们不会提供“粘贴”而不更新公式。最让我困扰的是,除了 MS Office、Google Sheet 或 WPS Office 之外,还有更多的电子表格提供商,它们只是互相重复。我怀念他们在技术和功能方面创新的时代。每次发布都会有巨大的改进。但一些基本的东西却缺失了。 - Mohammed Joraid

24
一个非常简单的解决方案是选择你想要复制的范围,然后使用查找和替换(Ctrl + h),将=替换成另一个在公式中未使用的符号(例如#) - 这将停止它作为一个活动公式。
然后,将所选范围复制并粘贴到新位置。
最后,再次使用查找和替换将原始范围和新范围中的#替换回=,从而将两个范围恢复为公式。

3
到目前为止,遗憾的是,这是我最满意的解决方案。如果有一个简单地实现这个功能的替代快捷方式就更好了。 - sshine
如果你正在将数据复制到不同的工作表,那么这个解决方案就不起作用了......可悲的是,这种功能大多数情况下都是需要的。 - Faustin Gashakamba

6
我来到这个网站是为了寻找一种简单的方法来复制而不改变单元格引用。但现在我认为我的解决方法比大多数方法都更简单。我的方法依赖于复制会更改引用,但移动不会更改的事实。以下是一个简单的例子。
假设您在A列和B列中有原始数据,在C列中有一个公式(例如,C=A+B),您希望在F列中使用相同的公式,但是从C复制到F会导致F=D+E。
1. 复制C的内容到任何空的临时列R中。相对引用将更改为R=P+Q,但忽略它即使它被标记为错误也一样。 2. 回到C并将其移动(而不是复制)到F。该公式应该保持不变,因此F=A+B。 3. 现在转到R并将其复制回C。相对引用将恢复为C=A+B。 4. 删除R中的临时公式。 5. 就这样!
我已经在一系列单元格中使用了此方法,因此我想它可以处理几乎任何复杂度水平的问题。您只需要一个空区域来停放复制的单元格。当然,您必须记住您把它们放在哪里了。

如果您想将引用第二行的第一行复制到第11行,则:
  1. 将其复制到第11行,然后它将引用第12行。
  2. 剪切并粘贴到第21行,然后它仍将引用第12行。
  3. 从21复制到11,然后它将引用第2行,正如所需。
- alexkovelsky
1
对我来说,这似乎很简单,将其复制到偏移量,移动原始内容,将偏移量复制回来,然后删除偏移量。 - will
对我来说,这是最简单的,因为我几乎可以闭着眼睛双手在键盘上完成。此外,您可以一次性完成整个区域或行:Ctrl+C -> Ctrl+V,然后Ctrl+X -> Ctrl+V,根据需要重复。例如,在具有指向表格外部的引用的表格中复制某些行时,这是最好的方法:它更新所选内容内部的引用,同时保留所选内容外部的引用。 - pjvleeuwen

1

这个简单的技巧很有效:复制并粘贴。不要剪切和粘贴。在粘贴后,重新选择你复制的部分,然后进入编辑,滑动到清除,清除内容。


1

我最近在类似的情况下使用了一个简单的解决方法:

  1. 复制工作表。
  2. 从复制的工作表(例如 Sheet1 的副本)中剪切+粘贴包含公式的单元格到原始工作表中。
  3. 删除新粘贴的公式中所有重复工作表名称的出现;例如,查找并替换所有搜索项 'Sheet1 的副本'! 为一个空字符串(即空白)。
  4. 删除重复的工作表以进行清理。

注意:如果您的工作表名称没有空格,则不需要使用单引号/撇号(')。

现在,您的单元格引用已经被复制而没有被更改。


听起来这可能是一个不错的解决方案,但我已经失去了对这个解决方案的掌握。您能否重新表述答案并更加明确地说明一下? - Faustin Gashakamba

0

我认为你需要使用你在编辑中提到的解决方案。

我会从将表格上的每个公式大致转换为文本开始:

Dim r As Range

For Each r In Worksheets("Sheet1").UsedRange
    If (Left$(r.Formula, 1) = "=") Then
        r.Formula = "'ZZZ" & r.Formula
    End If
Next r

在这里,'ZZZ 使用 ' 表示文本值,而 ZZZ 则是我们想要将文本转换回公式时要查找的值。显然,如果您的任何单元格实际上以文本 ZZZ 开头,则在 VBA 宏中更改 ZZZ 值为其他值。

当重新排列完成后,我会像这样将文本转换回公式:

For Each r In Worksheets("Sheet1").UsedRange
    If (Left$(r.Formula, 3) = "ZZZ") Then
        r.Formula = Mid$(r.Formula, 4)
    End If
Next r

这种方法的一个真正缺点是,当您重新排列时,无法查看任何公式的结果。例如,当您从文本转换回公式时,可能会发现有大量的#REF错误。

分阶段进行此操作可能会更有益,每隔一段时间将其转换回公式以检查是否发生了灾难。


0

在进行操作时,通常使用查找/替换来禁用公式。例如,使用转置复制。通过在公式前面放置一些占位符(例如“$ =”)来禁用公式。一旦完成操作,查找替换可以摆脱这些内容。

此VBA仅自动执行活动工作表的查找/替换。

' toggle forumlas on active sheet as active/ inactive
' by use of "$=" prefix

Sub toggle_active_formulas()
    Dim current_calc_method As String
    initial_calc_method = Application.Calculation
    Application.Calculation = xlCalculationManual
    Dim predominant As Integer
    Dim c As Range
    For Each c In ActiveSheet.UsedRange.Cells
        If c.HasFormula Then
            predominant = predominant + 1
        ElseIf "$=" = Left(c.Value, 2) Then
            predominant = predominant - 1
        End If
    Next c
    If predominant > 0 Then
        For Each c In ActiveSheet.UsedRange.Cells
            On Error Resume Next
            If c.HasFormula Then
                c.Value = "$" & c.Formula
            End If
        Next c
    Else
        For Each c In ActiveSheet.UsedRange.Cells
            On Error Resume Next
            If "$=" = Left(c.Value, 2) Then
                c.Formula = Right(c.Value, Len(c.Value) - 1)
            End If
        Next c
    End If
    Application.Calculation = initial_calc_method
End Sub

请问您能否在这篇文章中加入更多的细节呢? - cdomination

0
我找到了一个自动化@Alistair Collins解决方案的方法。
基本上,您将更改任何公式中的=为*,然后进行粘贴,之后再将其改回。
        Dim cell As Range

msgResult = MsgBox("Yes to lock" & vbNewLine & "No unlock ", vbYesNoCancel + vbQuestion, "Forumula locker")

If msgResult = vbNo Then
    For Each cell In Range("A1:i155")
        If InStr(1, cell.Value, "*") > 0 Then
            cell.Formula = Replace(cell.Formula, "*", "=")
        End If
    Next cell
ElseIf msgResult = vbYes Then
    For Each cell In Range("A1:i155")
        If cell.HasFormula = True Then
            cell.Formula = Replace(cell.Formula, "=", "*")
        End If
    Next cell
End If

0

这个宏完成了整个工作。

Sub Absolute_Reference_Copy_Paste()
'By changing "=" in formulas to "#" the content is no longer seen as a formula.
' C+S+e (my keyboard shortcut)

Dim Dummy As Range
Dim FirstSelection As Range
Dim SecondSelection As Range
Dim SheetFirst As Worksheet
Dim SheetSecond As Worksheet

On Error GoTo Whoa

Application.EnableEvents = False

' Set starting selection variable.
Set FirstSelection = Selection
Set SheetFirst = FirstSelection.Worksheet

' Reset the Find function so the scope of the search area is the current worksheet.
Set Dummy = Worksheets(1).Range("A1:A1").Find("Dummy", LookIn:=xlValues)

' Change "=" to "#" in selection.
Selection.Replace What:="=", Replacement:="#", LookAt:=xlPart, _
    SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, ReplaceFormat:=False

' Select the area you want to paste the formulas; must be same size as original
  selection and outside of the original selection.
Set SecondSelection = Application.InputBox("Select a range", "Obtain Range Object", Type:=8)
Set SheetSecond = SecondSelection.Worksheet

' Copy the original selection and paste it into the newly selected area. The active
  selection remains FirstSelection.
FirstSelection.Copy SecondSelection

' Restore "=" in FirstSelection.
Selection.Replace What:="#", Replacement:="=", LookAt:=xlPart, _
SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, ReplaceFormat:=False

' Select SecondSelection.
SheetSecond.Activate
SecondSelection.Select

' Restore "=" in SecondSelection.
Selection.Replace What:="#", Replacement:="=", LookAt:=xlPart, _
SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, ReplaceFormat:=False

' Return active selection to the original area: FirstSelection.
SheetFirst.Activate
FirstSelection.Select

Application.EnableEvents = True

Exit Sub

Whoa:
' If something goes wrong after "=" has been changed in FirstSelection, restore "=".
FirstSelection.Select
Selection.Replace What:="#", Replacement:="=", LookAt:=xlPart, _
    SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, ReplaceFormat:=False

End Sub

请注意,在进行新的选择时,必须匹配原始选择的大小和形状。

-1
尝试这个: 左击标签,复制整个工作表,然后剪切要保持不变的单元格,并将它们粘贴到您的原始工作表中。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接