给一个参考代码:Option Explicit'Active Cell
Private Type FlxCell
    row As Long
    col As Long
End Type
Private m_ActiveCell As FlxCell'Undo
Private Type UndoType
    uText As String         'The whole Grid
    uRows As Long           'Count of Rows
    uCols As Long           'Count of Cols
    uName As String         'Undo Name
End TypePrivate m_UndoBuffer() As UndoTypePrivate intMaxUndo As IntegerPrivate Sub Form_Load()
    MSFlexGrid1.RowHeightMin = txtEdit.Height
    
    intMaxUndo = 40
    
    'Initialize Undobuffer
    EmptyUndoBuffer
    MakeUndoBuffer
End SubPrivate Sub Form_Resize()
    With MSFlexGrid1
        .Left = 0
        .Top = tbrMain.Top + tbrMain.Height
        .Width = Me.ScaleWidth
        .Height = Me.ScaleHeight - .Top
    End With
End SubPrivate Sub mnuEditCopy_Click()
    Clipboard.Clear
    Clipboard.SetText MSFlexGrid1.ClipEnd SubPrivate Sub mnuEditcut_Click()
    Clipboard.Clear
    Clipboard.SetText MSFlexGrid1.Clip
    Dim i As Integer
    Dim j As Integer
    Dim strClip As String
    With MSFlexGrid1
        For i = 1 To .RowSel
            For j = 1 To .ColSel
                strClip = strClip & "" & vbTab
            Next
            strClip = strClip & vbCr
        Next
        .Clip = strClip
    End With
    MakeUndoBuffer "Cut"End SubPrivate Sub mnuEditDelete_Click()
    Dim i As Integer
    Dim j As Integer
    Dim strClip As String
    With MSFlexGrid1
        For i = 1 To .RowSel
            For j = 1 To .ColSel
                strClip = strClip & "" & vbTab
            Next
            strClip = strClip & vbCr
        Next
        .Clip = strClip
    End With
    MakeUndoBuffer "Delete"End SubPrivate Sub mnuEditDelRow_Click()
    With MSFlexGrid1
        If .Rows > 2 Then
            .RemoveItem .row
            MakeUndoBuffer "Remove Row"
        End If
    End WithEnd SubPrivate Sub mnuEditInsertRow_Click()
    MSFlexGrid1.AddItem "", MSFlexGrid1.row
    MakeUndoBuffer "Insert Row"End SubPrivate Sub mnuEditPaste_Click()
    If Len(Clipboard.GetText) Then
        MSFlexGrid1.Clip = Clipboard.GetText
        MakeUndoBuffer "Paste"
    End IfEnd SubPrivate Sub mnuEditSelectAll_Click()
    With MSFlexGrid1
        .Visible = False
        .row = 1
        .col = 1
        .RowSel = .Rows - 1
        .ColSel = .Cols - 1
        .TopRow = 1
        .Visible = True
    End WithEnd SubPrivate Sub mnuEditUndo_Click()
    Undo
End SubPrivate Sub mnuFileExit_Click()
    Unload Me
End SubPrivate Sub MSFlexGrid1_DblClick()
    'Show Textbox for Input
    If MSFlexGrid1.row > 0 Then
        m_ActiveCell.row = MSFlexGrid1.row
        m_ActiveCell.col = MSFlexGrid1.col
        With txtEdit
            .Top = MSFlexGrid1.CellTop + MSFlexGrid1.Top
            .Left = MSFlexGrid1.CellLeft + MSFlexGrid1.Left
            .Width = MSFlexGrid1.CellWidth
            .Text = MSFlexGrid1.Text
            .Visible = True
            .ZOrder
            .SetFocus
        End With
    End IfEnd SubPrivate Sub tbrMain_ButtonClick(ByVal Button As MSComctlLib.Button)
    Select Case Button.Key
        Case "Cut"
            mnuEditcut_Click
        Case "Copy"
            mnuEditCopy_Click
        Case "Paste"
            mnuEditPaste_Click
        Case "Delete"
            mnuEditDelete_Click
        Case "Undo"
            Undo
        Case "InsertRow"
            mnuEditInsertRow_Click
        Case "DelRow"
            mnuEditDelRow_Click
    End Select
    
End SubPrivate Sub txtEdit_LostFocus()
    'Write the Contents of the Textbox into the Grid and hide the Textbox
    MSFlexGrid1.TextMatrix(m_ActiveCell.row, m_ActiveCell.col) = txtEdit.Text
    txtEdit.Visible = False
    MakeUndoBuffer "Input"
