Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/vba/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java VBA获取带有空格字符的字符串长度,如新行和回车符_Java_Vba_Excel - Fatal编程技术网

Java VBA获取带有空格字符的字符串长度,如新行和回车符

Java VBA获取带有空格字符的字符串长度,如新行和回车符,java,vba,excel,Java,Vba,Excel,我试图在VBA中将Excel列截断到一定长度 但是LEN函数似乎不将\n和\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.GetFromClipb

我试图在VBA中将Excel列截断到一定长度

但是
LEN
函数似乎不将
\n和\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\r\nb\r\nc\r\nd

获取长度的代码

print len( replace(replace(sheet1.Cells(1,1).value, chr(10), "-" ), chr(13), "#"))
输出:

7
字符串的实际长度为
10

编辑

我终于明白了。它与空白字符无关,而是与其他一些特殊的Unicode字符有关

 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
VBA
LEN
函数和Java
String.length()
方法不提供字符串的大小,而是提供字符的计数。由于Oracle使用字节长度作为列的实际大小(
varchar(50)表示50字节
),因此即使在截断后也不允许插入字符串

我最终使用以下代码在Java端截断字符串,因为我在VBA中找不到任何方法来这样做

stringBytes = strCellValue.getBytes("UTF-8");
stringLength = stringBytes.length;

strCellValue = new String( stringBytes, 0, maxCellWidth, "UTF-8");
cell.setCellValue(strCellValue);

感谢David Zemens和P57提供的线索。

我怀疑这是最好的答案;事实上,我很确定,但一个相当复杂的方法是在使用
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
应用于相关单元格以获得完整长度。

您可以给出一个字符串示例吗

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

使用此功能可获得所需的结果

注意:考虑到\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

这就是你想要的吗

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

我刚刚测试了Notepad++的复制/粘贴功能,并确认它没有复制回车符

如果您检查手机,如:

Instr(表1.单元格(1,1).值,vbCrLF)

您将看到
0
的结果,表明
vbCrLF
Char(10)&Char(13)
)在单元格中根本不存在。剪贴板必须以某种方式更改文本流

所以Excel中字符串的实际长度只有7

要解决此问题,请将换行符转换为
vbCr&vbLf

Debug.Print Len(Replace(sheet1.Cells(1,1).value, vbLF, vbCR & vbLF))
注意:这可能不是一刀切的方法,它假设所有换行都应强制为回车+换行。你的里程可能会有所不同


建议不要从记事本++复制/粘贴文本文件,而直接将文本文件作为TextStream对象使用到VBA…

我仍然很好奇,如果从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
或force
\n\r
来处理
\n

的任何实例,如果您知道要剪切字符串的长度,请尝试
应用程序.Worksheetfunction.LEFT(字符串,#您要保留的字符)
它也会这样做,它不考虑空白字符。我需要将Excel发送到服务器,JDBC将其放入Oracle表中。使用了字符串的精确大小。您确定
Len
没有为您计算这些字符吗?这对我来说是2
Len(ChrW(10)&ChrW(13))
我正在从
notepad++
复制文本,选中时显示文本长度<代码>记事本+也计算特殊字符。我还尝试通过使用Javascript打印来复制字符串。在记事本中,我可以将
\r\n
替换为
#%
,它会给我
a#%b#%c#%d
Aww,复制并粘贴到Excel是非常重要的细节!您的回车符(字符代码13)在该点丢失,不再包含在单元格中的字符串值中。我已经想到了这一点,不幸的是第一行一次性替换了
\n和\r
。OK。我以为你想把它们都换掉?我是说,
\r\n
被认为是单个字符。因此,如果它们连续出现,它们将被视为一个。我想你可以替换组合
Replace(…,char(10)和char(13),“-”
@11thdimension再一次,您的实际字符串处理是可疑的<