指定Excel单元格注释中包含的特定信息时出现问题。我在总共超过1M的多个工作簿中有多个注释,所以我正在寻找一种方法,可以应用一个例程来清理一个工作簿,然后可能将它合并到所有工作簿的Workbook_Open()中。
示例注释-在第一行文本之前、任意两行文本之间或最后一行文本之后,可以有一个空白行或二十个空白行。
**
May 8
June 1
**我有一个小的例程,它能起到作用。
Sub RemoveBlankCommentRows()
Dim c As Comment
For Each c In ActiveSheet.Comments
c.Text Replace(c.Text, "" & Chr(10), " ")
rng.Comment.Shape.TextFrame.AutoSize = True
Next c结束子对象
这样做的唯一问题是它将所有评论数据放在一行上,如下所示。
**May 8 June 1**我希望返回的内容如下所示,文本之间有或没有空行:
**May 8
June 1**我正在寻找一种方法来区分注释中有文本的行和没有可见文本的行,但可能有一个空格或几个空格、vbNull、vbNullChar、vbNullString或任何其他不可打印的信息。我面临的问题是如何确定评论的哪一行正在被查看,或者是整个评论?
在这方面的任何帮助都将不胜感激。我已经搜索了所有我能找到的地方,但没有一种方法可以让我在不将所有文本放入一行的情况下解决这个问题。
发布于 2015-06-12 20:54:58
一种非常基本的方法,但请尝试以下方法:
Sub RemoveBlankCommentRows()
Dim c As Comment
For Each c In ActiveSheet.Comments
If Len(c.Text) < 2 Then c.Text Replace(c.Text, "" & Chr(10), " ")
rng.Comment.Shape.TextFrame.AutoSize = True
Next c编辑:
它需要做一些修改才能在评论中使用。由于特定于我的用例的原因,它被分成了3部分,但对于宏的使用(如在中,为了在更大的区域中使用它),我刚刚在工具栏上创建了一个名为cleanSpecialsFromSelection的按钮。
对于这个数据集,我处理导入的数据,由于我只能假设是字符编码问题,这些数据包含许多不可打印的字符,结果对我来说是完美的。然而,它并不优雅-它依赖于最基本的bruteforce方法,对于大型数据集,它需要时间才能完成。在我的工作站上,选择8x3000将需要近10秒的时间。
下面是我的代码:
Global bannedChars As String
Sub cleanSpecialCharacters(Optional str As Range)
bannedChars = Chr(127) & "," & Chr(129) & "," & Chr(141) & "," & Chr(143) & "," & Chr(144) & "," & Chr(157) & "," & Chr(160)
Application.ScreenUpdating = False
If IsMissing(str) Then Set str = Range(Selection.Item(1).Address)
Dim tVal As String, bChar As Variant
tVal = str.Value
tVal = Application.WorksheetFunction.Clean(tVal)
tVal = Application.WorksheetFunction.Trim(tVal)
For Each bChar In Split(bannedChars, ",")
tVal = Replace(tVal, bChar, "")
Next
If IsNumeric(tVal) Then
str.Value = CLng(tVal)
Else
str.Value = tVal
End If
Application.ScreenUpdating = True
End Sub
Sub cleanSpecialCharactersRange(str As Range)
' Argument passed to this sub should be >1 cell, otherwise call cleanSpecialCharacters() directly
Dim c As Range
For Each c In str.Cells
Call cleanSpecialCharacters(c)
Next
End Sub
Sub cleanSpecialsFromSelection()
Dim rng As Range
Set rng = Selection
Call cleanSpecialCharactersRange(rng)
End Sub发布于 2015-06-30 23:27:53
解决了!我最终通过使用Split函数找到了解决方案。它从我的标准代码开始,以加快速度并防止不需要的错误消息。这是一种真正的蛮力方法,我相信有一种更有说服力的方法来做到这一点。但是,这解决了我遇到的所有与不可打印字符、空格等相关的问题。现在,我将每行信息保留在数据行之前、之后或中间没有大段空白行的行中。
接近尾声时,我添加了一些代码,以使注释看起来更好。普通的淡黄色变得非常陈旧,真的很快。希望其他人将来也能用到这一点。
Sub SplitCellComment()
' Using the vba Split function: return each substring, and its
' length, on splitting a string; _
' number of occurrences of a character
' (ie. delimiter) within a string;
Dim Cmt As Excel.Comment
Dim i As Integer
Dim LArea As Long, xCmt As Long
Dim sText As String, sChr As String
Dim arr As Variant, varExp As Variant, varDelim As Variant
' Turn the following activity off to increase program speed.
With Application
.StatusBar = True
.EnableEvents = False
.DisplayAlerts = False
.ScreenUpdating = False
End With
For Each Cmt In ActiveSheet.Comments
sText = ""
' specify string expression which will be split into substrings:
varExp = Cmt.Text
' specify delimiter for substrings:
varDelim = Chr(10) '"s"
arr = Split(varExp, varDelim)
' includes an array element representing a sub-string of zero-
' length before the first character which is the delimiter.
For i = LBound(arr) To UBound(arr)
' return each element of the array - these are the substrings into
' which the string expression is split into.
' Remove any spaces that may be present on blank rows.
arr(i) = Trim(arr(i))
' If the left character of the first row = Chr(10)
' then delete it.
If Left(arr(0), 1) = Chr(10) Then Left(arr(0), 1) = ""
' If a row as a length of 0 then trim any spaces from the
' ends. Otherwise add a Chr(10) after the text.
If Len(arr(i)) = 0 Then
arr(i) = ""
sText = Trim(sText) & arr(i)
Else
sText = Trim(sText) & Chr(10) & arr(i)
End If
' Due to Chr(10) being inserted automatically at the
' beginning of the text, this will remove the first character.
If i = 0 Then
If Len(sText) <> Len(arr(0)) Then
sText = Mid(sText, 2, Len(sText))
End If
End If
' In some cases the next If...Then is required to remove
' non-printable characters.
On Error Resume Next
If Asc(Left(sText, 1)) < 32 Then sText = Mid(sText, 2, Len(sText))
On Error GoTo 0
Next i
Cmt.Text sText
' Format comment shape, size and font.
With Cmt
' Beveled button
.Shape.AutoShapeType = msoShapeActionButtonCustom
.Shape.TextFrame.Characters.Font.Name = "Tahoma"
.Shape.TextFrame.Characters.Font.Size = 10
.Shape.TextFrame.Characters.Font.ColorIndex = 2
.Shape.Line.ForeColor.RGB = RGB(0, 0, 0)
.Shape.Line.BackColor.RGB = RGB(255, 255, 255)
.Shape.Fill.Visible = msoTrue
.Shape.Fill.ForeColor.RGB = RGB(58, 82, 184)
.Shape.Fill.OneColorGradient msoGradientDiagonalUp, 1, 0.23
End With
Next Cmt
' Return the following activity on for future use.
With Application
.StatusBar = False
.EnableEvents = True
.DisplayAlerts = True
.ScreenUpdating = True
End With
End Subhttps://stackoverflow.com/questions/30803522
复制相似问题