我正在使用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
,但我宁愿用代码捕获这个特定的实例。
谢谢, 乔治
答案 0 :(得分:2)
Controls
集合是一个简化的控件集合(显然),并与控件的展示顺序共享相同的订单。
首先,即使是可创建的集合对象也缺少Exists
或Contains
等方法,因此您需要一个具有错误处理功能来检查/拉取集合中的小部件。
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
检查控件名是否存在更快。
但这只是个人意见。