Excel VBA获取完整的文本框值

我是VBA新手。 我有一个文本框,由条形码扫描器使用Excel填充。 表单上有不同的值,例如:

608001F 608001 001IN 

我需要检查代码是否包含“F”,然后执行某个操作,否则执行另一个操作。 我在Textbox_Change()函数上这样做,导致608001代码被首先触发。 我怎样才能让它首先触发代码中的'F'?

我的代码看起来像这样(为简洁起见编辑,如果有任何语法错误,请原谅):

 Private Sub TextBox1_Change() Value = TextBox1.Value If Value <> "" Then If (Len(Value) = 7 And Right(Value, 1) = "F") Then ActiveCell.Value = Value ActiveSheet.Cells(ActiveCell.Row + 1, 1).Select TextBox1.Value = "" TextBox1.Activate ElseIf (Len(Value) = 6 Or (Len(Value) = 5 And (Right(Value, 2) = "IN" Or Right(Value, 2) = "EM"))) Then ActiveCell.Value = Value Selection.Offset(0, 1).Select TextBox1.Value = "" TextBox1.Activate Else 'Do nothing End If End Sub 

编辑

我决定澄清正在发生的事情。 在使用_Change()函数时,首先满足达到字符6的条件,这意味着代码被视为608001而不是608001F。

与OP澄清后,问题是这样的:

  • 该string不是用户手动input的,而是由一个“作为一个人工作”的代码扫描器逐字母地input;
  • 插入的string可能会触发代码的错误部分,而不会完成。

我想到的一个可能的解决scheme是一个定时器 ,它正在等待代码扫描器将代码写入框中,然后运行代码。 基本上:

声明一个全局variables

记住倒计时是否已经开始

 Dim started As Boolean 

将您的代码写入另一个macros

…将标准代码添加到与Change事件无关的macros:

 Private Sub TextBox1_Change_Personal() '<-- not triggered if TextBox1 is changed! Value = TextBox1.Value If Value <> "" Then If (Len(Value) = 7 And Right(Value, 1) = "F") Then ActiveCell.Value = Value ActiveSheet.Cells(ActiveCell.Row + 1, 1).Select TextBox1.Value = "" TextBox1.Activate ElseIf (Len(Value) = 6 Or (Len(Value) = 5 And (Right(Value, 2) = "IN" Or Right(Value, 2) = "EM"))) Then ActiveCell.Value = Value Selection.Offset(0, 1).Select TextBox1.Value = "" TextBox1.Activate Else 'Do nothing End If started = False '<-- reset control variable for next code End Sub 

3秒后激活macros

…当代码扫描器将开始写入文本框,你“启动倒计时”(基本上,你安排你的个人macros在3秒开始)。 所以,在3秒钟之前,代码扫描器将完成编写代码,而不会陷入同样的​​错误。

 Private Sub TextBox1_Change() If started = False Then Application.OnTime TimeSerial(Hour(Now()), Minute(Now()),Second(Now())+3), "TextBox1_Change_Personal" started = True '<-- deactivating control variable to avoid re-scheduling each time End If End Sub 

当然, 3 seconds是一个模拟值, 你的代码扫描器在写入数据的时候可能会更快(在这种情况下,例如减less到1秒)或者更慢(在这种情况下,例如增加到5秒)。

最后(应该工作)的代码

 Dim started As Boolean Private Sub TextBox1_Change() If started = False Then Application.OnTime TimeSerial(Hour(Now()), Minute(Now()),Second(Now())+3), "TextBox1_Change_Personal" started = True '<-- deactivating control variable to avoid re-scheduling each time End If End Sub Private Sub TextBox1_Change_Personal() '<-- not triggered if TextBox1 is changed! Value = TextBox1.Value If Value <> "" Then If (Len(Value) = 7 And Right(Value, 1) = "F") Then ActiveCell.Value = Value ActiveSheet.Cells(ActiveCell.Row + 1, 1).Select TextBox1.Value = "" TextBox1.Activate ElseIf (Len(Value) = 6 Or (Len(Value) = 5 And (Right(Value, 2) = "IN" Or Right(Value, 2) = "EM"))) Then ActiveCell.Value = Value Selection.Offset(0, 1).Select TextBox1.Value = "" TextBox1.Activate Else 'Do nothing End If started = False '<-- reset control variable for next code End Sub 

