2

我有一个方法,给定 a VBComponent,我可以.Designer从那里访问 and.Controls集合:

 private void DeclareControlsAsMembers(VBComponent form)
 {
     var designer = form.Designer;
     if (designer == null)
     {
         return;
     }

      // using dynamic typing here, because not only MSForms could have a Controls collection (e.g. MS-Access forms are 'document' modules).
      foreach (var control in ((dynamic)designer).Controls)
      {
          var declaration = new Declaration(_qualifiedName.QualifyMemberName(control.Name), ...);
          OnNewDeclaration(declaration);
      }
  }

此方法的问题在于,当主机为 MS-Access 时,form.Designernull,因此该方法提前返回。

这里的dynamic演员表并不是特别有用,似乎我可以转换到一个UserForm界面,它会“正常工作”——至少在 Excel 主机中。

但由于 MS-Access 的表单没有设计器 (???),我如何去迭代 MS-Access 表单上的控件,因为 C# 代码是 VBE 加载项(即只能轻松访问任何内容VBIDE API 可用)?

4

2 回答 2

2

除非表单处于打开状态,否则您无法迭代 Access 表单上的控件。打开表单,即使是设计模式,也很昂贵,因为需要呈现控件,并且作为 Access,绑定的属性被解析为数据库对象。还有子表单和子报告的问题。

但是,此 VBA 代码将获取您的 vbComponent,打开表单(如果尚未打开,则在设计模式下),然后从 vbComponent 的 Properties 集合中返回控件集合。如果表格一开始没有打开,那么它就会关闭。

这段代码很容易复制到 Access Reports 中。

Function GetControls() As Access.Controls
  Dim comp As VBIDE.VBComponent
  Dim proj As VBIDE.VBProject
  Dim props As VBIDE.Properties
  Dim bCloseFormWhenDone As Boolean
  Dim formName As String

  Set proj = Application.VBE.ActiveVBProject
  Set comp = proj.VBComponents("Form_Form1")
  On Error Resume Next
  Set props = comp.Properties
  On Error GoTo 0

  If props Is Nothing Then
    bCloseFormWhenDone = True
    'The form is not open, so open it in design mode
    formName = Mid(comp.Name, 6)
    Application.DoCmd.OpenForm formName, acDesign
  End If

  'Get the controls collection
  Set GetControls = comp.Properties("Controls").Object

  'Close the form if it wasn't already open
  If bCloseFormWhenDone Then
    Application.DoCmd.Close acForm, formName
  End If

End Function
于 2016-05-07T03:05:28.183 回答
0

导出模块(使用可爱的Application.SaveAsText未记录功能),并解析内容。ACommandButton看起来像这样:

Begin CommandButton
    OverlapFlags =85
    Left =907
    Top =793
    Width =3118
    Height =1304
    ForeColor =4210752
    Name ="Command0"
    Caption ="Command0"
    OnClick ="[Event Procedure]"
    GUID = Begin
        0x925ed6d615e7594c83313637a6d582f4
    End
    GridlineColor =10921638

    LayoutCachedLeft =907
    LayoutCachedTop =793
    LayoutCachedWidth =4025
    LayoutCachedHeight =2097
    BackColor =15123357
    BorderColor =15123357
    HoverColor =15652797
    PressedColor =11957550
    HoverForeColor =4210752
    PressedForeColor =4210752
    WebImagePaddingLeft =2
    WebImagePaddingTop =2
    WebImagePaddingRight =1
    WebImagePaddingBottom =1
End

您可以检索Name所有控件的属性(以及您喜欢的任何其他属性)的值,甚至可以判断是否OnClick附加到事件处理程序过程。

于 2016-06-01T04:41:25.823 回答