End SubPrivate Sub EmptyUndoBuffer()
    
    ReDim m_UndoBuffer(0)
    EnableUndo
End SubPrivate Sub Undo()
    Dim lngRow As Long
    Dim lngCol As Long
    Dim lngTopRow As Long
    
    With MSFlexGrid1
        .Visible = False
        lngRow = .row
        lngCol = .col
        lngTopRow = .TopRow
        .Rows = m_UndoBuffer(UBound(m_UndoBuffer) - 1).uRows
        .Cols = m_UndoBuffer(UBound(m_UndoBuffer) - 1).uCols
        
        .row = 1
        .col = 1
        .RowSel = .Rows - 1
        .ColSel = .Cols - 1
        
        .Clip = m_UndoBuffer(UBound(m_UndoBuffer) - 1).uText
        ReDim Preserve m_UndoBuffer(UBound(m_UndoBuffer) - 1)
        On Error Resume Next
        .row = lngRow
        .col = lngCol
        .TopRow = lngTopRow
        .Visible = True
    End With    EnableUndo
        
End SubPublic Sub MakeUndoBuffer(Optional UndoName As String)
    'You should call this Sub on every changes in the Grid
    On Error GoTo DimBuff
    Dim i As Long
    Dim j As Long
    Dim strClip As String
    Dim tmpClip() As UndoType
    
    With MSFlexGrid1
        For i = 1 To .Rows - 1
            For j = 1 To .Cols - 1
                strClip = strClip & .TextMatrix(i, j) & vbTab
            Next
            strClip = strClip & vbCr
        Next
        
        'No Changes.
        If strClip = m_UndoBuffer(UBound(m_UndoBuffer)).uText And _
        m_UndoBuffer(UBound(m_UndoBuffer)).uRows = .Rows And _
        m_UndoBuffer(UBound(m_UndoBuffer)).uCols = .Cols Then Exit Sub
        
        'MaxUndo
        If UBound(m_UndoBuffer) = (intMaxUndo - 1) Then
            ReDim tmpClip(intMaxUndo - 1)
            ReDim m_UndoBuffer(intMaxUndo - 1)
            For i = 0 To intMaxUndo - 1
                tmpClip(i).uCols = m_UndoBuffer(i).uCols
                tmpClip(i).uRows = m_UndoBuffer(i).uRows
                tmpClip(i).uText = m_UndoBuffer(i).uText
                tmpClip(i).uName = m_UndoBuffer(i).uName
            Next i
            For i = 0 To intMaxUndo - 2
                m_UndoBuffer(i).uCols = tmpClip(i + 1).uCols
                m_UndoBuffer(i).uRows = tmpClip(i + 1).uRows
                m_UndoBuffer(i).uText = tmpClip(i + 1).uText
                tmpClip(i).uName = m_UndoBuffer(i).uName
            Next i
                
        Else
            ReDim Preserve m_UndoBuffer(UBound(m_UndoBuffer) + 1)
        End If
        
        'Make Undobuffer
        m_UndoBuffer(UBound(m_UndoBuffer)).uRows = .Rows
        m_UndoBuffer(UBound(m_UndoBuffer)).uCols = .Cols
        m_UndoBuffer(UBound(m_UndoBuffer)).uText = strClip
        If Len(UndoName) Then
            m_UndoBuffer(UBound(m_UndoBuffer)).uName = UndoName
        Else
            m_UndoBuffer(UBound(m_UndoBuffer)).uName = "Last Action"
        End If
    End With
    
    EnableUndo
    
    Exit Sub
DimBuff:
    ReDim m_UndoBuffer(0)
    Resume
End SubPrivate Sub EnableUndo()
    'Enable Controls e.g. Menuitem (mnuEditUndo) and Toolbarbutton
    mnuEditUndo.Enabled = (UBound(m_UndoBuffer) > 1)
    tbrMain.Buttons("Undo").Enabled = (UBound(m_UndoBuffer) > 1)
    If UBound(m_UndoBuffer) > 1 Then
        tbrMain.Buttons("Undo").ToolTipText = "Undo: " & _
        m_UndoBuffer(UBound(m_UndoBuffer)).uName & " (Ctrl+Z)"
        mnuEditUndo.Caption = "Undo: " & _
        m_UndoBuffer(UBound(m_UndoBuffer)).uName
    Else
        tbrMain.Buttons("Undo").ToolTipText = "Undo: Not possible (Ctrl+Z)"
        mnuEditUndo.Caption = "Undo: Not possible"
    End If
End Sub