是这样,下面的string都在同一个单一的文本框?

 608001F 608001 001IN 

如果是这样的话,使用SPLIT()函数,传入vbcrlf,以获得每个条形码的数组,通过它们的每一行文本和循环。

如果您的意思是文本框一次只保存其中的一个代码,而608001replace608001F,则使用一个私有variables来存储以前的文本框值。

 Private m_earlierBarcodeVal As String Private Sub UserForm_Initialize() m_earlierBarcodeVal = TextBox1.Text End Sub Private Sub TextBox1_Change() MsgBox "Old value= " & m_earlierBarcodeVal & vbCrLf & _ "New value= " & TextBox1.Text m_earlierBarcodeVal = TextBox1.Text End Sub 

您可以使用InStr()函数查找string中是否存在字符,如果该字符不存在,函数返回0。 然后检查返回值是否大于0。

这个简单的例子应该给你一个线索。

 Sub lookForF() Dim inVal As String inVal = Range("A4").Value If InStr(1, inVal, "F") > 0 Then 'Your code here when F exists Else 'Your code here for other case End If End Sub 

如果我理解了你的问题,看来你不希望Change事件被触发,直到你没有给出某种forms的确认来说“我完成了插入值”

在这种情况下,我可能会build议使用" "分隔符编写代码(即,直到您不按SpaceBar来确认插入成功,没有任何反应)。 为了达到这个目的,你只需要添加两行新的代码(见下面的编辑):

 Private Sub TextBox1_Change() Value = TextBox1.Value If Value <> "" Then If Right(Value,1) = " " Then '<-- new line If (Len(Value) = 7 And Right(Value, 1) = "F") Then ActiveCell.Value = Value ActiveSheet.Cells(ActiveCell.Row + 1, 1).Select TextBox1.Value = "" TextBox1.Activate ElseIf (Len(Value) = 6 Or (Len(Value) = 5 And (Right(Value, 2) = "IN" Or Right(Value, 2) = "EM"))) Then ActiveCell.Value = Value Selection.Offset(0, 1).Select TextBox1.Value = "" TextBox1.Activate Else 'Do nothing End If End If '<-- new line End If End Sub 

像那样,你的代码将会像这样工作:

1)你写608001

之前: Len() = 6条件被触发,所以你没有时间最终inputF ;

现在:等待用户确认

2)你写608001F

之前: Len() = 7将被触发,但是您没有时间键入最后一个字符F ;

现在:等待用户确认

3)按SpaceBar – >代码开始运行,你不会混淆6 charstring与7 charstring了。 请注意,按SpaceBar意味着“我正在提交我的条形码”。 这意味着,您可以用任何其他的Chr()集合( Enter ,数字,字母等)replaceSpaceBar字符。

那么这样的事情呢? 在更好地理解问题之后进行编辑(见下面的回复评论):

 Private m_previousBarcodeString As String Private m_isFirstBarcodeEntered As Boolean Private Sub UserForm_Initialize() m_isFirstBarcodeEntered = True ' Some test data only. You don't need to use the rest of this ' method code below as you have a barcode scanner. Dim barcodesArray(2) As String barcodesArray(0) = "608001F" barcodesArray(1) = "608001" barcodesArray(2) = "001IN" Dim barcodeIndex As Integer Dim barcodeCount As Long Dim charIndex As Integer Dim charCount As Integer barcodeCount = UBound(barcodesArray) For barcodeIndex = 0 To barcodeCount charCount = Len(barcodesArray(barcodeIndex)) For charIndex = 1 To charCount TextBox1.Text = TextBox1.Text & Mid(barcodesArray(barcodeIndex), charIndex, 1) Next charIndex TextBox1.Text = "" Next barcodeIndex End Sub Private Sub TextBox1_Change() If (m_isFirstBarcodeEntered = True) Then m_isFirstBarcodeEntered = False Else If Len(TextBox1.Text) = 0 Then MsgBox "Was '" & m_previousBarcodeString & "' ending in 'F'?: " & _ UCase(isValidBarcode(m_previousBarcodeString)) Else m_previousBarcodeString = TextBox1.Text End If End If End Sub Private Function isValidBarcode(ByVal singleBarcodesString As String) As Boolean isValidBarcode = False If Len(singleBarcodesString) = 7 Then If UCase(Right(singleBarcodesString, 1)) = "F" Then isValidBarcode = True End If End If End Function