' 功能：在数据行上方插入表头（除第二行外）
' 版本：1.0
' 说明：从最后一行向上循环插入表头，避免行号变动影响后续操作
Sub InsertHeadersWithExplanation()
    Dim lastRow As Long, i As Long
    Dim wsUndo As Worksheet

    ' 初始化撤销日志工作表
    On Error Resume Next
    Set wsUndo = ActiveWorkbook.Worksheets("UndoLog")
    On Error GoTo 0
    If wsUndo Is Nothing Then
        Set wsUndo = ActiveWorkbook.Worksheets.Add
        wsUndo.Name = "UndoLog"
        wsUndo.Visible = xlSheetHidden ' 使用普通隐藏，避免非常隐藏可能的权限问题
    End If
    ' 安全清除撤销记录
    On Error Resume Next
    wsUndo.Cells.Clear
    On Error GoTo 0

    ' 获取A列最后一个非空行的行号
    ' Rows.Count 返回工作表最大行数（Excel 2007+为1048576）
    ' .End(xlUp) 模拟手动按Ctrl+↑定位到最后一个非空行
    lastRow = Cells(Rows.Count, 1).End(xlUp).Row
    
    ' 从最后一行向上循环到第3行（第二行不插入表头）
    ' 向上循环的原因：如果向下循环，插入行后会导致后续行号变化，造成重复插入
    For i = lastRow To 3 Step -1
        ' 在当前行上方插入新行
        ' Shift:=xlDown 表示当前行及以下行下移，新行插入在当前行上方
        Rows(i).Insert Shift:=xlDown
        ' 记录插入的行号和工作表名称到撤销日志
        With wsUndo.Cells(wsUndo.Rows.Count, 1).End(xlUp).Offset(1, 0)
            .Value = i
            .Offset(0, 1).Value = ActiveSheet.Name ' 记录工作表名称
        End With
        
        ' 在新插入行的A列设置表头文本
        ' 复制第一行整行表头内容到新插入行
        Rows(1).Copy Destination:=Rows(i)
    Next i
    
    ' 提示操作完成
    MsgBox "表头插入完成！共处理 " & (lastRow - 1) & " 行数据。" & vbCrLf & "如需撤销，请运行UndoInsertHeaders宏", vbInformation
End Sub

' 代码关键点解释：
' 1. 向上循环（Step -1）：解决插入行导致行号变化的问题
' 2. 循环范围（To 3）：明确排除第二行，满足"第二行不能再插入表头"的要求
' 3. 动态获取lastRow：适应不同数据量，避免硬编码行号
' 4. 整行复制表头：复制第一行所有列内容，适应任意列数的表头
' 5. 操作反馈：通过MsgBox告知用户处理结果
' 4. 整行复制表头：复制第一行所有列内容，适应任意列数的表头
' 5. 操作反馈：通过MsgBox告知用户处理结果
' 使用方法：在Excel中按Alt+F11打开VBA编辑器，插入模块并粘贴此代码，运行InsertHeadersWithExplanation宏

Sub UndoInsertHeaders()
    On Error GoTo ErrorHandler ' 全局错误处理
    Dim wsUndo As Worksheet
    Dim targetSheet As Worksheet
    Dim lastRow As Long, i As Long, rowNum As Long ' 新增rowNum变量
    Dim arrRows() As Variant

    ' 记录当前活动工作表
    Set targetSheet = ActiveSheet
    
    ' 检查撤销日志是否存在
    On Error Resume Next
    Set wsUndo = ActiveWorkbook.Worksheets("UndoLog")
    On Error GoTo 0
    If wsUndo Is Nothing Then
        MsgBox "没有可撤销的操作", vbInformation
        Exit Sub
    End If

    ' 获取撤销记录
    lastRow = wsUndo.Cells(wsUndo.Rows.Count, 1).End(xlUp).Row
    If lastRow = 0 Then
        MsgBox "没有可撤销的操作", vbInformation
        Exit Sub
    End If

    ' 读取所有插入的行号
    ' 读取所有插入的行号和对应工作表名称
    arrRows = wsUndo.Range("A1:B" & lastRow).Value

    ' 从下往上删除插入的行（避免行号变动）
    For i = UBound(arrRows, 1) To LBound(arrRows, 1) Step -1
        ' 添加错误处理防止删除已不存在的行
        ' 验证行号是否有效
        If IsNumeric(arrRows(i, 1)) Then
            rowNum = CLng(arrRows(i, 1))
            ' 检查行号是否在有效范围内
            ' 使用目标工作表的行数进行验证
            If rowNum > 0 And rowNum <= targetSheet.Rows.Count Then
                ' 获取目标工作表
                On Error Resume Next
                Set targetSheet = ActiveWorkbook.Worksheets(arrRows(i, 2))
                On Error GoTo 0
                
                ' 执行删除（无需激活工作表）
                If Not targetSheet Is Nothing Then
                    ' 检查行号是否在有效范围内
                    If rowNum > 0 And rowNum <= targetSheet.Rows.Count Then
                        On Error Resume Next
                        targetSheet.Rows(rowNum).Delete
                        On Error GoTo 0
                    End If
                End If
            End If
        End If
    Next i

    ' 安全清除撤销记录并提示
    On Error Resume Next
    If Not wsUndo Is Nothing Then
        wsUndo.Cells.Clear
    End If
    On Error GoTo 0
    MsgBox "已成功撤销上一次表头插入操作", vbInformation

ExitSub:
    Exit Sub
ErrorHandler:
    MsgBox "撤销操作发生错误: " & Err.Description & " (错误代码: " & Err.Number & ")", vbExclamation
    ' 发生错误时仍清除撤销日志
    On Error Resume Next
    If Not wsUndo Is Nothing Then
        wsUndo.Cells.Clear
    End If
    On Error GoTo 0
    Resume ExitSub
End Sub