VBA获取字符串的长度,其中包含空行字符,如换行符和回车符

时间:2016-06-27 14:35:06

标签: java excel vba excel-vba

我正在尝试在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的线索。

6 个答案:

答案 0 :(得分:1)

我刚从Notepad ++测试了复制/粘贴,并确认它没有复制回车。

如果您检查您的单元格如下:

Instr(Sheet1.Cells(1,1).Value, vbCrLF)

您会看到0的结果,表明vbCrLFChar(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

enter image description here

编辑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

enter image description here

答案 5 :(得分:0)

这是你想要的吗?

Sub countStr()
   MsgBox (Len(Worksheets("sheet1").Cells(1, 1).Text))
End Sub

count text from cell