我正在尝试在Excel中将Excel列截断为特定长度。
但LEN
函数似乎不会将\n and \r
视为单个字符。
是否有任何其他功能可以给出确切的字符串长度?
例如,我试图在单元格中获取跟随字符串的长度。 (a\r\nb\r\nc\r\nd
)
a
b
c
d
获取长度的代码。
print len( replace(replace(sheet1.Cells(1,1).value, chr(10), "-" ), chr(13), "#"))
输出:
7
字符串的实际长度为10
。
修改
我终于明白了。它与空格字符无关,但与其他一些特殊的Unicode字符无关。
VBA LEN
函数和Java String.length()
方法不会给出字符串的大小,但会给出字符数。由于Oracle使用字节长度作为列的实际大小(varchar(50) means 50 bytes
),因此即使在截断后也不允许插入字符串。
我最后使用以下代码截断Java端的字符串,因为我无法在VBA中找到任何方法。
stringBytes = strCellValue.getBytes("UTF-8");
stringLength = stringBytes.length;
strCellValue = new String( stringBytes, 0, maxCellWidth, "UTF-8");
cell.setCellValue(strCellValue);
感谢David Zemens和P57的线索。
答案 0 :(得分:1)
我刚从Notepad ++测试了复制/粘贴,并确认它没有复制回车。
如果您检查您的单元格如下:
Instr(Sheet1.Cells(1,1).Value, vbCrLF)
您会看到0
的结果,表明vbCrLF
(Char(10) & Char(13)
)根本不存在于单元格中。剪贴板必须以某种方式改变文本流。
因此,Excel 中字符串的实际长度仅为7。
要解决此问题,请将换行符转换为vbCr & vbLf
:
Debug.Print Len(Replace(sheet1.Cells(1,1).value, vbLF, vbCR & vbLF))
注意:这可能不是一刀切的方法,它假设所有行Feed应该被强制转移到回车+行饲料。您的里程数可能会有所不同。
建议不是从Notepad ++复制/粘贴,而是直接将文本文件作为TextStream对象使用到VBA ......
答案 1 :(得分:1)
我仍然很好奇为什么如果从Java中读取Excel值,您的示例中的字符数为10。
此代码可以进一步了解Excel范围如何复制回剪贴板。它真的看起来像粘贴到单元格后回车已经消失了,而且复制后,实际的剪贴板文本包含引用并且有" \ n \ r"附加,但没有原始\r
字符的痕迹。
Sub CellStringCheck()
'Copy cell to clipboard
Range("A1").Copy
'Get clipboard contents directly
Dim obj As MSForms.DataObject
Set obj = New MSForms.DataObject
obj.GetFromClipboard
'Convert to string and set object to nothing
Dim s As String
s = obj.GetText
Set obj = Nothing
'Print Information
Debug.Print "___________________"
Debug.Print "String: "
Debug.Print s
Debug.Print "Len = " & Len(s)
Debug.Print "Characters:"
On Error Resume Next
For i = 1 To Len(s)
Debug.Print AscW(Mid(s, i, 1))
Next
End Sub
如果我将A\n\rA
粘贴到范围A1中,则此代码会生成以下内容:
___________________
String:
"A
A "
Len = 7
Characters:
34
65
10
65
34
13
10
如果您将此剪贴板内容粘贴回NP ++,则会获得所有引文,但NP ++会自动将单独的\n
转换回\n\r
,显然是单独的,因为它不属于剪贴板内容。
我想知道这是否与剪贴板格式为VbCFText有关,但如果VBA处理剪贴板粘贴,那么没有问题。如下所示,不会删除任何回车符:
Sub CellStringCheck()
'Set clipboard contents
Dim obj As MSForms.DataObject
Set obj = New MSForms.DataObject
obj.SetText vbLf & vbCr
obj.PutInClipboard
'Copy cell to clipboard
obj.GetFromClipboard
Range("A1") = obj.GetText
Range("A1").Copy
'Get clipboard contents directly
obj.GetFromClipboard
'Convert to string and set object to nothing
Dim s As String
s = obj.GetText
'Print Information
Debug.Print "___________________"
Debug.Print obj.GetFormat(1)
Debug.Print "String: "
Debug.Print s
Debug.Print "Len = " & Len(s)
Debug.Print "Characters:"
On Error Resume Next
For i = 1 To Len(s)
Debug.Print AscW(Mid(s, i, 1))
Next
Set obj = Nothing
End Sub
所以,所有这一切,我还是不确定为什么如果直接从Java读取单元格值,你根本找不到回车符,但如果你要通过剪贴板,那么你可能会拿起附加的回车。显然,Excel和NP ++在粘贴时会自己进行字符串处理。 Excel删除回车符,而NP ++将\n
转换为\n\r
。如果你直接通过剪贴板,这不会发生,所以我怀疑它与应用程序级事件处理有关。我没有测试直接读取或写入.Net或Java的值,但我猜测直接访问值可以避免这个问题。另一项解决方法是对Environment.NewLine
的任何实例使用\n\r
或强制\n
。
答案 2 :(得分:0)
我怀疑这是最好的答案;事实上,我对此非常肯定,但是一种相当复杂的方法是在使用Len
函数之前,对回车符和新行进行替换。像
for i = 1 to 10
cells(i,1) = Replace(Cells(i,1), Char(10), "-") 'newline Chr(10)
cells(i,1) = Replace(cells(i,1), Char(13), "-") 'carriage return Chr(13)
next i
然后你会有一个短划线,其中有换行符和回车符,并且可以将Len
应用于相关单元格以获得全长。
答案 3 :(得分:0)
你能给出一个你的字符串的例子。
Const vcr As String = "L" & vbCr & _
"n" & vbCr & _
"." & vbCr & _
"."
Const vlf As String = "L" & vbLf & _
"n" & vbLf & _
"." & vbLf & _
"."
Const vslashn As String = "l\nn\n.\n."
len(vcr) gives 7
len(vlf) gives 7
Dim vslashnConverted As String
vslashnConverted = Replace(vslashn, "\n", crlf)
Len(vslashn) : 10
Len(vslashnConverted) : 4
答案 4 :(得分:0)
使用此功能获得所需的结果
注意:认为\ r和\ n是两个不同的字符
Public Function getlength(d As Range) As Long
getlength = WorksheetFunction.Sum((Len(d) - Len(WorksheetFunction.Substitute(d, "\r", ""))) / 2, (Len(d) - Len(WorksheetFunction.Substitute(d, "\n", ""))) / 2, Len(WorksheetFunction.Substitute(WorksheetFunction.Substitute(d, "\r", ""), "\n", "")))
End Function
编辑1:
注意:下面的功能被认为\ r \ n为单个字符
Public Function getlength(d As Range) As Long
getlength = WorksheetFunction.Sum((Len(d) - Len(WorksheetFunction.Substitute(d, "\r\n", ""))) / 4, Len(WorksheetFunction.Substitute(d, "\r\n", "")))
End Function
答案 5 :(得分:0)
这是你想要的吗?
Sub countStr()
MsgBox (Len(Worksheets("sheet1").Cells(1, 1).Text))
End Sub