我有一个像这样的代码:
Sub MoveToBeginningSentence()
Application.ScreenUpdating = False
Dim selectedWords As Range
Dim selectedText As String
Const punctuation As String = " & Chr(145) & "
On Error GoTo ErrorReport
' Cancel macro when there's no text selected
Selection.Cut
Selection.MoveLeft Unit:=wdSentence, Count:=1, Extend:=wdMove
Selection.MoveRight Unit:=wdCharacter, Count:=1, Extend:=wdExtend
Set selectedWords = Selection.Range
selectedText = selectedWords
If InStr(selectedText, punctuation) = 0 Then
Selection.MoveLeft Unit:=wdSentence, Count:=1, Extend:=wdMove
Selection.Paste
Else
Selection.MoveLeft Unit:=wdSentence, Count:=1, Extend:=wdMove
Selection.Paste
Selection.Paste
Selection.Paste
Selection.Paste
End If
ErrorReport:
End Sub
基本上,它帮助我将我选择的任何文本移动到Word中句子的开头。如果没有引号,则粘贴一次。如果有引号,请粘贴4次。
问题在于是否有任何引用,它只会粘贴一次。如果我将宏设置为检测任何其他字符,它将正常工作。但每次我试图强迫它检测智能报价时,它都会失败。
有没有办法解决它?
答案 0 :(得分:1)
使用Selection对象总是有点意义;总的来说,使用Range对象更好。你只能有一个选择;您可以根据需要拥有尽可能多的范围。
因为您的代码使用了Selection对象,所以它并不是100%清楚代码的作用。基于我的最佳猜测,我将以下示例放在一起,如果它不完全正确,您可以调整它。
一开始,我会检查选择中是否有某些内容,或者它是一个闪烁的插入点。如果未选择任何文本,则宏结束。这比调用错误处理更好,然后不处理任何事情:如果代码中出现其他问题,你就不会知道它们。
Range对象被实例化以供选择 - 不需要" cut"它,正如你将进一步看到的那样。基于此,整个句子也被分配给Range对象。拾取句子的文本,然后句子的范围是"折叠"到它的起点。 (想象一下,就像按下键盘上的左箭头一样。)
现在检查句子的文本是否有字符Chr(145)。如果不存在,则在句子的开头添加原始选择的文本(包括格式)。如果它在那里,那么它会被添加四次。
最后,删除原始选择。
Sub MoveToBeginningSentence()
Application.ScreenUpdating = False
Dim selectedText As String
Dim punctuation As String
punctuation = Chr(145) ' ‘ "smart" apostrophe
Dim selRange As word.Range
Dim curSentence As word.Range
Dim i As Long
' Cancel macro when there's no text selected
If Selection.Type = wdSelectionIP Then Exit Sub
Set selRange = Selection.Range
Set curSentence = selRange.Sentences(1)
selectedText = curSentence.Text
curSentence.Collapse wdCollapseStart
If InStr(selectedText, punctuation) = 0 Then
curSentence.FormattedText = selRange.FormattedText
Else
For i = 1 To 4
curSentence.FormattedText = selRange.FormattedText
curSentence.Collapse wdCollapseEnd
Next
End If
selRange.Delete
End Sub
答案 1 :(得分:0)
请查看此代码。
Sub MoveToBeginningSentence()
' 19 Jan 2018
Dim Rng As Range
Dim SelText As String
Dim Repeats As Integer
Dim i As Integer
With Selection.Range
SelText = .Text ' copy the selected text
Set Rng = .Sentences(1) ' identify the current sentence
End With
If Len(SelText) Then ' Skip when no text is selected
With Rng
Application.ScreenUpdating = False
Selection.Range.Text = "" ' delete the selected text
Repeats = IIf(IsQuote(.Text), 4, 1)
If Repeats = 4 Then .MoveStart wdCharacter, 1
For i = 1 To Repeats
.Text = SelText & .Text
Next i
Application.ScreenUpdating = True
End With
Else
MsgBox "Please select some text.", _
vbExclamation, "Selection is empty"
End If
End Sub
Private Function IsQuote(Txt As String) As Boolean
' 19 Jan 2018
Dim Quotes
Dim Ch As Long
Dim i As Long
Quotes = Array(34, 147, 148, -24143, -24144)
Ch = Asc(Txt)
' Debug.Print Ch ' read ASCII code of first character
For i = 0 To UBound(Quotes)
If Ch = Quotes(i) Then Exit For
Next i
IsQuote = (i <= UBound(Quotes))
End Function
采用的方法是使用ASC()函数识别所选句子的第一个字符。对于正常的引号,这将是34.在我的测试中,我提出了-24143和-24144(打开和关闭)。我无法识别Chr(145),但发现MS说明卷曲引号分别是Chr(147)和Chr(148)。因此我添加了一个检查所有这些功能的函数。如果在函数中启用行Debug.Print Ch
,则实际找到的字符代码将打印到即时窗口。您可以向数组Quotes
添加更多字符代码。
代码本身并不考虑单词之间的空格。也许Word会照顾到这一点,也许你不需要它。
答案 2 :(得分:-1)
您需要提供InStr
作为第一个参数的起始位置:
If InStr(1, selectedText, punctuation) = 0 Then
另外
Const punctuation As String = " & Chr(145) & "
将搜索space-ampersand-space-Chr(145)-space-ampersand-space
。如果要搜索智能引号字符,请使用
Const punctuation As String = Chr(145)
希望有所帮助。