Excel ,“无效的r1c1本地地址” 如果Len(row_letter_local)=1和Len(column_letter_local)=1,则 Mid$(R1C1LocalAddress,第1行字母位置)=“R” Mid$(R1C1LocalAddress,第1列字母位置)=“C” ConvertR1C1LocalAddressToR1C1=R1C1LocalAddress 其他的 convertr1c1localaddressor1c1=“R”和Mid$(R1C1LocalAddress,row_letter_pos+Len(row_letter_local),column_letter_pos-(row_letter_pos+Len(row_letter_local)),以及“C”和Mid$(R1C1LocalAddress,column_letter_pos+Len(column_letter_local)) 如果结束 端函数

Excel ,“无效的r1c1本地地址” 如果Len(row_letter_local)=1和Len(column_letter_local)=1,则 Mid$(R1C1LocalAddress,第1行字母位置)=“R” Mid$(R1C1LocalAddress,第1列字母位置)=“C” ConvertR1C1LocalAddressToR1C1=R1C1LocalAddress 其他的 convertr1c1localaddressor1c1=“R”和Mid$(R1C1LocalAddress,row_letter_pos+Len(row_letter_local),column_letter_pos-(row_letter_pos+Len(row_letter_local)),以及“C”和Mid$(R1C1LocalAddress,column_letter_pos+Len(column_letter_local)) 如果结束 端函数,excel,vba,Excel,Vba,学分归。除非我误读了你的问题,否则你不能使用格式画师吗Selection.PasteSpecial Paste:=xlPasteFormats,Operation:=xlNone,SkipBlanks:=False,Transpose:=False,这会复制例如颜色。这不会改变其他格式,如背景、边框等(不仅仅是数字格式)?首先,粘贴值或像范围(“B10:B20”)。值=范围(“A10:A20”).Value,然后以相同的方式分配数字格式范围(“A10:A20”)。NumberFormat=Ran

学分归。

除非我误读了你的问题,否则你不能使用格式画师吗
Selection.PasteSpecial Paste:=xlPasteFormats,Operation:=xlNone,SkipBlanks:=False,Transpose:=False,这会复制例如颜色。这不会改变其他格式,如背景、边框等(不仅仅是数字格式)?首先,粘贴值或像
范围(“B10:B20”)。值=范围(“A10:A20”).Value
,然后以相同的方式分配数字格式<代码>范围(“A10:A20”)。NumberFormat=Range(“B10”)。NumberFormat
。我想我应该提到的是,我最终编写的实际宏将比上述代码更复杂(例如,使用逻辑来复制与“粘贴”命令相同的行为)。我关心的是获取复制的范围,然后我可以合并该逻辑。
NumberFormat
返回
Null
,如果不是所有单元格都具有相同的数字格式。此外,复制格式也没有问题,问题是在按下宏按钮之前先确定复制了什么范围。只有当范围
A1:A10
中的所有单元格都有相同的编号时,此操作才有效format@GSerg问题是在按下宏按钮之前,要确定复制的范围。解决方法是将“复制”作为过程的一部分,并且不依赖于用户的
选择
…我试图获取它,以便用户可以使用Excel的复制功能(Ctrl+C),选择另一个范围,然后让宏以某种方式抓取复制的范围,并将其存储在一个变量中,以便对其进行操作。据我所知,上面的硬编码范围,这不是我要找的。@DavidZemens你需要两个范围,源和目标。首先选择目标,然后单击“复制”(标准Excel按钮),范围将在其周围显示边框。然后选择目标范围并单击宏按钮。哇,太棒了!太棒了。哇,任何Excel VBA程序员的圣歌!我只需要添加一个小小的修改,因为在我的例子中,原始范围名称类似于“!Sheet1!L1C1”,而xlR1C1的正确语法是“!Sheet1!R1C1”,因此对Application.ConvertFormula的调用总是失败,并出现“Error 1004:Application defined Error”。我仍然不敢相信我已经错过了这篇文章4年了…@GSerg我一直在一个简单的过程中使用你的代码,粘贴一个SUM()公式,引用复制的范围作为参数。但是使用包含多个
区域的复制区域时,Excel似乎“记住”了实际复制的单元格,而使用Alexey Merson的CompositeMoniker方法时,返回的区域由复制区域的左上角单元格和右下角单元格分隔。这会导致比最初复制的单元更多。。。你知道这个问题能否解决吗?我无法用IMoniker解决这个问题(也许它不是优秀的原生方式…@hymced我不知道。我知道你已经在codeproject上问过了,这可能是你最好的机会。这里的另一个方法:,仍然基于“链接”格式,产生相同的结果:复制区域之间的单元格返回复制范围,即使没有真正复制。。。
Dim A As Range
Set A = Range("ZZ99999")
A.PasteSpecial Paste:=xlPasteAll
Selection.NumberFormat = A.NumberFormat
Dim foo As Variant

foo = Sheet1.Range("A1:A10").NumberFormat

Sheet1.Range("D1:D10").NumberFormat = foo
Sheet1.Range("D1:D10").NumberFormat = Sheet1.Range("A1:A10").NumberFormat
Sheet1.Range("D1:D10").NumberFormat = Sheet1.Range("A1").NumberFormat
Option Explicit

' No point in #If VBA7 and PtrSafe, as the Edanmo's olelib is 32-bit
Private Declare Function OpenClipboard Lib "user32.dll" (ByVal hwnd As Long) As Long
Private Declare Function GetClipboardData Lib "user32.dll" (ByVal wFormat As Long) As Long
Private Declare Function CloseClipboard Lib "user32.dll" () As Long


Public Function GetCopiedRange() As Excel.Range

  Dim CF_LINKSOURCE As Long
  CF_LINKSOURCE = olelib.RegisterClipboardFormat("Link Source")
  If CF_LINKSOURCE = 0 Then Err.Raise 5, , "Failed to obtain clipboard format CF_LINKSOURCE"

  If OpenClipboard(0) = 0 Then Err.Raise 5, , "Failed to open clipboard."


  On Error GoTo cleanup

  Dim hGlobal As Long
  hGlobal = GetClipboardData(CF_LINKSOURCE)

  If hGlobal = 0 Then Err.Raise 5, , "Failed to get data from clipboard."

  Dim pStream As olelib.IStream
  Set pStream = olelib.CreateStreamOnHGlobal(hGlobal, 0)

  Dim IID_Moniker As olelib.UUID
  olelib.CLSIDFromString "{0000000f-0000-0000-C000-000000000046}", IID_Moniker

  Dim pMoniker As olelib.IMoniker
  olelib.OleLoadFromStream pStream, IID_Moniker, pMoniker


  Set GetCopiedRange = RangeFromCompositeMoniker(pMoniker)

cleanup:
  Set pMoniker = Nothing 'To make sure moniker releases before the stream

  CloseClipboard
  If Err.Number > 0 Then Err.Raise Err.Number, Err.Source, Err.Description, Err.HelpFile, Err.HelpContext

End Function


Private Function RangeFromCompositeMoniker(ByVal pCompositeMoniker As olelib.IMoniker) As Excel.Range
  Dim monikers() As olelib.IMoniker
  monikers = SplitCompositeMoniker(pCompositeMoniker)

  If UBound(monikers) - LBound(monikers) + 1 <> 2 Then Err.Raise 5, , "Invalid composite moniker."

  Dim binding_context As olelib.IBindCtx
  Set binding_context = olelib.CreateBindCtx(0)

  Dim WorkbookUUID As olelib.UUID
  olelib.CLSIDFromString "{000208DA-0000-0000-C000-000000000046}", WorkbookUUID

  Dim wb As Excel.Workbook
  monikers(LBound(monikers)).BindToObject binding_context, Nothing, WorkbookUUID, wb

  Dim pDisplayName As Long
  pDisplayName = monikers(LBound(monikers) + 1).GetDisplayName(binding_context, Nothing)

  Dim raw_range_name As String ' Contains address in the form of "!SheetName!R1C1Local", need to convert to non-local
  raw_range_name = olelib.SysAllocString(pDisplayName)
  olelib.CoGetMalloc(1).Free pDisplayName

  Dim split_range_name() As String
  split_range_name = Split(raw_range_name, "!")

  Dim worksheet_name As String, range_address As String
  worksheet_name = split_range_name(LBound(split_range_name) + 1)
  range_address = Application.ConvertFormula(ConvertR1C1LocalAddressToR1C1(split_range_name(LBound(split_range_name) + 2)), xlR1C1, xlA1)

  Set RangeFromCompositeMoniker = wb.Worksheets(worksheet_name).Range(range_address)

End Function

Private Function SplitCompositeMoniker(ByVal pCompositeMoniker As olelib.IMoniker) As olelib.IMoniker()

  Dim MonikerList As New Collection
  Dim enumMoniker As olelib.IEnumMoniker

  Set enumMoniker = pCompositeMoniker.Enum(True)

  If enumMoniker Is Nothing Then Err.Raise 5, , "IMoniker is not composite"

  Dim currentMoniker As olelib.IMoniker
  Do While enumMoniker.Next(1, currentMoniker) = olelib.S_OK
    MonikerList.Add currentMoniker
  Loop

  If MonikerList.Count > 0 Then
    Dim res() As olelib.IMoniker
    ReDim res(1 To MonikerList.Count)

    Dim i As Long
    For i = 1 To MonikerList.Count
      Set res(i) = MonikerList(i)
    Next

    SplitCompositeMoniker = res
  Else
    Err.Raise 5, , "No monikers found in the composite moniker."
  End If

End Function

Private Function ConvertR1C1LocalAddressToR1C1(ByVal R1C1LocalAddress As String) As String
  ' Being extra careful here and not doing simple Replace(Replace()),
  ' because e.g. non-localized row letter may be equal to localized column letter which will lead to double replace.
  Dim row_letter_local As String, column_letter_local As String
  row_letter_local = Application.International(xlUpperCaseRowLetter)
  column_letter_local = Application.International(xlUpperCaseColumnLetter)

  Dim row_letter_pos As Long, column_letter_pos As Long
  row_letter_pos = InStr(1, R1C1LocalAddress, row_letter_local, vbTextCompare)
  column_letter_pos = InStr(1, R1C1LocalAddress, column_letter_local, vbTextCompare)

  If row_letter_pos = 0 Or column_letter_pos = 0 Or row_letter_pos >= column_letter_pos Then Err.Raise 5, , "Invalid R1C1Local address"

  If Len(row_letter_local) = 1 And Len(column_letter_local) = 1 Then
    Mid$(R1C1LocalAddress, row_letter_pos, 1) = "R"
    Mid$(R1C1LocalAddress, column_letter_pos, 1) = "C"
    ConvertR1C1LocalAddressToR1C1 = R1C1LocalAddress
  Else
    ConvertR1C1LocalAddressToR1C1 = "R" & Mid$(R1C1LocalAddress, row_letter_pos + Len(row_letter_local), column_letter_pos - (row_letter_pos + Len(row_letter_local))) & "C" & Mid$(R1C1LocalAddress, column_letter_pos + Len(column_letter_local))
  End If
End Function