ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 效率神器,一键搞定繁琐工作
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
让更多数据处理,一键完成 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
查看: 178|回复: 2

excel2007版代码在2016中运行错误,下标越界,实在是不明白

[复制链接]

TA的精华主题

TA的得分主题

发表于 2024-7-17 14:17 | 显示全部楼层 |阅读模式
本帖最后由 wulai8377 于 2024-7-17 17:29 编辑

Declare PtrSafe Function OpenClipboard Lib "user32" (ByVal hWnd As Long) As Long
Declare PtrSafe Function CloseClipboard Lib "user32" () As Long
Declare PtrSafe Function RegisterClipboardFormat Lib "user32.dll" Alias "RegisterClipboardFormatA" (ByVal lpString As String) As Long
Declare PtrSafe Function GetClipboardData Lib "user32" (ByVal wFormat As Long) As Long

Declare PtrSafe Function GlobalLock Lib "kernel32" (ByVal hMem As Long) As Long
Declare PtrSafe Function GlobalUnlock Lib "kernel32" (ByVal hMem As Long) As Long
Declare PtrSafe Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
Declare PtrSafe Function GlobalSize Lib "kernel32" (ByVal hMem As Long) As Long

Option Explicit
'**************************************************
Type RangeCellInfo '自定义类型存储宏运行所作出的改变
    CellContent As Variant
    CellAddress As String
End Type

Public OrgWB As Workbook
Public OrgWS As Worksheet

Public OrgCells() As RangeCellInfo


Private Function GetCutCopyRange() As Range
    Dim sBuffer As String
    Dim sItem As Variant
    Dim hMem As Long
    Dim nSize As Long
    Dim lpData As Long
    Dim lFormat As Long

    Dim sWorkbook As String
    Dim sSheet As String
    Dim sRange As String

    OpenClipboard 0&
    lFormat = RegisterClipboardFormat("Link")
    If lFormat <> 0 Then
        hMem = GetClipboardData(lFormat)
        If hMem <> 0 Then
            lpData = GlobalLock(hMem)
            If lpData <> 0 Then
                nSize = GlobalSize(hMem)
                sBuffer = Space(nSize)
                CopyMemory ByVal StrPtr(sBuffer), ByVal lpData, ByVal nSize
                sBuffer = StrConv(sBuffer, vbUnicode)
            End If
            GlobalUnlock hMem
        Else
            CloseClipboard
            Exit Function
        End If
    End If
    CloseClipboard
    sItem = Split(sBuffer, Chr(0))
   sItem(1) = Mid(sItem(1), InStr(sItem(1), "[") + 1)
    sWorkbook = Left(sItem(1), InStr(sItem(1), "]") - 1)
    sSheet = Mid(sItem(1), InStr(sItem(1), "]") + 1)
    sRange = sItem(2)
    Set GetCutCopyRange = Workbooks(sWorkbook).Sheets(sSheet).Range(Application.ConvertFormula(sRange, xlR1C1, xlA1))
End Function

'**************************************************
Sub 数值加()
  ' 在所有被选取的单元格中插入X
  If Application.CutCopyMode = False Then Exit Sub '没有复制时退出本过程

    '获取复制区域的行数和列数
    Dim r As Range
    Dim s As String
    Dim a As String
    Set r = GetCutCopyRange
    If r Is Nothing Then
        s = "目前剪贴板中没有Excel单元格区域"
    Else
        s = "工作簿:" & vbTab & r.Worksheet.Parent.FullName & vbCrLf
        s = s & "工作表:" & vbTab & r.Worksheet.Name & vbCrLf
        s = s & "单元格区域:" & vbTab & r.Address
        s = s & "行数:" & vbTab & r.Rows.Count
        s = s & "列数:" & vbTab & r.Columns.Count
    End If
    'MsgBox s'信息框

    a = ActiveCell.Address '取得当前激活的单元格地址
    Range(a).Resize(r.Rows.Count, r.Columns.Count).Select '以当前单元格为基础选定所复制的转置后的范围

  Dim i As Integer, cl As Range
  If TypeName(Selection) <> "Range" Then Exit Sub '如果被选中区域不是单元格(或者说如果鼠标焦点不再工作表中),那么结束过程

  Application.ScreenUpdating = False '屏蔽刷新
  ReDim OrgCells(Selection.Count)
  Set OrgWB = ActiveWorkbook
  Set OrgWS = ActiveSheet
  i = 1
  '记录下宏程序对工作表作出改变前的状态
  For Each cl In Selection
    OrgCells(i).CellContent = cl.Formula
    OrgCells(i).CellAddress = cl.Address
    i = i + 1
  Next cl

    Range(a).Resize(1, 1).Select '取消选择范围,重新激活当前单元格,防止多填充数据

' 转置数值 Macro
    Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlAdd, SkipBlanks _
        :=False, Transpose:=False
  '指定在“撤销”菜单项中的文字及选择该命令时所执行的宏程序
  Application.OnUndo "撤销最后运行的宏过程操作", "UndoEditRange2"

End Sub
'**************************************************
'恢复工作表原先的状态
Sub UndoEditRange2()
  Dim i As Integer
  Application.ScreenUpdating = False
  On Error GoTo NoWBorWS
  OrgWB.Activate
  OrgWS.Activate
  On Error GoTo 0
  '恢复宏运行所作的改变
  For i = 1 To UBound(OrgCells)
      Range(OrgCells(i).CellAddress).Formula = OrgCells(i).CellContent
  Next i
  Set OrgWB = Nothing
  Set OrgWS = Nothing
  Erase OrgCells
NoWBorWS:
End Sub

以上代码中标黄颜色的部分,在excel2007中正常,在2016中提示错误9,下标越界

那位大佬给看看吧

TA的精华主题

TA的得分主题

 楼主| 发表于 2024-7-17 23:35 | 显示全部楼层
1.jpg 3.jpg 5.jpg 9.jpg
以上为excel2007版中运行代码返回值
以下为excel2016中返回的值,测试位置是一样的,电脑也是同一台,我估计是返回值不一样导致的,但是不会改,哪位大神能否知道一下!
A.jpg B.jpg
2.jpg
4.jpg
6.jpg
7.jpg
8.jpg
10.jpg

TA的精华主题

TA的得分主题

 楼主| 发表于 2024-7-18 11:32 | 显示全部楼层
撤销多行多列转置,宏的最后一次执行结果(原版).zip (17.14 KB, 下载次数: 1)

附件上传了
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2024-11-18 03:33 , Processed in 0.038873 second(s), 11 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

快速回复 返回顶部 返回列表