How to disable Excel's automatic cell reference change after copy/paste?

后端 未结 13 2235
温柔的废话
温柔的废话 2020-12-07 23:14

I\'ve got a massive Excel 2003 spreadsheet I\'m working on. There are a lot of very large formulas with a lot of cell references. Here\'s a simple example.

=         


        
相关标签:
13条回答
  • 2020-12-07 23:31

    Simple workaround I used just now while in a similar situation:

    1. Make a duplicate of the worksheet.
    2. Cut + Paste the cells with formulas from the duplicate worksheet (e.g. Copy of Sheet1) into the original worksheet.
    3. Remove all occurrences of the the duplicate sheet's name from the newly pasted formulas; e.g. find-and-replace all occurrences of the search term 'Copy of Sheet1'! with an empty string (i.e. blank).
    4. Delete duplicate worksheet to clean up.

    Note: if your sheet name lacks spaces you won't need to use the single quote/apostrophe (').

    Your cell references are now copied without being altered.

    0 讨论(0)
  • 2020-12-07 23:33

    It's common to use find/ replace to disable formulas whilst performing manipulations. For example, copy with transpose. The formula is disabled by placing some placeholder (e.g. "$=") in front of it. Find replace can get rid of these once the manipulation is complete.

    This vba just automates the find/ replace for the active sheet.

    ' 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
    
    0 讨论(0)
  • 2020-12-07 23:39

    I think that you're stuck with the workaround you mentioned in your edit.

    I would start by converting every formula on the sheet to text roughly like this:

    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
    

    where the 'ZZZ uses the ' to signify a text value and the ZZZ as a value that we can look for when we want to convert the text back to being a formula. Obviously if any of your cells actually start with the text ZZZ then change the ZZZ value in the VBA macro to something else

    When the re-arranging is complete, I would then convert the text back to a formula like this:

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

    One real downside to this method is that you can't see the results of any formula while you are re-arranging. You may find that when you convert back from text to formula that you have a slew of #REF errors for example.

    It might be beneficial to work on this in stages and convert back to formulas every so often to check that no catastrophes have occurred

    0 讨论(0)
  • 2020-12-07 23:40

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

    1. Put Excel in formula view mode. The easiest way to do this is to press Ctrl+` (that character is a "backwards apostrophe," and is usually on the same key that has the ~ (tilde).
    2. Select the range to copy.
    3. Press Ctrl+C
    4. Start Windows Notepad
    5. Press Ctrl+V to past the copied data into Notepad
    6. In Notepad, press Ctrl+A followed by Ctrl+C to copy the text
    7. Activate Excel and activate the upper left cell where you want to paste the formulas. And, make sure that the sheet you are copying to is in formula view mode.
    8. Press Ctrl+V to paste.
    9. Press Ctrl+` to toggle out of formula view mode.

    Note: If the paste operation back to Excel doesn't work correctly, chances are that you've used Excel's Text-to-Columns feature recently, and Excel is trying to be helpful by remembering how you last parsed your data. You need to fire up the Convert Text to Columns Wizard. Choose the Delimited option and click Next. Clear all of the Delimiter option checkmarks except Tab.

    Or, from 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
    
    0 讨论(0)
  • 2020-12-07 23:42

    This macro does the whole job.

    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
    

    Note that you must match the size and shape of the original selection when you make your new selection.

    0 讨论(0)
  • 2020-12-07 23:42

    I found this solution which automates @Alistair Collins solution.

    Basically you will change the = in any formula to * then do the paste after that you will change it back

            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 讨论(0)
提交回复
热议问题