检查文本框是否存在vba(使用名称)

时间:2017-05-30 08:25:25

标签: vba

我正在使用Ms-Access,我创建了一个userform,上面有许多Textbox。这些方框名为:Box1,Box2,Box3 ......

我需要遍历所有框,但我不知道哪一个是最后一个。为了避免遍历所有用户窗体控件,我想尝试以下方法:

For i =1 To 20

if Me.Conrtols("Box" & i).value = MyCondition Then

'do stuff

Next i

Box6的错误,这是第一个找不到的框。有没有办法捕获此错误并在发生时退出循环。

我知道我可以使用On Error,但我宁愿用代码捕获这个特定的实例。

谢谢, 乔治

4 个答案:

答案 0 :(得分:2)

Controls集合是一个简化的控件集合(显然),并与控件的展示顺序共享相同的订单。

首先,即使是可创建的集合对象也缺少ExistsContains等方法,因此您需要一个具有错误处理功能来检查/拉取集合中的小部件。

Public Function ExistsWidget(ByVal Name As String) As Boolean
    On Error Resume Next
        ExistsWidget = Not Me.Controls(Name) Is Nothing
    On Error GoTo 0
End Function

如果你真的不喜欢"请求宽恕而不是许可" 选项你可以拉出文本框的整个有序集合(和/或在具有类似逻辑的另一个循环中按名称检查存在)。

Public Function PullBoxes() As Collection
    Dim Control As MSForms.Control

    Set PullBoxes = New Collection

    For Each Control In Me.Controls
        If TypeOf Control Is MSForms.TextBox And _
                Left(Control.Name, 3) = "Box" Then
                Call PullBoxes.Add(Control)
        End If
    Next
End Function

由于窗口小部件的名称是唯一的 - 您可以从该函数返回Dictionary,其中包含(Control.Name,Control)对,并且能够正确地检查窗口小部件的存在而没有错误抑制。 There's Dictionary的良好指南,如果它是您的新信息。

无论如何,无论您选择哪个对象,如果用户(或代码)无法创建更多的文本框 - 您可以将上面的Function转换为Static Property Get或仅转换为{{ 1}}里面有Property Get个集合,所以你只迭代所有控件一次(例如在Static事件上)!

UserForm_Initialize

毕竟,最后创建的名为Public Property Get Boxes() As Collection Static PreservedBoxes As Collection 'There's no loop, but call to PullBoxes to reduce duplicate code in answer If PreservedBoxes Is Nothing Then _ Set PreservedBoxes = PullBoxes Set Boxes = PreservedBoxes End Property 的{​​{1}}将是:

TextBox

我认为现在事情对你来说更清楚了!干杯!

注意:所有代码肯定是表单的一堆方法/属性,因此所有内容都应该放在表单模块中。

答案 1 :(得分:0)

长话短说 - 你无法用VBA做你想做的事。 但是,有一种很好的方法可以解决它 - 使用import {Component} from '@angular/core'; import {AlertController, NavController} from 'ionic-angular'; import {BluetoothSerial} from '@ionic-native/bluetooth-serial'; @Component({ selector: 'page-home', templateUrl: 'home.html' }) export class HomePage { public deviceList:any; constructor(public navCtrl: NavController, private alertCtrl:AlertController, private bluetoothSerial: BluetoothSerial) { this.getAllBluetoothDevices(); } // put BluetoothSerial inside a function, can't be called different getAllBluetoothDevices() { // async so keep everything in this method this.bluetoothSerial.isEnabled().then(data => { if(data){ this.bluetoothSerial.list().then(allDevices=> { // set the list to returned value if(allDevices.length > 0){ this.deviceList=allDevices; }else{ let alert = this.alertCtrl.create({ title: 'Bluetooth', subTitle: 'No devices found.', buttons: ['Dismiss'] }); alert.present(); } }); } }).catch(err=>{ let alert = this.alertCtrl.create({ title: 'Bluetooth', subTitle: 'Check your bluetooth connection.', buttons: ['Dismiss'] }); alert.present(); }); } } 制作一个布尔公式,检查对象是否存在。因此,您的代码不会被它破坏。

On Error

从这里采取:http://www.tek-tips.com/viewthread.cfm?qid=1029435

要查看整个代码是否有效,请按以下方式检查:

Function ControlExists(ControlName As String, FormCheck As Form) As Boolean
   Dim strTest As String
   On Error Resume Next
   strTest = FormCheck(ControlName).Name
   ControlExists = (Err.Number = 0)
End Function

答案 2 :(得分:0)

我建议在下面的另一个程序中测试存在: -

Private Sub Command1_Click()
Dim i As Long

i = 1
Do Until Not BoxExists(i)
    If Me.Conrtols("Box" & i).Value = MyCondition Then
        'Do stuff
    End If
    i = i + 1
Next
End Sub

Private Function BoxExists(ByVal LngID As Long) As Boolean
Dim Ctrl As Control

On Error GoTo ErrorHandle

Set Ctrl = Me.Controls("BoX" & LngID)
Set Ctrl = Nothing

BoxExists = True

Exit Function
ErrorHandle:
Err.Clear
End Function

在上文中,BoxExists仅在框存在时才返回true。

答案 3 :(得分:0)

你在这里采取了不正确的方法。

如果要限制循环,只能在控件所在的部分循环,例如详细。您可以使用ControlType属性将控件限制为TextBox。

Dim ctl As Control
For Each ctl In Me.Detail.Controls
    If ctl.ControlType = acTextBox Then
        If ctl.Value = MyCondition Then
            'do stuff
        End If
    End If
Next ctl

我相信循环比通过辅助函数和On Error Resume Next检查控件名是否存在更快。

但这只是个人意见。