【问题标题】:VBA Excel Interface implementation and inheritance issuesVBA Excel 接口实现和继承问题
【发布时间】:2021-06-24 17:36:51
【问题描述】:

我的任务有点复杂,首先我告诉你问题,然后我尝试了什么以及我迷路的地方。

假设我有三个工作表(A、B、C)。这些床单有一张桌子。该表的标题具有相似和不同的名称。另外标题的位置不同,顺序很重要:

  • 工作表表标题:AA、BB、CC、DD、FF
  • B 表表标题:BB、AA、DD、EE
  • C 表表标题:AA、DD、BB、CC

我的代码中有不同的模块(Module1、Module2、...)。这些模块分配给工作表。所以:

  • Module1,Module2 -> 一张表
  • Module3、Module4 -> B 表
  • Module5、Module6 -> C 表

原样功能是这些模块对表标题的列名具有静态引用 ->

  • Module1 和 Module2 'know' 工作表“A”中的标题“DD”位于“D”列。
  • Module3 和 Module4 'know' 工作表“B”中的标题“DD”位于“C”列。
  • Module5 和 Module6 “知道”工作表“C”中的标题“DD”位于“B”列。
  • 等等....

我的问题是当我必须在任何工作表中添加一个新标题时,这是一种痛苦 ->

  • Sheet A 新标题 -> AA、BB、XX、CC、DD、FF

此时的原样功能是,由于新标题,我必须调试与工作表“A”相关的所有模块以更改列引用。在上面的示例中,我必须更改每个模块(Module1 和 Module2)中的标题 CC、DD、FF 列引用。

所以我尝试设计一些集中的列引用存储,在其中放置与每张工作表相关的标题的列引用。模块从该存储中检索列信息,因此如果随时弹出新标题,我必须在此处更改标题的列引用。看起来我真的很喜欢编码:D

我最初的想法是为每个工作表创建一个 ClassModule。这个类模块会有公共功能,标题列的引用是什么->

Function titleDDinsheetA() As String
   titleDDinsheetA = "D"
End Function 

但正如您在示例中看到的那样,存在相似的标题名称,例如“AA”存在于所有工作表中。所以我计划创建一个接口来确保每个常见的标题都会出现在每个类模块实现中。所以->

接口称为 ICommonTitles

Option Explicit

Public Function titleDD()
End Function

工作表 A 的类模块称为 SheetATitles

Option Explicit
Implements ICommonTitles

Public Function ICommonTitles_titleDD()
    ICommonTitles_titleDD = "D"
End Function

但是正如您在上面的标题结构中看到的那样,我有工作表指定标题,例如工作表 A 中的 FF。还有所有工作表的子集中存在的标题 -> 工作表 A 和 C 中存在标题 CC。所以我尝试将自定义公共函数添加到 SheetATtitles 类模块,例如 ->

Option Explicit
Implements ICommonTitles

Public Function ICommonTitles_titleDD()
  ICommonTitles_titleDD = "D"
End Function

Public Function titleCC()
  titleCC = "C"
End Function

此时我开始遇到错误。上面的例子给出了这个:

Sub test()
  Dim testcls As ICommonTitles 
  Set testcls = New SheetATitles

  MsgBox testcls.titleDD
  MsgBox testcls.titleCC
End Sub

此时我在 MsgBox testcls.titleCC 行遇到了类似 Method or data member not found 的错误。我试图将实例更改为:

Sub test()
  Dim test_cls As SheetATitles
  Set test_cls = New SheetATitles

  MsgBox testcls.titleDD
  MsgBox testcls.titleCC
End Sub

此时我遇到了同样的错误,但在 MsgBox test_cls.titleDD 行

我尝试做一些类似接口继承的事情。所以我创建了一个特定于工作表的接口,并在 SheetATTitles 中实现了它。所以:

接口称为 ICommonTitles

Option Explicit

Public Function titleDD()
End Function

接口称为 ISheetATTitles

Option Explicit
Implements ICommonTitles

Public Function ICommonTitles_titleDD()
End Function

Public Function titleCC()
End Function

工作表 A 的类模块称为 SheetATitles

Option Explicit
Implements ISheetATitles

Public Function ISheetATitles_ICommonTitles_titleDD()
  ISheetATitles_ICommonTitles_titleDD = "D"
End Function

Public Function ISheetATitles_titleCC()
  ISheetATitles_titleCC="C"
End Function

但此时我得到了编译错误,例如:对象模块需要为接口 ISheetATitles 实现 ICommonTitles_titleDD

所以我在这一点上迷路了:D 首先,当我在类模块中实现一个接口时,我根本不明白为什么我不能在类模块中创建自定义公共函数。我也不明白为什么会出现上述错误。此外,我来自编程世界的 Java 方面,还没有深入了解 VBA,所以我可能会错过一些基本的东西。

各位有什么想法吗?

rgds,

'孩子

【问题讨论】:

  • 下划线是 VBA 界面中的重要分隔符。它不应出现在除接口和方法名称之间的任何方法名称中,因此应将诸如“Call_me_if_You_Can”之类的方法名称重命名为“CallMeIfYouCan”
  • @freeflow 信息!我的确切代码在方法命名方式上略有不同。我更新了问题以显示更像原始问题。
  • @Nathan_Sav 你能描述一下我在哪里可以在我的问题中使用 MATCH 函数吗?我没明白.. :(
  • application.WorksheetFunction.Match("DD",rows(1),false)

标签: excel vba inheritance interface instantiation


【解决方案1】:

更简单的方法:

Enum Sheet1Headers
    AA = 1
    BB = 2
    CC = 3
End Enum

Enum Sheet2Headers
    AA = 1
    BB = 3
    CC = 5
    DD = 7
End Enum

Enum Sheet3Headers
    AA = 1
    BB = 3
    XX = 4
    DD = 7
End Enum

然后你可以这样做:

With Sheet1.Cells(2, Sheet1Headers.AA)

如果您还想选择使用列字母:

Function Letter(v As Long)
    Letter = Replace(Cells(1, v).Address(False, False), "1", "")
End Function

然后:

? letter(Sheet2Headers.BB)  'C

【讨论】:

  • 这解决了我的问题!只有一件事:我不能在枚举常量中添加字母,而是在数字中添加字母。因此,如果我想要列的字母引用,我需要一个转换,如:Split(Cells(, Sheet1Headers.AA).Address, "$")(1)
  • 是的,枚举值必须是数字,但与 Cells 一起工作正常
  • 没错,我只是不想将我的 Range() 相关代码更改为 Cells()。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多