我有一张表单,其中一些单元格有多色文本,并以粗体/下划线/斜体显示。
我需要能够拉出单元格内容并在表单上显示保持相同格式的信息。
我遇到了支持RichText的InkEdit控件,但我无法从单元格复制到此框。
请帮助
答案 0 :(得分:7)
InkEdit控件支持粘贴富文本,因此您真正需要做的就是复制Range
,然后将其粘贴到控件中。由于控件公开它的.hWnd
,您需要做的就是使用SendMessage API函数发送WM_PASTE消息:
'UserForm1
Option Explicit
Private Declare Function SendMessage Lib "user32" Alias _
"SendMessageW" (ByVal hwnd As Long, ByVal wMsg As Long, _
ByVal wParam As Long, lParam As Any) As Long
Private Const WM_PASTE = &H302
Private Sub UserForm_Initialize()
RangeToInkEdit ActiveSheet.Cells(1, 1), InkEdit1
Application.CutCopyMode = False
End Sub
Sub RangeToInkEdit(source As Range, target As InkEdit)
source.Copy
SendMessage InkEdit1.hwnd, WM_PASTE, 0&, 0&
End Sub
Private Sub CommandButton1_Click()
Unload Me
End Sub
请注意,此还有一个类似于@ JohnColeman方法的轻微问题 - 它在拾取颜色时没有做那么好的工作。这似乎是Excel在RTF编码中发送到剪贴板的问题,而不是InkEdit控件本身的问题(您可以通过复制并粘贴到写字板(基本上是RTF编辑器)来确认)。有些颜色可以使用,有些颜色没有 - 所有颜色的颜色深度都会减少到基本上是RTF支持的最接近颜色。
答案 1 :(得分:6)
问题似乎是Excel对象模型深深掩盖了单元格内容的RTF格式,并没有提供简单的方法来提取它。
这是一个似乎有点工作的kludge:
Sub CopyRichText(source As Range, target As InkEdit)
Dim i As Long, n As Long
target.Text = source.Text
n = Len(target.Text)
For i = 1 To n
target.SelStart = i - 1
target.SelLength = 1
target.SelBold = source.Characters(i, 1).Font.Bold
target.SelColor = source.Characters(i, 1).Font.Color
target.SelFontName = source.Characters(i, 1).Font.FontStyle
target.SelFontSize = source.Characters(i, 1).Font.Size
target.SelItalic = source.Characters(i, 1).Font.Italic
'target.SelUnderline = source.Characters(i, 1).Font.Underline '-- doesn't work as expected!
Next i
target.SelStart = n
target.SelLength = 0
End Sub
像这样使用:
Private Sub UserForm_Initialize()
CopyRichText Range("A1"), Me.InkEdit1
End Sub
例如,在A1中我有:
然后,当我显示userform时,它看起来像:
墨水编辑的SelUnderline
方法似乎存在一个彻头彻尾的错误。取消注释该行以查看我的意思。也许有一些解决方法。
我怀疑上面的内容有些脆弱。我还没有测试过这么多。如果它适合你(也许适当调整) - 好。如果没有,我怀疑使用剪贴板有一种深刻的魔法方法。 InkEdit控件没有粘贴方法 - 但它确实有一个Hwnd
方法,听起来它可以为Window粘贴提供目标。
答案 2 :(得分:4)
我提供了两个使用InkEdit Control的函数。
Private Declare Function PasteToControl Lib "user32" Alias "SendMessageA" (ByVal hWnd As Long, Optional ByVal wMsg As Long = &H302, Optional ByVal wParam As Long = 0, Optional lParam As Any = 0&) As Long
'http://www.devx.com/vb2themax/Tip/18632
Private Sub UserForm_Layout()
InkEdit1.Text = vbCrLf
Range("A6").Copy
PasteToControl InkEdit1.hWnd
PutInClipBoard vbCrLf & "How about Range?" & vbCrLf
PasteToControl InkEdit1.hWnd
Range("A2:G4").Copy
PasteToControl InkEdit1.hWnd
PutInClipBoard vbCrLf & "Can we do Tables?" & vbCrLf
PasteToControl InkEdit1.hWnd
Sheet4.ListObjects("Orders").Range.Copy
PasteToControl InkEdit1.hWnd
PutInClipBoard vbCrLf & "Pictures?"
PasteToControl InkEdit1.hWnd
Sheet4.Shapes("Picture 1").Copy
PasteToControl InkEdit1.hWnd
PutInClipBoard vbCrLf & "Charts?"
PasteToControl InkEdit1.hWnd
Sheet4.ChartObjects("Chart 4").Copy
PasteToControl InkEdit1.hWnd
PutInClipBoard vbCrLf & "Can we take a snapshot of a Range?" & vbCrLf
PasteToControl InkEdit1.hWnd
Range("A6:I12").CopyPicture
PasteToControl InkEdit1.hWnd
End Sub
Sub PutInClipBoard(Text As String)
Dim clip As DataObject
Set clip = New DataObject
clip.SetText Text
clip.PutInClipBoard
End Sub
答案 3 :(得分:0)
您需要能够编辑文本吗?如果没有,那么我会尝试复制范围并将其粘贴为UserForm中的图片。查看Stephen Bullen的PastePicture示例代码。
答案 4 :(得分:0)
所以...前一段时间,我想在Excel的UserForms中使用markdown。我创建了一个名为SimpleDown的简单解析器和词法分析器。它有明显的局限性,因此效果非常好。当前,它使用MSForms.Frame作为基本容器,然后使用MSForms.Label(s)作为SimpleDown的每个元素。
下面是一个示例:
# Header Test||
---||
* Unordered List 1||
* Unordered List 2||
TESTING of stuff....
上面将产生如下内容:
正在测试东西.....
查看科尔曼先生的代码后,我意识到实际上不需要使用Range,Cell或类似的东西。相反,我们可以执行以下操作: