使用 vb.net 统计 TextBox 中出现的所有 vbCrLf
Using vb.net Count all occurrences of vbCrLf in TextBox
我有一个文本框,我正在尝试计算 vbCrLf
.
的所有出现次数
计数正常,问题是每次发出 vbCrLf
我想从某个整数中减去 33。
现在写的代码只减去vbCrLf
的数字,而不是数字+33。
问题是每次按下 Enter 键并发出 vbCrLf 时如何减去 33?
我已经发布了更新的代码问题得到了回答和问题已解决
我还添加了额外的代码来增强 TextBox
的管理
您将需要这些导入
进口 System.IO
进口 System.Text
Public Class frmThree
Dim path As String = "C:/Users/Me/source/repos/TestForms/TestForms/Resource/"
Dim total As Integer
Dim vbLfTotal As Integer
Dim chrPermited As Integer = 333 'chrPermited
Private Sub btnBack_Click(sender As Object, e As EventArgs) Handles btnBack.Click
Me.Close()
frmOne.Show()
End Sub
Private Sub tbHaveOne_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tbHaveOne.TextChanged
Dim spaceCount, letterCount, carReturn As Integer
spaceCount = 0
letterCount = 0
carReturn = 0
Dim str As String = tbHaveOne.Text
For Each chr As Char In str
If chr = vbLf Then
carReturn += 1
ElseIf Char.IsLetterOrDigit(chr) Then
letterCount += 1
ElseIf Char.IsWhiteSpace(chr) Then
spaceCount += 1
End If
Next
vbLfTotal = carReturn * 29
total = chrPermited - letterCount - spaceCount - vbLfTotal
tbHaveTwo.ForeColor = Color.Black
tbHaveTwo.Text = total & " More Character Can Be Entered"
While total < 10
tbHaveTwo.Clear()
tbHaveTwo.ForeColor = Color.Red
tbHaveTwo.Text = "Only " & total & " More Character Can Be Entered"
Exit While
End While
If total = 5 Then
PlaySystemSound()
End If
If total < 1 Then
tbHaveTwo.Clear()
tbHaveTwo.Text = "No More Data Entry" & total
Call ansQ()
End If
End Sub
Sub PlaySystemSound()
My.Computer.Audio.PlaySystemSound(
System.Media.SystemSounds.Hand)
End Sub
Public Sub ansQ()
Const Msg As String = "YES Save Data" + vbCrLf + vbNewLine + "NO CANCEL"
Const Title As String = "Save or Exit"
Const Style = vbYesNo + vbQuestion + vbDefaultButton2
Dim result = MsgBox(Msg, Style, Title)
If result = vbYes Then
Call writeDATA()
ElseIf result = vbNo Then
'tbHaveOne.ReadOnly = True
'tbHaveOne.Enabled = False
tbHaveTwo.Text = "NO Was Selected"
'result = 0
End If
End Sub
Public Shared Sub tbHaveOne_KeyDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles tbHaveOne.KeyDown
'NOTE this Sub is Shared It seems to run all the time like a listener
If e.KeyCode = Keys.Enter And frmThree.total < 40 Then
e.SuppressKeyPress = True
End If
End Sub
您无法检查当前字符是否为vbcrlf,因为CRLF 是两个字符。只需检查 LF,这样,如果您曾经在 unix 系统准备的文件上使用逻辑,它仍然有效(unix 有 LF,Windows 有 CRLF)
Private Sub tbHaveOne_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tbHaveOne.TextChanged
Dim spaceCount = 0
Dim letterCount = 0
Dim lineCount = 0
For Each c As Char In tbHaveOne.Text
If c = vbLf Then
lineCount += 1
ElseIf Char.IsLetterOrDigit(c) Then
letterCount += 1
ElseIf Char.IsWhiteSpace(c) Then
spaceCount += 1
End If
Next c
someInteger -= (lineCount * 33)
System.Char 具有检查字符是否在特定 Unicode 范围内的静态方法 - 对于您的字母计数,您正在计算任何不是 space 的字符,包括回车符 returns,标点符号和其他不是字母的东西,作为字母。如果你愿意,你可以继续这样做,但如果你对换行符进行三次计数,可能会导致一些混乱的计数
The counting is working the issue is every time a vbCrLf is issued I would like to subtract 33 from some Integer
The code as written now only subtracts the number of vbCrLf NOT the number + 33
我不太明白。你说你想在每次换行时减去 33,这就是我所做的。第二句读起来好像要求是从 someInteger 中减去(新行数 + 33)。如果这是您想要执行的操作,请将最后一行的 * 更改为 +
Question is how to subtract 33 every time the Enter Key is pressed and a vbCrLf is issued ?
这与"count all occurrences of"完全不同;这与计算文本框中的行数无关,并且您无法通过此类代码来完成。计算用户在文本框中按下 enter 的次数需要一个钩子,该事件是在文本框具有焦点时用户按下某个键时引发的事件。为 KeyPress 或 KeyDown 事件添加处理程序:
Private Sub tbHaveOne_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles tbHaveOne.KeyPress 'KeyEventArgs for KeyDown event
If e.KeyChar = vbCr Then 'use e.KeyCode = Keys.Enter in KeyDown event
someInteger -= 33
End If
End Sub
TextBox.Lines.Count
returns 换行符分隔的行数(ControlChars.NewLine 或 Environment.NewLine 当您按下 Enter 键时。)而不是多行 TextBox 中换行的行数。如果设置WordWrap property to False
you will see the difference. See the TextBoxBase.Lines备注部分。
如果您需要获取行数,无论它们是自动换行还是分隔换行,您可以调用 SendMessage 方法和 EM_GETLINECOUNT
消息:
Imports System.Runtime.InteropServices
Private Const EM_GETLINECOUNT As UInteger = &HBA
<DllImport("user32.dll")>
Private Shared Function SendMessage(ByVal hWnd As IntPtr,
ByVal msg As Integer,
ByVal wp As IntPtr,
ByVal lp As IntPtr) As IntPtr
End Function
Private Sub PrintCounts()
Dim c = tbHaveOne.Text.
Aggregate(New With {
.WhiteSpaces = 0, .Lf = 0, .NewLines = 0, .Lines = 0, .Others = 0
},
Function(x, y)
x.Lf += If(y = ControlChars.Cr, 1, 0)
x.WhiteSpaces += If(Char.IsSeparator(y), 1, 0)
x.Others += If(Not Char.IsWhiteSpace(y), 1, 0)
Return x
End Function)
c.NewLines = tbHaveOne.Lines.Count
c.Lines = SendMessage(tbHaveOne.Handle, EM_GETLINECOUNT,
IntPtr.Zero, IntPtr.Zero).ToInt32
tbHaveTwo.Text = $"WhiteSpaces: {c.WhiteSpaces} Lf: {c.Lf} " +
$"New Lines: {c.NewLines} Lines {c.Lines} Others: {c.Others}"
End Sub
Private Sub tbHaveOne_TextChanged(sender As Object,
e As EventArgs) Handles tbHaveOne.TextChanged
PrintCounts()
End Sub
请注意:
我们对这个问题有很多很好的讨论和固定答案
讨论中的一个问题是如何处理标点符号和特殊字符
我们想提供此代码作为管理标点符号和特殊字符的方法
Dim spaceCount, letterCount, carReturn, punCount, syCount As Integer
spaceCount = 0
letterCount = 0
carReturn = 0
punCount = 0
syCount = 0
Dim str As String = tbHaveOne.Text
For Each chr As Char In str
If chr = vbLf Then
carReturn += 1
ElseIf Char.IsLetterOrDigit(chr) Then
letterCount += 1
ElseIf Char.IsWhiteSpace(chr) Then
spaceCount += 1
ElseIf Char.IsPunctuation(chr) Then
punCount += 1
ElseIf Char.IsSymbol(chr) Then
syCount += 1
End If
Next
vbLfTotal = carReturn * 29
total = chrPermited - letterCount - spaceCount - vbLfTotal - punCount - syCount
tbHaveTwo.ForeColor = Color.Black
tbHaveTwo.Text = total & " More Character Can Be Entered"
我有一个文本框,我正在尝试计算 vbCrLf
.
计数正常,问题是每次发出 vbCrLf
我想从某个整数中减去 33。
现在写的代码只减去vbCrLf
的数字,而不是数字+33。
问题是每次按下 Enter 键并发出 vbCrLf 时如何减去 33?
我已经发布了更新的代码问题得到了回答和问题已解决
我还添加了额外的代码来增强 TextBox
的管理
您将需要这些导入
进口 System.IO
进口 System.Text
Public Class frmThree
Dim path As String = "C:/Users/Me/source/repos/TestForms/TestForms/Resource/"
Dim total As Integer
Dim vbLfTotal As Integer
Dim chrPermited As Integer = 333 'chrPermited
Private Sub btnBack_Click(sender As Object, e As EventArgs) Handles btnBack.Click
Me.Close()
frmOne.Show()
End Sub
Private Sub tbHaveOne_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tbHaveOne.TextChanged
Dim spaceCount, letterCount, carReturn As Integer
spaceCount = 0
letterCount = 0
carReturn = 0
Dim str As String = tbHaveOne.Text
For Each chr As Char In str
If chr = vbLf Then
carReturn += 1
ElseIf Char.IsLetterOrDigit(chr) Then
letterCount += 1
ElseIf Char.IsWhiteSpace(chr) Then
spaceCount += 1
End If
Next
vbLfTotal = carReturn * 29
total = chrPermited - letterCount - spaceCount - vbLfTotal
tbHaveTwo.ForeColor = Color.Black
tbHaveTwo.Text = total & " More Character Can Be Entered"
While total < 10
tbHaveTwo.Clear()
tbHaveTwo.ForeColor = Color.Red
tbHaveTwo.Text = "Only " & total & " More Character Can Be Entered"
Exit While
End While
If total = 5 Then
PlaySystemSound()
End If
If total < 1 Then
tbHaveTwo.Clear()
tbHaveTwo.Text = "No More Data Entry" & total
Call ansQ()
End If
End Sub
Sub PlaySystemSound()
My.Computer.Audio.PlaySystemSound(
System.Media.SystemSounds.Hand)
End Sub
Public Sub ansQ()
Const Msg As String = "YES Save Data" + vbCrLf + vbNewLine + "NO CANCEL"
Const Title As String = "Save or Exit"
Const Style = vbYesNo + vbQuestion + vbDefaultButton2
Dim result = MsgBox(Msg, Style, Title)
If result = vbYes Then
Call writeDATA()
ElseIf result = vbNo Then
'tbHaveOne.ReadOnly = True
'tbHaveOne.Enabled = False
tbHaveTwo.Text = "NO Was Selected"
'result = 0
End If
End Sub
Public Shared Sub tbHaveOne_KeyDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles tbHaveOne.KeyDown
'NOTE this Sub is Shared It seems to run all the time like a listener
If e.KeyCode = Keys.Enter And frmThree.total < 40 Then
e.SuppressKeyPress = True
End If
End Sub
您无法检查当前字符是否为vbcrlf,因为CRLF 是两个字符。只需检查 LF,这样,如果您曾经在 unix 系统准备的文件上使用逻辑,它仍然有效(unix 有 LF,Windows 有 CRLF)
Private Sub tbHaveOne_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tbHaveOne.TextChanged
Dim spaceCount = 0
Dim letterCount = 0
Dim lineCount = 0
For Each c As Char In tbHaveOne.Text
If c = vbLf Then
lineCount += 1
ElseIf Char.IsLetterOrDigit(c) Then
letterCount += 1
ElseIf Char.IsWhiteSpace(c) Then
spaceCount += 1
End If
Next c
someInteger -= (lineCount * 33)
System.Char 具有检查字符是否在特定 Unicode 范围内的静态方法 - 对于您的字母计数,您正在计算任何不是 space 的字符,包括回车符 returns,标点符号和其他不是字母的东西,作为字母。如果你愿意,你可以继续这样做,但如果你对换行符进行三次计数,可能会导致一些混乱的计数
The counting is working the issue is every time a vbCrLf is issued I would like to subtract 33 from some Integer The code as written now only subtracts the number of vbCrLf NOT the number + 33
我不太明白。你说你想在每次换行时减去 33,这就是我所做的。第二句读起来好像要求是从 someInteger 中减去(新行数 + 33)。如果这是您想要执行的操作,请将最后一行的 * 更改为 +
Question is how to subtract 33 every time the Enter Key is pressed and a vbCrLf is issued ?
这与"count all occurrences of"完全不同;这与计算文本框中的行数无关,并且您无法通过此类代码来完成。计算用户在文本框中按下 enter 的次数需要一个钩子,该事件是在文本框具有焦点时用户按下某个键时引发的事件。为 KeyPress 或 KeyDown 事件添加处理程序:
Private Sub tbHaveOne_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles tbHaveOne.KeyPress 'KeyEventArgs for KeyDown event
If e.KeyChar = vbCr Then 'use e.KeyCode = Keys.Enter in KeyDown event
someInteger -= 33
End If
End Sub
TextBox.Lines.Count
returns 换行符分隔的行数(ControlChars.NewLine 或 Environment.NewLine 当您按下 Enter 键时。)而不是多行 TextBox 中换行的行数。如果设置WordWrap property to False
you will see the difference. See the TextBoxBase.Lines备注部分。
如果您需要获取行数,无论它们是自动换行还是分隔换行,您可以调用 SendMessage 方法和 EM_GETLINECOUNT
消息:
Imports System.Runtime.InteropServices
Private Const EM_GETLINECOUNT As UInteger = &HBA
<DllImport("user32.dll")>
Private Shared Function SendMessage(ByVal hWnd As IntPtr,
ByVal msg As Integer,
ByVal wp As IntPtr,
ByVal lp As IntPtr) As IntPtr
End Function
Private Sub PrintCounts()
Dim c = tbHaveOne.Text.
Aggregate(New With {
.WhiteSpaces = 0, .Lf = 0, .NewLines = 0, .Lines = 0, .Others = 0
},
Function(x, y)
x.Lf += If(y = ControlChars.Cr, 1, 0)
x.WhiteSpaces += If(Char.IsSeparator(y), 1, 0)
x.Others += If(Not Char.IsWhiteSpace(y), 1, 0)
Return x
End Function)
c.NewLines = tbHaveOne.Lines.Count
c.Lines = SendMessage(tbHaveOne.Handle, EM_GETLINECOUNT,
IntPtr.Zero, IntPtr.Zero).ToInt32
tbHaveTwo.Text = $"WhiteSpaces: {c.WhiteSpaces} Lf: {c.Lf} " +
$"New Lines: {c.NewLines} Lines {c.Lines} Others: {c.Others}"
End Sub
Private Sub tbHaveOne_TextChanged(sender As Object,
e As EventArgs) Handles tbHaveOne.TextChanged
PrintCounts()
End Sub
请注意:
我们对这个问题有很多很好的讨论和固定答案
讨论中的一个问题是如何处理标点符号和特殊字符
我们想提供此代码作为管理标点符号和特殊字符的方法
Dim spaceCount, letterCount, carReturn, punCount, syCount As Integer
spaceCount = 0
letterCount = 0
carReturn = 0
punCount = 0
syCount = 0
Dim str As String = tbHaveOne.Text
For Each chr As Char In str
If chr = vbLf Then
carReturn += 1
ElseIf Char.IsLetterOrDigit(chr) Then
letterCount += 1
ElseIf Char.IsWhiteSpace(chr) Then
spaceCount += 1
ElseIf Char.IsPunctuation(chr) Then
punCount += 1
ElseIf Char.IsSymbol(chr) Then
syCount += 1
End If
Next
vbLfTotal = carReturn * 29
total = chrPermited - letterCount - spaceCount - vbLfTotal - punCount - syCount
tbHaveTwo.ForeColor = Color.Black
tbHaveTwo.Text = total & " More Character Can Be Entered"