- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
单元格可以包含大量字符。我不确定限制,但我正在测试 450 多个字符。在 VBA 中,我可以毫无问题地将该单元格的值插入字符串中,通过 debug.print 读取它,使用 Len(str) 等函数来查找字符数。
我的问题
我要使用的字符串是 HTML 字符串,我在其上应用格式,然后删除 HTML 标记。格式应用没有问题,使用我认为没有必要显示的宏(它很长)但是当需要删除 HTML 标记时,当字符串高于 255 个字符时我会遇到问题。
自己转载看看
这是一段代码的一部分,用于删除有关字体颜色的 HTML 标记,经过调整以使情况突出。要使用它,请选择一个包含 HTML 标记的单元格并运行代码。请注意 - 当长度大于 255 个字符时,它将运行一个无限循环,因此请使用 F8 单步执行并第一次查看 debug.prints。删除被简单地跳过,甚至没有出现任何错误。
Sub removeColorTags()
Dim i As Integer
Dim rng As Range
Dim str As String
Set rng = ActiveCell
i = InStr(rng.Value, "<font")
Do Until i = 0
Debug.Print Len(rng.Value)
str = rng.Value
Debug.Print str 'Displays correctly
rng.Characters(i, 20).Delete
i = InStr(rng.Value, "</font>")
rng.Characters(i, 7).Delete
i = InStr(rng.Value, "<font")
Loop
End Sub
<font color=#8DB4E2><size=09>Action ligne 3</font><font color=#8DB4E2><size=09>Action ligne 3</font><font color=#8DB4E2><size=09>Action ligne 3</font><font color=#8DB4E2><size=09>Action ligne 3</font><font color=#8DB4E2><size=09>Action ligne 3</font>
<font color=#8DB4E2><size=09>Action ligne 3</font><font color=#8DB4E2><size=09>Action ligne 3</font><font color=#8DB4E2><size=09>Action ligne 3</font><font color=#8DB4E2><size=09>Action ligne 3</font><font color=#8DB4E2><size=09>Action ligne 3</font><font color=#8DB4E2><size=09>Action ligne 3</font><font color=#8DB4E2><size=09>Action ligne 3</font><font color=#8DB4E2><size=09>Action ligne 3</font><font color=#8DB4E2><size=09>Action ligne 3</font>
最佳答案
这就是我最终要做的。首先,让我们看一下输入、转换信息和输出的屏幕截图。我从带有文本的普通格式的 excel 单元格开始,然后将其转换为类似于(但不太像)HTML 的内容。这个问题是问我如何在不丢失格式的情况下从 HTMl 字符串(屏幕截图的中间部分)中删除子字符串(HTML 标记)。
这如何回答问题
我需要一种在不丢失超过 255 个字符的单元格格式的情况下删除子字符串的方法。这意味着不使用 characters.insert
或 characters.delete
,因为正如蒂姆威廉姆斯指出的那样,它们在 255 个字符后会引起问题。因此,作为一种解决方法,我在要删除的子字符串之间分割输入字符串,记录它们的格式,将它们重新组合在一起,然后使用 characters(x,y).font
重新应用格式.
我将要展示的 sub 逐个字符地扫描 HTML 字符串,并将其记录在一个临时字符串中。当它遇到 HTML 标记时,它会停止记录临时字符串并将其连同与该临时字符串相关的格式记录在一个数组中。然后它读取标签并将“当前格式”更改为 HTML 标签所做的,并在新的临时字符串中再次开始录制。我承认可以通过调用函数来缩短 sub,但它可以工作。
Sub FromHTML(rngToConvert As Range)
Dim i As Integer, j As Integer, k As Integer
Dim strHTML As String, strTemp As String
Dim rng As Range
Dim arr()
Dim lengthFormatted As Integer
Dim optBold As Boolean, optIta As Boolean, optUnd As Boolean, optCol As String, optSize As Integer
Dim inStrTemp As Boolean
Dim nbChars As Integer
Set rng = rngToConvert.Offset(0, 2)
rng.Clear
strHTML = rngToConvert.Value
If InStr(strHTML, "<") = 0 Then Exit Sub
ReDim arr(6, 0)
inStrTemp = False
strTemp = ""
optBold = False
optIta = False
optUnd = False
optCol = "0,0,0"
optSize = "11"
For i = 1 To Len(strHTML)
If Not Mid(strHTML, i, 1) = "<" And Not Mid(strHTML, i, 4) = "[LF]" Then
'All WANTED characters go here
strTemp = strTemp & Mid(strHTML, i, 1)
inStrTemp = True
If Len(strTemp) > 200 Or i = Len(strHTML) Then
'Cuts them shorter than 200 chars
'In retrospect this isn't necessary but doesn't interfere
ReDim Preserve arr(6, j)
arr(0, j) = strTemp
arr(1, j) = optBold
arr(2, j) = optIta
arr(3, j) = optUnd
arr(4, j) = optCol
arr(5, j) = optSize
arr(6, j) = Len(strTemp)
strTemp = ""
j = j + 1
End If
ElseIf Mid(strHTML, i, 4) = "[LF]" Then
'[LF] is what I used to indicate that there was a line change in the original text
ReDim Preserve arr(6, j)
arr(0, j) = strTemp
arr(1, j) = optBold
arr(2, j) = optIta
arr(3, j) = optUnd
arr(4, j) = optCol
arr(5, j) = optSize
arr(6, j) = Len(strTemp)
strTemp = ""
j = j + 1
strTemp = vbLf
inStrTemp = True
i = i + 3
ReDim Preserve arr(6, j)
arr(0, j) = strTemp
arr(1, j) = optBold
arr(2, j) = optIta
arr(3, j) = optUnd
arr(4, j) = optCol
arr(5, j) = optSize
arr(6, j) = Len(strTemp)
strTemp = ""
j = j + 1
Else
If inStrTemp = True Then
'Records the temporary string and the formats it used
ReDim Preserve arr(6, j)
arr(0, j) = strTemp
arr(1, j) = optBold
arr(2, j) = optIta
arr(3, j) = optUnd
arr(4, j) = optCol
arr(5, j) = optSize
arr(6, j) = Len(strTemp)
strTemp = ""
j = j + 1
inStrTemp = False
End If
'If we get here we hit a HTML tag, so we read it and skip to after it
If Mid(strHTML, i, 3) = "<b>" Then
optBold = True
i = i + 2
ElseIf Mid(strHTML, i, 4) = "</b>" Then
optBold = False
i = i + 3
ElseIf Mid(strHTML, i, 3) = "<i>" Then
optIta = True
i = i + 2
ElseIf Mid(strHTML, i, 4) = "</i>" Then
optIta = False
i = i + 3
ElseIf Mid(strHTML, i, 3) = "<u>" Then
optUnd = True
i = i + 2
ElseIf Mid(strHTML, i, 4) = "</u>" Then
optUnd = False
i = i + 3
ElseIf Mid(strHTML, i, 11) Like "<c=???????>" Then
'optCol = RED, GREEN, BLUE
optCol = CInt("&H" & Mid(strHTML, i + 4, 2)) & "," & _
CInt("&H" & Mid(strHTML, i + 6, 2)) & "," & _
CInt("&H" & Mid(strHTML, i + 8, 2))
i = i + 10
ElseIf Mid(strHTML, i, 6) Like "<s=??>" Then
optSize = CInt(Mid(strHTML, i + 3, 2))
i = i + 5
End If
End If
Next
'Filling the cell with unformatted text
For i = 0 To UBound(arr, 2)
'This debug.print shows the tempString that was recorded and the associated formats
Debug.Print arr(0, i) & " Bold=" & arr(1, i) & " Italic=" & arr(2, i) & " Underline=" & arr(3, i) & " RGB=" & arr(4, i) & " Size =" & arr(5, i)
rng.Value = rng.Value + arr(0, i)
Next
'Applying formats according to the arrays
nbChars = 1
For i = 0 To UBound(arr, 2)
If arr(0, i) = vbLf Then
nbChars = nbChars + 1
Else
rng.Characters(nbChars, arr(6, i)).Font.Bold = arr(1, i)
rng.Characters(nbChars, arr(6, i)).Font.Italic = arr(2, i)
rng.Characters(nbChars, arr(6, i)).Font.Underline = arr(3, i)
rng.Characters(nbChars, arr(6, i)).Font.Color = RGB(Split(arr(4, i), ",")(0), Split(arr(4, i), ",")(1), Split(arr(4, i), ",")(2))
rng.Characters(nbChars, arr(6, i)).Font.Size = CInt(arr(5, i))
nbChars = nbChars + arr(6, i)
End If
Next
End Sub
<html>
和
</html>
此函数放置的 HTML 字符串的开头和结尾处的标签。
Function fnConvert2HTML(myCell As Range) As String
Dim bldTagOn, itlTagOn, ulnTagOn, colTagOn, sizTagOn As Boolean
Dim i, chrCount As Integer
Dim chrCol, chrLastCol, chrSiz, chrLastSiz, htmlTxt As String
bldTagOn = False
itlTagOn = False
ulnTagOn = False
colTagOn = False
sizTagOn = False
chrCol = "NONE"
htmlTxt = "<html>"
chrCount = myCell.Characters.Count
For i = 1 To chrCount
With myCell.Characters(i, 1)
'If (.Font.Color) Then
chrCol = fnGetCol(.Font.Color)
If chrCol <> chrLastCol Then
htmlTxt = htmlTxt & "<c=#" & chrCol & ">"
chrLastCol = chrCol
End If
'End If
If (.Font.Size) Then
chrSiz = .Font.Size
If Len(chrSiz) = 1 Then chrSiz = "0" & chrSiz
If Not chrLastSiz = chrSiz Then
htmlTxt = htmlTxt & "<s=" & chrSiz & ">"
End If
chrLastSiz = chrSiz
End If
If .Font.Bold = True Then
If Not bldTagOn Then
htmlTxt = htmlTxt & "<b>"
bldTagOn = True
End If
Else
If bldTagOn Then
htmlTxt = htmlTxt & "</b>"
bldTagOn = False
End If
End If
If .Font.Italic = True Then
If Not itlTagOn Then
htmlTxt = htmlTxt & "<i>"
itlTagOn = True
End If
Else
If itlTagOn Then
htmlTxt = htmlTxt & "</i>"
itlTagOn = False
End If
End If
If .Font.Underline > 0 Then
If Not ulnTagOn Then
htmlTxt = htmlTxt & "<u>"
ulnTagOn = True
End If
Else
If ulnTagOn Then
htmlTxt = htmlTxt & "</u>"
ulnTagOn = False
End If
End If
If (Asc(.Text) = 10) Then
htmlTxt = htmlTxt & "[LF]"
Else
htmlTxt = htmlTxt & .Text
End If
End With
Next
If bldTagOn Then
htmlTxt = htmlTxt & "</b>"
bldTagOn = False
End If
If itlTagOn Then
htmlTxt = htmlTxt & "</i>"
itlTagOn = False
End If
If ulnTagOn Then
htmlTxt = htmlTxt & "</u>"
ulnTagOn = False
End If
htmlTxt = htmlTxt & "</html>"
fnConvert2HTML = htmlTxt
End Function
关于string - 处理字符串的字符限制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38375431/
如果您想使用 String.Concat() 连接 5 个或更多字符串,则它会使用 Concat(String[])。 为什么不一直使用 Concat(String[]) 而不再需要 Concat(S
今天在使用 String 时,我遇到了一种我以前不知道的行为。我无法理解内部发生的事情。 public String returnVal(){ return "5";
似乎在我所看到的任何地方,都有一些过时的版本,这些版本不再起作用。 我的问题似乎很简单。我有一个Java类,它映射到derby数据库。我正在使用注释,并且已经成功地在数据库中创建了所有其他表,但是在这
一、string::size_type() 在C++标准库类型 string ,在调用size函数求解string 对象时,返回值为size_type类型,一种类似于unsigned类型的int 数据
我正在尝试将数据保存到我的 plist 文件中,其中包含字符串数组的定义。我的plist - enter image description here 我将数据写入 plist 的代码是 -- let
我有一个带有键/值对的 JavaScript 对象,其中值是字符串数组: var errors = { "Message": ["Error #1", "Error #2"], "Em
例如,为了使用相同的函数迭代 List 和 List> ,我可以编写如下内容: import java.util.*; public class Test{ public static voi
第一个Dictionary就像 Dictionary ParentDict = new Dictionary(); ParentDict.Add("A_1", "1")
这是我的 jsp 文件: 我遇到了错误 The method replace(String, String, String) in the type Functions is not appl
我需要一些帮助。我有一个方法应该输出一个包含列表内容的 txt 文件(每行中的每个项目)。列表项是字符串数组。问题是,当我调用 string.Join 时,它返回文字字符串 "System.Strin
一位同事告诉我,使用以下方法: string url = "SomeURL"; string ext = "SomeExt"; string sub = "SomeSub"; string s
给定类: public class CategoryValuePair { String category; String value; } 还有一个方法: public
我正在尝试合并 Stream>>对象与所有 Streams 中的键一起映射到单个映射中. 例如, final Map someObject; final List>> list = someObjec
在这里使用 IDictionary 的值(value)是什么? 最佳答案 使用接口(interface)的值(value)始终相同:切换到另一个后端实现时,您不必更改客户端代码。 请考虑稍后分析您的代
我可以知道这两个字典声明之间的区别吗? var places = [String: String]() var places = [Dictionary()] 为什么当我尝试以这种方式附加声明时,只有
在 .NET 4.0 及更高版本中存在 string.IsNullOrWhiteSpace(string) 时,在检查字符串时使用 string.IsNullOrEmpty(string) 是否被视为
这个名字背后的原因是什么? SS64在 PowerShell 中解释此处的字符串如下: A here string is a single-quoted or double-quoted string
我打算离开 this 文章,尝试编写一个接受字符串和 &str 的函数,但我遇到了问题。我有以下功能: pub fn new(t_num: S) -> BigNum where S: Into {
我有一个结构为 [String: [String: String]] 的多维数组。我可以使用 for 循环到达 [String: String] 位,但我不知道如何访问主键(这个位 [String:
我正在尝试使用 sarama(管理员模式)创建主题。没有 ConfigEntries 工作正常。但我需要定义一些配置。 我设置了主题配置(这里发生了错误): tConfigs := map[s
我是一名优秀的程序员,十分优秀!