将两个字符对象添加在一起,以连接它们的文本,但保留每个字符的格式

Add two Characters Objects together so as to concatenate their text but retain formats from each

我正在将单元格的内容添加到形状对象中。内容都是文本,但每个单元格的格式可能不同。我希望在将单元格的内容添加到形状时能够保留此格式,以便粗体单元格将显示为这样等等。

我一直在尝试获取当前 Shape.TextFrame.Characters 对象并向其添加新的 Range("TargetCell").Characters 对象,对于我的源范围中的每个目标单元格。

有没有一种简单的方法可以将两个 .Characters 对象强制放在一起,从而使文本连接起来并更改格式以反映新文本边界处的来源 - 我看到了 .Characters.Insert(string) 方法,但这只会插入文本,不会插入格式。每次我在输出列表中添加一个新的单元格时,我都需要重新计算文本的每个部分在哪里有什么格式,这被证明是困难的。

我一直在尝试这些方法,但在尝试获取或设置 .Characters(n).Font.Bold 属性.

时一直遇到困难
Private Sub buildMainText(Target As Range, oSh As Shape)
On Error GoTo 0
Dim chrExistingText As Characters
Dim chrTextToAdd As Characters
Dim chrNewText As Characters
Dim o As Characters
Dim i As Integer
Dim isBold As Boolean
Dim startOfNew As Integer
i = 0
 
  With oSh.TextFrame
    Set chrExistingText = .Characters
    Set chrTextToAdd = Target.Characters
    Set chrNewText = chrTextToAdd
    chrNewText.Text = chrExistingText.Text & chrTextToAdd.Text
    startOfNew = Len(chrExistingText.Text) + 1
    
    .Characters.Text = chrNewText.Text
    
    For i = 1 To Len(chrNewText.Text)
        If i < startOfNew Then
            If chrExistingText(i, 1).Font.Bold Then
                .Characters(i, 1).Font.Bold = True
            Else
                .Characters(i, 1).Font.Bold = False
            End If
        Else
            If chrNewText(i - startOfNew + 1, 1).Font.Bold Then
                .Characters(i, 1).Font.Bold = True
            Else
                .Characters(i, 1).Font.Bold = False
            End If
        End If
    Next i
  End With
End Sub

这是一个示例,它采用单个单元格并将其附加到形状;保留、形状和范围的格式。在下面的示例中,我们将保留 BOLD (B)ITALICS (I)UNDERLINE (U)。随意修改代码以存储更多格式化属性。

逻辑:

  1. 形状的文本框中可以包含的最大字符长度为 32767。所以我们将创建一个数组(如上面评论中提到的@SJR),比如TextAr(1 To 32767, 1 To 3),来存储格式选项。 3 列用于 BUI。如果您想添加更多属性,请将其更改为相关数字。
  2. 将形状的格式存储在数组中。
  3. 将单元格的格式存储在数组中。
  4. 将单元格的文本附加到形状。
  5. 遍历数组并re-apply格式化。

代码:

我已经对代码进行了评论,但如果您在理解代码时遇到问题,请直接提问。我很快就写了这个,所以我必须承认我没有对这段代码进行过广泛的测试。我假设 cell/shape 除了 BIU(msoUnderlineSingleLine) 之外没有任何其他格式。如果是这样,那么您将不得不相应地修改代码。

Option Explicit

Sub Sample()
    Dim ws As Worksheet
    
    '~~> Change this to the relevant sheet
    Set ws = Sheet1
    
     AddTextToShape ws.Range("F3"), ws.Shapes("MyShape")
End Sub

'~~> Proc to add cell range to shape
Sub AddTextToShape(rng As Range, shp As Shape)
                  
    '~~> Check for single cell
    If rng.Cells.Count > 1 Then
        MsgBox "Select a single cell and try again"
        Exit Sub
    End If
    
    Dim rngTextLength  As Long
    Dim shpTextLength  As Long
    
    '~~> Get the length of the text in the supplied range
    rngTextLength = Len(rng.Value)
    
    '~~> Get the length of the text in the supplied shape
    shpTextLength = Len(shp.TextFrame.Characters.Text)
    
    '~~> Check if the shape can hold the extra text
    If rngTextLength + shpTextLength > 32767 Then
        MsgBox "Cell text will not fit in Shape. Choose another cell with maximum " & _
        (32767 - shpTextLength) & " characters"
        Exit Sub
    End If
    
    Dim TextAr(1 To 32767, 1 To 3) As String
    Dim i As Long
    
    '~~> Store the value and formatting from the shape in the array
    For i = 1 To shpTextLength
        With shp.TextFrame.Characters(i, 1)
            With .Font
                If .Bold = True Then TextAr(i, 1) = "T" Else TextAr(i, 1) = "F"
                If .Italic = True Then TextAr(i, 2) = "T" Else TextAr(i, 2) = "F"
                If .Underline = xlUnderlineStyleSingle Then TextAr(i, 3) = "T" Else TextAr(i, 3) = "F"
            End With
        End With
    Next i
    
    '~~> Store the value and formatting from the range in the array
    Dim j As Long: j = shpTextLength + 2
    
    For i = 1 To rngTextLength
        With rng.Characters(Start:=i, Length:=1)
            With .Font
                If .Bold = True Then TextAr(j, 1) = "T" Else TextAr(j, 1) = "F"
                If .Italic = True Then TextAr(j, 2) = "T" Else TextAr(j, 2) = "F"
                If .Underline = xlUnderlineStyleSingle Then TextAr(j, 3) = "T" Else TextAr(j, 3) = "F"
                j = j + 1
            End With
        End With
    Next i
    
    '~~> Add the cell text to shape
    shp.TextFrame.Characters.Text = shp.TextFrame.Characters.Text & " " & rng.Value2
    
    '~~> Get the new text length of the shape
    shpTextLength = Len(shp.TextFrame.Characters.Text)
    
    '~~> Apply the formatting
    With shp
        For i = 1 To shpTextLength
            With .TextFrame2.TextRange.Characters(i, 1).Font
                If TextAr(i, 1) = "T" Then .Bold = msoTrue Else .Bold = msoFalse
                
                If TextAr(i, 2) = "T" Then .Italic = msoTrue Else .Italic = msoFalse
                
                If TextAr(i, 3) = "T" Then .UnderlineStyle = msoUnderlineSingleLine _
                Else .UnderlineStyle = msoNoUnderline
            End With
        Next i
    End With
End Sub

进行中